rustc_builtin_macros/
edition_panic.rs1use rustc_ast::token::Delimiter;
2use rustc_ast::tokenstream::{DelimSpan, TokenStream};
3use rustc_ast::*;
4use rustc_expand::base::*;
5use rustc_span::edition::Edition;
6use rustc_span::{Span, sym};
7
8pub(crate) fn expand_panic<'cx>(
18 cx: &'cx mut ExtCtxt<'_>,
19 sp: Span,
20 tts: TokenStream,
21) -> MacroExpanderResult<'cx> {
22 let mac = if use_panic_2021(sp) { sym::panic_2021 } else { sym::panic_2015 };
23 expand(mac, cx, sp, tts)
24}
25
26pub(crate) fn expand_unreachable<'cx>(
31 cx: &'cx mut ExtCtxt<'_>,
32 sp: Span,
33 tts: TokenStream,
34) -> MacroExpanderResult<'cx> {
35 let mac = if use_panic_2021(sp) { sym::unreachable_2021 } else { sym::unreachable_2015 };
36 expand(mac, cx, sp, tts)
37}
38
39fn expand<'cx>(
40 mac: rustc_span::Symbol,
41 cx: &'cx ExtCtxt<'_>,
42 sp: Span,
43 tts: TokenStream,
44) -> MacroExpanderResult<'cx> {
45 let sp = cx.with_call_site_ctxt(sp);
46
47 ExpandResult::Ready(MacEager::expr(
48 cx.expr(
49 sp,
50 ExprKind::MacCall(Box::new(MacCall {
51 path: Path {
52 span: sp,
53 segments: cx
54 .std_path(&[sym::panic, mac])
55 .into_iter()
56 .map(|ident| PathSegment::from_ident(ident))
57 .collect(),
58 tokens: None,
59 },
60 args: Box::new(DelimArgs {
61 dspan: DelimSpan::from_single(sp),
62 delim: Delimiter::Parenthesis,
63 tokens: tts,
64 }),
65 })),
66 ),
67 ))
68}
69
70pub(crate) fn use_panic_2021(mut span: Span) -> bool {
71 loop {
75 let expn = span.ctxt().outer_expn_data();
76 if let Some(features) = expn.allow_internal_unstable
77 && features.contains(&sym::edition_panic)
78 {
79 span = expn.call_site;
80 continue;
81 }
82 break expn.edition >= Edition::Edition2021;
83 }
84}