2 use rustc_ast::tokenstream::{DelimSpan, TokenStream};
4 use rustc_expand::base::*;
5 use rustc_span::edition::Edition;
6 use rustc_span::symbol::sym;
9 /// This expands to either
10 /// - `$crate::panic::panic_2015!(...)` or
11 /// - `$crate::panic::panic_2021!(...)`
12 /// depending on the edition.
14 /// This is used for both std::panic!() and core::panic!().
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<'_>,
22 ) -> Box<dyn MacResult + 'cx> {
23 let mac = if use_panic_2021(sp) { sym::panic_2021 } else { sym::panic_2015 };
24 expand(mac, cx, sp, tts)
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<'_>,
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)
41 mac: rustc_span::Symbol,
42 cx: &'cx mut ExtCtxt<'_>,
45 ) -> Box<dyn MacResult + 'cx> {
46 let sp = cx.with_call_site_ctxt(sp);
51 ExprKind::MacCall(P(MacCall {
55 .std_path(&[sym::panic, mac])
57 .map(|ident| PathSegment::from_ident(ident))
62 dspan: DelimSpan::from_single(sp),
63 delim: MacDelimiter::Parenthesis,
66 prior_type_ascription: None,
72 pub fn use_panic_2021(mut span: Span) -> bool {
73 // To determine the edition, we check the first span up the expansion
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.)
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;
84 break expn.edition >= Edition::Edition2021;