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