]>
Commit | Line | Data |
---|---|---|
5869c6ff XL |
1 | use rustc_ast::ptr::P; |
2 | use rustc_ast::tokenstream::{DelimSpan, TokenStream}; | |
3 | use rustc_ast::*; | |
4 | use rustc_expand::base::*; | |
dc3f5686 | 5 | use rustc_span::edition::Edition; |
5869c6ff XL |
6 | use rustc_span::symbol::sym; |
7 | use rustc_span::Span; | |
8 | ||
9 | // This expands to either | |
10 | // - `$crate::panic::panic_2015!(...)` or | |
11 | // - `$crate::panic::panic_2021!(...)` | |
12 | // depending on the edition. | |
13 | // | |
14 | // This is used for both std::panic!() and core::panic!(). | |
15 | // | |
16 | // `$crate` will refer to either the `std` or `core` crate depending on which | |
17 | // one we're expanding from. | |
18 | pub fn expand_panic<'cx>( | |
19 | cx: &'cx mut ExtCtxt<'_>, | |
20 | sp: Span, | |
21 | tts: TokenStream, | |
22 | ) -> Box<dyn MacResult + 'cx> { | |
a2a8927a XL |
23 | let mac = if use_panic_2021(sp) { sym::panic_2021 } else { sym::panic_2015 }; |
24 | expand(mac, cx, sp, tts) | |
25 | } | |
5869c6ff | 26 | |
a2a8927a XL |
27 | // This expands to either |
28 | // - `$crate::panic::unreachable_2015!(...)` or | |
29 | // - `$crate::panic::unreachable_2021!(...)` | |
30 | // depending on the edition. | |
31 | pub fn expand_unreachable<'cx>( | |
32 | cx: &'cx mut ExtCtxt<'_>, | |
33 | sp: Span, | |
34 | tts: TokenStream, | |
35 | ) -> Box<dyn MacResult + 'cx> { | |
36 | let mac = if use_panic_2021(sp) { sym::unreachable_2021 } else { sym::unreachable_2015 }; | |
37 | expand(mac, cx, sp, tts) | |
38 | } | |
39 | ||
40 | fn expand<'cx>( | |
41 | mac: rustc_span::Symbol, | |
42 | cx: &'cx mut ExtCtxt<'_>, | |
43 | sp: Span, | |
44 | tts: TokenStream, | |
45 | ) -> Box<dyn MacResult + 'cx> { | |
5869c6ff XL |
46 | let sp = cx.with_call_site_ctxt(sp); |
47 | ||
48 | MacEager::expr( | |
49 | cx.expr( | |
50 | sp, | |
f2b60f7d | 51 | ExprKind::MacCall(P(MacCall { |
5869c6ff XL |
52 | path: Path { |
53 | span: sp, | |
54 | segments: cx | |
a2a8927a | 55 | .std_path(&[sym::panic, mac]) |
5869c6ff XL |
56 | .into_iter() |
57 | .map(|ident| PathSegment::from_ident(ident)) | |
58 | .collect(), | |
59 | tokens: None, | |
60 | }, | |
61 | args: P(MacArgs::Delimited( | |
62 | DelimSpan::from_single(sp), | |
63 | MacDelimiter::Parenthesis, | |
64 | tts, | |
65 | )), | |
66 | prior_type_ascription: None, | |
f2b60f7d | 67 | })), |
5869c6ff XL |
68 | ), |
69 | ) | |
70 | } | |
dc3f5686 XL |
71 | |
72 | pub fn use_panic_2021(mut span: Span) -> bool { | |
5e7ed085 | 73 | // To determine the edition, we check the first span up the expansion |
dc3f5686 XL |
74 | // stack that does not have #[allow_internal_unstable(edition_panic)]. |
75 | // (To avoid using the edition of e.g. the assert!() or debug_assert!() definition.) | |
76 | loop { | |
77 | let expn = span.ctxt().outer_expn_data(); | |
78 | if let Some(features) = expn.allow_internal_unstable { | |
79 | if features.iter().any(|&f| f == sym::edition_panic) { | |
80 | span = expn.call_site; | |
81 | continue; | |
82 | } | |
83 | } | |
84 | break expn.edition >= Edition::Edition2021; | |
85 | } | |
86 | } |