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::{Limit, 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::{Stability, find_attr};
21use rustc_lint_defs::RegisteredTools;
22use rustc_parse::MACRO_ARGUMENTS;
23use rustc_parse::parser::Parser;
24use rustc_session::Session;
25use rustc_session::parse::ParseSess;
26use rustc_span::def_id::{CrateNum, DefId, LocalDefId, ModId};
27use rustc_span::edition::Edition;
28use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId, MacroKind};
29use rustc_span::source_map::SourceMap;
30use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw};
31use smallvec::{SmallVec, smallvec};
32use thin_vec::ThinVec;
33
34use crate::diagnostics;
35use crate::expand::{self, AstFragment, Invocation};
36use crate::mbe::macro_rules::ParserAnyMacro;
37use crate::module::DirOwnership;
38use crate::stats::MacroStat;
39
40#[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 {
123 match self {
124 Annotatable::Item(node) => TokenStream::from_ast(node),
125 Annotatable::AssocItem(node, _) => TokenStream::from_ast(node),
126 Annotatable::ForeignItem(node) => TokenStream::from_ast(node),
127 Annotatable::Stmt(node) => {
128 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));
129 TokenStream::from_ast(node)
130 }
131 Annotatable::Expr(node) => TokenStream::from_ast(node),
132 Annotatable::Arm(..)
133 | Annotatable::ExprField(..)
134 | Annotatable::PatField(..)
135 | Annotatable::GenericParam(..)
136 | Annotatable::Param(..)
137 | Annotatable::FieldDef(..)
138 | Annotatable::Variant(..)
139 | Annotatable::WherePredicate(..)
140 | Annotatable::Crate(..) => { ::core::panicking::panic_fmt(format_args!("unexpected annotatable")); }panic!("unexpected annotatable"),
141 }
142 }
143
144 pub fn expect_item(self) -> Box<ast::Item> {
145 match self {
146 Annotatable::Item(i) => i,
147 _ => { ::core::panicking::panic_fmt(format_args!("expected Item")); }panic!("expected Item"),
148 }
149 }
150
151 pub fn expect_trait_item(self) -> Box<ast::AssocItem> {
152 match self {
153 Annotatable::AssocItem(i, AssocCtxt::Trait) => i,
154 _ => { ::core::panicking::panic_fmt(format_args!("expected trait item")); }panic!("expected trait item"),
155 }
156 }
157
158 pub fn expect_impl_item(self) -> Box<ast::AssocItem> {
159 match self {
160 Annotatable::AssocItem(i, AssocCtxt::Impl { .. }) => i,
161 _ => { ::core::panicking::panic_fmt(format_args!("expected impl item")); }panic!("expected impl item"),
162 }
163 }
164
165 pub fn expect_foreign_item(self) -> Box<ast::ForeignItem> {
166 match self {
167 Annotatable::ForeignItem(i) => i,
168 _ => { ::core::panicking::panic_fmt(format_args!("expected foreign item")); }panic!("expected foreign item"),
169 }
170 }
171
172 pub fn expect_stmt(self) -> ast::Stmt {
173 match self {
174 Annotatable::Stmt(stmt) => *stmt,
175 _ => { ::core::panicking::panic_fmt(format_args!("expected statement")); }panic!("expected statement"),
176 }
177 }
178
179 pub fn expect_expr(self) -> Box<ast::Expr> {
180 match self {
181 Annotatable::Expr(expr) => expr,
182 _ => { ::core::panicking::panic_fmt(format_args!("expected expression")); }panic!("expected expression"),
183 }
184 }
185
186 pub fn expect_arm(self) -> ast::Arm {
187 match self {
188 Annotatable::Arm(arm) => arm,
189 _ => { ::core::panicking::panic_fmt(format_args!("expected match arm")); }panic!("expected match arm"),
190 }
191 }
192
193 pub fn expect_expr_field(self) -> ast::ExprField {
194 match self {
195 Annotatable::ExprField(field) => field,
196 _ => { ::core::panicking::panic_fmt(format_args!("expected field")); }panic!("expected field"),
197 }
198 }
199
200 pub fn expect_pat_field(self) -> ast::PatField {
201 match self {
202 Annotatable::PatField(fp) => fp,
203 _ => { ::core::panicking::panic_fmt(format_args!("expected field pattern")); }panic!("expected field pattern"),
204 }
205 }
206
207 pub fn expect_generic_param(self) -> ast::GenericParam {
208 match self {
209 Annotatable::GenericParam(gp) => gp,
210 _ => { ::core::panicking::panic_fmt(format_args!("expected generic parameter")); }panic!("expected generic parameter"),
211 }
212 }
213
214 pub fn expect_param(self) -> ast::Param {
215 match self {
216 Annotatable::Param(param) => param,
217 _ => { ::core::panicking::panic_fmt(format_args!("expected parameter")); }panic!("expected parameter"),
218 }
219 }
220
221 pub fn expect_field_def(self) -> ast::FieldDef {
222 match self {
223 Annotatable::FieldDef(sf) => sf,
224 _ => { ::core::panicking::panic_fmt(format_args!("expected struct field")); }panic!("expected struct field"),
225 }
226 }
227
228 pub fn expect_variant(self) -> ast::Variant {
229 match self {
230 Annotatable::Variant(v) => v,
231 _ => { ::core::panicking::panic_fmt(format_args!("expected variant")); }panic!("expected variant"),
232 }
233 }
234
235 pub fn expect_where_predicate(self) -> ast::WherePredicate {
236 match self {
237 Annotatable::WherePredicate(wp) => wp,
238 _ => { ::core::panicking::panic_fmt(format_args!("expected where predicate")); }panic!("expected where predicate"),
239 }
240 }
241
242 pub fn expect_crate(self) -> ast::Crate {
243 match self {
244 Annotatable::Crate(krate) => krate,
245 _ => { ::core::panicking::panic_fmt(format_args!("expected krate")); }panic!("expected krate"),
246 }
247 }
248}
249
250pub enum ExpandResult<T, U> {
253 Ready(T),
255 Retry(U),
257}
258
259impl<T, U> ExpandResult<T, U> {
260 pub fn map<E, F: FnOnce(T) -> E>(self, f: F) -> ExpandResult<E, U> {
261 match self {
262 ExpandResult::Ready(t) => ExpandResult::Ready(f(t)),
263 ExpandResult::Retry(u) => ExpandResult::Retry(u),
264 }
265 }
266}
267
268impl<'cx> MacroExpanderResult<'cx> {
269 pub fn from_tts(
273 cx: &'cx mut ExtCtxt<'_>,
274 tts: TokenStream,
275 site_span: Span,
276 arm_span: Span,
277 macro_ident: Ident,
278 ) -> Self {
279 let is_local = true;
281 let parser =
282 ParserAnyMacro::from_tts(cx, tts, site_span, arm_span, is_local, macro_ident, &[], &[]);
283 ExpandResult::Ready(Box::new(parser))
284 }
285}
286
287pub trait MultiItemModifier {
288 fn expand(
290 &self,
291 ecx: &mut ExtCtxt<'_>,
292 span: Span,
293 meta_item: &ast::MetaItem,
294 item: Annotatable,
295 is_derive_const: bool,
296 ) -> ExpandResult<Vec<Annotatable>, Annotatable>;
297}
298
299impl<F> MultiItemModifier for F
300where
301 F: Fn(&mut ExtCtxt<'_>, Span, &ast::MetaItem, Annotatable) -> Vec<Annotatable>,
302{
303 fn expand(
304 &self,
305 ecx: &mut ExtCtxt<'_>,
306 span: Span,
307 meta_item: &ast::MetaItem,
308 item: Annotatable,
309 _is_derive_const: bool,
310 ) -> ExpandResult<Vec<Annotatable>, Annotatable> {
311 ExpandResult::Ready(self(ecx, span, meta_item, item))
312 }
313}
314
315pub trait BangProcMacro {
316 fn expand<'cx>(
317 &self,
318 ecx: &'cx mut ExtCtxt<'_>,
319 span: Span,
320 ts: TokenStream,
321 ) -> Result<TokenStream, ErrorGuaranteed>;
322}
323
324impl<F> BangProcMacro for F
325where
326 F: Fn(&mut ExtCtxt<'_>, Span, TokenStream) -> Result<TokenStream, ErrorGuaranteed>,
327{
328 fn expand<'cx>(
329 &self,
330 ecx: &'cx mut ExtCtxt<'_>,
331 span: Span,
332 ts: TokenStream,
333 ) -> Result<TokenStream, ErrorGuaranteed> {
334 self(ecx, span, ts)
336 }
337}
338
339pub trait AttrProcMacro {
340 fn expand<'cx>(
341 &self,
342 ecx: &'cx mut ExtCtxt<'_>,
343 span: Span,
344 annotation: TokenStream,
345 annotated: TokenStream,
346 ) -> Result<TokenStream, ErrorGuaranteed>;
347
348 fn expand_with_safety<'cx>(
350 &self,
351 ecx: &'cx mut ExtCtxt<'_>,
352 safety: Safety,
353 span: Span,
354 annotation: TokenStream,
355 annotated: TokenStream,
356 ) -> Result<TokenStream, ErrorGuaranteed> {
357 if let Safety::Unsafe(span) = safety {
358 ecx.dcx().span_err(span, "unnecessary `unsafe` on safe attribute");
359 }
360 self.expand(ecx, span, annotation, annotated)
361 }
362}
363
364impl<F> AttrProcMacro for F
365where
366 F: Fn(TokenStream, TokenStream) -> TokenStream,
367{
368 fn expand<'cx>(
369 &self,
370 _ecx: &'cx mut ExtCtxt<'_>,
371 _span: Span,
372 annotation: TokenStream,
373 annotated: TokenStream,
374 ) -> Result<TokenStream, ErrorGuaranteed> {
375 Ok(self(annotation, annotated))
377 }
378}
379
380pub trait TTMacroExpander: Any {
382 fn expand<'cx, 'a: 'cx>(
383 &'a self,
384 ecx: &'cx mut ExtCtxt<'_>,
385 span: Span,
386 input: TokenStream,
387 ) -> MacroExpanderResult<'cx>;
388}
389
390pub type MacroExpanderResult<'cx> = ExpandResult<Box<dyn MacResult + 'cx>, ()>;
391
392pub type MacroExpanderFn =
393 for<'cx> fn(&'cx mut ExtCtxt<'_>, Span, TokenStream) -> MacroExpanderResult<'cx>;
394
395impl<F: 'static> TTMacroExpander for F
396where
397 F: for<'cx> Fn(&'cx mut ExtCtxt<'_>, Span, TokenStream) -> MacroExpanderResult<'cx>,
398{
399 fn expand<'cx, 'a: 'cx>(
400 &'a self,
401 ecx: &'cx mut ExtCtxt<'_>,
402 span: Span,
403 input: TokenStream,
404 ) -> MacroExpanderResult<'cx> {
405 self(ecx, span, input)
406 }
407}
408
409pub trait GlobDelegationExpander {
410 fn expand(&self, ecx: &mut ExtCtxt<'_>) -> ExpandResult<Vec<(Ident, Option<Ident>)>, ()>;
411}
412
413fn make_stmts_default(expr: Option<Box<ast::Expr>>) -> Option<SmallVec<[ast::Stmt; 1]>> {
414 expr.map(|e| {
415 {
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) }]
416 })
417}
418
419pub trait MacResult {
422 fn make_expr(self: Box<Self>) -> Option<Box<ast::Expr>> {
424 None
425 }
426
427 fn make_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::Item>; 1]>> {
429 None
430 }
431
432 fn make_impl_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
434 None
435 }
436
437 fn make_trait_impl_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
439 None
440 }
441
442 fn make_trait_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
444 None
445 }
446
447 fn make_foreign_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::ForeignItem>; 1]>> {
449 None
450 }
451
452 fn make_pat(self: Box<Self>) -> Option<Box<ast::Pat>> {
454 None
455 }
456
457 fn make_stmts(self: Box<Self>) -> Option<SmallVec<[ast::Stmt; 1]>> {
462 make_stmts_default(self.make_expr())
463 }
464
465 fn make_ty(self: Box<Self>) -> Option<Box<ast::Ty>> {
466 None
467 }
468
469 fn make_arms(self: Box<Self>) -> Option<SmallVec<[ast::Arm; 1]>> {
470 None
471 }
472
473 fn make_expr_fields(self: Box<Self>) -> Option<SmallVec<[ast::ExprField; 1]>> {
474 None
475 }
476
477 fn make_pat_fields(self: Box<Self>) -> Option<SmallVec<[ast::PatField; 1]>> {
478 None
479 }
480
481 fn make_generic_params(self: Box<Self>) -> Option<SmallVec<[ast::GenericParam; 1]>> {
482 None
483 }
484
485 fn make_params(self: Box<Self>) -> Option<SmallVec<[ast::Param; 1]>> {
486 None
487 }
488
489 fn make_field_defs(self: Box<Self>) -> Option<SmallVec<[ast::FieldDef; 1]>> {
490 None
491 }
492
493 fn make_variants(self: Box<Self>) -> Option<SmallVec<[ast::Variant; 1]>> {
494 None
495 }
496
497 fn make_where_predicates(self: Box<Self>) -> Option<SmallVec<[ast::WherePredicate; 1]>> {
498 None
499 }
500
501 fn make_crate(self: Box<Self>) -> Option<ast::Crate> {
502 ::core::panicking::panic("internal error: entered unreachable code")unreachable!()
504 }
505}
506
507#[derive(#[automatically_derived]
impl ::core::default::Default for MacEager {
#[inline]
fn default() -> MacEager {
MacEager {
expr: ::core::default::Default::default(),
items: ::core::default::Default::default(),
ty: ::core::default::Default::default(),
}
}
}Default)]
510pub struct MacEager {
511 pub expr: Option<Box<ast::Expr>>,
512 pub items: Option<SmallVec<[Box<ast::Item>; 1]>>,
513 pub ty: Option<Box<ast::Ty>>,
514}
515
516impl MacEager {
517 pub fn expr(v: Box<ast::Expr>) -> Box<dyn MacResult> {
518 Box::new(MacEager { expr: Some(v), ..Default::default() })
519 }
520
521 pub fn items(v: SmallVec<[Box<ast::Item>; 1]>) -> Box<dyn MacResult> {
522 Box::new(MacEager { items: Some(v), ..Default::default() })
523 }
524
525 pub fn ty(v: Box<ast::Ty>) -> Box<dyn MacResult> {
526 Box::new(MacEager { ty: Some(v), ..Default::default() })
527 }
528}
529
530impl MacResult for MacEager {
531 fn make_expr(self: Box<Self>) -> Option<Box<ast::Expr>> {
532 self.expr
533 }
534
535 fn make_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::Item>; 1]>> {
536 self.items
537 }
538
539 fn make_pat(self: Box<Self>) -> Option<Box<ast::Pat>> {
540 if let Some(e) = self.expr {
541 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(_)) {
542 return Some(Box::new(ast::Pat {
543 id: ast::DUMMY_NODE_ID,
544 span: e.span,
545 kind: PatKind::Expr(e),
546 }));
547 }
548 }
549 None
550 }
551
552 fn make_ty(self: Box<Self>) -> Option<Box<ast::Ty>> {
553 self.ty
554 }
555}
556
557#[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)]
560pub struct DummyResult {
561 guar: Option<ErrorGuaranteed>,
562 span: Span,
563}
564
565impl DummyResult {
566 pub fn any(span: Span, guar: ErrorGuaranteed) -> Box<dyn MacResult + 'static> {
571 Box::new(DummyResult { guar: Some(guar), span })
572 }
573
574 pub fn any_valid(span: Span) -> Box<dyn MacResult + 'static> {
576 Box::new(DummyResult { guar: None, span })
577 }
578
579 pub fn raw_expr(sp: Span, guar: Option<ErrorGuaranteed>) -> Box<ast::Expr> {
581 Box::new(ast::Expr {
582 id: ast::DUMMY_NODE_ID,
583 kind: if let Some(guar) = guar {
584 ast::ExprKind::Err(guar)
585 } else {
586 ast::ExprKind::Tup(ThinVec::new())
587 },
588 span: sp,
589 attrs: ast::AttrVec::new(),
590 tokens: None,
591 })
592 }
593}
594
595impl MacResult for DummyResult {
596 fn make_expr(self: Box<DummyResult>) -> Option<Box<ast::Expr>> {
597 Some(DummyResult::raw_expr(self.span, self.guar))
598 }
599
600 fn make_pat(self: Box<DummyResult>) -> Option<Box<ast::Pat>> {
601 Some(Box::new(ast::Pat { id: ast::DUMMY_NODE_ID, kind: PatKind::Wild, span: self.span }))
602 }
603
604 fn make_items(self: Box<DummyResult>) -> Option<SmallVec<[Box<ast::Item>; 1]>> {
605 Some(SmallVec::new())
606 }
607
608 fn make_impl_items(self: Box<DummyResult>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
609 Some(SmallVec::new())
610 }
611
612 fn make_trait_impl_items(self: Box<DummyResult>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
613 Some(SmallVec::new())
614 }
615
616 fn make_trait_items(self: Box<DummyResult>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
617 Some(SmallVec::new())
618 }
619
620 fn make_foreign_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::ForeignItem>; 1]>> {
621 Some(SmallVec::new())
622 }
623
624 fn make_stmts(self: Box<DummyResult>) -> Option<SmallVec<[ast::Stmt; 1]>> {
625 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 {
626 id: ast::DUMMY_NODE_ID,
627 kind: ast::StmtKind::Expr(DummyResult::raw_expr(self.span, self.guar)),
628 span: self.span,
629 }])
630 }
631
632 fn make_ty(self: Box<DummyResult>) -> Option<Box<ast::Ty>> {
633 Some(Box::new(ast::Ty {
637 id: ast::DUMMY_NODE_ID,
638 kind: ast::TyKind::Tup(ThinVec::new()),
639 span: self.span,
640 }))
641 }
642
643 fn make_arms(self: Box<DummyResult>) -> Option<SmallVec<[ast::Arm; 1]>> {
644 Some(SmallVec::new())
645 }
646
647 fn make_expr_fields(self: Box<DummyResult>) -> Option<SmallVec<[ast::ExprField; 1]>> {
648 Some(SmallVec::new())
649 }
650
651 fn make_pat_fields(self: Box<DummyResult>) -> Option<SmallVec<[ast::PatField; 1]>> {
652 Some(SmallVec::new())
653 }
654
655 fn make_generic_params(self: Box<DummyResult>) -> Option<SmallVec<[ast::GenericParam; 1]>> {
656 Some(SmallVec::new())
657 }
658
659 fn make_params(self: Box<DummyResult>) -> Option<SmallVec<[ast::Param; 1]>> {
660 Some(SmallVec::new())
661 }
662
663 fn make_field_defs(self: Box<DummyResult>) -> Option<SmallVec<[ast::FieldDef; 1]>> {
664 Some(SmallVec::new())
665 }
666
667 fn make_variants(self: Box<DummyResult>) -> Option<SmallVec<[ast::Variant; 1]>> {
668 Some(SmallVec::new())
669 }
670
671 fn make_crate(self: Box<DummyResult>) -> Option<ast::Crate> {
672 Some(ast::Crate {
673 attrs: Default::default(),
674 items: Default::default(),
675 spans: Default::default(),
676 id: ast::DUMMY_NODE_ID,
677 is_placeholder: Default::default(),
678 })
679 }
680}
681
682#[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)]
684pub enum SyntaxExtensionKind {
685 MacroRules(Arc<crate::MacroRulesMacroExpander>),
687
688 Bang(
690 Arc<dyn BangProcMacro + sync::DynSync + sync::DynSend>,
692 ),
693
694 LegacyBang(
696 Arc<dyn TTMacroExpander + sync::DynSync + sync::DynSend>,
698 ),
699
700 Attr(
702 Arc<dyn AttrProcMacro + sync::DynSync + sync::DynSend>,
706 ),
707
708 LegacyAttr(
710 Arc<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
714 ),
715
716 NonMacroAttr,
721
722 Derive(
724 Arc<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
732 ),
733
734 LegacyDerive(
736 Arc<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
739 ),
740
741 GlobDelegation(Arc<dyn GlobDelegationExpander + sync::DynSync + sync::DynSend>),
745}
746
747impl SyntaxExtensionKind {
748 pub fn as_legacy_bang(&self) -> Option<&(dyn TTMacroExpander + sync::DynSync + sync::DynSend)> {
752 match self {
753 SyntaxExtensionKind::LegacyBang(exp) => Some(exp.as_ref()),
754 SyntaxExtensionKind::MacroRules(exp) if exp.kinds().contains(MacroKinds::BANG) => {
755 Some(exp.as_ref())
756 }
757 _ => None,
758 }
759 }
760
761 pub fn as_attr(&self) -> Option<&(dyn AttrProcMacro + sync::DynSync + sync::DynSend)> {
765 match self {
766 SyntaxExtensionKind::Attr(exp) => Some(exp.as_ref()),
767 SyntaxExtensionKind::MacroRules(exp) if exp.kinds().contains(MacroKinds::ATTR) => {
768 Some(exp.as_ref())
769 }
770 _ => None,
771 }
772 }
773}
774
775pub struct SyntaxExtension {
777 pub kind: SyntaxExtensionKind,
779 pub span: Span,
781 pub allow_internal_unstable: Option<Arc<[Symbol]>>,
783 pub stability: Option<Stability>,
785 pub deprecation: Option<Deprecation>,
787 pub helper_attrs: Vec<Symbol>,
789 pub edition: Edition,
791 pub builtin_name: Option<Symbol>,
794 pub allow_internal_unsafe: bool,
796 pub local_inner_macros: bool,
798 pub collapse_debuginfo: bool,
801 pub diagnostic_opaque: bool,
804}
805
806impl SyntaxExtension {
807 pub fn macro_kinds(&self) -> MacroKinds {
809 match self.kind {
810 SyntaxExtensionKind::Bang(..)
811 | SyntaxExtensionKind::LegacyBang(..)
812 | SyntaxExtensionKind::GlobDelegation(..) => MacroKinds::BANG,
813 SyntaxExtensionKind::Attr(..)
814 | SyntaxExtensionKind::LegacyAttr(..)
815 | SyntaxExtensionKind::NonMacroAttr => MacroKinds::ATTR,
816 SyntaxExtensionKind::Derive(..) | SyntaxExtensionKind::LegacyDerive(..) => {
817 MacroKinds::DERIVE
818 }
819 SyntaxExtensionKind::MacroRules(ref m) => m.kinds(),
820 }
821 }
822
823 pub fn default(kind: SyntaxExtensionKind, edition: Edition) -> SyntaxExtension {
825 SyntaxExtension {
826 span: DUMMY_SP,
827 allow_internal_unstable: None,
828 stability: None,
829 deprecation: None,
830 helper_attrs: Vec::new(),
831 edition,
832 builtin_name: None,
833 kind,
834 allow_internal_unsafe: false,
835 local_inner_macros: false,
836 collapse_debuginfo: false,
837 diagnostic_opaque: false,
838 }
839 }
840
841 fn get_collapse_debuginfo(sess: &Session, attrs: &[hir::Attribute], ext: bool) -> bool {
848 let flag = sess.opts.cg.collapse_macro_debuginfo;
849 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) {
850 *info
851 } 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 { .. }) {
852 CollapseMacroDebuginfo::Yes
853 } else {
854 CollapseMacroDebuginfo::Unspecified
855 };
856
857 #[rustfmt::skip]
858 let collapse_table = [
859 [false, false, false, false],
860 [false, ext, ext, true],
861 [false, ext, ext, true],
862 [true, true, true, true],
863 ];
864 collapse_table[flag as usize][attr as usize]
865 }
866
867 pub fn new(
870 sess: &Session,
871 kind: SyntaxExtensionKind,
872 span: Span,
873 helper_attrs: Vec<Symbol>,
874 edition: Edition,
875 name: Symbol,
876 attrs: &[hir::Attribute],
877 is_local: bool,
878 ) -> SyntaxExtension {
879 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)
880 .map(|i| i.as_slice())
881 .unwrap_or_default();
882 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(_));
883
884 let local_inner_macros =
885 *{
'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);
886 let collapse_debuginfo = Self::get_collapse_debuginfo(sess, attrs, !is_local);
887 {
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:887",
"rustc_expand::base", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_expand/src/base.rs"),
::tracing_core::__macro_support::Option::Some(887u32),
::tracing_core::__macro_support::Option::Some("rustc_expand::base"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("name")
}> =
::tracing::__macro_support::FieldName::new("name");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("local_inner_macros")
}> =
::tracing::__macro_support::FieldName::new("local_inner_macros");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("collapse_debuginfo")
}> =
::tracing::__macro_support::FieldName::new("collapse_debuginfo");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("allow_internal_unsafe")
}> =
::tracing::__macro_support::FieldName::new("allow_internal_unsafe");
NAME.as_str()
}], ::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&name)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&local_inner_macros)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&collapse_debuginfo)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&allow_internal_unsafe)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};tracing::debug!(?name, ?local_inner_macros, ?collapse_debuginfo, ?allow_internal_unsafe);
888
889 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))
890 {
891 Some((Some(name), helper_attrs)) => {
894 (Some(*name), helper_attrs.iter().copied().collect())
895 }
896 Some((None, _)) => (Some(name), Vec::new()),
897
898 None => (None, helper_attrs),
900 };
901 let diagnostic_opaque = builtin_name.is_some()
902 || (!sess.opts.unstable_opts.macro_backtrace && {
{
'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(Opaque) => {
break 'done Some(());
}
::rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}.is_some()
}find_attr!(attrs, Opaque));
903
904 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);
905
906 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) {
907 sess.dcx().emit_err(diagnostics::MacroBodyStability {
908 span: sp,
909 head_span: sess.source_map().guess_head_span(span),
910 });
911 }
912
913 SyntaxExtension {
914 kind,
915 span,
916 allow_internal_unstable: (!allow_internal_unstable.is_empty())
917 .then(|| allow_internal_unstable.iter().map(|i| i.0).collect::<Vec<_>>().into()),
919 stability,
920 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!(
921 attrs,
922 Deprecated { deprecation, .. } => *deprecation
923 ),
924 helper_attrs,
925 edition,
926 builtin_name,
927 allow_internal_unsafe,
928 local_inner_macros,
929 collapse_debuginfo,
930 diagnostic_opaque,
931 }
932 }
933
934 pub fn dummy_bang(edition: Edition) -> SyntaxExtension {
936 fn expand(
937 ecx: &mut ExtCtxt<'_>,
938 span: Span,
939 _ts: TokenStream,
940 ) -> Result<TokenStream, ErrorGuaranteed> {
941 Err(ecx.dcx().span_delayed_bug(span, "expanded a dummy bang macro"))
942 }
943 SyntaxExtension::default(SyntaxExtensionKind::Bang(Arc::new(expand)), edition)
944 }
945
946 pub fn dummy_derive(edition: Edition) -> SyntaxExtension {
948 fn expander(
949 _: &mut ExtCtxt<'_>,
950 _: Span,
951 _: &ast::MetaItem,
952 _: Annotatable,
953 ) -> Vec<Annotatable> {
954 Vec::new()
955 }
956 SyntaxExtension::default(SyntaxExtensionKind::Derive(Arc::new(expander)), edition)
957 }
958
959 pub fn non_macro_attr(edition: Edition) -> SyntaxExtension {
960 SyntaxExtension::default(SyntaxExtensionKind::NonMacroAttr, edition)
961 }
962
963 pub fn glob_delegation(
964 trait_def_id: DefId,
965 impl_def_id: LocalDefId,
966 star_span: Span,
967 edition: Edition,
968 ) -> SyntaxExtension {
969 struct GlobDelegationExpanderImpl {
970 trait_def_id: DefId,
971 impl_def_id: LocalDefId,
972 star_span: Span,
973 }
974 impl GlobDelegationExpander for GlobDelegationExpanderImpl {
975 fn expand(
976 &self,
977 ecx: &mut ExtCtxt<'_>,
978 ) -> ExpandResult<Vec<(Ident, Option<Ident>)>, ()> {
979 match ecx.resolver.glob_delegation_suffixes(
980 self.trait_def_id,
981 self.impl_def_id,
982 self.star_span,
983 ) {
984 Ok(suffixes) => ExpandResult::Ready(suffixes),
985 Err(Indeterminate) if ecx.force_mode => ExpandResult::Ready(Vec::new()),
986 Err(Indeterminate) => ExpandResult::Retry(()),
987 }
988 }
989 }
990
991 let expander = GlobDelegationExpanderImpl { trait_def_id, impl_def_id, star_span };
992 SyntaxExtension::default(SyntaxExtensionKind::GlobDelegation(Arc::new(expander)), edition)
993 }
994
995 pub fn expn_data(
996 &self,
997 parent: LocalExpnId,
998 call_site: Span,
999 descr: Symbol,
1000 kind: MacroKind,
1001 macro_def_id: Option<DefId>,
1002 parent_module: Option<ModId>,
1003 ) -> ExpnData {
1004 ExpnData::new(
1005 ExpnKind::Macro(kind, descr),
1006 parent.to_expn_id(),
1007 call_site,
1008 self.span,
1009 self.allow_internal_unstable.clone(),
1010 self.edition,
1011 macro_def_id,
1012 parent_module,
1013 self.allow_internal_unsafe,
1014 self.local_inner_macros,
1015 self.collapse_debuginfo,
1016 self.diagnostic_opaque,
1017 )
1018 }
1019}
1020
1021pub struct Indeterminate;
1023
1024pub struct DeriveResolution {
1025 pub path: ast::Path,
1026 pub item: Annotatable,
1027 pub exts: Option<Arc<SyntaxExtension>>,
1031 pub is_const: bool,
1032}
1033
1034pub trait ResolverExpand {
1035 fn next_node_id(&mut self) -> NodeId;
1036 fn invocation_parent(&self, id: LocalExpnId) -> LocalDefId;
1037
1038 fn resolve_dollar_crates(&self);
1039 fn visit_ast_fragment_with_placeholders(
1040 &mut self,
1041 expn_id: LocalExpnId,
1042 fragment: &AstFragment,
1043 );
1044 fn register_builtin_macro(&mut self, name: Symbol, ext: SyntaxExtensionKind);
1045
1046 fn expansion_for_ast_pass(
1047 &mut self,
1048 call_site: Span,
1049 pass: AstPass,
1050 features: &[Symbol],
1051 parent_module_id: Option<NodeId>,
1052 ) -> LocalExpnId;
1053
1054 fn resolve_imports(&mut self);
1055
1056 fn resolve_macro_invocation(
1057 &mut self,
1058 invoc: &Invocation,
1059 eager_expansion_root: LocalExpnId,
1060 force: bool,
1061 ) -> Result<Arc<SyntaxExtension>, Indeterminate>;
1062
1063 fn record_macro_rule_usage(&mut self, mac_id: NodeId, rule_index: usize);
1064
1065 fn check_unused_macros(&mut self);
1066
1067 fn has_derive_copy(&self, expn_id: LocalExpnId) -> bool;
1070 fn has_derive_ord(&self, expn_id: LocalExpnId) -> bool;
1072 fn resolve_derives(
1074 &mut self,
1075 expn_id: LocalExpnId,
1076 force: bool,
1077 derive_paths: &dyn Fn() -> Vec<DeriveResolution>,
1078 ) -> Result<(), Indeterminate>;
1079 fn take_derive_resolutions(&mut self, expn_id: LocalExpnId) -> Option<Vec<DeriveResolution>>;
1082 fn cfg_accessible(
1084 &mut self,
1085 expn_id: LocalExpnId,
1086 path: &ast::Path,
1087 ) -> Result<bool, Indeterminate>;
1088 fn macro_accessible(
1089 &mut self,
1090 expn_id: LocalExpnId,
1091 path: &ast::Path,
1092 ) -> Result<bool, Indeterminate>;
1093
1094 fn get_proc_macro_quoted_span(&self, krate: CrateNum, id: usize) -> Span;
1097
1098 fn declare_proc_macro(&mut self, id: NodeId);
1105
1106 fn append_stripped_cfg_item(
1107 &mut self,
1108 parent_node: NodeId,
1109 ident: Ident,
1110 cfg: CfgEntry,
1111 cfg_span: Span,
1112 );
1113
1114 fn registered_tools(&self) -> &RegisteredTools;
1116
1117 fn register_glob_delegation(&mut self, invoc_id: LocalExpnId);
1119
1120 fn glob_delegation_suffixes(
1122 &self,
1123 trait_def_id: DefId,
1124 impl_def_id: LocalDefId,
1125 star_span: Span,
1126 ) -> Result<Vec<(Ident, Option<Ident>)>, Indeterminate>;
1127
1128 fn insert_impl_trait_name(&mut self, id: NodeId, name: Symbol);
1131
1132 fn mark_scope_with_compile_error(&mut self, parent_node: NodeId);
1135}
1136
1137pub trait LintStoreExpand {
1138 fn pre_expansion_lint(
1139 &self,
1140 sess: &Session,
1141 features: &Features,
1142 registered_tools: &RegisteredTools,
1143 node_id: NodeId,
1144 attrs: &[Attribute],
1145 items: &[Box<Item>],
1146 name: Symbol,
1147 );
1148}
1149
1150type LintStoreExpandDyn<'a> = Option<&'a (dyn LintStoreExpand + 'a)>;
1151
1152#[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::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)]
1153pub struct ModuleData {
1154 pub mod_path: Vec<Ident>,
1156 pub file_path_stack: Vec<PathBuf>,
1159 pub dir_path: PathBuf,
1162}
1163
1164impl ModuleData {
1165 pub fn with_dir_path(&self, dir_path: PathBuf) -> ModuleData {
1166 ModuleData {
1167 mod_path: self.mod_path.clone(),
1168 file_path_stack: self.file_path_stack.clone(),
1169 dir_path,
1170 }
1171 }
1172}
1173
1174#[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)]
1175pub struct ExpansionData {
1176 pub id: LocalExpnId,
1177 pub depth: usize,
1178 pub module: Rc<ModuleData>,
1179 pub dir_ownership: DirOwnership,
1180 pub lint_node_id: NodeId,
1182 pub is_trailing_mac: bool,
1183}
1184
1185pub struct ExtCtxt<'a> {
1189 pub sess: &'a Session,
1190 pub ecfg: expand::ExpansionConfig<'a>,
1191 pub num_standard_library_imports: usize,
1192 pub reduced_recursion_limit: Option<(Limit, ErrorGuaranteed)>,
1193 pub root_path: PathBuf,
1194 pub resolver: &'a mut dyn ResolverExpand,
1195 pub current_expansion: ExpansionData,
1196 pub force_mode: bool,
1199 pub expansions: FxIndexMap<Span, Vec<String>>,
1200 pub(super) lint_store: LintStoreExpandDyn<'a>,
1202 pub buffered_early_lint: Vec<BufferedEarlyLint>,
1204 pub(super) expanded_inert_attrs: MarkedAttrs,
1208 pub macro_stats: FxHashMap<(Symbol, MacroKind), MacroStat>,
1210 pub nb_macro_errors: usize,
1211}
1212
1213impl<'a> ExtCtxt<'a> {
1214 pub fn new(
1215 sess: &'a Session,
1216 ecfg: expand::ExpansionConfig<'a>,
1217 resolver: &'a mut dyn ResolverExpand,
1218 lint_store: LintStoreExpandDyn<'a>,
1219 ) -> ExtCtxt<'a> {
1220 ExtCtxt {
1221 sess,
1222 ecfg,
1223 num_standard_library_imports: 0,
1224 reduced_recursion_limit: None,
1225 resolver,
1226 lint_store,
1227 root_path: PathBuf::new(),
1228 current_expansion: ExpansionData {
1229 id: LocalExpnId::ROOT,
1230 depth: 0,
1231 module: Default::default(),
1232 dir_ownership: DirOwnership::Owned { relative: None },
1233 lint_node_id: ast::CRATE_NODE_ID,
1234 is_trailing_mac: false,
1235 },
1236 force_mode: false,
1237 expansions: FxIndexMap::default(),
1238 expanded_inert_attrs: MarkedAttrs::new(),
1239 buffered_early_lint: ::alloc::vec::Vec::new()vec![],
1240 macro_stats: Default::default(),
1241 nb_macro_errors: 0,
1242 }
1243 }
1244
1245 pub fn dcx(&self) -> DiagCtxtHandle<'a> {
1246 self.sess.dcx()
1247 }
1248
1249 pub fn expander<'b>(&'b mut self) -> expand::MacroExpander<'b, 'a> {
1251 expand::MacroExpander::new(self, false)
1252 }
1253
1254 pub fn monotonic_expander<'b>(&'b mut self) -> expand::MacroExpander<'b, 'a> {
1257 expand::MacroExpander::new(self, true)
1258 }
1259 pub fn new_parser_from_tts(&self, stream: TokenStream) -> Parser<'a> {
1260 Parser::new(&self.sess.psess, stream, MACRO_ARGUMENTS)
1261 }
1262 pub fn source_map(&self) -> &'a SourceMap {
1263 self.sess.psess.source_map()
1264 }
1265 pub fn psess(&self) -> &'a ParseSess {
1266 &self.sess.psess
1267 }
1268 pub fn call_site(&self) -> Span {
1269 self.current_expansion.id.expn_data().call_site
1270 }
1271
1272 pub(crate) fn expansion_descr(&self) -> String {
1274 let expn_data = self.current_expansion.id.expn_data();
1275 expn_data.kind.descr()
1276 }
1277
1278 pub fn with_def_site_ctxt(&self, span: Span) -> Span {
1281 span.with_def_site_ctxt(self.current_expansion.id.to_expn_id())
1282 }
1283
1284 pub fn with_call_site_ctxt(&self, span: Span) -> Span {
1287 span.with_call_site_ctxt(self.current_expansion.id.to_expn_id())
1288 }
1289
1290 pub fn with_mixed_site_ctxt(&self, span: Span) -> Span {
1293 span.with_mixed_site_ctxt(self.current_expansion.id.to_expn_id())
1294 }
1295
1296 pub fn expansion_cause(&self) -> Option<Span> {
1300 self.current_expansion.id.expansion_cause()
1301 }
1302
1303 pub fn macro_error_and_trace_macros_diag(&mut self) {
1305 self.nb_macro_errors += 1;
1306 self.trace_macros_diag();
1307 }
1308
1309 pub fn trace_macros_diag(&mut self) {
1310 for (span, notes) in self.expansions.iter() {
1311 let mut db = self.dcx().create_note(diagnostics::TraceMacro { span: *span });
1312 for note in notes {
1313 db.note(note.clone());
1314 }
1315 db.emit();
1316 }
1317 self.expansions.clear();
1319 }
1320 pub fn trace_macros(&self) -> bool {
1321 self.ecfg.trace_mac
1322 }
1323 pub fn set_trace_macros(&mut self, x: bool) {
1324 self.ecfg.trace_mac = x
1325 }
1326 pub fn std_path(&self, components: &[Symbol]) -> Vec<Ident> {
1327 let def_site = self.with_def_site_ctxt(DUMMY_SP);
1328 iter::once(Ident::new(kw::DollarCrate, def_site))
1329 .chain(components.iter().map(|&s| Ident::new(s, def_site)))
1330 .collect()
1331 }
1332 pub fn def_site_path(&self, components: &[Symbol]) -> Vec<Ident> {
1333 let def_site = self.with_def_site_ctxt(DUMMY_SP);
1334 components.iter().map(|&s| Ident::new(s, def_site)).collect()
1335 }
1336
1337 pub fn check_unused_macros(&mut self) {
1338 self.resolver.check_unused_macros();
1339 }
1340}
1341
1342pub fn resolve_path(sess: &Session, path: impl Into<PathBuf>, span: Span) -> PResult<'_, PathBuf> {
1346 let path = path.into();
1347
1348 if !path.is_absolute() {
1351 let callsite = span.source_callsite();
1352 let source_map = sess.source_map();
1353 let Some(mut base_path) = source_map.span_to_filename(callsite).into_local_path() else {
1354 return Err(sess.dcx().create_err(diagnostics::ResolveRelativePath {
1355 span,
1356 path: source_map
1357 .filename_for_diagnostics(&source_map.span_to_filename(callsite))
1358 .to_string(),
1359 }));
1360 };
1361 base_path.pop();
1362 base_path.push(path);
1363 Ok(base_path)
1364 } else {
1365 match path.components().next() {
1368 Some(Prefix(prefix)) if prefix.kind().is_verbatim() => Ok(path.components().collect()),
1369 _ => Ok(path),
1370 }
1371 }
1372}