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::MarkedAttrs;
10use rustc_ast::token::MetaVarKind;
11use rustc_ast::tokenstream::TokenStream;
12use rustc_ast::visit::{AssocCtxt, Visitor};
13use rustc_ast::{self as ast, AttrVec, Attribute, HasAttrs, Item, NodeId, PatKind, Safety};
14use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
15use rustc_data_structures::sync;
16use rustc_errors::{BufferedEarlyLint, DiagCtxtHandle, ErrorGuaranteed, PResult};
17use rustc_feature::Features;
18use rustc_hir as hir;
19use rustc_hir::attrs::{AttributeKind, CfgEntry, CollapseMacroDebuginfo, Deprecation};
20use rustc_hir::def::MacroKinds;
21use rustc_hir::limit::Limit;
22use rustc_hir::{Stability, find_attr};
23use rustc_lint_defs::RegisteredTools;
24use rustc_parse::MACRO_ARGUMENTS;
25use rustc_parse::parser::{AllowConstBlockItems, ForceCollect, Parser};
26use rustc_session::Session;
27use rustc_session::parse::ParseSess;
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::errors;
37use crate::expand::{self, AstFragment, Invocation};
38use crate::mbe::macro_rules::ParserAnyMacro;
39use crate::module::DirOwnership;
40use crate::stats::MacroStat;
41
42#[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)]
46pub enum Annotatable {
47 Item(Box<ast::Item>),
48 AssocItem(Box<ast::AssocItem>, AssocCtxt),
49 ForeignItem(Box<ast::ForeignItem>),
50 Stmt(Box<ast::Stmt>),
51 Expr(Box<ast::Expr>),
52 Arm(ast::Arm),
53 ExprField(ast::ExprField),
54 PatField(ast::PatField),
55 GenericParam(ast::GenericParam),
56 Param(ast::Param),
57 FieldDef(ast::FieldDef),
58 Variant(ast::Variant),
59 WherePredicate(ast::WherePredicate),
60 Crate(ast::Crate),
61}
62
63impl Annotatable {
64 pub fn span(&self) -> Span {
65 match self {
66 Annotatable::Item(item) => item.span,
67 Annotatable::AssocItem(assoc_item, _) => assoc_item.span,
68 Annotatable::ForeignItem(foreign_item) => foreign_item.span,
69 Annotatable::Stmt(stmt) => stmt.span,
70 Annotatable::Expr(expr) => expr.span,
71 Annotatable::Arm(arm) => arm.span,
72 Annotatable::ExprField(field) => field.span,
73 Annotatable::PatField(fp) => fp.pat.span,
74 Annotatable::GenericParam(gp) => gp.ident.span,
75 Annotatable::Param(p) => p.span,
76 Annotatable::FieldDef(sf) => sf.span,
77 Annotatable::Variant(v) => v.span,
78 Annotatable::WherePredicate(wp) => wp.span,
79 Annotatable::Crate(c) => c.spans.inner_span,
80 }
81 }
82
83 pub fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) {
84 match self {
85 Annotatable::Item(item) => item.visit_attrs(f),
86 Annotatable::AssocItem(assoc_item, _) => assoc_item.visit_attrs(f),
87 Annotatable::ForeignItem(foreign_item) => foreign_item.visit_attrs(f),
88 Annotatable::Stmt(stmt) => stmt.visit_attrs(f),
89 Annotatable::Expr(expr) => expr.visit_attrs(f),
90 Annotatable::Arm(arm) => arm.visit_attrs(f),
91 Annotatable::ExprField(field) => field.visit_attrs(f),
92 Annotatable::PatField(fp) => fp.visit_attrs(f),
93 Annotatable::GenericParam(gp) => gp.visit_attrs(f),
94 Annotatable::Param(p) => p.visit_attrs(f),
95 Annotatable::FieldDef(sf) => sf.visit_attrs(f),
96 Annotatable::Variant(v) => v.visit_attrs(f),
97 Annotatable::WherePredicate(wp) => wp.visit_attrs(f),
98 Annotatable::Crate(c) => c.visit_attrs(f),
99 }
100 }
101
102 pub fn visit_with<'a, V: Visitor<'a>>(&'a self, visitor: &mut V) -> V::Result {
103 match self {
104 Annotatable::Item(item) => visitor.visit_item(item),
105 Annotatable::AssocItem(item, ctxt) => visitor.visit_assoc_item(item, *ctxt),
106 Annotatable::ForeignItem(foreign_item) => visitor.visit_foreign_item(foreign_item),
107 Annotatable::Stmt(stmt) => visitor.visit_stmt(stmt),
108 Annotatable::Expr(expr) => visitor.visit_expr(expr),
109 Annotatable::Arm(arm) => visitor.visit_arm(arm),
110 Annotatable::ExprField(field) => visitor.visit_expr_field(field),
111 Annotatable::PatField(fp) => visitor.visit_pat_field(fp),
112 Annotatable::GenericParam(gp) => visitor.visit_generic_param(gp),
113 Annotatable::Param(p) => visitor.visit_param(p),
114 Annotatable::FieldDef(sf) => visitor.visit_field_def(sf),
115 Annotatable::Variant(v) => visitor.visit_variant(v),
116 Annotatable::WherePredicate(wp) => visitor.visit_where_predicate(wp),
117 Annotatable::Crate(c) => visitor.visit_crate(c),
118 }
119 }
120
121 pub fn to_tokens(&self) -> TokenStream {
122 match self {
123 Annotatable::Item(node) => TokenStream::from_ast(node),
124 Annotatable::AssocItem(node, _) => TokenStream::from_ast(node),
125 Annotatable::ForeignItem(node) => TokenStream::from_ast(node),
126 Annotatable::Stmt(node) => {
127 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));
128 TokenStream::from_ast(node)
129 }
130 Annotatable::Expr(node) => TokenStream::from_ast(node),
131 Annotatable::Arm(..)
132 | Annotatable::ExprField(..)
133 | Annotatable::PatField(..)
134 | Annotatable::GenericParam(..)
135 | Annotatable::Param(..)
136 | Annotatable::FieldDef(..)
137 | Annotatable::Variant(..)
138 | Annotatable::WherePredicate(..)
139 | Annotatable::Crate(..) => { ::core::panicking::panic_fmt(format_args!("unexpected annotatable")); }panic!("unexpected annotatable"),
140 }
141 }
142
143 pub fn expect_item(self) -> Box<ast::Item> {
144 match self {
145 Annotatable::Item(i) => i,
146 _ => { ::core::panicking::panic_fmt(format_args!("expected Item")); }panic!("expected Item"),
147 }
148 }
149
150 pub fn expect_trait_item(self) -> Box<ast::AssocItem> {
151 match self {
152 Annotatable::AssocItem(i, AssocCtxt::Trait) => i,
153 _ => { ::core::panicking::panic_fmt(format_args!("expected Item")); }panic!("expected Item"),
154 }
155 }
156
157 pub fn expect_impl_item(self) -> Box<ast::AssocItem> {
158 match self {
159 Annotatable::AssocItem(i, AssocCtxt::Impl { .. }) => i,
160 _ => { ::core::panicking::panic_fmt(format_args!("expected Item")); }panic!("expected Item"),
161 }
162 }
163
164 pub fn expect_foreign_item(self) -> Box<ast::ForeignItem> {
165 match self {
166 Annotatable::ForeignItem(i) => i,
167 _ => { ::core::panicking::panic_fmt(format_args!("expected foreign item")); }panic!("expected foreign item"),
168 }
169 }
170
171 pub fn expect_stmt(self) -> ast::Stmt {
172 match self {
173 Annotatable::Stmt(stmt) => *stmt,
174 _ => { ::core::panicking::panic_fmt(format_args!("expected statement")); }panic!("expected statement"),
175 }
176 }
177
178 pub fn expect_expr(self) -> Box<ast::Expr> {
179 match self {
180 Annotatable::Expr(expr) => expr,
181 _ => { ::core::panicking::panic_fmt(format_args!("expected expression")); }panic!("expected expression"),
182 }
183 }
184
185 pub fn expect_arm(self) -> ast::Arm {
186 match self {
187 Annotatable::Arm(arm) => arm,
188 _ => { ::core::panicking::panic_fmt(format_args!("expected match arm")); }panic!("expected match arm"),
189 }
190 }
191
192 pub fn expect_expr_field(self) -> ast::ExprField {
193 match self {
194 Annotatable::ExprField(field) => field,
195 _ => { ::core::panicking::panic_fmt(format_args!("expected field")); }panic!("expected field"),
196 }
197 }
198
199 pub fn expect_pat_field(self) -> ast::PatField {
200 match self {
201 Annotatable::PatField(fp) => fp,
202 _ => { ::core::panicking::panic_fmt(format_args!("expected field pattern")); }panic!("expected field pattern"),
203 }
204 }
205
206 pub fn expect_generic_param(self) -> ast::GenericParam {
207 match self {
208 Annotatable::GenericParam(gp) => gp,
209 _ => { ::core::panicking::panic_fmt(format_args!("expected generic parameter")); }panic!("expected generic parameter"),
210 }
211 }
212
213 pub fn expect_param(self) -> ast::Param {
214 match self {
215 Annotatable::Param(param) => param,
216 _ => { ::core::panicking::panic_fmt(format_args!("expected parameter")); }panic!("expected parameter"),
217 }
218 }
219
220 pub fn expect_field_def(self) -> ast::FieldDef {
221 match self {
222 Annotatable::FieldDef(sf) => sf,
223 _ => { ::core::panicking::panic_fmt(format_args!("expected struct field")); }panic!("expected struct field"),
224 }
225 }
226
227 pub fn expect_variant(self) -> ast::Variant {
228 match self {
229 Annotatable::Variant(v) => v,
230 _ => { ::core::panicking::panic_fmt(format_args!("expected variant")); }panic!("expected variant"),
231 }
232 }
233
234 pub fn expect_where_predicate(self) -> ast::WherePredicate {
235 match self {
236 Annotatable::WherePredicate(wp) => wp,
237 _ => { ::core::panicking::panic_fmt(format_args!("expected where predicate")); }panic!("expected where predicate"),
238 }
239 }
240
241 pub fn expect_crate(self) -> ast::Crate {
242 match self {
243 Annotatable::Crate(krate) => krate,
244 _ => { ::core::panicking::panic_fmt(format_args!("expected krate")); }panic!("expected krate"),
245 }
246 }
247}
248
249pub enum ExpandResult<T, U> {
252 Ready(T),
254 Retry(U),
256}
257
258impl<T, U> ExpandResult<T, U> {
259 pub fn map<E, F: FnOnce(T) -> E>(self, f: F) -> ExpandResult<E, U> {
260 match self {
261 ExpandResult::Ready(t) => ExpandResult::Ready(f(t)),
262 ExpandResult::Retry(u) => ExpandResult::Retry(u),
263 }
264 }
265}
266
267impl<'cx> MacroExpanderResult<'cx> {
268 pub fn from_tts(
272 cx: &'cx mut ExtCtxt<'_>,
273 tts: TokenStream,
274 site_span: Span,
275 arm_span: Span,
276 macro_ident: Ident,
277 ) -> Self {
278 let is_local = true;
280
281 let parser = 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>(
382 &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>(
399 &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
412macro_rules! make_stmts_default {
414 ($me:expr) => {
415 $me.make_expr().map(|e| {
416 smallvec![ast::Stmt {
417 id: ast::DUMMY_NODE_ID,
418 span: e.span,
419 kind: ast::StmtKind::Expr(e),
420 }]
421 })
422 };
423}
424
425pub trait MacResult {
428 fn make_expr(self: Box<Self>) -> Option<Box<ast::Expr>> {
430 None
431 }
432
433 fn make_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::Item>; 1]>> {
435 None
436 }
437
438 fn make_impl_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
440 None
441 }
442
443 fn make_trait_impl_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
445 None
446 }
447
448 fn make_trait_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
450 None
451 }
452
453 fn make_foreign_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::ForeignItem>; 1]>> {
455 None
456 }
457
458 fn make_pat(self: Box<Self>) -> Option<Box<ast::Pat>> {
460 None
461 }
462
463 fn make_stmts(self: Box<Self>) -> Option<SmallVec<[ast::Stmt; 1]>> {
468 self.make_expr().map(|e|
{
{
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(<[_]>::into_vec(::alloc::boxed::box_new([ast::Stmt {
id: ast::DUMMY_NODE_ID,
span: e.span,
kind: ast::StmtKind::Expr(e),
}])))
}
}
})make_stmts_default!(self)
469 }
470
471 fn make_ty(self: Box<Self>) -> Option<Box<ast::Ty>> {
472 None
473 }
474
475 fn make_arms(self: Box<Self>) -> Option<SmallVec<[ast::Arm; 1]>> {
476 None
477 }
478
479 fn make_expr_fields(self: Box<Self>) -> Option<SmallVec<[ast::ExprField; 1]>> {
480 None
481 }
482
483 fn make_pat_fields(self: Box<Self>) -> Option<SmallVec<[ast::PatField; 1]>> {
484 None
485 }
486
487 fn make_generic_params(self: Box<Self>) -> Option<SmallVec<[ast::GenericParam; 1]>> {
488 None
489 }
490
491 fn make_params(self: Box<Self>) -> Option<SmallVec<[ast::Param; 1]>> {
492 None
493 }
494
495 fn make_field_defs(self: Box<Self>) -> Option<SmallVec<[ast::FieldDef; 1]>> {
496 None
497 }
498
499 fn make_variants(self: Box<Self>) -> Option<SmallVec<[ast::Variant; 1]>> {
500 None
501 }
502
503 fn make_where_predicates(self: Box<Self>) -> Option<SmallVec<[ast::WherePredicate; 1]>> {
504 None
505 }
506
507 fn make_crate(self: Box<Self>) -> Option<ast::Crate> {
508 ::core::panicking::panic("internal error: entered unreachable code")unreachable!()
510 }
511}
512
513macro_rules! make_MacEager {
514 ( $( $fld:ident: $t:ty, )* ) => {
515 #[derive(Default)]
518 pub struct MacEager {
519 $(
520 pub $fld: Option<$t>,
521 )*
522 }
523
524 impl MacEager {
525 $(
526 pub fn $fld(v: $t) -> Box<dyn MacResult> {
527 Box::new(MacEager {
528 $fld: Some(v),
529 ..Default::default()
530 })
531 }
532 )*
533 }
534 }
535}
536
537pub 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! {
538 expr: Box<ast::Expr>,
539 pat: Box<ast::Pat>,
540 items: SmallVec<[Box<ast::Item>; 1]>,
541 impl_items: SmallVec<[Box<ast::AssocItem>; 1]>,
542 trait_items: SmallVec<[Box<ast::AssocItem>; 1]>,
543 foreign_items: SmallVec<[Box<ast::ForeignItem>; 1]>,
544 stmts: SmallVec<[ast::Stmt; 1]>,
545 ty: Box<ast::Ty>,
546}
547
548impl MacResult for MacEager {
549 fn make_expr(self: Box<Self>) -> Option<Box<ast::Expr>> {
550 self.expr
551 }
552
553 fn make_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::Item>; 1]>> {
554 self.items
555 }
556
557 fn make_impl_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
558 self.impl_items
559 }
560
561 fn make_trait_impl_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
562 self.impl_items
563 }
564
565 fn make_trait_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
566 self.trait_items
567 }
568
569 fn make_foreign_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::ForeignItem>; 1]>> {
570 self.foreign_items
571 }
572
573 fn make_stmts(self: Box<Self>) -> Option<SmallVec<[ast::Stmt; 1]>> {
574 match self.stmts.as_ref().map_or(0, |s| s.len()) {
575 0 => self.make_expr().map(|e|
{
{
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(<[_]>::into_vec(::alloc::boxed::box_new([ast::Stmt {
id: ast::DUMMY_NODE_ID,
span: e.span,
kind: ast::StmtKind::Expr(e),
}])))
}
}
})make_stmts_default!(self),
576 _ => self.stmts,
577 }
578 }
579
580 fn make_pat(self: Box<Self>) -> Option<Box<ast::Pat>> {
581 if let Some(p) = self.pat {
582 return Some(p);
583 }
584 if let Some(e) = self.expr {
585 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(_)) {
586 return Some(Box::new(ast::Pat {
587 id: ast::DUMMY_NODE_ID,
588 span: e.span,
589 kind: PatKind::Expr(e),
590 tokens: None,
591 }));
592 }
593 }
594 None
595 }
596
597 fn make_ty(self: Box<Self>) -> Option<Box<ast::Ty>> {
598 self.ty
599 }
600}
601
602#[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)]
605pub struct DummyResult {
606 guar: Option<ErrorGuaranteed>,
607 span: Span,
608}
609
610impl DummyResult {
611 pub fn any(span: Span, guar: ErrorGuaranteed) -> Box<dyn MacResult + 'static> {
616 Box::new(DummyResult { guar: Some(guar), span })
617 }
618
619 pub fn any_valid(span: Span) -> Box<dyn MacResult + 'static> {
621 Box::new(DummyResult { guar: None, span })
622 }
623
624 pub fn raw_expr(sp: Span, guar: Option<ErrorGuaranteed>) -> Box<ast::Expr> {
626 Box::new(ast::Expr {
627 id: ast::DUMMY_NODE_ID,
628 kind: if let Some(guar) = guar {
629 ast::ExprKind::Err(guar)
630 } else {
631 ast::ExprKind::Tup(ThinVec::new())
632 },
633 span: sp,
634 attrs: ast::AttrVec::new(),
635 tokens: None,
636 })
637 }
638}
639
640impl MacResult for DummyResult {
641 fn make_expr(self: Box<DummyResult>) -> Option<Box<ast::Expr>> {
642 Some(DummyResult::raw_expr(self.span, self.guar))
643 }
644
645 fn make_pat(self: Box<DummyResult>) -> Option<Box<ast::Pat>> {
646 Some(Box::new(ast::Pat {
647 id: ast::DUMMY_NODE_ID,
648 kind: PatKind::Wild,
649 span: self.span,
650 tokens: None,
651 }))
652 }
653
654 fn make_items(self: Box<DummyResult>) -> Option<SmallVec<[Box<ast::Item>; 1]>> {
655 Some(SmallVec::new())
656 }
657
658 fn make_impl_items(self: Box<DummyResult>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
659 Some(SmallVec::new())
660 }
661
662 fn make_trait_impl_items(self: Box<DummyResult>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
663 Some(SmallVec::new())
664 }
665
666 fn make_trait_items(self: Box<DummyResult>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
667 Some(SmallVec::new())
668 }
669
670 fn make_foreign_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::ForeignItem>; 1]>> {
671 Some(SmallVec::new())
672 }
673
674 fn make_stmts(self: Box<DummyResult>) -> Option<SmallVec<[ast::Stmt; 1]>> {
675 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(<[_]>::into_vec(::alloc::boxed::box_new([ast::Stmt {
id: ast::DUMMY_NODE_ID,
kind: ast::StmtKind::Expr(DummyResult::raw_expr(self.span,
self.guar)),
span: self.span,
}])))
}
}smallvec![ast::Stmt {
676 id: ast::DUMMY_NODE_ID,
677 kind: ast::StmtKind::Expr(DummyResult::raw_expr(self.span, self.guar)),
678 span: self.span,
679 }])
680 }
681
682 fn make_ty(self: Box<DummyResult>) -> Option<Box<ast::Ty>> {
683 Some(Box::new(ast::Ty {
687 id: ast::DUMMY_NODE_ID,
688 kind: ast::TyKind::Tup(ThinVec::new()),
689 span: self.span,
690 tokens: None,
691 }))
692 }
693
694 fn make_arms(self: Box<DummyResult>) -> Option<SmallVec<[ast::Arm; 1]>> {
695 Some(SmallVec::new())
696 }
697
698 fn make_expr_fields(self: Box<DummyResult>) -> Option<SmallVec<[ast::ExprField; 1]>> {
699 Some(SmallVec::new())
700 }
701
702 fn make_pat_fields(self: Box<DummyResult>) -> Option<SmallVec<[ast::PatField; 1]>> {
703 Some(SmallVec::new())
704 }
705
706 fn make_generic_params(self: Box<DummyResult>) -> Option<SmallVec<[ast::GenericParam; 1]>> {
707 Some(SmallVec::new())
708 }
709
710 fn make_params(self: Box<DummyResult>) -> Option<SmallVec<[ast::Param; 1]>> {
711 Some(SmallVec::new())
712 }
713
714 fn make_field_defs(self: Box<DummyResult>) -> Option<SmallVec<[ast::FieldDef; 1]>> {
715 Some(SmallVec::new())
716 }
717
718 fn make_variants(self: Box<DummyResult>) -> Option<SmallVec<[ast::Variant; 1]>> {
719 Some(SmallVec::new())
720 }
721
722 fn make_crate(self: Box<DummyResult>) -> Option<ast::Crate> {
723 Some(ast::Crate {
724 attrs: Default::default(),
725 items: Default::default(),
726 spans: Default::default(),
727 id: ast::DUMMY_NODE_ID,
728 is_placeholder: Default::default(),
729 })
730 }
731}
732
733#[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)]
735pub enum SyntaxExtensionKind {
736 MacroRules(Arc<crate::MacroRulesMacroExpander>),
738
739 Bang(
741 Arc<dyn BangProcMacro + sync::DynSync + sync::DynSend>,
743 ),
744
745 LegacyBang(
747 Arc<dyn TTMacroExpander + sync::DynSync + sync::DynSend>,
749 ),
750
751 Attr(
753 Arc<dyn AttrProcMacro + sync::DynSync + sync::DynSend>,
757 ),
758
759 LegacyAttr(
761 Arc<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
765 ),
766
767 NonMacroAttr,
772
773 Derive(
775 Arc<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
783 ),
784
785 LegacyDerive(
787 Arc<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
790 ),
791
792 GlobDelegation(Arc<dyn GlobDelegationExpander + sync::DynSync + sync::DynSend>),
796}
797
798impl SyntaxExtensionKind {
799 pub fn as_legacy_bang(&self) -> Option<&(dyn TTMacroExpander + sync::DynSync + sync::DynSend)> {
803 match self {
804 SyntaxExtensionKind::LegacyBang(exp) => Some(exp.as_ref()),
805 SyntaxExtensionKind::MacroRules(exp) if exp.kinds().contains(MacroKinds::BANG) => {
806 Some(exp.as_ref())
807 }
808 _ => None,
809 }
810 }
811
812 pub fn as_attr(&self) -> Option<&(dyn AttrProcMacro + sync::DynSync + sync::DynSend)> {
816 match self {
817 SyntaxExtensionKind::Attr(exp) => Some(exp.as_ref()),
818 SyntaxExtensionKind::MacroRules(exp) if exp.kinds().contains(MacroKinds::ATTR) => {
819 Some(exp.as_ref())
820 }
821 _ => None,
822 }
823 }
824}
825
826pub struct SyntaxExtension {
828 pub kind: SyntaxExtensionKind,
830 pub span: Span,
832 pub allow_internal_unstable: Option<Arc<[Symbol]>>,
834 pub stability: Option<Stability>,
836 pub deprecation: Option<Deprecation>,
838 pub helper_attrs: Vec<Symbol>,
840 pub edition: Edition,
842 pub builtin_name: Option<Symbol>,
845 pub allow_internal_unsafe: bool,
847 pub local_inner_macros: bool,
849 pub collapse_debuginfo: bool,
852 pub hide_backtrace: bool,
855}
856
857impl SyntaxExtension {
858 pub fn macro_kinds(&self) -> MacroKinds {
860 match self.kind {
861 SyntaxExtensionKind::Bang(..)
862 | SyntaxExtensionKind::LegacyBang(..)
863 | SyntaxExtensionKind::GlobDelegation(..) => MacroKinds::BANG,
864 SyntaxExtensionKind::Attr(..)
865 | SyntaxExtensionKind::LegacyAttr(..)
866 | SyntaxExtensionKind::NonMacroAttr => MacroKinds::ATTR,
867 SyntaxExtensionKind::Derive(..) | SyntaxExtensionKind::LegacyDerive(..) => {
868 MacroKinds::DERIVE
869 }
870 SyntaxExtensionKind::MacroRules(ref m) => m.kinds(),
871 }
872 }
873
874 pub fn default(kind: SyntaxExtensionKind, edition: Edition) -> SyntaxExtension {
876 SyntaxExtension {
877 span: DUMMY_SP,
878 allow_internal_unstable: None,
879 stability: None,
880 deprecation: None,
881 helper_attrs: Vec::new(),
882 edition,
883 builtin_name: None,
884 kind,
885 allow_internal_unsafe: false,
886 local_inner_macros: false,
887 collapse_debuginfo: false,
888 hide_backtrace: false,
889 }
890 }
891
892 fn get_collapse_debuginfo(sess: &Session, attrs: &[hir::Attribute], ext: bool) -> bool {
899 let flag = sess.opts.cg.collapse_macro_debuginfo;
900 let attr =
901 if let Some(info) = {
'done:
{
for i in attrs {
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(AttributeKind::CollapseDebugInfo(info))
=> {
break 'done Some(info);
}
_ => {}
}
}
None
}
}find_attr!(attrs, AttributeKind::CollapseDebugInfo(info) => info) {
902 info.clone()
903 } else if {
{
'done:
{
for i in attrs {
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(AttributeKind::RustcBuiltinMacro {
.. }) => {
break 'done Some(());
}
_ => {}
}
}
None
}
}.is_some()
}find_attr!(attrs, AttributeKind::RustcBuiltinMacro { .. }) {
904 CollapseMacroDebuginfo::Yes
905 } else {
906 CollapseMacroDebuginfo::Unspecified
907 };
908
909 #[rustfmt::skip]
910 let collapse_table = [
911 [false, false, false, false],
912 [false, ext, ext, true],
913 [false, ext, ext, true],
914 [true, true, true, true],
915 ];
916 collapse_table[flag as usize][attr as usize]
917 }
918
919 fn get_hide_backtrace(attrs: &[hir::Attribute]) -> bool {
920 ast::attr::find_by_name(attrs, sym::rustc_diagnostic_item).is_some()
923 }
924
925 pub fn new(
928 sess: &Session,
929 kind: SyntaxExtensionKind,
930 span: Span,
931 helper_attrs: Vec<Symbol>,
932 edition: Edition,
933 name: Symbol,
934 attrs: &[hir::Attribute],
935 is_local: bool,
936 ) -> SyntaxExtension {
937 let allow_internal_unstable =
938 {
'done:
{
for i in attrs {
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(AttributeKind::AllowInternalUnstable(i,
_)) => {
break 'done Some(i);
}
_ => {}
}
}
None
}
}find_attr!(attrs, AttributeKind::AllowInternalUnstable(i, _) => i)
939 .map(|i| i.as_slice())
940 .unwrap_or_default();
941 let allow_internal_unsafe = {
{
'done:
{
for i in attrs {
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(AttributeKind::AllowInternalUnsafe(_))
=> {
break 'done Some(());
}
_ => {}
}
}
None
}
}.is_some()
}find_attr!(attrs, AttributeKind::AllowInternalUnsafe(_));
942
943 let local_inner_macros =
944 *{
'done:
{
for i in attrs {
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(AttributeKind::MacroExport {
local_inner_macros: l, .. }) => {
break 'done Some(l);
}
_ => {}
}
}
None
}
}find_attr!(attrs, AttributeKind::MacroExport {local_inner_macros: l, ..} => l)
945 .unwrap_or(&false);
946 let collapse_debuginfo = Self::get_collapse_debuginfo(sess, attrs, !is_local);
947 {
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:947",
"rustc_expand::base", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_expand/src/base.rs"),
::tracing_core::__macro_support::Option::Some(947u32),
::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);
948
949 let (builtin_name, helper_attrs) = match {
'done:
{
for i in attrs {
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(AttributeKind::RustcBuiltinMacro {
builtin_name, helper_attrs, .. }) => {
break 'done Some((builtin_name, helper_attrs));
}
_ => {}
}
}
None
}
}find_attr!(attrs, AttributeKind::RustcBuiltinMacro { builtin_name, helper_attrs, .. } => (builtin_name, helper_attrs))
950 {
951 Some((Some(name), helper_attrs)) => {
954 (Some(*name), helper_attrs.iter().copied().collect())
955 }
956 Some((None, _)) => (Some(name), Vec::new()),
957
958 None => (None, helper_attrs),
960 };
961 let hide_backtrace = builtin_name.is_some() || Self::get_hide_backtrace(attrs);
962
963 let stability = {
'done:
{
for i in attrs {
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(AttributeKind::Stability {
stability, .. }) => {
break 'done Some(*stability);
}
_ => {}
}
}
None
}
}find_attr!(attrs, AttributeKind::Stability { stability, .. } => *stability);
964
965 if let Some(sp) =
967 {
'done:
{
for i in attrs {
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(AttributeKind::RustcConstStability {
span, .. }) => {
break 'done Some(*span);
}
_ => {}
}
}
None
}
}find_attr!(attrs, AttributeKind::RustcConstStability { span, .. } => *span)
968 {
969 sess.dcx().emit_err(errors::MacroConstStability {
970 span: sp,
971 head_span: sess.source_map().guess_head_span(span),
972 });
973 }
974 if let Some(sp) = {
'done:
{
for i in attrs {
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(AttributeKind::RustcBodyStability {
span, .. }) => {
break 'done Some(*span);
}
_ => {}
}
}
None
}
}find_attr!(attrs, AttributeKind::RustcBodyStability{ span, .. } => *span)
975 {
976 sess.dcx().emit_err(errors::MacroBodyStability {
977 span: sp,
978 head_span: sess.source_map().guess_head_span(span),
979 });
980 }
981
982 SyntaxExtension {
983 kind,
984 span,
985 allow_internal_unstable: (!allow_internal_unstable.is_empty())
986 .then(|| allow_internal_unstable.iter().map(|i| i.0).collect::<Vec<_>>().into()),
988 stability,
989 deprecation: {
'done:
{
for i in attrs {
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(AttributeKind::Deprecation {
deprecation, .. }) => {
break 'done Some(*deprecation);
}
_ => {}
}
}
None
}
}find_attr!(
990 attrs,
991 AttributeKind::Deprecation { deprecation, .. } => *deprecation
992 ),
993 helper_attrs,
994 edition,
995 builtin_name,
996 allow_internal_unsafe,
997 local_inner_macros,
998 collapse_debuginfo,
999 hide_backtrace,
1000 }
1001 }
1002
1003 pub fn dummy_bang(edition: Edition) -> SyntaxExtension {
1005 fn expand(
1006 ecx: &mut ExtCtxt<'_>,
1007 span: Span,
1008 _ts: TokenStream,
1009 ) -> Result<TokenStream, ErrorGuaranteed> {
1010 Err(ecx.dcx().span_delayed_bug(span, "expanded a dummy bang macro"))
1011 }
1012 SyntaxExtension::default(SyntaxExtensionKind::Bang(Arc::new(expand)), edition)
1013 }
1014
1015 pub fn dummy_derive(edition: Edition) -> SyntaxExtension {
1017 fn expander(
1018 _: &mut ExtCtxt<'_>,
1019 _: Span,
1020 _: &ast::MetaItem,
1021 _: Annotatable,
1022 ) -> Vec<Annotatable> {
1023 Vec::new()
1024 }
1025 SyntaxExtension::default(SyntaxExtensionKind::Derive(Arc::new(expander)), edition)
1026 }
1027
1028 pub fn non_macro_attr(edition: Edition) -> SyntaxExtension {
1029 SyntaxExtension::default(SyntaxExtensionKind::NonMacroAttr, edition)
1030 }
1031
1032 pub fn glob_delegation(
1033 trait_def_id: DefId,
1034 impl_def_id: LocalDefId,
1035 edition: Edition,
1036 ) -> SyntaxExtension {
1037 struct GlobDelegationExpanderImpl {
1038 trait_def_id: DefId,
1039 impl_def_id: LocalDefId,
1040 }
1041 impl GlobDelegationExpander for GlobDelegationExpanderImpl {
1042 fn expand(
1043 &self,
1044 ecx: &mut ExtCtxt<'_>,
1045 ) -> ExpandResult<Vec<(Ident, Option<Ident>)>, ()> {
1046 match ecx.resolver.glob_delegation_suffixes(self.trait_def_id, self.impl_def_id) {
1047 Ok(suffixes) => ExpandResult::Ready(suffixes),
1048 Err(Indeterminate) if ecx.force_mode => ExpandResult::Ready(Vec::new()),
1049 Err(Indeterminate) => ExpandResult::Retry(()),
1050 }
1051 }
1052 }
1053
1054 let expander = GlobDelegationExpanderImpl { trait_def_id, impl_def_id };
1055 SyntaxExtension::default(SyntaxExtensionKind::GlobDelegation(Arc::new(expander)), edition)
1056 }
1057
1058 pub fn expn_data(
1059 &self,
1060 parent: LocalExpnId,
1061 call_site: Span,
1062 descr: Symbol,
1063 kind: MacroKind,
1064 macro_def_id: Option<DefId>,
1065 parent_module: Option<DefId>,
1066 ) -> ExpnData {
1067 ExpnData::new(
1068 ExpnKind::Macro(kind, descr),
1069 parent.to_expn_id(),
1070 call_site,
1071 self.span,
1072 self.allow_internal_unstable.clone(),
1073 self.edition,
1074 macro_def_id,
1075 parent_module,
1076 self.allow_internal_unsafe,
1077 self.local_inner_macros,
1078 self.collapse_debuginfo,
1079 self.hide_backtrace,
1080 )
1081 }
1082}
1083
1084pub struct Indeterminate;
1086
1087pub struct DeriveResolution {
1088 pub path: ast::Path,
1089 pub item: Annotatable,
1090 pub exts: Option<Arc<SyntaxExtension>>,
1094 pub is_const: bool,
1095}
1096
1097pub trait ResolverExpand {
1098 fn next_node_id(&mut self) -> NodeId;
1099 fn invocation_parent(&self, id: LocalExpnId) -> LocalDefId;
1100
1101 fn resolve_dollar_crates(&self);
1102 fn visit_ast_fragment_with_placeholders(
1103 &mut self,
1104 expn_id: LocalExpnId,
1105 fragment: &AstFragment,
1106 );
1107 fn register_builtin_macro(&mut self, name: Symbol, ext: SyntaxExtensionKind);
1108
1109 fn expansion_for_ast_pass(
1110 &mut self,
1111 call_site: Span,
1112 pass: AstPass,
1113 features: &[Symbol],
1114 parent_module_id: Option<NodeId>,
1115 ) -> LocalExpnId;
1116
1117 fn resolve_imports(&mut self);
1118
1119 fn resolve_macro_invocation(
1120 &mut self,
1121 invoc: &Invocation,
1122 eager_expansion_root: LocalExpnId,
1123 force: bool,
1124 ) -> Result<Arc<SyntaxExtension>, Indeterminate>;
1125
1126 fn record_macro_rule_usage(&mut self, mac_id: NodeId, rule_index: usize);
1127
1128 fn check_unused_macros(&mut self);
1129
1130 fn has_derive_copy(&self, expn_id: LocalExpnId) -> bool;
1133 fn resolve_derives(
1135 &mut self,
1136 expn_id: LocalExpnId,
1137 force: bool,
1138 derive_paths: &dyn Fn() -> Vec<DeriveResolution>,
1139 ) -> Result<(), Indeterminate>;
1140 fn take_derive_resolutions(&mut self, expn_id: LocalExpnId) -> Option<Vec<DeriveResolution>>;
1143 fn cfg_accessible(
1145 &mut self,
1146 expn_id: LocalExpnId,
1147 path: &ast::Path,
1148 ) -> Result<bool, Indeterminate>;
1149 fn macro_accessible(
1150 &mut self,
1151 expn_id: LocalExpnId,
1152 path: &ast::Path,
1153 ) -> Result<bool, Indeterminate>;
1154
1155 fn get_proc_macro_quoted_span(&self, krate: CrateNum, id: usize) -> Span;
1158
1159 fn declare_proc_macro(&mut self, id: NodeId);
1166
1167 fn append_stripped_cfg_item(
1168 &mut self,
1169 parent_node: NodeId,
1170 ident: Ident,
1171 cfg: CfgEntry,
1172 cfg_span: Span,
1173 );
1174
1175 fn registered_tools(&self) -> &RegisteredTools;
1177
1178 fn register_glob_delegation(&mut self, invoc_id: LocalExpnId);
1180
1181 fn glob_delegation_suffixes(
1183 &self,
1184 trait_def_id: DefId,
1185 impl_def_id: LocalDefId,
1186 ) -> Result<Vec<(Ident, Option<Ident>)>, Indeterminate>;
1187
1188 fn insert_impl_trait_name(&mut self, id: NodeId, name: Symbol);
1191
1192 fn mark_scope_with_compile_error(&mut self, parent_node: NodeId);
1195}
1196
1197pub trait LintStoreExpand {
1198 fn pre_expansion_lint(
1199 &self,
1200 sess: &Session,
1201 features: &Features,
1202 registered_tools: &RegisteredTools,
1203 node_id: NodeId,
1204 attrs: &[Attribute],
1205 items: &[Box<Item>],
1206 name: Symbol,
1207 );
1208}
1209
1210type LintStoreExpandDyn<'a> = Option<&'a (dyn LintStoreExpand + 'a)>;
1211
1212#[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)]
1213pub struct ModuleData {
1214 pub mod_path: Vec<Ident>,
1216 pub file_path_stack: Vec<PathBuf>,
1219 pub dir_path: PathBuf,
1222}
1223
1224impl ModuleData {
1225 pub fn with_dir_path(&self, dir_path: PathBuf) -> ModuleData {
1226 ModuleData {
1227 mod_path: self.mod_path.clone(),
1228 file_path_stack: self.file_path_stack.clone(),
1229 dir_path,
1230 }
1231 }
1232}
1233
1234#[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)]
1235pub struct ExpansionData {
1236 pub id: LocalExpnId,
1237 pub depth: usize,
1238 pub module: Rc<ModuleData>,
1239 pub dir_ownership: DirOwnership,
1240 pub lint_node_id: NodeId,
1242 pub is_trailing_mac: bool,
1243}
1244
1245pub struct ExtCtxt<'a> {
1249 pub sess: &'a Session,
1250 pub ecfg: expand::ExpansionConfig<'a>,
1251 pub num_standard_library_imports: usize,
1252 pub reduced_recursion_limit: Option<(Limit, ErrorGuaranteed)>,
1253 pub root_path: PathBuf,
1254 pub resolver: &'a mut dyn ResolverExpand,
1255 pub current_expansion: ExpansionData,
1256 pub force_mode: bool,
1259 pub expansions: FxIndexMap<Span, Vec<String>>,
1260 pub(super) lint_store: LintStoreExpandDyn<'a>,
1262 pub buffered_early_lint: Vec<BufferedEarlyLint>,
1264 pub(super) expanded_inert_attrs: MarkedAttrs,
1268 pub macro_stats: FxHashMap<(Symbol, MacroKind), MacroStat>,
1270 pub nb_macro_errors: usize,
1271}
1272
1273impl<'a> ExtCtxt<'a> {
1274 pub fn new(
1275 sess: &'a Session,
1276 ecfg: expand::ExpansionConfig<'a>,
1277 resolver: &'a mut dyn ResolverExpand,
1278 lint_store: LintStoreExpandDyn<'a>,
1279 ) -> ExtCtxt<'a> {
1280 ExtCtxt {
1281 sess,
1282 ecfg,
1283 num_standard_library_imports: 0,
1284 reduced_recursion_limit: None,
1285 resolver,
1286 lint_store,
1287 root_path: PathBuf::new(),
1288 current_expansion: ExpansionData {
1289 id: LocalExpnId::ROOT,
1290 depth: 0,
1291 module: Default::default(),
1292 dir_ownership: DirOwnership::Owned { relative: None },
1293 lint_node_id: ast::CRATE_NODE_ID,
1294 is_trailing_mac: false,
1295 },
1296 force_mode: false,
1297 expansions: FxIndexMap::default(),
1298 expanded_inert_attrs: MarkedAttrs::new(),
1299 buffered_early_lint: ::alloc::vec::Vec::new()vec![],
1300 macro_stats: Default::default(),
1301 nb_macro_errors: 0,
1302 }
1303 }
1304
1305 pub fn dcx(&self) -> DiagCtxtHandle<'a> {
1306 self.sess.dcx()
1307 }
1308
1309 pub fn expander<'b>(&'b mut self) -> expand::MacroExpander<'b, 'a> {
1311 expand::MacroExpander::new(self, false)
1312 }
1313
1314 pub fn monotonic_expander<'b>(&'b mut self) -> expand::MacroExpander<'b, 'a> {
1317 expand::MacroExpander::new(self, true)
1318 }
1319 pub fn new_parser_from_tts(&self, stream: TokenStream) -> Parser<'a> {
1320 Parser::new(&self.sess.psess, stream, MACRO_ARGUMENTS)
1321 }
1322 pub fn source_map(&self) -> &'a SourceMap {
1323 self.sess.psess.source_map()
1324 }
1325 pub fn psess(&self) -> &'a ParseSess {
1326 &self.sess.psess
1327 }
1328 pub fn call_site(&self) -> Span {
1329 self.current_expansion.id.expn_data().call_site
1330 }
1331
1332 pub(crate) fn expansion_descr(&self) -> String {
1334 let expn_data = self.current_expansion.id.expn_data();
1335 expn_data.kind.descr()
1336 }
1337
1338 pub fn with_def_site_ctxt(&self, span: Span) -> Span {
1341 span.with_def_site_ctxt(self.current_expansion.id.to_expn_id())
1342 }
1343
1344 pub fn with_call_site_ctxt(&self, span: Span) -> Span {
1347 span.with_call_site_ctxt(self.current_expansion.id.to_expn_id())
1348 }
1349
1350 pub fn with_mixed_site_ctxt(&self, span: Span) -> Span {
1353 span.with_mixed_site_ctxt(self.current_expansion.id.to_expn_id())
1354 }
1355
1356 pub fn expansion_cause(&self) -> Option<Span> {
1360 self.current_expansion.id.expansion_cause()
1361 }
1362
1363 pub fn macro_error_and_trace_macros_diag(&mut self) {
1365 self.nb_macro_errors += 1;
1366 self.trace_macros_diag();
1367 }
1368
1369 pub fn trace_macros_diag(&mut self) {
1370 for (span, notes) in self.expansions.iter() {
1371 let mut db = self.dcx().create_note(errors::TraceMacro { span: *span });
1372 for note in notes {
1373 db.note(note.clone());
1374 }
1375 db.emit();
1376 }
1377 self.expansions.clear();
1379 }
1380 pub fn trace_macros(&self) -> bool {
1381 self.ecfg.trace_mac
1382 }
1383 pub fn set_trace_macros(&mut self, x: bool) {
1384 self.ecfg.trace_mac = x
1385 }
1386 pub fn std_path(&self, components: &[Symbol]) -> Vec<Ident> {
1387 let def_site = self.with_def_site_ctxt(DUMMY_SP);
1388 iter::once(Ident::new(kw::DollarCrate, def_site))
1389 .chain(components.iter().map(|&s| Ident::with_dummy_span(s)))
1390 .collect()
1391 }
1392 pub fn def_site_path(&self, components: &[Symbol]) -> Vec<Ident> {
1393 let def_site = self.with_def_site_ctxt(DUMMY_SP);
1394 components.iter().map(|&s| Ident::new(s, def_site)).collect()
1395 }
1396
1397 pub fn check_unused_macros(&mut self) {
1398 self.resolver.check_unused_macros();
1399 }
1400}
1401
1402pub fn resolve_path(sess: &Session, path: impl Into<PathBuf>, span: Span) -> PResult<'_, PathBuf> {
1406 let path = path.into();
1407
1408 if !path.is_absolute() {
1411 let callsite = span.source_callsite();
1412 let source_map = sess.source_map();
1413 let Some(mut base_path) = source_map.span_to_filename(callsite).into_local_path() else {
1414 return Err(sess.dcx().create_err(errors::ResolveRelativePath {
1415 span,
1416 path: source_map
1417 .filename_for_diagnostics(&source_map.span_to_filename(callsite))
1418 .to_string(),
1419 }));
1420 };
1421 base_path.pop();
1422 base_path.push(path);
1423 Ok(base_path)
1424 } else {
1425 match path.components().next() {
1428 Some(Prefix(prefix)) if prefix.kind().is_verbatim() => Ok(path.components().collect()),
1429 _ => Ok(path),
1430 }
1431 }
1432}
1433
1434fn pretty_printing_compatibility_hack(item: &Item, psess: &ParseSess) {
1438 if let ast::ItemKind::Enum(ident, _, enum_def) = &item.kind
1439 && ident.name == sym::ProceduralMasqueradeDummyType
1440 && let [variant] = &*enum_def.variants
1441 && variant.ident.name == sym::Input
1442 && let FileName::Real(real) = psess.source_map().span_to_filename(ident.span)
1443 && let Some(c) = real
1444 .local_path()
1445 .unwrap_or(Path::new(""))
1446 .components()
1447 .flat_map(|c| c.as_os_str().to_str())
1448 .find(|c| c.starts_with("rental") || c.starts_with("allsorts-rental"))
1449 {
1450 let crate_matches = if c.starts_with("allsorts-rental") {
1451 true
1452 } else {
1453 let mut version = c.trim_start_matches("rental-").split('.');
1454 version.next() == Some("0")
1455 && version.next() == Some("5")
1456 && version.next().and_then(|c| c.parse::<u32>().ok()).is_some_and(|v| v < 6)
1457 };
1458
1459 if crate_matches {
1460 psess.dcx().emit_fatal(errors::ProcMacroBackCompat {
1461 crate_name: "rental".to_string(),
1462 fixed_version: "0.5.6".to_string(),
1463 });
1464 }
1465 }
1466}
1467
1468pub(crate) fn ann_pretty_printing_compatibility_hack(ann: &Annotatable, psess: &ParseSess) {
1469 let item = match ann {
1470 Annotatable::Item(item) => item,
1471 Annotatable::Stmt(stmt) => match &stmt.kind {
1472 ast::StmtKind::Item(item) => item,
1473 _ => return,
1474 },
1475 _ => return,
1476 };
1477 pretty_printing_compatibility_hack(item, psess)
1478}
1479
1480pub(crate) fn stream_pretty_printing_compatibility_hack(
1481 kind: MetaVarKind,
1482 stream: &TokenStream,
1483 psess: &ParseSess,
1484) {
1485 let item = match kind {
1486 MetaVarKind::Item => {
1487 let mut parser = Parser::new(psess, stream.clone(), None);
1488 parser
1490 .parse_item(ForceCollect::No, AllowConstBlockItems::No)
1491 .expect("failed to reparse item")
1492 .expect("an actual item")
1493 }
1494 MetaVarKind::Stmt => {
1495 let mut parser = Parser::new(psess, stream.clone(), None);
1496 let stmt = parser
1498 .parse_stmt(ForceCollect::No)
1499 .expect("failed to reparse")
1500 .expect("an actual stmt");
1501 match &stmt.kind {
1502 ast::StmtKind::Item(item) => item.clone(),
1503 _ => return,
1504 }
1505 }
1506 _ => return,
1507 };
1508 pretty_printing_compatibility_hack(&item, psess)
1509}