1use std::any::Any;
2use std::default::Default;
3use std::iter;
4use std::path::Component::Prefix;
5use std::path::PathBuf;
6use std::rc::Rc;
7use std::sync::Arc;
8
9use rustc_ast::attr::MarkedAttrs;
10use rustc_ast::tokenstream::TokenStream;
11use rustc_ast::visit::{AssocCtxt, Visitor};
12use rustc_ast::{self as ast, AttrVec, Attribute, HasAttrs, Item, NodeId, PatKind, Safety};
13use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
14use rustc_data_structures::sync;
15use rustc_errors::{BufferedEarlyLint, DiagCtxtHandle, ErrorGuaranteed, PResult};
16use rustc_feature::Features;
17use rustc_hir as hir;
18use rustc_hir::attrs::{CfgEntry, CollapseMacroDebuginfo, Deprecation};
19use rustc_hir::def::MacroKinds;
20use rustc_hir::limit::Limit;
21use rustc_hir::{Stability, find_attr};
22use rustc_lint_defs::RegisteredTools;
23use rustc_parse::MACRO_ARGUMENTS;
24use rustc_parse::parser::Parser;
25use rustc_session::Session;
26use rustc_session::parse::ParseSess;
27use rustc_span::def_id::{CrateNum, DefId, LocalDefId};
28use rustc_span::edition::Edition;
29use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId, MacroKind};
30use rustc_span::source_map::SourceMap;
31use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw};
32use smallvec::{SmallVec, smallvec};
33use thin_vec::ThinVec;
34
35use crate::errors;
36use crate::expand::{self, AstFragment, Invocation};
37use crate::mbe::macro_rules::ParserAnyMacro;
38use crate::module::DirOwnership;
39use crate::stats::MacroStat;
40
41#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Annotatable {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
Annotatable::Item(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Item",
&__self_0),
Annotatable::AssocItem(__self_0, __self_1) =>
::core::fmt::Formatter::debug_tuple_field2_finish(f,
"AssocItem", __self_0, &__self_1),
Annotatable::ForeignItem(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"ForeignItem", &__self_0),
Annotatable::Stmt(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Stmt",
&__self_0),
Annotatable::Expr(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Expr",
&__self_0),
Annotatable::Arm(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Arm",
&__self_0),
Annotatable::ExprField(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"ExprField", &__self_0),
Annotatable::PatField(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"PatField", &__self_0),
Annotatable::GenericParam(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"GenericParam", &__self_0),
Annotatable::Param(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Param",
&__self_0),
Annotatable::FieldDef(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"FieldDef", &__self_0),
Annotatable::Variant(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"Variant", &__self_0),
Annotatable::WherePredicate(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"WherePredicate", &__self_0),
Annotatable::Crate(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Crate",
&__self_0),
}
}
}Debug, #[automatically_derived]
impl ::core::clone::Clone for Annotatable {
#[inline]
fn clone(&self) -> Annotatable {
match self {
Annotatable::Item(__self_0) =>
Annotatable::Item(::core::clone::Clone::clone(__self_0)),
Annotatable::AssocItem(__self_0, __self_1) =>
Annotatable::AssocItem(::core::clone::Clone::clone(__self_0),
::core::clone::Clone::clone(__self_1)),
Annotatable::ForeignItem(__self_0) =>
Annotatable::ForeignItem(::core::clone::Clone::clone(__self_0)),
Annotatable::Stmt(__self_0) =>
Annotatable::Stmt(::core::clone::Clone::clone(__self_0)),
Annotatable::Expr(__self_0) =>
Annotatable::Expr(::core::clone::Clone::clone(__self_0)),
Annotatable::Arm(__self_0) =>
Annotatable::Arm(::core::clone::Clone::clone(__self_0)),
Annotatable::ExprField(__self_0) =>
Annotatable::ExprField(::core::clone::Clone::clone(__self_0)),
Annotatable::PatField(__self_0) =>
Annotatable::PatField(::core::clone::Clone::clone(__self_0)),
Annotatable::GenericParam(__self_0) =>
Annotatable::GenericParam(::core::clone::Clone::clone(__self_0)),
Annotatable::Param(__self_0) =>
Annotatable::Param(::core::clone::Clone::clone(__self_0)),
Annotatable::FieldDef(__self_0) =>
Annotatable::FieldDef(::core::clone::Clone::clone(__self_0)),
Annotatable::Variant(__self_0) =>
Annotatable::Variant(::core::clone::Clone::clone(__self_0)),
Annotatable::WherePredicate(__self_0) =>
Annotatable::WherePredicate(::core::clone::Clone::clone(__self_0)),
Annotatable::Crate(__self_0) =>
Annotatable::Crate(::core::clone::Clone::clone(__self_0)),
}
}
}Clone)]
45pub enum Annotatable {
46 Item(Box<ast::Item>),
47 AssocItem(Box<ast::AssocItem>, AssocCtxt),
48 ForeignItem(Box<ast::ForeignItem>),
49 Stmt(Box<ast::Stmt>),
50 Expr(Box<ast::Expr>),
51 Arm(ast::Arm),
52 ExprField(ast::ExprField),
53 PatField(ast::PatField),
54 GenericParam(ast::GenericParam),
55 Param(ast::Param),
56 FieldDef(ast::FieldDef),
57 Variant(ast::Variant),
58 WherePredicate(ast::WherePredicate),
59 Crate(ast::Crate),
60}
61
62impl Annotatable {
63 pub fn span(&self) -> Span {
64 match self {
65 Annotatable::Item(item) => item.span,
66 Annotatable::AssocItem(assoc_item, _) => assoc_item.span,
67 Annotatable::ForeignItem(foreign_item) => foreign_item.span,
68 Annotatable::Stmt(stmt) => stmt.span,
69 Annotatable::Expr(expr) => expr.span,
70 Annotatable::Arm(arm) => arm.span,
71 Annotatable::ExprField(field) => field.span,
72 Annotatable::PatField(fp) => fp.pat.span,
73 Annotatable::GenericParam(gp) => gp.ident.span,
74 Annotatable::Param(p) => p.span,
75 Annotatable::FieldDef(sf) => sf.span,
76 Annotatable::Variant(v) => v.span,
77 Annotatable::WherePredicate(wp) => wp.span,
78 Annotatable::Crate(c) => c.spans.inner_span,
79 }
80 }
81
82 pub fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) {
83 match self {
84 Annotatable::Item(item) => item.visit_attrs(f),
85 Annotatable::AssocItem(assoc_item, _) => assoc_item.visit_attrs(f),
86 Annotatable::ForeignItem(foreign_item) => foreign_item.visit_attrs(f),
87 Annotatable::Stmt(stmt) => stmt.visit_attrs(f),
88 Annotatable::Expr(expr) => expr.visit_attrs(f),
89 Annotatable::Arm(arm) => arm.visit_attrs(f),
90 Annotatable::ExprField(field) => field.visit_attrs(f),
91 Annotatable::PatField(fp) => fp.visit_attrs(f),
92 Annotatable::GenericParam(gp) => gp.visit_attrs(f),
93 Annotatable::Param(p) => p.visit_attrs(f),
94 Annotatable::FieldDef(sf) => sf.visit_attrs(f),
95 Annotatable::Variant(v) => v.visit_attrs(f),
96 Annotatable::WherePredicate(wp) => wp.visit_attrs(f),
97 Annotatable::Crate(c) => c.visit_attrs(f),
98 }
99 }
100
101 pub fn visit_with<'a, V: Visitor<'a>>(&'a self, visitor: &mut V) -> V::Result {
102 match self {
103 Annotatable::Item(item) => visitor.visit_item(item),
104 Annotatable::AssocItem(item, ctxt) => visitor.visit_assoc_item(item, *ctxt),
105 Annotatable::ForeignItem(foreign_item) => visitor.visit_foreign_item(foreign_item),
106 Annotatable::Stmt(stmt) => visitor.visit_stmt(stmt),
107 Annotatable::Expr(expr) => visitor.visit_expr(expr),
108 Annotatable::Arm(arm) => visitor.visit_arm(arm),
109 Annotatable::ExprField(field) => visitor.visit_expr_field(field),
110 Annotatable::PatField(fp) => visitor.visit_pat_field(fp),
111 Annotatable::GenericParam(gp) => visitor.visit_generic_param(gp),
112 Annotatable::Param(p) => visitor.visit_param(p),
113 Annotatable::FieldDef(sf) => visitor.visit_field_def(sf),
114 Annotatable::Variant(v) => visitor.visit_variant(v),
115 Annotatable::WherePredicate(wp) => visitor.visit_where_predicate(wp),
116 Annotatable::Crate(c) => visitor.visit_crate(c),
117 }
118 }
119
120 pub fn to_tokens(&self) -> TokenStream {
121 match self {
122 Annotatable::Item(node) => TokenStream::from_ast(node),
123 Annotatable::AssocItem(node, _) => TokenStream::from_ast(node),
124 Annotatable::ForeignItem(node) => TokenStream::from_ast(node),
125 Annotatable::Stmt(node) => {
126 if !!#[allow(non_exhaustive_omitted_patterns)] match node.kind {
ast::StmtKind::Empty => true,
_ => false,
} {
::core::panicking::panic("assertion failed: !matches!(node.kind, ast::StmtKind::Empty)")
};assert!(!matches!(node.kind, ast::StmtKind::Empty));
127 TokenStream::from_ast(node)
128 }
129 Annotatable::Expr(node) => TokenStream::from_ast(node),
130 Annotatable::Arm(..)
131 | Annotatable::ExprField(..)
132 | Annotatable::PatField(..)
133 | Annotatable::GenericParam(..)
134 | Annotatable::Param(..)
135 | Annotatable::FieldDef(..)
136 | Annotatable::Variant(..)
137 | Annotatable::WherePredicate(..)
138 | Annotatable::Crate(..) => { ::core::panicking::panic_fmt(format_args!("unexpected annotatable")); }panic!("unexpected annotatable"),
139 }
140 }
141
142 pub fn expect_item(self) -> Box<ast::Item> {
143 match self {
144 Annotatable::Item(i) => i,
145 _ => { ::core::panicking::panic_fmt(format_args!("expected Item")); }panic!("expected Item"),
146 }
147 }
148
149 pub fn expect_trait_item(self) -> Box<ast::AssocItem> {
150 match self {
151 Annotatable::AssocItem(i, AssocCtxt::Trait) => i,
152 _ => { ::core::panicking::panic_fmt(format_args!("expected trait item")); }panic!("expected trait item"),
153 }
154 }
155
156 pub fn expect_impl_item(self) -> Box<ast::AssocItem> {
157 match self {
158 Annotatable::AssocItem(i, AssocCtxt::Impl { .. }) => i,
159 _ => { ::core::panicking::panic_fmt(format_args!("expected impl item")); }panic!("expected impl item"),
160 }
161 }
162
163 pub fn expect_foreign_item(self) -> Box<ast::ForeignItem> {
164 match self {
165 Annotatable::ForeignItem(i) => i,
166 _ => { ::core::panicking::panic_fmt(format_args!("expected foreign item")); }panic!("expected foreign item"),
167 }
168 }
169
170 pub fn expect_stmt(self) -> ast::Stmt {
171 match self {
172 Annotatable::Stmt(stmt) => *stmt,
173 _ => { ::core::panicking::panic_fmt(format_args!("expected statement")); }panic!("expected statement"),
174 }
175 }
176
177 pub fn expect_expr(self) -> Box<ast::Expr> {
178 match self {
179 Annotatable::Expr(expr) => expr,
180 _ => { ::core::panicking::panic_fmt(format_args!("expected expression")); }panic!("expected expression"),
181 }
182 }
183
184 pub fn expect_arm(self) -> ast::Arm {
185 match self {
186 Annotatable::Arm(arm) => arm,
187 _ => { ::core::panicking::panic_fmt(format_args!("expected match arm")); }panic!("expected match arm"),
188 }
189 }
190
191 pub fn expect_expr_field(self) -> ast::ExprField {
192 match self {
193 Annotatable::ExprField(field) => field,
194 _ => { ::core::panicking::panic_fmt(format_args!("expected field")); }panic!("expected field"),
195 }
196 }
197
198 pub fn expect_pat_field(self) -> ast::PatField {
199 match self {
200 Annotatable::PatField(fp) => fp,
201 _ => { ::core::panicking::panic_fmt(format_args!("expected field pattern")); }panic!("expected field pattern"),
202 }
203 }
204
205 pub fn expect_generic_param(self) -> ast::GenericParam {
206 match self {
207 Annotatable::GenericParam(gp) => gp,
208 _ => { ::core::panicking::panic_fmt(format_args!("expected generic parameter")); }panic!("expected generic parameter"),
209 }
210 }
211
212 pub fn expect_param(self) -> ast::Param {
213 match self {
214 Annotatable::Param(param) => param,
215 _ => { ::core::panicking::panic_fmt(format_args!("expected parameter")); }panic!("expected parameter"),
216 }
217 }
218
219 pub fn expect_field_def(self) -> ast::FieldDef {
220 match self {
221 Annotatable::FieldDef(sf) => sf,
222 _ => { ::core::panicking::panic_fmt(format_args!("expected struct field")); }panic!("expected struct field"),
223 }
224 }
225
226 pub fn expect_variant(self) -> ast::Variant {
227 match self {
228 Annotatable::Variant(v) => v,
229 _ => { ::core::panicking::panic_fmt(format_args!("expected variant")); }panic!("expected variant"),
230 }
231 }
232
233 pub fn expect_where_predicate(self) -> ast::WherePredicate {
234 match self {
235 Annotatable::WherePredicate(wp) => wp,
236 _ => { ::core::panicking::panic_fmt(format_args!("expected where predicate")); }panic!("expected where predicate"),
237 }
238 }
239
240 pub fn expect_crate(self) -> ast::Crate {
241 match self {
242 Annotatable::Crate(krate) => krate,
243 _ => { ::core::panicking::panic_fmt(format_args!("expected krate")); }panic!("expected krate"),
244 }
245 }
246}
247
248pub enum ExpandResult<T, U> {
251 Ready(T),
253 Retry(U),
255}
256
257impl<T, U> ExpandResult<T, U> {
258 pub fn map<E, F: FnOnce(T) -> E>(self, f: F) -> ExpandResult<E, U> {
259 match self {
260 ExpandResult::Ready(t) => ExpandResult::Ready(f(t)),
261 ExpandResult::Retry(u) => ExpandResult::Retry(u),
262 }
263 }
264}
265
266impl<'cx> MacroExpanderResult<'cx> {
267 pub fn from_tts(
271 cx: &'cx mut ExtCtxt<'_>,
272 tts: TokenStream,
273 site_span: Span,
274 arm_span: Span,
275 macro_ident: Ident,
276 ) -> Self {
277 let is_local = true;
279
280 let parser =
281 ParserAnyMacro::from_tts(cx, tts, site_span, arm_span, is_local, macro_ident, &[], &[]);
282 ExpandResult::Ready(Box::new(parser))
283 }
284}
285
286pub trait MultiItemModifier {
287 fn expand(
289 &self,
290 ecx: &mut ExtCtxt<'_>,
291 span: Span,
292 meta_item: &ast::MetaItem,
293 item: Annotatable,
294 is_derive_const: bool,
295 ) -> ExpandResult<Vec<Annotatable>, Annotatable>;
296}
297
298impl<F> MultiItemModifier for F
299where
300 F: Fn(&mut ExtCtxt<'_>, Span, &ast::MetaItem, Annotatable) -> Vec<Annotatable>,
301{
302 fn expand(
303 &self,
304 ecx: &mut ExtCtxt<'_>,
305 span: Span,
306 meta_item: &ast::MetaItem,
307 item: Annotatable,
308 _is_derive_const: bool,
309 ) -> ExpandResult<Vec<Annotatable>, Annotatable> {
310 ExpandResult::Ready(self(ecx, span, meta_item, item))
311 }
312}
313
314pub trait BangProcMacro {
315 fn expand<'cx>(
316 &self,
317 ecx: &'cx mut ExtCtxt<'_>,
318 span: Span,
319 ts: TokenStream,
320 ) -> Result<TokenStream, ErrorGuaranteed>;
321}
322
323impl<F> BangProcMacro for F
324where
325 F: Fn(&mut ExtCtxt<'_>, Span, TokenStream) -> Result<TokenStream, ErrorGuaranteed>,
326{
327 fn expand<'cx>(
328 &self,
329 ecx: &'cx mut ExtCtxt<'_>,
330 span: Span,
331 ts: TokenStream,
332 ) -> Result<TokenStream, ErrorGuaranteed> {
333 self(ecx, span, ts)
335 }
336}
337
338pub trait AttrProcMacro {
339 fn expand<'cx>(
340 &self,
341 ecx: &'cx mut ExtCtxt<'_>,
342 span: Span,
343 annotation: TokenStream,
344 annotated: TokenStream,
345 ) -> Result<TokenStream, ErrorGuaranteed>;
346
347 fn expand_with_safety<'cx>(
349 &self,
350 ecx: &'cx mut ExtCtxt<'_>,
351 safety: Safety,
352 span: Span,
353 annotation: TokenStream,
354 annotated: TokenStream,
355 ) -> Result<TokenStream, ErrorGuaranteed> {
356 if let Safety::Unsafe(span) = safety {
357 ecx.dcx().span_err(span, "unnecessary `unsafe` on safe attribute");
358 }
359 self.expand(ecx, span, annotation, annotated)
360 }
361}
362
363impl<F> AttrProcMacro for F
364where
365 F: Fn(TokenStream, TokenStream) -> TokenStream,
366{
367 fn expand<'cx>(
368 &self,
369 _ecx: &'cx mut ExtCtxt<'_>,
370 _span: Span,
371 annotation: TokenStream,
372 annotated: TokenStream,
373 ) -> Result<TokenStream, ErrorGuaranteed> {
374 Ok(self(annotation, annotated))
376 }
377}
378
379pub trait TTMacroExpander: Any {
381 fn expand<'cx, 'a: 'cx>(
382 &'a self,
383 ecx: &'cx mut ExtCtxt<'_>,
384 span: Span,
385 input: TokenStream,
386 ) -> MacroExpanderResult<'cx>;
387}
388
389pub type MacroExpanderResult<'cx> = ExpandResult<Box<dyn MacResult + 'cx>, ()>;
390
391pub type MacroExpanderFn =
392 for<'cx> fn(&'cx mut ExtCtxt<'_>, Span, TokenStream) -> MacroExpanderResult<'cx>;
393
394impl<F: 'static> TTMacroExpander for F
395where
396 F: for<'cx> Fn(&'cx mut ExtCtxt<'_>, Span, TokenStream) -> MacroExpanderResult<'cx>,
397{
398 fn expand<'cx, 'a: 'cx>(
399 &'a self,
400 ecx: &'cx mut ExtCtxt<'_>,
401 span: Span,
402 input: TokenStream,
403 ) -> MacroExpanderResult<'cx> {
404 self(ecx, span, input)
405 }
406}
407
408pub trait GlobDelegationExpander {
409 fn expand(&self, ecx: &mut ExtCtxt<'_>) -> ExpandResult<Vec<(Ident, Option<Ident>)>, ()>;
410}
411
412fn make_stmts_default(expr: Option<Box<ast::Expr>>) -> Option<SmallVec<[ast::Stmt; 1]>> {
413 expr.map(|e| {
414 {
let count = 0usize + 1usize;
let mut vec = ::smallvec::SmallVec::new();
if count <= vec.inline_size() {
vec.push(ast::Stmt {
id: ast::DUMMY_NODE_ID,
span: e.span,
kind: ast::StmtKind::Expr(e),
});
vec
} else {
::smallvec::SmallVec::from_vec(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[ast::Stmt {
id: ast::DUMMY_NODE_ID,
span: e.span,
kind: ast::StmtKind::Expr(e),
}])))
}
}smallvec![ast::Stmt { id: ast::DUMMY_NODE_ID, span: e.span, kind: ast::StmtKind::Expr(e) }]
415 })
416}
417
418pub trait MacResult {
421 fn make_expr(self: Box<Self>) -> Option<Box<ast::Expr>> {
423 None
424 }
425
426 fn make_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::Item>; 1]>> {
428 None
429 }
430
431 fn make_impl_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
433 None
434 }
435
436 fn make_trait_impl_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
438 None
439 }
440
441 fn make_trait_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
443 None
444 }
445
446 fn make_foreign_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::ForeignItem>; 1]>> {
448 None
449 }
450
451 fn make_pat(self: Box<Self>) -> Option<Box<ast::Pat>> {
453 None
454 }
455
456 fn make_stmts(self: Box<Self>) -> Option<SmallVec<[ast::Stmt; 1]>> {
461 make_stmts_default(self.make_expr())
462 }
463
464 fn make_ty(self: Box<Self>) -> Option<Box<ast::Ty>> {
465 None
466 }
467
468 fn make_arms(self: Box<Self>) -> Option<SmallVec<[ast::Arm; 1]>> {
469 None
470 }
471
472 fn make_expr_fields(self: Box<Self>) -> Option<SmallVec<[ast::ExprField; 1]>> {
473 None
474 }
475
476 fn make_pat_fields(self: Box<Self>) -> Option<SmallVec<[ast::PatField; 1]>> {
477 None
478 }
479
480 fn make_generic_params(self: Box<Self>) -> Option<SmallVec<[ast::GenericParam; 1]>> {
481 None
482 }
483
484 fn make_params(self: Box<Self>) -> Option<SmallVec<[ast::Param; 1]>> {
485 None
486 }
487
488 fn make_field_defs(self: Box<Self>) -> Option<SmallVec<[ast::FieldDef; 1]>> {
489 None
490 }
491
492 fn make_variants(self: Box<Self>) -> Option<SmallVec<[ast::Variant; 1]>> {
493 None
494 }
495
496 fn make_where_predicates(self: Box<Self>) -> Option<SmallVec<[ast::WherePredicate; 1]>> {
497 None
498 }
499
500 fn make_crate(self: Box<Self>) -> Option<ast::Crate> {
501 ::core::panicking::panic("internal error: entered unreachable code")unreachable!()
503 }
504}
505
506macro_rules! make_MacEager {
507 ( $( $fld:ident: $t:ty, )* ) => {
508 #[derive(Default)]
511 pub struct MacEager {
512 $(
513 pub $fld: Option<$t>,
514 )*
515 }
516
517 impl MacEager {
518 $(
519 pub fn $fld(v: $t) -> Box<dyn MacResult> {
520 Box::new(MacEager {
521 $fld: Some(v),
522 ..Default::default()
523 })
524 }
525 )*
526 }
527 }
528}
529
530pub struct MacEager {
pub expr: Option<Box<ast::Expr>>,
pub pat: Option<Box<ast::Pat>>,
pub items: Option<SmallVec<[Box<ast::Item>; 1]>>,
pub impl_items: Option<SmallVec<[Box<ast::AssocItem>; 1]>>,
pub trait_items: Option<SmallVec<[Box<ast::AssocItem>; 1]>>,
pub foreign_items: Option<SmallVec<[Box<ast::ForeignItem>; 1]>>,
pub stmts: Option<SmallVec<[ast::Stmt; 1]>>,
pub ty: Option<Box<ast::Ty>>,
}
#[automatically_derived]
impl ::core::default::Default for MacEager {
#[inline]
fn default() -> MacEager {
MacEager {
expr: ::core::default::Default::default(),
pat: ::core::default::Default::default(),
items: ::core::default::Default::default(),
impl_items: ::core::default::Default::default(),
trait_items: ::core::default::Default::default(),
foreign_items: ::core::default::Default::default(),
stmts: ::core::default::Default::default(),
ty: ::core::default::Default::default(),
}
}
}
impl MacEager {
pub fn expr(v: Box<ast::Expr>) -> Box<dyn MacResult> {
Box::new(MacEager { expr: Some(v), ..Default::default() })
}
pub fn pat(v: Box<ast::Pat>) -> Box<dyn MacResult> {
Box::new(MacEager { pat: Some(v), ..Default::default() })
}
pub fn items(v: SmallVec<[Box<ast::Item>; 1]>) -> Box<dyn MacResult> {
Box::new(MacEager { items: Some(v), ..Default::default() })
}
pub fn impl_items(v: SmallVec<[Box<ast::AssocItem>; 1]>)
-> Box<dyn MacResult> {
Box::new(MacEager { impl_items: Some(v), ..Default::default() })
}
pub fn trait_items(v: SmallVec<[Box<ast::AssocItem>; 1]>)
-> Box<dyn MacResult> {
Box::new(MacEager { trait_items: Some(v), ..Default::default() })
}
pub fn foreign_items(v: SmallVec<[Box<ast::ForeignItem>; 1]>)
-> Box<dyn MacResult> {
Box::new(MacEager { foreign_items: Some(v), ..Default::default() })
}
pub fn stmts(v: SmallVec<[ast::Stmt; 1]>) -> Box<dyn MacResult> {
Box::new(MacEager { stmts: Some(v), ..Default::default() })
}
pub fn ty(v: Box<ast::Ty>) -> Box<dyn MacResult> {
Box::new(MacEager { ty: Some(v), ..Default::default() })
}
}make_MacEager! {
531 expr: Box<ast::Expr>,
532 pat: Box<ast::Pat>,
533 items: SmallVec<[Box<ast::Item>; 1]>,
534 impl_items: SmallVec<[Box<ast::AssocItem>; 1]>,
535 trait_items: SmallVec<[Box<ast::AssocItem>; 1]>,
536 foreign_items: SmallVec<[Box<ast::ForeignItem>; 1]>,
537 stmts: SmallVec<[ast::Stmt; 1]>,
538 ty: Box<ast::Ty>,
539}
540
541impl MacResult for MacEager {
542 fn make_expr(self: Box<Self>) -> Option<Box<ast::Expr>> {
543 self.expr
544 }
545
546 fn make_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::Item>; 1]>> {
547 self.items
548 }
549
550 fn make_impl_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
551 self.impl_items
552 }
553
554 fn make_trait_impl_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
555 self.impl_items
556 }
557
558 fn make_trait_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
559 self.trait_items
560 }
561
562 fn make_foreign_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::ForeignItem>; 1]>> {
563 self.foreign_items
564 }
565
566 fn make_stmts(self: Box<Self>) -> Option<SmallVec<[ast::Stmt; 1]>> {
567 if self.stmts.as_ref().is_none_or(|s| s.is_empty()) {
568 make_stmts_default(self.make_expr())
569 } else {
570 self.stmts
571 }
572 }
573
574 fn make_pat(self: Box<Self>) -> Option<Box<ast::Pat>> {
575 if let Some(p) = self.pat {
576 return Some(p);
577 }
578 if let Some(e) = self.expr {
579 if #[allow(non_exhaustive_omitted_patterns)] match e.kind {
ast::ExprKind::Lit(_) | ast::ExprKind::IncludedBytes(_) => true,
_ => false,
}matches!(e.kind, ast::ExprKind::Lit(_) | ast::ExprKind::IncludedBytes(_)) {
580 return Some(Box::new(ast::Pat {
581 id: ast::DUMMY_NODE_ID,
582 span: e.span,
583 kind: PatKind::Expr(e),
584 tokens: None,
585 }));
586 }
587 }
588 None
589 }
590
591 fn make_ty(self: Box<Self>) -> Option<Box<ast::Ty>> {
592 self.ty
593 }
594}
595
596#[derive(#[automatically_derived]
impl ::core::marker::Copy for DummyResult { }Copy, #[automatically_derived]
impl ::core::clone::Clone for DummyResult {
#[inline]
fn clone(&self) -> DummyResult {
let _: ::core::clone::AssertParamIsClone<Option<ErrorGuaranteed>>;
let _: ::core::clone::AssertParamIsClone<Span>;
*self
}
}Clone)]
599pub struct DummyResult {
600 guar: Option<ErrorGuaranteed>,
601 span: Span,
602}
603
604impl DummyResult {
605 pub fn any(span: Span, guar: ErrorGuaranteed) -> Box<dyn MacResult + 'static> {
610 Box::new(DummyResult { guar: Some(guar), span })
611 }
612
613 pub fn any_valid(span: Span) -> Box<dyn MacResult + 'static> {
615 Box::new(DummyResult { guar: None, span })
616 }
617
618 pub fn raw_expr(sp: Span, guar: Option<ErrorGuaranteed>) -> Box<ast::Expr> {
620 Box::new(ast::Expr {
621 id: ast::DUMMY_NODE_ID,
622 kind: if let Some(guar) = guar {
623 ast::ExprKind::Err(guar)
624 } else {
625 ast::ExprKind::Tup(ThinVec::new())
626 },
627 span: sp,
628 attrs: ast::AttrVec::new(),
629 tokens: None,
630 })
631 }
632}
633
634impl MacResult for DummyResult {
635 fn make_expr(self: Box<DummyResult>) -> Option<Box<ast::Expr>> {
636 Some(DummyResult::raw_expr(self.span, self.guar))
637 }
638
639 fn make_pat(self: Box<DummyResult>) -> Option<Box<ast::Pat>> {
640 Some(Box::new(ast::Pat {
641 id: ast::DUMMY_NODE_ID,
642 kind: PatKind::Wild,
643 span: self.span,
644 tokens: None,
645 }))
646 }
647
648 fn make_items(self: Box<DummyResult>) -> Option<SmallVec<[Box<ast::Item>; 1]>> {
649 Some(SmallVec::new())
650 }
651
652 fn make_impl_items(self: Box<DummyResult>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
653 Some(SmallVec::new())
654 }
655
656 fn make_trait_impl_items(self: Box<DummyResult>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
657 Some(SmallVec::new())
658 }
659
660 fn make_trait_items(self: Box<DummyResult>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
661 Some(SmallVec::new())
662 }
663
664 fn make_foreign_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::ForeignItem>; 1]>> {
665 Some(SmallVec::new())
666 }
667
668 fn make_stmts(self: Box<DummyResult>) -> Option<SmallVec<[ast::Stmt; 1]>> {
669 Some({
let count = 0usize + 1usize;
let mut vec = ::smallvec::SmallVec::new();
if count <= vec.inline_size() {
vec.push(ast::Stmt {
id: ast::DUMMY_NODE_ID,
kind: ast::StmtKind::Expr(DummyResult::raw_expr(self.span,
self.guar)),
span: self.span,
});
vec
} else {
::smallvec::SmallVec::from_vec(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[ast::Stmt {
id: ast::DUMMY_NODE_ID,
kind: ast::StmtKind::Expr(DummyResult::raw_expr(self.span,
self.guar)),
span: self.span,
}])))
}
}smallvec![ast::Stmt {
670 id: ast::DUMMY_NODE_ID,
671 kind: ast::StmtKind::Expr(DummyResult::raw_expr(self.span, self.guar)),
672 span: self.span,
673 }])
674 }
675
676 fn make_ty(self: Box<DummyResult>) -> Option<Box<ast::Ty>> {
677 Some(Box::new(ast::Ty {
681 id: ast::DUMMY_NODE_ID,
682 kind: ast::TyKind::Tup(ThinVec::new()),
683 span: self.span,
684 tokens: None,
685 }))
686 }
687
688 fn make_arms(self: Box<DummyResult>) -> Option<SmallVec<[ast::Arm; 1]>> {
689 Some(SmallVec::new())
690 }
691
692 fn make_expr_fields(self: Box<DummyResult>) -> Option<SmallVec<[ast::ExprField; 1]>> {
693 Some(SmallVec::new())
694 }
695
696 fn make_pat_fields(self: Box<DummyResult>) -> Option<SmallVec<[ast::PatField; 1]>> {
697 Some(SmallVec::new())
698 }
699
700 fn make_generic_params(self: Box<DummyResult>) -> Option<SmallVec<[ast::GenericParam; 1]>> {
701 Some(SmallVec::new())
702 }
703
704 fn make_params(self: Box<DummyResult>) -> Option<SmallVec<[ast::Param; 1]>> {
705 Some(SmallVec::new())
706 }
707
708 fn make_field_defs(self: Box<DummyResult>) -> Option<SmallVec<[ast::FieldDef; 1]>> {
709 Some(SmallVec::new())
710 }
711
712 fn make_variants(self: Box<DummyResult>) -> Option<SmallVec<[ast::Variant; 1]>> {
713 Some(SmallVec::new())
714 }
715
716 fn make_crate(self: Box<DummyResult>) -> Option<ast::Crate> {
717 Some(ast::Crate {
718 attrs: Default::default(),
719 items: Default::default(),
720 spans: Default::default(),
721 id: ast::DUMMY_NODE_ID,
722 is_placeholder: Default::default(),
723 })
724 }
725}
726
727#[derive(#[automatically_derived]
impl ::core::clone::Clone for SyntaxExtensionKind {
#[inline]
fn clone(&self) -> SyntaxExtensionKind {
match self {
SyntaxExtensionKind::MacroRules(__self_0) =>
SyntaxExtensionKind::MacroRules(::core::clone::Clone::clone(__self_0)),
SyntaxExtensionKind::Bang(__self_0) =>
SyntaxExtensionKind::Bang(::core::clone::Clone::clone(__self_0)),
SyntaxExtensionKind::LegacyBang(__self_0) =>
SyntaxExtensionKind::LegacyBang(::core::clone::Clone::clone(__self_0)),
SyntaxExtensionKind::Attr(__self_0) =>
SyntaxExtensionKind::Attr(::core::clone::Clone::clone(__self_0)),
SyntaxExtensionKind::LegacyAttr(__self_0) =>
SyntaxExtensionKind::LegacyAttr(::core::clone::Clone::clone(__self_0)),
SyntaxExtensionKind::NonMacroAttr =>
SyntaxExtensionKind::NonMacroAttr,
SyntaxExtensionKind::Derive(__self_0) =>
SyntaxExtensionKind::Derive(::core::clone::Clone::clone(__self_0)),
SyntaxExtensionKind::LegacyDerive(__self_0) =>
SyntaxExtensionKind::LegacyDerive(::core::clone::Clone::clone(__self_0)),
SyntaxExtensionKind::GlobDelegation(__self_0) =>
SyntaxExtensionKind::GlobDelegation(::core::clone::Clone::clone(__self_0)),
}
}
}Clone)]
729pub enum SyntaxExtensionKind {
730 MacroRules(Arc<crate::MacroRulesMacroExpander>),
732
733 Bang(
735 Arc<dyn BangProcMacro + sync::DynSync + sync::DynSend>,
737 ),
738
739 LegacyBang(
741 Arc<dyn TTMacroExpander + sync::DynSync + sync::DynSend>,
743 ),
744
745 Attr(
747 Arc<dyn AttrProcMacro + sync::DynSync + sync::DynSend>,
751 ),
752
753 LegacyAttr(
755 Arc<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
759 ),
760
761 NonMacroAttr,
766
767 Derive(
769 Arc<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
777 ),
778
779 LegacyDerive(
781 Arc<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
784 ),
785
786 GlobDelegation(Arc<dyn GlobDelegationExpander + sync::DynSync + sync::DynSend>),
790}
791
792impl SyntaxExtensionKind {
793 pub fn as_legacy_bang(&self) -> Option<&(dyn TTMacroExpander + sync::DynSync + sync::DynSend)> {
797 match self {
798 SyntaxExtensionKind::LegacyBang(exp) => Some(exp.as_ref()),
799 SyntaxExtensionKind::MacroRules(exp) if exp.kinds().contains(MacroKinds::BANG) => {
800 Some(exp.as_ref())
801 }
802 _ => None,
803 }
804 }
805
806 pub fn as_attr(&self) -> Option<&(dyn AttrProcMacro + sync::DynSync + sync::DynSend)> {
810 match self {
811 SyntaxExtensionKind::Attr(exp) => Some(exp.as_ref()),
812 SyntaxExtensionKind::MacroRules(exp) if exp.kinds().contains(MacroKinds::ATTR) => {
813 Some(exp.as_ref())
814 }
815 _ => None,
816 }
817 }
818}
819
820pub struct SyntaxExtension {
822 pub kind: SyntaxExtensionKind,
824 pub span: Span,
826 pub allow_internal_unstable: Option<Arc<[Symbol]>>,
828 pub stability: Option<Stability>,
830 pub deprecation: Option<Deprecation>,
832 pub helper_attrs: Vec<Symbol>,
834 pub edition: Edition,
836 pub builtin_name: Option<Symbol>,
839 pub allow_internal_unsafe: bool,
841 pub local_inner_macros: bool,
843 pub collapse_debuginfo: bool,
846 pub hide_backtrace: bool,
849}
850
851impl SyntaxExtension {
852 pub fn macro_kinds(&self) -> MacroKinds {
854 match self.kind {
855 SyntaxExtensionKind::Bang(..)
856 | SyntaxExtensionKind::LegacyBang(..)
857 | SyntaxExtensionKind::GlobDelegation(..) => MacroKinds::BANG,
858 SyntaxExtensionKind::Attr(..)
859 | SyntaxExtensionKind::LegacyAttr(..)
860 | SyntaxExtensionKind::NonMacroAttr => MacroKinds::ATTR,
861 SyntaxExtensionKind::Derive(..) | SyntaxExtensionKind::LegacyDerive(..) => {
862 MacroKinds::DERIVE
863 }
864 SyntaxExtensionKind::MacroRules(ref m) => m.kinds(),
865 }
866 }
867
868 pub fn default(kind: SyntaxExtensionKind, edition: Edition) -> SyntaxExtension {
870 SyntaxExtension {
871 span: DUMMY_SP,
872 allow_internal_unstable: None,
873 stability: None,
874 deprecation: None,
875 helper_attrs: Vec::new(),
876 edition,
877 builtin_name: None,
878 kind,
879 allow_internal_unsafe: false,
880 local_inner_macros: false,
881 collapse_debuginfo: false,
882 hide_backtrace: false,
883 }
884 }
885
886 fn get_collapse_debuginfo(sess: &Session, attrs: &[hir::Attribute], ext: bool) -> bool {
893 let flag = sess.opts.cg.collapse_macro_debuginfo;
894 let attr = if let Some(info) = {
'done:
{
for i in attrs {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(CollapseDebugInfo(info)) => {
break 'done Some(info);
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}find_attr!(attrs, CollapseDebugInfo(info) => info) {
895 *info
896 } else if {
{
'done:
{
for i in attrs {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(RustcBuiltinMacro { .. }) => {
break 'done Some(());
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}.is_some()
}find_attr!(attrs, RustcBuiltinMacro { .. }) {
897 CollapseMacroDebuginfo::Yes
898 } else {
899 CollapseMacroDebuginfo::Unspecified
900 };
901
902 #[rustfmt::skip]
903 let collapse_table = [
904 [false, false, false, false],
905 [false, ext, ext, true],
906 [false, ext, ext, true],
907 [true, true, true, true],
908 ];
909 collapse_table[flag as usize][attr as usize]
910 }
911
912 fn get_hide_backtrace(attrs: &[hir::Attribute]) -> bool {
913 {
{
'done:
{
for i in attrs {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(RustcDiagnosticItem(..)) => {
break 'done Some(());
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}.is_some()
}find_attr!(attrs, RustcDiagnosticItem(..))
916 }
917
918 pub fn new(
921 sess: &Session,
922 kind: SyntaxExtensionKind,
923 span: Span,
924 helper_attrs: Vec<Symbol>,
925 edition: Edition,
926 name: Symbol,
927 attrs: &[hir::Attribute],
928 is_local: bool,
929 ) -> SyntaxExtension {
930 let allow_internal_unstable = {
'done:
{
for i in attrs {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(AllowInternalUnstable(i, _)) => {
break 'done Some(i);
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}find_attr!(attrs, AllowInternalUnstable(i, _) => i)
931 .map(|i| i.as_slice())
932 .unwrap_or_default();
933 let allow_internal_unsafe = {
{
'done:
{
for i in attrs {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(AllowInternalUnsafe(_)) => {
break 'done Some(());
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}.is_some()
}find_attr!(attrs, AllowInternalUnsafe(_));
934
935 let local_inner_macros =
936 *{
'done:
{
for i in attrs {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(MacroExport {
local_inner_macros: l, .. }) => {
break 'done Some(l);
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}find_attr!(attrs, MacroExport {local_inner_macros: l, ..} => l).unwrap_or(&false);
937 let collapse_debuginfo = Self::get_collapse_debuginfo(sess, attrs, !is_local);
938 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_expand/src/base.rs:938",
"rustc_expand::base", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_expand/src/base.rs"),
::tracing_core::__macro_support::Option::Some(938u32),
::tracing_core::__macro_support::Option::Some("rustc_expand::base"),
::tracing_core::field::FieldSet::new(&["name",
"local_inner_macros", "collapse_debuginfo",
"allow_internal_unsafe"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&name) as
&dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&local_inner_macros)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&collapse_debuginfo)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&allow_internal_unsafe)
as &dyn Value))])
});
} else { ; }
};tracing::debug!(?name, ?local_inner_macros, ?collapse_debuginfo, ?allow_internal_unsafe);
939
940 let (builtin_name, helper_attrs) = match {
'done:
{
for i in attrs {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(RustcBuiltinMacro {
builtin_name, helper_attrs, .. }) => {
break 'done Some((builtin_name, helper_attrs));
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}find_attr!(attrs, RustcBuiltinMacro { builtin_name, helper_attrs, .. } => (builtin_name, helper_attrs))
941 {
942 Some((Some(name), helper_attrs)) => {
945 (Some(*name), helper_attrs.iter().copied().collect())
946 }
947 Some((None, _)) => (Some(name), Vec::new()),
948
949 None => (None, helper_attrs),
951 };
952 let hide_backtrace = builtin_name.is_some() || Self::get_hide_backtrace(attrs);
953
954 let stability = {
'done:
{
for i in attrs {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(Stability { stability, .. }) => {
break 'done Some(*stability);
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}find_attr!(attrs, Stability { stability, .. } => *stability);
955
956 if let Some(sp) = {
'done:
{
for i in attrs {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(RustcBodyStability { span, .. })
=> {
break 'done Some(*span);
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}find_attr!(attrs, RustcBodyStability{ span, .. } => *span) {
957 sess.dcx().emit_err(errors::MacroBodyStability {
958 span: sp,
959 head_span: sess.source_map().guess_head_span(span),
960 });
961 }
962
963 SyntaxExtension {
964 kind,
965 span,
966 allow_internal_unstable: (!allow_internal_unstable.is_empty())
967 .then(|| allow_internal_unstable.iter().map(|i| i.0).collect::<Vec<_>>().into()),
969 stability,
970 deprecation: {
'done:
{
for i in attrs {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(Deprecated { deprecation, .. })
=> {
break 'done Some(*deprecation);
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}find_attr!(
971 attrs,
972 Deprecated { deprecation, .. } => *deprecation
973 ),
974 helper_attrs,
975 edition,
976 builtin_name,
977 allow_internal_unsafe,
978 local_inner_macros,
979 collapse_debuginfo,
980 hide_backtrace,
981 }
982 }
983
984 pub fn dummy_bang(edition: Edition) -> SyntaxExtension {
986 fn expand(
987 ecx: &mut ExtCtxt<'_>,
988 span: Span,
989 _ts: TokenStream,
990 ) -> Result<TokenStream, ErrorGuaranteed> {
991 Err(ecx.dcx().span_delayed_bug(span, "expanded a dummy bang macro"))
992 }
993 SyntaxExtension::default(SyntaxExtensionKind::Bang(Arc::new(expand)), edition)
994 }
995
996 pub fn dummy_derive(edition: Edition) -> SyntaxExtension {
998 fn expander(
999 _: &mut ExtCtxt<'_>,
1000 _: Span,
1001 _: &ast::MetaItem,
1002 _: Annotatable,
1003 ) -> Vec<Annotatable> {
1004 Vec::new()
1005 }
1006 SyntaxExtension::default(SyntaxExtensionKind::Derive(Arc::new(expander)), edition)
1007 }
1008
1009 pub fn non_macro_attr(edition: Edition) -> SyntaxExtension {
1010 SyntaxExtension::default(SyntaxExtensionKind::NonMacroAttr, edition)
1011 }
1012
1013 pub fn glob_delegation(
1014 trait_def_id: DefId,
1015 impl_def_id: LocalDefId,
1016 star_span: Span,
1017 edition: Edition,
1018 ) -> SyntaxExtension {
1019 struct GlobDelegationExpanderImpl {
1020 trait_def_id: DefId,
1021 impl_def_id: LocalDefId,
1022 star_span: Span,
1023 }
1024 impl GlobDelegationExpander for GlobDelegationExpanderImpl {
1025 fn expand(
1026 &self,
1027 ecx: &mut ExtCtxt<'_>,
1028 ) -> ExpandResult<Vec<(Ident, Option<Ident>)>, ()> {
1029 match ecx.resolver.glob_delegation_suffixes(
1030 self.trait_def_id,
1031 self.impl_def_id,
1032 self.star_span,
1033 ) {
1034 Ok(suffixes) => ExpandResult::Ready(suffixes),
1035 Err(Indeterminate) if ecx.force_mode => ExpandResult::Ready(Vec::new()),
1036 Err(Indeterminate) => ExpandResult::Retry(()),
1037 }
1038 }
1039 }
1040
1041 let expander = GlobDelegationExpanderImpl { trait_def_id, impl_def_id, star_span };
1042 SyntaxExtension::default(SyntaxExtensionKind::GlobDelegation(Arc::new(expander)), edition)
1043 }
1044
1045 pub fn expn_data(
1046 &self,
1047 parent: LocalExpnId,
1048 call_site: Span,
1049 descr: Symbol,
1050 kind: MacroKind,
1051 macro_def_id: Option<DefId>,
1052 parent_module: Option<DefId>,
1053 ) -> ExpnData {
1054 ExpnData::new(
1055 ExpnKind::Macro(kind, descr),
1056 parent.to_expn_id(),
1057 call_site,
1058 self.span,
1059 self.allow_internal_unstable.clone(),
1060 self.edition,
1061 macro_def_id,
1062 parent_module,
1063 self.allow_internal_unsafe,
1064 self.local_inner_macros,
1065 self.collapse_debuginfo,
1066 self.hide_backtrace,
1067 )
1068 }
1069}
1070
1071pub struct Indeterminate;
1073
1074pub struct DeriveResolution {
1075 pub path: ast::Path,
1076 pub item: Annotatable,
1077 pub exts: Option<Arc<SyntaxExtension>>,
1081 pub is_const: bool,
1082}
1083
1084pub trait ResolverExpand {
1085 fn next_node_id(&mut self) -> NodeId;
1086 fn invocation_parent(&self, id: LocalExpnId) -> LocalDefId;
1087
1088 fn resolve_dollar_crates(&self);
1089 fn visit_ast_fragment_with_placeholders(
1090 &mut self,
1091 expn_id: LocalExpnId,
1092 fragment: &AstFragment,
1093 );
1094 fn register_builtin_macro(&mut self, name: Symbol, ext: SyntaxExtensionKind);
1095
1096 fn expansion_for_ast_pass(
1097 &mut self,
1098 call_site: Span,
1099 pass: AstPass,
1100 features: &[Symbol],
1101 parent_module_id: Option<NodeId>,
1102 ) -> LocalExpnId;
1103
1104 fn resolve_imports(&mut self);
1105
1106 fn resolve_macro_invocation(
1107 &mut self,
1108 invoc: &Invocation,
1109 eager_expansion_root: LocalExpnId,
1110 force: bool,
1111 ) -> Result<Arc<SyntaxExtension>, Indeterminate>;
1112
1113 fn record_macro_rule_usage(&mut self, mac_id: NodeId, rule_index: usize);
1114
1115 fn check_unused_macros(&mut self);
1116
1117 fn has_derive_copy(&self, expn_id: LocalExpnId) -> bool;
1120 fn resolve_derives(
1122 &mut self,
1123 expn_id: LocalExpnId,
1124 force: bool,
1125 derive_paths: &dyn Fn() -> Vec<DeriveResolution>,
1126 ) -> Result<(), Indeterminate>;
1127 fn take_derive_resolutions(&mut self, expn_id: LocalExpnId) -> Option<Vec<DeriveResolution>>;
1130 fn cfg_accessible(
1132 &mut self,
1133 expn_id: LocalExpnId,
1134 path: &ast::Path,
1135 ) -> Result<bool, Indeterminate>;
1136 fn macro_accessible(
1137 &mut self,
1138 expn_id: LocalExpnId,
1139 path: &ast::Path,
1140 ) -> Result<bool, Indeterminate>;
1141
1142 fn get_proc_macro_quoted_span(&self, krate: CrateNum, id: usize) -> Span;
1145
1146 fn declare_proc_macro(&mut self, id: NodeId);
1153
1154 fn append_stripped_cfg_item(
1155 &mut self,
1156 parent_node: NodeId,
1157 ident: Ident,
1158 cfg: CfgEntry,
1159 cfg_span: Span,
1160 );
1161
1162 fn registered_tools(&self) -> &RegisteredTools;
1164
1165 fn register_glob_delegation(&mut self, invoc_id: LocalExpnId);
1167
1168 fn glob_delegation_suffixes(
1170 &self,
1171 trait_def_id: DefId,
1172 impl_def_id: LocalDefId,
1173 star_span: Span,
1174 ) -> Result<Vec<(Ident, Option<Ident>)>, Indeterminate>;
1175
1176 fn insert_impl_trait_name(&mut self, id: NodeId, name: Symbol);
1179
1180 fn mark_scope_with_compile_error(&mut self, parent_node: NodeId);
1183}
1184
1185pub trait LintStoreExpand {
1186 fn pre_expansion_lint(
1187 &self,
1188 sess: &Session,
1189 features: &Features,
1190 registered_tools: &RegisteredTools,
1191 node_id: NodeId,
1192 attrs: &[Attribute],
1193 items: &[Box<Item>],
1194 name: Symbol,
1195 );
1196}
1197
1198type LintStoreExpandDyn<'a> = Option<&'a (dyn LintStoreExpand + 'a)>;
1199
1200#[derive(#[automatically_derived]
impl ::core::fmt::Debug for ModuleData {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f, "ModuleData",
"mod_path", &self.mod_path, "file_path_stack",
&self.file_path_stack, "dir_path", &&self.dir_path)
}
}Debug, #[automatically_derived]
impl ::core::clone::Clone for ModuleData {
#[inline]
fn clone(&self) -> ModuleData {
ModuleData {
mod_path: ::core::clone::Clone::clone(&self.mod_path),
file_path_stack: ::core::clone::Clone::clone(&self.file_path_stack),
dir_path: ::core::clone::Clone::clone(&self.dir_path),
}
}
}Clone, #[automatically_derived]
impl ::core::default::Default for ModuleData {
#[inline]
fn default() -> ModuleData {
ModuleData {
mod_path: ::core::default::Default::default(),
file_path_stack: ::core::default::Default::default(),
dir_path: ::core::default::Default::default(),
}
}
}Default)]
1201pub struct ModuleData {
1202 pub mod_path: Vec<Ident>,
1204 pub file_path_stack: Vec<PathBuf>,
1207 pub dir_path: PathBuf,
1210}
1211
1212impl ModuleData {
1213 pub fn with_dir_path(&self, dir_path: PathBuf) -> ModuleData {
1214 ModuleData {
1215 mod_path: self.mod_path.clone(),
1216 file_path_stack: self.file_path_stack.clone(),
1217 dir_path,
1218 }
1219 }
1220}
1221
1222#[derive(#[automatically_derived]
impl ::core::clone::Clone for ExpansionData {
#[inline]
fn clone(&self) -> ExpansionData {
ExpansionData {
id: ::core::clone::Clone::clone(&self.id),
depth: ::core::clone::Clone::clone(&self.depth),
module: ::core::clone::Clone::clone(&self.module),
dir_ownership: ::core::clone::Clone::clone(&self.dir_ownership),
lint_node_id: ::core::clone::Clone::clone(&self.lint_node_id),
is_trailing_mac: ::core::clone::Clone::clone(&self.is_trailing_mac),
}
}
}Clone)]
1223pub struct ExpansionData {
1224 pub id: LocalExpnId,
1225 pub depth: usize,
1226 pub module: Rc<ModuleData>,
1227 pub dir_ownership: DirOwnership,
1228 pub lint_node_id: NodeId,
1230 pub is_trailing_mac: bool,
1231}
1232
1233pub struct ExtCtxt<'a> {
1237 pub sess: &'a Session,
1238 pub ecfg: expand::ExpansionConfig<'a>,
1239 pub num_standard_library_imports: usize,
1240 pub reduced_recursion_limit: Option<(Limit, ErrorGuaranteed)>,
1241 pub root_path: PathBuf,
1242 pub resolver: &'a mut dyn ResolverExpand,
1243 pub current_expansion: ExpansionData,
1244 pub force_mode: bool,
1247 pub expansions: FxIndexMap<Span, Vec<String>>,
1248 pub(super) lint_store: LintStoreExpandDyn<'a>,
1250 pub buffered_early_lint: Vec<BufferedEarlyLint>,
1252 pub(super) expanded_inert_attrs: MarkedAttrs,
1256 pub macro_stats: FxHashMap<(Symbol, MacroKind), MacroStat>,
1258 pub nb_macro_errors: usize,
1259}
1260
1261impl<'a> ExtCtxt<'a> {
1262 pub fn new(
1263 sess: &'a Session,
1264 ecfg: expand::ExpansionConfig<'a>,
1265 resolver: &'a mut dyn ResolverExpand,
1266 lint_store: LintStoreExpandDyn<'a>,
1267 ) -> ExtCtxt<'a> {
1268 ExtCtxt {
1269 sess,
1270 ecfg,
1271 num_standard_library_imports: 0,
1272 reduced_recursion_limit: None,
1273 resolver,
1274 lint_store,
1275 root_path: PathBuf::new(),
1276 current_expansion: ExpansionData {
1277 id: LocalExpnId::ROOT,
1278 depth: 0,
1279 module: Default::default(),
1280 dir_ownership: DirOwnership::Owned { relative: None },
1281 lint_node_id: ast::CRATE_NODE_ID,
1282 is_trailing_mac: false,
1283 },
1284 force_mode: false,
1285 expansions: FxIndexMap::default(),
1286 expanded_inert_attrs: MarkedAttrs::new(),
1287 buffered_early_lint: ::alloc::vec::Vec::new()vec![],
1288 macro_stats: Default::default(),
1289 nb_macro_errors: 0,
1290 }
1291 }
1292
1293 pub fn dcx(&self) -> DiagCtxtHandle<'a> {
1294 self.sess.dcx()
1295 }
1296
1297 pub fn expander<'b>(&'b mut self) -> expand::MacroExpander<'b, 'a> {
1299 expand::MacroExpander::new(self, false)
1300 }
1301
1302 pub fn monotonic_expander<'b>(&'b mut self) -> expand::MacroExpander<'b, 'a> {
1305 expand::MacroExpander::new(self, true)
1306 }
1307 pub fn new_parser_from_tts(&self, stream: TokenStream) -> Parser<'a> {
1308 Parser::new(&self.sess.psess, stream, MACRO_ARGUMENTS)
1309 }
1310 pub fn source_map(&self) -> &'a SourceMap {
1311 self.sess.psess.source_map()
1312 }
1313 pub fn psess(&self) -> &'a ParseSess {
1314 &self.sess.psess
1315 }
1316 pub fn call_site(&self) -> Span {
1317 self.current_expansion.id.expn_data().call_site
1318 }
1319
1320 pub(crate) fn expansion_descr(&self) -> String {
1322 let expn_data = self.current_expansion.id.expn_data();
1323 expn_data.kind.descr()
1324 }
1325
1326 pub fn with_def_site_ctxt(&self, span: Span) -> Span {
1329 span.with_def_site_ctxt(self.current_expansion.id.to_expn_id())
1330 }
1331
1332 pub fn with_call_site_ctxt(&self, span: Span) -> Span {
1335 span.with_call_site_ctxt(self.current_expansion.id.to_expn_id())
1336 }
1337
1338 pub fn with_mixed_site_ctxt(&self, span: Span) -> Span {
1341 span.with_mixed_site_ctxt(self.current_expansion.id.to_expn_id())
1342 }
1343
1344 pub fn expansion_cause(&self) -> Option<Span> {
1348 self.current_expansion.id.expansion_cause()
1349 }
1350
1351 pub fn macro_error_and_trace_macros_diag(&mut self) {
1353 self.nb_macro_errors += 1;
1354 self.trace_macros_diag();
1355 }
1356
1357 pub fn trace_macros_diag(&mut self) {
1358 for (span, notes) in self.expansions.iter() {
1359 let mut db = self.dcx().create_note(errors::TraceMacro { span: *span });
1360 for note in notes {
1361 db.note(note.clone());
1362 }
1363 db.emit();
1364 }
1365 self.expansions.clear();
1367 }
1368 pub fn trace_macros(&self) -> bool {
1369 self.ecfg.trace_mac
1370 }
1371 pub fn set_trace_macros(&mut self, x: bool) {
1372 self.ecfg.trace_mac = x
1373 }
1374 pub fn std_path(&self, components: &[Symbol]) -> Vec<Ident> {
1375 let def_site = self.with_def_site_ctxt(DUMMY_SP);
1376 iter::once(Ident::new(kw::DollarCrate, def_site))
1377 .chain(components.iter().map(|&s| Ident::with_dummy_span(s)))
1378 .collect()
1379 }
1380 pub fn def_site_path(&self, components: &[Symbol]) -> Vec<Ident> {
1381 let def_site = self.with_def_site_ctxt(DUMMY_SP);
1382 components.iter().map(|&s| Ident::new(s, def_site)).collect()
1383 }
1384
1385 pub fn check_unused_macros(&mut self) {
1386 self.resolver.check_unused_macros();
1387 }
1388}
1389
1390pub fn resolve_path(sess: &Session, path: impl Into<PathBuf>, span: Span) -> PResult<'_, PathBuf> {
1394 let path = path.into();
1395
1396 if !path.is_absolute() {
1399 let callsite = span.source_callsite();
1400 let source_map = sess.source_map();
1401 let Some(mut base_path) = source_map.span_to_filename(callsite).into_local_path() else {
1402 return Err(sess.dcx().create_err(errors::ResolveRelativePath {
1403 span,
1404 path: source_map
1405 .filename_for_diagnostics(&source_map.span_to_filename(callsite))
1406 .to_string(),
1407 }));
1408 };
1409 base_path.pop();
1410 base_path.push(path);
1411 Ok(base_path)
1412 } else {
1413 match path.components().next() {
1416 Some(Prefix(prefix)) if prefix.kind().is_verbatim() => Ok(path.components().collect()),
1417 _ => Ok(path),
1418 }
1419 }
1420}