1use std::any::Any;
2use std::default::Default;
3use std::iter;
4use std::path::Component::Prefix;
5use std::path::{Path, PathBuf};
6use std::rc::Rc;
7use std::sync::Arc;
8
9use rustc_ast::attr::{AttributeExt, MarkedAttrs};
10use rustc_ast::ptr::P;
11use rustc_ast::token::MetaVarKind;
12use rustc_ast::tokenstream::TokenStream;
13use rustc_ast::visit::{AssocCtxt, Visitor};
14use rustc_ast::{self as ast, AttrVec, Attribute, HasAttrs, Item, NodeId, PatKind};
15use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
16use rustc_data_structures::sync;
17use rustc_errors::{DiagCtxtHandle, ErrorGuaranteed, PResult};
18use rustc_feature::Features;
19use rustc_hir as hir;
20use rustc_hir::attrs::{AttributeKind, CfgEntry, Deprecation};
21use rustc_hir::{Stability, find_attr};
22use rustc_lint_defs::{BufferedEarlyLint, RegisteredTools};
23use rustc_parse::MACRO_ARGUMENTS;
24use rustc_parse::parser::{ForceCollect, Parser};
25use rustc_session::config::CollapseMacroDebuginfo;
26use rustc_session::parse::ParseSess;
27use rustc_session::{Limit, Session};
28use rustc_span::def_id::{CrateNum, DefId, LocalDefId};
29use rustc_span::edition::Edition;
30use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId, MacroKind};
31use rustc_span::source_map::SourceMap;
32use rustc_span::{DUMMY_SP, FileName, Ident, Span, Symbol, kw, sym};
33use smallvec::{SmallVec, smallvec};
34use thin_vec::ThinVec;
35
36use crate::base::ast::MetaItemInner;
37use crate::errors;
38use crate::expand::{self, AstFragment, Invocation};
39use crate::mbe::macro_rules::ParserAnyMacro;
40use crate::module::DirOwnership;
41use crate::stats::MacroStat;
42
43#[derive(Debug, Clone)]
47pub enum Annotatable {
48 Item(P<ast::Item>),
49 AssocItem(P<ast::AssocItem>, AssocCtxt),
50 ForeignItem(P<ast::ForeignItem>),
51 Stmt(P<ast::Stmt>),
52 Expr(P<ast::Expr>),
53 Arm(ast::Arm),
54 ExprField(ast::ExprField),
55 PatField(ast::PatField),
56 GenericParam(ast::GenericParam),
57 Param(ast::Param),
58 FieldDef(ast::FieldDef),
59 Variant(ast::Variant),
60 WherePredicate(ast::WherePredicate),
61 Crate(ast::Crate),
62}
63
64impl Annotatable {
65 pub fn span(&self) -> Span {
66 match self {
67 Annotatable::Item(item) => item.span,
68 Annotatable::AssocItem(assoc_item, _) => assoc_item.span,
69 Annotatable::ForeignItem(foreign_item) => foreign_item.span,
70 Annotatable::Stmt(stmt) => stmt.span,
71 Annotatable::Expr(expr) => expr.span,
72 Annotatable::Arm(arm) => arm.span,
73 Annotatable::ExprField(field) => field.span,
74 Annotatable::PatField(fp) => fp.pat.span,
75 Annotatable::GenericParam(gp) => gp.ident.span,
76 Annotatable::Param(p) => p.span,
77 Annotatable::FieldDef(sf) => sf.span,
78 Annotatable::Variant(v) => v.span,
79 Annotatable::WherePredicate(wp) => wp.span,
80 Annotatable::Crate(c) => c.spans.inner_span,
81 }
82 }
83
84 pub fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) {
85 match self {
86 Annotatable::Item(item) => item.visit_attrs(f),
87 Annotatable::AssocItem(assoc_item, _) => assoc_item.visit_attrs(f),
88 Annotatable::ForeignItem(foreign_item) => foreign_item.visit_attrs(f),
89 Annotatable::Stmt(stmt) => stmt.visit_attrs(f),
90 Annotatable::Expr(expr) => expr.visit_attrs(f),
91 Annotatable::Arm(arm) => arm.visit_attrs(f),
92 Annotatable::ExprField(field) => field.visit_attrs(f),
93 Annotatable::PatField(fp) => fp.visit_attrs(f),
94 Annotatable::GenericParam(gp) => gp.visit_attrs(f),
95 Annotatable::Param(p) => p.visit_attrs(f),
96 Annotatable::FieldDef(sf) => sf.visit_attrs(f),
97 Annotatable::Variant(v) => v.visit_attrs(f),
98 Annotatable::WherePredicate(wp) => wp.visit_attrs(f),
99 Annotatable::Crate(c) => c.visit_attrs(f),
100 }
101 }
102
103 pub fn visit_with<'a, V: Visitor<'a>>(&'a self, visitor: &mut V) -> V::Result {
104 match self {
105 Annotatable::Item(item) => visitor.visit_item(item),
106 Annotatable::AssocItem(item, ctxt) => visitor.visit_assoc_item(item, *ctxt),
107 Annotatable::ForeignItem(foreign_item) => visitor.visit_foreign_item(foreign_item),
108 Annotatable::Stmt(stmt) => visitor.visit_stmt(stmt),
109 Annotatable::Expr(expr) => visitor.visit_expr(expr),
110 Annotatable::Arm(arm) => visitor.visit_arm(arm),
111 Annotatable::ExprField(field) => visitor.visit_expr_field(field),
112 Annotatable::PatField(fp) => visitor.visit_pat_field(fp),
113 Annotatable::GenericParam(gp) => visitor.visit_generic_param(gp),
114 Annotatable::Param(p) => visitor.visit_param(p),
115 Annotatable::FieldDef(sf) => visitor.visit_field_def(sf),
116 Annotatable::Variant(v) => visitor.visit_variant(v),
117 Annotatable::WherePredicate(wp) => visitor.visit_where_predicate(wp),
118 Annotatable::Crate(c) => visitor.visit_crate(c),
119 }
120 }
121
122 pub fn to_tokens(&self) -> TokenStream {
123 match self {
124 Annotatable::Item(node) => TokenStream::from_ast(node),
125 Annotatable::AssocItem(node, _) => TokenStream::from_ast(node),
126 Annotatable::ForeignItem(node) => TokenStream::from_ast(node),
127 Annotatable::Stmt(node) => {
128 assert!(!matches!(node.kind, ast::StmtKind::Empty));
129 TokenStream::from_ast(node)
130 }
131 Annotatable::Expr(node) => TokenStream::from_ast(node),
132 Annotatable::Arm(..)
133 | Annotatable::ExprField(..)
134 | Annotatable::PatField(..)
135 | Annotatable::GenericParam(..)
136 | Annotatable::Param(..)
137 | Annotatable::FieldDef(..)
138 | Annotatable::Variant(..)
139 | Annotatable::WherePredicate(..)
140 | Annotatable::Crate(..) => panic!("unexpected annotatable"),
141 }
142 }
143
144 pub fn expect_item(self) -> P<ast::Item> {
145 match self {
146 Annotatable::Item(i) => i,
147 _ => panic!("expected Item"),
148 }
149 }
150
151 pub fn expect_trait_item(self) -> P<ast::AssocItem> {
152 match self {
153 Annotatable::AssocItem(i, AssocCtxt::Trait) => i,
154 _ => panic!("expected Item"),
155 }
156 }
157
158 pub fn expect_impl_item(self) -> P<ast::AssocItem> {
159 match self {
160 Annotatable::AssocItem(i, AssocCtxt::Impl { .. }) => i,
161 _ => panic!("expected Item"),
162 }
163 }
164
165 pub fn expect_foreign_item(self) -> P<ast::ForeignItem> {
166 match self {
167 Annotatable::ForeignItem(i) => i,
168 _ => panic!("expected foreign item"),
169 }
170 }
171
172 pub fn expect_stmt(self) -> ast::Stmt {
173 match self {
174 Annotatable::Stmt(stmt) => *stmt,
175 _ => panic!("expected statement"),
176 }
177 }
178
179 pub fn expect_expr(self) -> P<ast::Expr> {
180 match self {
181 Annotatable::Expr(expr) => expr,
182 _ => panic!("expected expression"),
183 }
184 }
185
186 pub fn expect_arm(self) -> ast::Arm {
187 match self {
188 Annotatable::Arm(arm) => arm,
189 _ => panic!("expected match arm"),
190 }
191 }
192
193 pub fn expect_expr_field(self) -> ast::ExprField {
194 match self {
195 Annotatable::ExprField(field) => field,
196 _ => panic!("expected field"),
197 }
198 }
199
200 pub fn expect_pat_field(self) -> ast::PatField {
201 match self {
202 Annotatable::PatField(fp) => fp,
203 _ => panic!("expected field pattern"),
204 }
205 }
206
207 pub fn expect_generic_param(self) -> ast::GenericParam {
208 match self {
209 Annotatable::GenericParam(gp) => gp,
210 _ => panic!("expected generic parameter"),
211 }
212 }
213
214 pub fn expect_param(self) -> ast::Param {
215 match self {
216 Annotatable::Param(param) => param,
217 _ => panic!("expected parameter"),
218 }
219 }
220
221 pub fn expect_field_def(self) -> ast::FieldDef {
222 match self {
223 Annotatable::FieldDef(sf) => sf,
224 _ => panic!("expected struct field"),
225 }
226 }
227
228 pub fn expect_variant(self) -> ast::Variant {
229 match self {
230 Annotatable::Variant(v) => v,
231 _ => panic!("expected variant"),
232 }
233 }
234
235 pub fn expect_where_predicate(self) -> ast::WherePredicate {
236 match self {
237 Annotatable::WherePredicate(wp) => wp,
238 _ => panic!("expected where predicate"),
239 }
240 }
241
242 pub fn expect_crate(self) -> ast::Crate {
243 match self {
244 Annotatable::Crate(krate) => krate,
245 _ => panic!("expected krate"),
246 }
247 }
248}
249
250pub enum ExpandResult<T, U> {
253 Ready(T),
255 Retry(U),
257}
258
259impl<T, U> ExpandResult<T, U> {
260 pub fn map<E, F: FnOnce(T) -> E>(self, f: F) -> ExpandResult<E, U> {
261 match self {
262 ExpandResult::Ready(t) => ExpandResult::Ready(f(t)),
263 ExpandResult::Retry(u) => ExpandResult::Retry(u),
264 }
265 }
266}
267
268impl<'cx> MacroExpanderResult<'cx> {
269 pub fn from_tts(
273 cx: &'cx mut ExtCtxt<'_>,
274 tts: TokenStream,
275 site_span: Span,
276 arm_span: Span,
277 macro_ident: Ident,
278 ) -> Self {
279 let is_local = true;
281
282 let parser = ParserAnyMacro::from_tts(cx, tts, site_span, arm_span, is_local, macro_ident);
283 ExpandResult::Ready(Box::new(parser))
284 }
285}
286
287pub trait MultiItemModifier {
288 fn expand(
290 &self,
291 ecx: &mut ExtCtxt<'_>,
292 span: Span,
293 meta_item: &ast::MetaItem,
294 item: Annotatable,
295 is_derive_const: bool,
296 ) -> ExpandResult<Vec<Annotatable>, Annotatable>;
297}
298
299impl<F> MultiItemModifier for F
300where
301 F: Fn(&mut ExtCtxt<'_>, Span, &ast::MetaItem, Annotatable) -> Vec<Annotatable>,
302{
303 fn expand(
304 &self,
305 ecx: &mut ExtCtxt<'_>,
306 span: Span,
307 meta_item: &ast::MetaItem,
308 item: Annotatable,
309 _is_derive_const: bool,
310 ) -> ExpandResult<Vec<Annotatable>, Annotatable> {
311 ExpandResult::Ready(self(ecx, span, meta_item, item))
312 }
313}
314
315pub trait BangProcMacro {
316 fn expand<'cx>(
317 &self,
318 ecx: &'cx mut ExtCtxt<'_>,
319 span: Span,
320 ts: TokenStream,
321 ) -> Result<TokenStream, ErrorGuaranteed>;
322}
323
324impl<F> BangProcMacro for F
325where
326 F: Fn(TokenStream) -> TokenStream,
327{
328 fn expand<'cx>(
329 &self,
330 _ecx: &'cx mut ExtCtxt<'_>,
331 _span: Span,
332 ts: TokenStream,
333 ) -> Result<TokenStream, ErrorGuaranteed> {
334 Ok(self(ts))
336 }
337}
338
339pub trait AttrProcMacro {
340 fn expand<'cx>(
341 &self,
342 ecx: &'cx mut ExtCtxt<'_>,
343 span: Span,
344 annotation: TokenStream,
345 annotated: TokenStream,
346 ) -> Result<TokenStream, ErrorGuaranteed>;
347}
348
349impl<F> AttrProcMacro for F
350where
351 F: Fn(TokenStream, TokenStream) -> TokenStream,
352{
353 fn expand<'cx>(
354 &self,
355 _ecx: &'cx mut ExtCtxt<'_>,
356 _span: Span,
357 annotation: TokenStream,
358 annotated: TokenStream,
359 ) -> Result<TokenStream, ErrorGuaranteed> {
360 Ok(self(annotation, annotated))
362 }
363}
364
365pub trait TTMacroExpander: Any {
367 fn expand<'cx>(
368 &self,
369 ecx: &'cx mut ExtCtxt<'_>,
370 span: Span,
371 input: TokenStream,
372 ) -> MacroExpanderResult<'cx>;
373}
374
375pub type MacroExpanderResult<'cx> = ExpandResult<Box<dyn MacResult + 'cx>, ()>;
376
377pub type MacroExpanderFn =
378 for<'cx> fn(&'cx mut ExtCtxt<'_>, Span, TokenStream) -> MacroExpanderResult<'cx>;
379
380impl<F: 'static> TTMacroExpander for F
381where
382 F: for<'cx> Fn(&'cx mut ExtCtxt<'_>, Span, TokenStream) -> MacroExpanderResult<'cx>,
383{
384 fn expand<'cx>(
385 &self,
386 ecx: &'cx mut ExtCtxt<'_>,
387 span: Span,
388 input: TokenStream,
389 ) -> MacroExpanderResult<'cx> {
390 self(ecx, span, input)
391 }
392}
393
394pub trait GlobDelegationExpander {
395 fn expand(&self, ecx: &mut ExtCtxt<'_>) -> ExpandResult<Vec<(Ident, Option<Ident>)>, ()>;
396}
397
398macro_rules! make_stmts_default {
400 ($me:expr) => {
401 $me.make_expr().map(|e| {
402 smallvec![ast::Stmt {
403 id: ast::DUMMY_NODE_ID,
404 span: e.span,
405 kind: ast::StmtKind::Expr(e),
406 }]
407 })
408 };
409}
410
411pub trait MacResult {
414 fn make_expr(self: Box<Self>) -> Option<P<ast::Expr>> {
416 None
417 }
418
419 fn make_items(self: Box<Self>) -> Option<SmallVec<[P<ast::Item>; 1]>> {
421 None
422 }
423
424 fn make_impl_items(self: Box<Self>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
426 None
427 }
428
429 fn make_trait_impl_items(self: Box<Self>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
431 None
432 }
433
434 fn make_trait_items(self: Box<Self>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
436 None
437 }
438
439 fn make_foreign_items(self: Box<Self>) -> Option<SmallVec<[P<ast::ForeignItem>; 1]>> {
441 None
442 }
443
444 fn make_pat(self: Box<Self>) -> Option<P<ast::Pat>> {
446 None
447 }
448
449 fn make_stmts(self: Box<Self>) -> Option<SmallVec<[ast::Stmt; 1]>> {
454 make_stmts_default!(self)
455 }
456
457 fn make_ty(self: Box<Self>) -> Option<P<ast::Ty>> {
458 None
459 }
460
461 fn make_arms(self: Box<Self>) -> Option<SmallVec<[ast::Arm; 1]>> {
462 None
463 }
464
465 fn make_expr_fields(self: Box<Self>) -> Option<SmallVec<[ast::ExprField; 1]>> {
466 None
467 }
468
469 fn make_pat_fields(self: Box<Self>) -> Option<SmallVec<[ast::PatField; 1]>> {
470 None
471 }
472
473 fn make_generic_params(self: Box<Self>) -> Option<SmallVec<[ast::GenericParam; 1]>> {
474 None
475 }
476
477 fn make_params(self: Box<Self>) -> Option<SmallVec<[ast::Param; 1]>> {
478 None
479 }
480
481 fn make_field_defs(self: Box<Self>) -> Option<SmallVec<[ast::FieldDef; 1]>> {
482 None
483 }
484
485 fn make_variants(self: Box<Self>) -> Option<SmallVec<[ast::Variant; 1]>> {
486 None
487 }
488
489 fn make_where_predicates(self: Box<Self>) -> Option<SmallVec<[ast::WherePredicate; 1]>> {
490 None
491 }
492
493 fn make_crate(self: Box<Self>) -> Option<ast::Crate> {
494 unreachable!()
496 }
497}
498
499macro_rules! make_MacEager {
500 ( $( $fld:ident: $t:ty, )* ) => {
501 #[derive(Default)]
504 pub struct MacEager {
505 $(
506 pub $fld: Option<$t>,
507 )*
508 }
509
510 impl MacEager {
511 $(
512 pub fn $fld(v: $t) -> Box<dyn MacResult> {
513 Box::new(MacEager {
514 $fld: Some(v),
515 ..Default::default()
516 })
517 }
518 )*
519 }
520 }
521}
522
523make_MacEager! {
524 expr: P<ast::Expr>,
525 pat: P<ast::Pat>,
526 items: SmallVec<[P<ast::Item>; 1]>,
527 impl_items: SmallVec<[P<ast::AssocItem>; 1]>,
528 trait_items: SmallVec<[P<ast::AssocItem>; 1]>,
529 foreign_items: SmallVec<[P<ast::ForeignItem>; 1]>,
530 stmts: SmallVec<[ast::Stmt; 1]>,
531 ty: P<ast::Ty>,
532}
533
534impl MacResult for MacEager {
535 fn make_expr(self: Box<Self>) -> Option<P<ast::Expr>> {
536 self.expr
537 }
538
539 fn make_items(self: Box<Self>) -> Option<SmallVec<[P<ast::Item>; 1]>> {
540 self.items
541 }
542
543 fn make_impl_items(self: Box<Self>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
544 self.impl_items
545 }
546
547 fn make_trait_impl_items(self: Box<Self>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
548 self.impl_items
549 }
550
551 fn make_trait_items(self: Box<Self>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
552 self.trait_items
553 }
554
555 fn make_foreign_items(self: Box<Self>) -> Option<SmallVec<[P<ast::ForeignItem>; 1]>> {
556 self.foreign_items
557 }
558
559 fn make_stmts(self: Box<Self>) -> Option<SmallVec<[ast::Stmt; 1]>> {
560 match self.stmts.as_ref().map_or(0, |s| s.len()) {
561 0 => make_stmts_default!(self),
562 _ => self.stmts,
563 }
564 }
565
566 fn make_pat(self: Box<Self>) -> Option<P<ast::Pat>> {
567 if let Some(p) = self.pat {
568 return Some(p);
569 }
570 if let Some(e) = self.expr {
571 if matches!(e.kind, ast::ExprKind::Lit(_) | ast::ExprKind::IncludedBytes(_)) {
572 return Some(P(ast::Pat {
573 id: ast::DUMMY_NODE_ID,
574 span: e.span,
575 kind: PatKind::Expr(e),
576 tokens: None,
577 }));
578 }
579 }
580 None
581 }
582
583 fn make_ty(self: Box<Self>) -> Option<P<ast::Ty>> {
584 self.ty
585 }
586}
587
588#[derive(Copy, Clone)]
591pub struct DummyResult {
592 guar: Option<ErrorGuaranteed>,
593 span: Span,
594}
595
596impl DummyResult {
597 pub fn any(span: Span, guar: ErrorGuaranteed) -> Box<dyn MacResult + 'static> {
602 Box::new(DummyResult { guar: Some(guar), span })
603 }
604
605 pub fn any_valid(span: Span) -> Box<dyn MacResult + 'static> {
607 Box::new(DummyResult { guar: None, span })
608 }
609
610 pub fn raw_expr(sp: Span, guar: Option<ErrorGuaranteed>) -> P<ast::Expr> {
612 P(ast::Expr {
613 id: ast::DUMMY_NODE_ID,
614 kind: if let Some(guar) = guar {
615 ast::ExprKind::Err(guar)
616 } else {
617 ast::ExprKind::Tup(ThinVec::new())
618 },
619 span: sp,
620 attrs: ast::AttrVec::new(),
621 tokens: None,
622 })
623 }
624}
625
626impl MacResult for DummyResult {
627 fn make_expr(self: Box<DummyResult>) -> Option<P<ast::Expr>> {
628 Some(DummyResult::raw_expr(self.span, self.guar))
629 }
630
631 fn make_pat(self: Box<DummyResult>) -> Option<P<ast::Pat>> {
632 Some(P(ast::Pat {
633 id: ast::DUMMY_NODE_ID,
634 kind: PatKind::Wild,
635 span: self.span,
636 tokens: None,
637 }))
638 }
639
640 fn make_items(self: Box<DummyResult>) -> Option<SmallVec<[P<ast::Item>; 1]>> {
641 Some(SmallVec::new())
642 }
643
644 fn make_impl_items(self: Box<DummyResult>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
645 Some(SmallVec::new())
646 }
647
648 fn make_trait_impl_items(self: Box<DummyResult>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
649 Some(SmallVec::new())
650 }
651
652 fn make_trait_items(self: Box<DummyResult>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
653 Some(SmallVec::new())
654 }
655
656 fn make_foreign_items(self: Box<Self>) -> Option<SmallVec<[P<ast::ForeignItem>; 1]>> {
657 Some(SmallVec::new())
658 }
659
660 fn make_stmts(self: Box<DummyResult>) -> Option<SmallVec<[ast::Stmt; 1]>> {
661 Some(smallvec![ast::Stmt {
662 id: ast::DUMMY_NODE_ID,
663 kind: ast::StmtKind::Expr(DummyResult::raw_expr(self.span, self.guar)),
664 span: self.span,
665 }])
666 }
667
668 fn make_ty(self: Box<DummyResult>) -> Option<P<ast::Ty>> {
669 Some(P(ast::Ty {
673 id: ast::DUMMY_NODE_ID,
674 kind: ast::TyKind::Tup(ThinVec::new()),
675 span: self.span,
676 tokens: None,
677 }))
678 }
679
680 fn make_arms(self: Box<DummyResult>) -> Option<SmallVec<[ast::Arm; 1]>> {
681 Some(SmallVec::new())
682 }
683
684 fn make_expr_fields(self: Box<DummyResult>) -> Option<SmallVec<[ast::ExprField; 1]>> {
685 Some(SmallVec::new())
686 }
687
688 fn make_pat_fields(self: Box<DummyResult>) -> Option<SmallVec<[ast::PatField; 1]>> {
689 Some(SmallVec::new())
690 }
691
692 fn make_generic_params(self: Box<DummyResult>) -> Option<SmallVec<[ast::GenericParam; 1]>> {
693 Some(SmallVec::new())
694 }
695
696 fn make_params(self: Box<DummyResult>) -> Option<SmallVec<[ast::Param; 1]>> {
697 Some(SmallVec::new())
698 }
699
700 fn make_field_defs(self: Box<DummyResult>) -> Option<SmallVec<[ast::FieldDef; 1]>> {
701 Some(SmallVec::new())
702 }
703
704 fn make_variants(self: Box<DummyResult>) -> Option<SmallVec<[ast::Variant; 1]>> {
705 Some(SmallVec::new())
706 }
707
708 fn make_crate(self: Box<DummyResult>) -> Option<ast::Crate> {
709 Some(ast::Crate {
710 attrs: Default::default(),
711 items: Default::default(),
712 spans: Default::default(),
713 id: ast::DUMMY_NODE_ID,
714 is_placeholder: Default::default(),
715 })
716 }
717}
718
719#[derive(Clone)]
721pub enum SyntaxExtensionKind {
722 Bang(
724 Arc<dyn BangProcMacro + sync::DynSync + sync::DynSend>,
726 ),
727
728 LegacyBang(
730 Arc<dyn TTMacroExpander + sync::DynSync + sync::DynSend>,
732 ),
733
734 Attr(
736 Arc<dyn AttrProcMacro + sync::DynSync + sync::DynSend>,
740 ),
741
742 LegacyAttr(
744 Arc<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
748 ),
749
750 NonMacroAttr,
755
756 Derive(
758 Arc<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
766 ),
767
768 LegacyDerive(
770 Arc<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
773 ),
774
775 GlobDelegation(Arc<dyn GlobDelegationExpander + sync::DynSync + sync::DynSend>),
777}
778
779pub struct SyntaxExtension {
781 pub kind: SyntaxExtensionKind,
783 pub span: Span,
785 pub allow_internal_unstable: Option<Arc<[Symbol]>>,
787 pub stability: Option<Stability>,
789 pub deprecation: Option<Deprecation>,
791 pub helper_attrs: Vec<Symbol>,
793 pub edition: Edition,
795 pub builtin_name: Option<Symbol>,
798 pub allow_internal_unsafe: bool,
800 pub local_inner_macros: bool,
802 pub collapse_debuginfo: bool,
805}
806
807impl SyntaxExtension {
808 pub fn macro_kind(&self) -> MacroKind {
810 match self.kind {
811 SyntaxExtensionKind::Bang(..)
812 | SyntaxExtensionKind::LegacyBang(..)
813 | SyntaxExtensionKind::GlobDelegation(..) => MacroKind::Bang,
814 SyntaxExtensionKind::Attr(..)
815 | SyntaxExtensionKind::LegacyAttr(..)
816 | SyntaxExtensionKind::NonMacroAttr => MacroKind::Attr,
817 SyntaxExtensionKind::Derive(..) | SyntaxExtensionKind::LegacyDerive(..) => {
818 MacroKind::Derive
819 }
820 }
821 }
822
823 pub fn default(kind: SyntaxExtensionKind, edition: Edition) -> SyntaxExtension {
825 SyntaxExtension {
826 span: DUMMY_SP,
827 allow_internal_unstable: None,
828 stability: None,
829 deprecation: None,
830 helper_attrs: Vec::new(),
831 edition,
832 builtin_name: None,
833 kind,
834 allow_internal_unsafe: false,
835 local_inner_macros: false,
836 collapse_debuginfo: false,
837 }
838 }
839
840 fn collapse_debuginfo_by_name(
841 attr: &impl AttributeExt,
842 ) -> Result<CollapseMacroDebuginfo, Span> {
843 let list = attr.meta_item_list();
844 let Some([MetaItemInner::MetaItem(item)]) = list.as_deref() else {
845 return Err(attr.span());
846 };
847 if !item.is_word() {
848 return Err(item.span);
849 }
850
851 match item.name() {
852 Some(sym::no) => Ok(CollapseMacroDebuginfo::No),
853 Some(sym::external) => Ok(CollapseMacroDebuginfo::External),
854 Some(sym::yes) => Ok(CollapseMacroDebuginfo::Yes),
855 _ => Err(item.path.span),
856 }
857 }
858
859 fn get_collapse_debuginfo(sess: &Session, attrs: &[hir::Attribute], ext: bool) -> bool {
866 let flag = sess.opts.cg.collapse_macro_debuginfo;
867 let attr = ast::attr::find_by_name(attrs, sym::collapse_debuginfo)
868 .and_then(|attr| {
869 Self::collapse_debuginfo_by_name(attr)
870 .map_err(|span| {
871 sess.dcx().emit_err(errors::CollapseMacroDebuginfoIllegal { span })
872 })
873 .ok()
874 })
875 .unwrap_or_else(|| {
876 if find_attr!(attrs, AttributeKind::RustcBuiltinMacro { .. }) {
877 CollapseMacroDebuginfo::Yes
878 } else {
879 CollapseMacroDebuginfo::Unspecified
880 }
881 });
882 #[rustfmt::skip]
883 let collapse_table = [
884 [false, false, false, false],
885 [false, ext, ext, true],
886 [false, ext, ext, true],
887 [true, true, true, true],
888 ];
889 collapse_table[flag as usize][attr as usize]
890 }
891
892 pub fn new(
895 sess: &Session,
896 kind: SyntaxExtensionKind,
897 span: Span,
898 helper_attrs: Vec<Symbol>,
899 edition: Edition,
900 name: Symbol,
901 attrs: &[hir::Attribute],
902 is_local: bool,
903 ) -> SyntaxExtension {
904 let allow_internal_unstable =
905 find_attr!(attrs, AttributeKind::AllowInternalUnstable(i, _) => i)
906 .map(|i| i.as_slice())
907 .unwrap_or_default();
908 let allow_internal_unsafe =
911 ast::attr::find_by_name(attrs, sym::allow_internal_unsafe).is_some();
912
913 let local_inner_macros = ast::attr::find_by_name(attrs, sym::macro_export)
914 .and_then(|macro_export| macro_export.meta_item_list())
915 .is_some_and(|l| ast::attr::list_contains_name(&l, sym::local_inner_macros));
916 let collapse_debuginfo = Self::get_collapse_debuginfo(sess, attrs, !is_local);
917 tracing::debug!(?name, ?local_inner_macros, ?collapse_debuginfo, ?allow_internal_unsafe);
918
919 let (builtin_name, helper_attrs) = match find_attr!(attrs, AttributeKind::RustcBuiltinMacro { builtin_name, helper_attrs, .. } => (builtin_name, helper_attrs))
920 {
921 Some((Some(name), helper_attrs)) => {
924 (Some(*name), helper_attrs.iter().copied().collect())
925 }
926 Some((None, _)) => (Some(name), Vec::new()),
927
928 None => (None, helper_attrs),
930 };
931
932 let stability = find_attr!(attrs, AttributeKind::Stability { stability, .. } => *stability);
933
934 if let Some(sp) = find_attr!(attrs, AttributeKind::ConstStability { span, .. } => *span) {
936 sess.dcx().emit_err(errors::MacroConstStability {
937 span: sp,
938 head_span: sess.source_map().guess_head_span(span),
939 });
940 }
941 if let Some(sp) = find_attr!(attrs, AttributeKind::BodyStability{ span, .. } => *span) {
942 sess.dcx().emit_err(errors::MacroBodyStability {
943 span: sp,
944 head_span: sess.source_map().guess_head_span(span),
945 });
946 }
947
948 SyntaxExtension {
949 kind,
950 span,
951 allow_internal_unstable: (!allow_internal_unstable.is_empty())
952 .then(|| allow_internal_unstable.iter().map(|i| i.0).collect::<Vec<_>>().into()),
954 stability,
955 deprecation: find_attr!(
956 attrs,
957 AttributeKind::Deprecation { deprecation, .. } => *deprecation
958 ),
959 helper_attrs,
960 edition,
961 builtin_name,
962 allow_internal_unsafe,
963 local_inner_macros,
964 collapse_debuginfo,
965 }
966 }
967
968 pub fn dummy_bang(edition: Edition) -> SyntaxExtension {
970 fn expander<'cx>(
971 cx: &'cx mut ExtCtxt<'_>,
972 span: Span,
973 _: TokenStream,
974 ) -> MacroExpanderResult<'cx> {
975 ExpandResult::Ready(DummyResult::any(
976 span,
977 cx.dcx().span_delayed_bug(span, "expanded a dummy bang macro"),
978 ))
979 }
980 SyntaxExtension::default(SyntaxExtensionKind::LegacyBang(Arc::new(expander)), edition)
981 }
982
983 pub fn dummy_derive(edition: Edition) -> SyntaxExtension {
985 fn expander(
986 _: &mut ExtCtxt<'_>,
987 _: Span,
988 _: &ast::MetaItem,
989 _: Annotatable,
990 ) -> Vec<Annotatable> {
991 Vec::new()
992 }
993 SyntaxExtension::default(SyntaxExtensionKind::Derive(Arc::new(expander)), edition)
994 }
995
996 pub fn non_macro_attr(edition: Edition) -> SyntaxExtension {
997 SyntaxExtension::default(SyntaxExtensionKind::NonMacroAttr, edition)
998 }
999
1000 pub fn glob_delegation(
1001 trait_def_id: DefId,
1002 impl_def_id: LocalDefId,
1003 edition: Edition,
1004 ) -> SyntaxExtension {
1005 struct GlobDelegationExpanderImpl {
1006 trait_def_id: DefId,
1007 impl_def_id: LocalDefId,
1008 }
1009 impl GlobDelegationExpander for GlobDelegationExpanderImpl {
1010 fn expand(
1011 &self,
1012 ecx: &mut ExtCtxt<'_>,
1013 ) -> ExpandResult<Vec<(Ident, Option<Ident>)>, ()> {
1014 match ecx.resolver.glob_delegation_suffixes(self.trait_def_id, self.impl_def_id) {
1015 Ok(suffixes) => ExpandResult::Ready(suffixes),
1016 Err(Indeterminate) if ecx.force_mode => ExpandResult::Ready(Vec::new()),
1017 Err(Indeterminate) => ExpandResult::Retry(()),
1018 }
1019 }
1020 }
1021
1022 let expander = GlobDelegationExpanderImpl { trait_def_id, impl_def_id };
1023 SyntaxExtension::default(SyntaxExtensionKind::GlobDelegation(Arc::new(expander)), edition)
1024 }
1025
1026 pub fn expn_data(
1027 &self,
1028 parent: LocalExpnId,
1029 call_site: Span,
1030 descr: Symbol,
1031 macro_def_id: Option<DefId>,
1032 parent_module: Option<DefId>,
1033 ) -> ExpnData {
1034 ExpnData::new(
1035 ExpnKind::Macro(self.macro_kind(), descr),
1036 parent.to_expn_id(),
1037 call_site,
1038 self.span,
1039 self.allow_internal_unstable.clone(),
1040 self.edition,
1041 macro_def_id,
1042 parent_module,
1043 self.allow_internal_unsafe,
1044 self.local_inner_macros,
1045 self.collapse_debuginfo,
1046 self.builtin_name.is_some(),
1047 )
1048 }
1049}
1050
1051pub struct Indeterminate;
1053
1054pub struct DeriveResolution {
1055 pub path: ast::Path,
1056 pub item: Annotatable,
1057 pub exts: Option<Arc<SyntaxExtension>>,
1058 pub is_const: bool,
1059}
1060
1061pub trait ResolverExpand {
1062 fn next_node_id(&mut self) -> NodeId;
1063 fn invocation_parent(&self, id: LocalExpnId) -> LocalDefId;
1064
1065 fn resolve_dollar_crates(&self);
1066 fn visit_ast_fragment_with_placeholders(
1067 &mut self,
1068 expn_id: LocalExpnId,
1069 fragment: &AstFragment,
1070 );
1071 fn register_builtin_macro(&mut self, name: Symbol, ext: SyntaxExtensionKind);
1072
1073 fn expansion_for_ast_pass(
1074 &mut self,
1075 call_site: Span,
1076 pass: AstPass,
1077 features: &[Symbol],
1078 parent_module_id: Option<NodeId>,
1079 ) -> LocalExpnId;
1080
1081 fn resolve_imports(&mut self);
1082
1083 fn resolve_macro_invocation(
1084 &mut self,
1085 invoc: &Invocation,
1086 eager_expansion_root: LocalExpnId,
1087 force: bool,
1088 ) -> Result<Arc<SyntaxExtension>, Indeterminate>;
1089
1090 fn record_macro_rule_usage(&mut self, mac_id: NodeId, rule_index: usize);
1091
1092 fn check_unused_macros(&mut self);
1093
1094 fn has_derive_copy(&self, expn_id: LocalExpnId) -> bool;
1097 fn resolve_derives(
1099 &mut self,
1100 expn_id: LocalExpnId,
1101 force: bool,
1102 derive_paths: &dyn Fn() -> Vec<DeriveResolution>,
1103 ) -> Result<(), Indeterminate>;
1104 fn take_derive_resolutions(&mut self, expn_id: LocalExpnId) -> Option<Vec<DeriveResolution>>;
1107 fn cfg_accessible(
1109 &mut self,
1110 expn_id: LocalExpnId,
1111 path: &ast::Path,
1112 ) -> Result<bool, Indeterminate>;
1113 fn macro_accessible(
1114 &mut self,
1115 expn_id: LocalExpnId,
1116 path: &ast::Path,
1117 ) -> Result<bool, Indeterminate>;
1118
1119 fn get_proc_macro_quoted_span(&self, krate: CrateNum, id: usize) -> Span;
1122
1123 fn declare_proc_macro(&mut self, id: NodeId);
1130
1131 fn append_stripped_cfg_item(
1132 &mut self,
1133 parent_node: NodeId,
1134 ident: Ident,
1135 cfg: CfgEntry,
1136 cfg_span: Span,
1137 );
1138
1139 fn registered_tools(&self) -> &RegisteredTools;
1141
1142 fn register_glob_delegation(&mut self, invoc_id: LocalExpnId);
1144
1145 fn glob_delegation_suffixes(
1147 &self,
1148 trait_def_id: DefId,
1149 impl_def_id: LocalDefId,
1150 ) -> Result<Vec<(Ident, Option<Ident>)>, Indeterminate>;
1151
1152 fn insert_impl_trait_name(&mut self, id: NodeId, name: Symbol);
1155}
1156
1157pub trait LintStoreExpand {
1158 fn pre_expansion_lint(
1159 &self,
1160 sess: &Session,
1161 features: &Features,
1162 registered_tools: &RegisteredTools,
1163 node_id: NodeId,
1164 attrs: &[Attribute],
1165 items: &[P<Item>],
1166 name: Symbol,
1167 );
1168}
1169
1170type LintStoreExpandDyn<'a> = Option<&'a (dyn LintStoreExpand + 'a)>;
1171
1172#[derive(Debug, Clone, Default)]
1173pub struct ModuleData {
1174 pub mod_path: Vec<Ident>,
1176 pub file_path_stack: Vec<PathBuf>,
1179 pub dir_path: PathBuf,
1182}
1183
1184impl ModuleData {
1185 pub fn with_dir_path(&self, dir_path: PathBuf) -> ModuleData {
1186 ModuleData {
1187 mod_path: self.mod_path.clone(),
1188 file_path_stack: self.file_path_stack.clone(),
1189 dir_path,
1190 }
1191 }
1192}
1193
1194#[derive(Clone)]
1195pub struct ExpansionData {
1196 pub id: LocalExpnId,
1197 pub depth: usize,
1198 pub module: Rc<ModuleData>,
1199 pub dir_ownership: DirOwnership,
1200 pub lint_node_id: NodeId,
1202 pub is_trailing_mac: bool,
1203}
1204
1205pub struct ExtCtxt<'a> {
1209 pub sess: &'a Session,
1210 pub ecfg: expand::ExpansionConfig<'a>,
1211 pub num_standard_library_imports: usize,
1212 pub reduced_recursion_limit: Option<(Limit, ErrorGuaranteed)>,
1213 pub root_path: PathBuf,
1214 pub resolver: &'a mut dyn ResolverExpand,
1215 pub current_expansion: ExpansionData,
1216 pub force_mode: bool,
1219 pub expansions: FxIndexMap<Span, Vec<String>>,
1220 pub(super) lint_store: LintStoreExpandDyn<'a>,
1222 pub buffered_early_lint: Vec<BufferedEarlyLint>,
1224 pub(super) expanded_inert_attrs: MarkedAttrs,
1228 pub macro_stats: FxHashMap<(Symbol, MacroKind), MacroStat>,
1230 pub nb_macro_errors: usize,
1231}
1232
1233impl<'a> ExtCtxt<'a> {
1234 pub fn new(
1235 sess: &'a Session,
1236 ecfg: expand::ExpansionConfig<'a>,
1237 resolver: &'a mut dyn ResolverExpand,
1238 lint_store: LintStoreExpandDyn<'a>,
1239 ) -> ExtCtxt<'a> {
1240 ExtCtxt {
1241 sess,
1242 ecfg,
1243 num_standard_library_imports: 0,
1244 reduced_recursion_limit: None,
1245 resolver,
1246 lint_store,
1247 root_path: PathBuf::new(),
1248 current_expansion: ExpansionData {
1249 id: LocalExpnId::ROOT,
1250 depth: 0,
1251 module: Default::default(),
1252 dir_ownership: DirOwnership::Owned { relative: None },
1253 lint_node_id: ast::CRATE_NODE_ID,
1254 is_trailing_mac: false,
1255 },
1256 force_mode: false,
1257 expansions: FxIndexMap::default(),
1258 expanded_inert_attrs: MarkedAttrs::new(),
1259 buffered_early_lint: vec![],
1260 macro_stats: Default::default(),
1261 nb_macro_errors: 0,
1262 }
1263 }
1264
1265 pub fn dcx(&self) -> DiagCtxtHandle<'a> {
1266 self.sess.dcx()
1267 }
1268
1269 pub fn expander<'b>(&'b mut self) -> expand::MacroExpander<'b, 'a> {
1271 expand::MacroExpander::new(self, false)
1272 }
1273
1274 pub fn monotonic_expander<'b>(&'b mut self) -> expand::MacroExpander<'b, 'a> {
1277 expand::MacroExpander::new(self, true)
1278 }
1279 pub fn new_parser_from_tts(&self, stream: TokenStream) -> Parser<'a> {
1280 Parser::new(&self.sess.psess, stream, MACRO_ARGUMENTS)
1281 }
1282 pub fn source_map(&self) -> &'a SourceMap {
1283 self.sess.psess.source_map()
1284 }
1285 pub fn psess(&self) -> &'a ParseSess {
1286 &self.sess.psess
1287 }
1288 pub fn call_site(&self) -> Span {
1289 self.current_expansion.id.expn_data().call_site
1290 }
1291
1292 pub(crate) fn expansion_descr(&self) -> String {
1294 let expn_data = self.current_expansion.id.expn_data();
1295 expn_data.kind.descr()
1296 }
1297
1298 pub fn with_def_site_ctxt(&self, span: Span) -> Span {
1301 span.with_def_site_ctxt(self.current_expansion.id.to_expn_id())
1302 }
1303
1304 pub fn with_call_site_ctxt(&self, span: Span) -> Span {
1307 span.with_call_site_ctxt(self.current_expansion.id.to_expn_id())
1308 }
1309
1310 pub fn with_mixed_site_ctxt(&self, span: Span) -> Span {
1313 span.with_mixed_site_ctxt(self.current_expansion.id.to_expn_id())
1314 }
1315
1316 pub fn expansion_cause(&self) -> Option<Span> {
1320 self.current_expansion.id.expansion_cause()
1321 }
1322
1323 pub fn macro_error_and_trace_macros_diag(&mut self) {
1325 self.nb_macro_errors += 1;
1326 self.trace_macros_diag();
1327 }
1328
1329 pub fn trace_macros_diag(&mut self) {
1330 for (span, notes) in self.expansions.iter() {
1331 let mut db = self.dcx().create_note(errors::TraceMacro { span: *span });
1332 for note in notes {
1333 #[allow(rustc::untranslatable_diagnostic)]
1335 db.note(note.clone());
1336 }
1337 db.emit();
1338 }
1339 self.expansions.clear();
1341 }
1342 pub fn trace_macros(&self) -> bool {
1343 self.ecfg.trace_mac
1344 }
1345 pub fn set_trace_macros(&mut self, x: bool) {
1346 self.ecfg.trace_mac = x
1347 }
1348 pub fn std_path(&self, components: &[Symbol]) -> Vec<Ident> {
1349 let def_site = self.with_def_site_ctxt(DUMMY_SP);
1350 iter::once(Ident::new(kw::DollarCrate, def_site))
1351 .chain(components.iter().map(|&s| Ident::with_dummy_span(s)))
1352 .collect()
1353 }
1354 pub fn def_site_path(&self, components: &[Symbol]) -> Vec<Ident> {
1355 let def_site = self.with_def_site_ctxt(DUMMY_SP);
1356 components.iter().map(|&s| Ident::new(s, def_site)).collect()
1357 }
1358
1359 pub fn check_unused_macros(&mut self) {
1360 self.resolver.check_unused_macros();
1361 }
1362}
1363
1364pub fn resolve_path(sess: &Session, path: impl Into<PathBuf>, span: Span) -> PResult<'_, PathBuf> {
1368 let path = path.into();
1369
1370 if !path.is_absolute() {
1373 let callsite = span.source_callsite();
1374 let source_map = sess.source_map();
1375 let Some(mut base_path) = source_map.span_to_filename(callsite).into_local_path() else {
1376 return Err(sess.dcx().create_err(errors::ResolveRelativePath {
1377 span,
1378 path: source_map
1379 .filename_for_diagnostics(&source_map.span_to_filename(callsite))
1380 .to_string(),
1381 }));
1382 };
1383 base_path.pop();
1384 base_path.push(path);
1385 Ok(base_path)
1386 } else {
1387 match path.components().next() {
1390 Some(Prefix(prefix)) if prefix.kind().is_verbatim() => Ok(path.components().collect()),
1391 _ => Ok(path),
1392 }
1393 }
1394}
1395
1396fn pretty_printing_compatibility_hack(item: &Item, psess: &ParseSess) {
1400 if let ast::ItemKind::Enum(ident, _, enum_def) = &item.kind
1401 && ident.name == sym::ProceduralMasqueradeDummyType
1402 && let [variant] = &*enum_def.variants
1403 && variant.ident.name == sym::Input
1404 && let FileName::Real(real) = psess.source_map().span_to_filename(ident.span)
1405 && let Some(c) = real
1406 .local_path()
1407 .unwrap_or(Path::new(""))
1408 .components()
1409 .flat_map(|c| c.as_os_str().to_str())
1410 .find(|c| c.starts_with("rental") || c.starts_with("allsorts-rental"))
1411 {
1412 let crate_matches = if c.starts_with("allsorts-rental") {
1413 true
1414 } else {
1415 let mut version = c.trim_start_matches("rental-").split('.');
1416 version.next() == Some("0")
1417 && version.next() == Some("5")
1418 && version.next().and_then(|c| c.parse::<u32>().ok()).is_some_and(|v| v < 6)
1419 };
1420
1421 if crate_matches {
1422 psess.dcx().emit_fatal(errors::ProcMacroBackCompat {
1423 crate_name: "rental".to_string(),
1424 fixed_version: "0.5.6".to_string(),
1425 });
1426 }
1427 }
1428}
1429
1430pub(crate) fn ann_pretty_printing_compatibility_hack(ann: &Annotatable, psess: &ParseSess) {
1431 let item = match ann {
1432 Annotatable::Item(item) => item,
1433 Annotatable::Stmt(stmt) => match &stmt.kind {
1434 ast::StmtKind::Item(item) => item,
1435 _ => return,
1436 },
1437 _ => return,
1438 };
1439 pretty_printing_compatibility_hack(item, psess)
1440}
1441
1442pub(crate) fn stream_pretty_printing_compatibility_hack(
1443 kind: MetaVarKind,
1444 stream: &TokenStream,
1445 psess: &ParseSess,
1446) {
1447 let item = match kind {
1448 MetaVarKind::Item => {
1449 let mut parser = Parser::new(psess, stream.clone(), None);
1450 parser
1452 .parse_item(ForceCollect::No)
1453 .expect("failed to reparse item")
1454 .expect("an actual item")
1455 }
1456 MetaVarKind::Stmt => {
1457 let mut parser = Parser::new(psess, stream.clone(), None);
1458 let stmt = parser
1460 .parse_stmt(ForceCollect::No)
1461 .expect("failed to reparse")
1462 .expect("an actual stmt");
1463 match &stmt.kind {
1464 ast::StmtKind::Item(item) => item.clone(),
1465 _ => return,
1466 }
1467 }
1468 _ => return,
1469 };
1470 pretty_printing_compatibility_hack(&item, psess)
1471}