]> git.lizzy.rs Git - rust.git/blob - src/librustc_expand/expand.rs
Fix missed same-sized member clash in ClashingExternDeclarations.
[rust.git] / src / librustc_expand / expand.rs
1 use crate::base::*;
2 use crate::config::StripUnconfigured;
3 use crate::configure;
4 use crate::hygiene::{ExpnData, ExpnKind, SyntaxContext};
5 use crate::mbe::macro_rules::annotate_err_with_kind;
6 use crate::module::{parse_external_mod, push_directory, Directory, DirectoryOwnership};
7 use crate::placeholders::{placeholder, PlaceholderExpander};
8 use crate::proc_macro::collect_derives;
9
10 use rustc_ast::ast::{self, AttrItem, Block, LitKind, NodeId, PatKind, Path};
11 use rustc_ast::ast::{ItemKind, MacArgs, MacStmtStyle, StmtKind};
12 use rustc_ast::mut_visit::*;
13 use rustc_ast::ptr::P;
14 use rustc_ast::token;
15 use rustc_ast::tokenstream::TokenStream;
16 use rustc_ast::visit::{self, AssocCtxt, Visitor};
17 use rustc_ast_pretty::pprust;
18 use rustc_attr::{self as attr, is_builtin_attr, HasAttrs};
19 use rustc_data_structures::map_in_place::MapInPlace;
20 use rustc_data_structures::stack::ensure_sufficient_stack;
21 use rustc_errors::{Applicability, PResult};
22 use rustc_feature::Features;
23 use rustc_parse::parser::Parser;
24 use rustc_parse::validate_attr;
25 use rustc_session::lint::builtin::UNUSED_DOC_COMMENTS;
26 use rustc_session::lint::BuiltinLintDiagnostics;
27 use rustc_session::parse::{feature_err, ParseSess};
28 use rustc_session::Limit;
29 use rustc_span::source_map::respan;
30 use rustc_span::symbol::{sym, Ident, Symbol};
31 use rustc_span::{ExpnId, FileName, Span, DUMMY_SP};
32
33 use smallvec::{smallvec, SmallVec};
34 use std::io::ErrorKind;
35 use std::ops::DerefMut;
36 use std::path::PathBuf;
37 use std::rc::Rc;
38 use std::{iter, mem, slice};
39
40 macro_rules! ast_fragments {
41     (
42         $($Kind:ident($AstTy:ty) {
43             $kind_name:expr;
44             $(one fn $mut_visit_ast:ident; fn $visit_ast:ident;)?
45             $(many fn $flat_map_ast_elt:ident; fn $visit_ast_elt:ident($($args:tt)*);)?
46             fn $make_ast:ident;
47         })*
48     ) => {
49         /// A fragment of AST that can be produced by a single macro expansion.
50         /// Can also serve as an input and intermediate result for macro expansion operations.
51         pub enum AstFragment {
52             OptExpr(Option<P<ast::Expr>>),
53             $($Kind($AstTy),)*
54         }
55
56         /// "Discriminant" of an AST fragment.
57         #[derive(Copy, Clone, PartialEq, Eq)]
58         pub enum AstFragmentKind {
59             OptExpr,
60             $($Kind,)*
61         }
62
63         impl AstFragmentKind {
64             pub fn name(self) -> &'static str {
65                 match self {
66                     AstFragmentKind::OptExpr => "expression",
67                     $(AstFragmentKind::$Kind => $kind_name,)*
68                 }
69             }
70
71             fn make_from<'a>(self, result: Box<dyn MacResult + 'a>) -> Option<AstFragment> {
72                 match self {
73                     AstFragmentKind::OptExpr =>
74                         result.make_expr().map(Some).map(AstFragment::OptExpr),
75                     $(AstFragmentKind::$Kind => result.$make_ast().map(AstFragment::$Kind),)*
76                 }
77             }
78         }
79
80         impl AstFragment {
81             pub fn add_placeholders(&mut self, placeholders: &[NodeId]) {
82                 if placeholders.is_empty() {
83                     return;
84                 }
85                 match self {
86                     $($(AstFragment::$Kind(ast) => ast.extend(placeholders.iter().flat_map(|id| {
87                         // We are repeating through arguments with `many`, to do that we have to
88                         // mention some macro variable from those arguments even if it's not used.
89                         macro _repeating($flat_map_ast_elt) {}
90                         placeholder(AstFragmentKind::$Kind, *id, None).$make_ast()
91                     })),)?)*
92                     _ => panic!("unexpected AST fragment kind")
93                 }
94             }
95
96             pub fn make_opt_expr(self) -> Option<P<ast::Expr>> {
97                 match self {
98                     AstFragment::OptExpr(expr) => expr,
99                     _ => panic!("AstFragment::make_* called on the wrong kind of fragment"),
100                 }
101             }
102
103             $(pub fn $make_ast(self) -> $AstTy {
104                 match self {
105                     AstFragment::$Kind(ast) => ast,
106                     _ => panic!("AstFragment::make_* called on the wrong kind of fragment"),
107                 }
108             })*
109
110             pub fn mut_visit_with<F: MutVisitor>(&mut self, vis: &mut F) {
111                 match self {
112                     AstFragment::OptExpr(opt_expr) => {
113                         visit_clobber(opt_expr, |opt_expr| {
114                             if let Some(expr) = opt_expr {
115                                 vis.filter_map_expr(expr)
116                             } else {
117                                 None
118                             }
119                         });
120                     }
121                     $($(AstFragment::$Kind(ast) => vis.$mut_visit_ast(ast),)?)*
122                     $($(AstFragment::$Kind(ast) =>
123                         ast.flat_map_in_place(|ast| vis.$flat_map_ast_elt(ast)),)?)*
124                 }
125             }
126
127             pub fn visit_with<'a, V: Visitor<'a>>(&'a self, visitor: &mut V) {
128                 match *self {
129                     AstFragment::OptExpr(Some(ref expr)) => visitor.visit_expr(expr),
130                     AstFragment::OptExpr(None) => {}
131                     $($(AstFragment::$Kind(ref ast) => visitor.$visit_ast(ast),)?)*
132                     $($(AstFragment::$Kind(ref ast) => for ast_elt in &ast[..] {
133                         visitor.$visit_ast_elt(ast_elt, $($args)*);
134                     })?)*
135                 }
136             }
137         }
138
139         impl<'a> MacResult for crate::mbe::macro_rules::ParserAnyMacro<'a> {
140             $(fn $make_ast(self: Box<crate::mbe::macro_rules::ParserAnyMacro<'a>>)
141                            -> Option<$AstTy> {
142                 Some(self.make(AstFragmentKind::$Kind).$make_ast())
143             })*
144         }
145     }
146 }
147
148 ast_fragments! {
149     Expr(P<ast::Expr>) { "expression"; one fn visit_expr; fn visit_expr; fn make_expr; }
150     Pat(P<ast::Pat>) { "pattern"; one fn visit_pat; fn visit_pat; fn make_pat; }
151     Ty(P<ast::Ty>) { "type"; one fn visit_ty; fn visit_ty; fn make_ty; }
152     Stmts(SmallVec<[ast::Stmt; 1]>) {
153         "statement"; many fn flat_map_stmt; fn visit_stmt(); fn make_stmts;
154     }
155     Items(SmallVec<[P<ast::Item>; 1]>) {
156         "item"; many fn flat_map_item; fn visit_item(); fn make_items;
157     }
158     TraitItems(SmallVec<[P<ast::AssocItem>; 1]>) {
159         "trait item";
160         many fn flat_map_trait_item;
161         fn visit_assoc_item(AssocCtxt::Trait);
162         fn make_trait_items;
163     }
164     ImplItems(SmallVec<[P<ast::AssocItem>; 1]>) {
165         "impl item";
166         many fn flat_map_impl_item;
167         fn visit_assoc_item(AssocCtxt::Impl);
168         fn make_impl_items;
169     }
170     ForeignItems(SmallVec<[P<ast::ForeignItem>; 1]>) {
171         "foreign item";
172         many fn flat_map_foreign_item;
173         fn visit_foreign_item();
174         fn make_foreign_items;
175     }
176     Arms(SmallVec<[ast::Arm; 1]>) {
177         "match arm"; many fn flat_map_arm; fn visit_arm(); fn make_arms;
178     }
179     Fields(SmallVec<[ast::Field; 1]>) {
180         "field expression"; many fn flat_map_field; fn visit_field(); fn make_fields;
181     }
182     FieldPats(SmallVec<[ast::FieldPat; 1]>) {
183         "field pattern";
184         many fn flat_map_field_pattern;
185         fn visit_field_pattern();
186         fn make_field_patterns;
187     }
188     GenericParams(SmallVec<[ast::GenericParam; 1]>) {
189         "generic parameter";
190         many fn flat_map_generic_param;
191         fn visit_generic_param();
192         fn make_generic_params;
193     }
194     Params(SmallVec<[ast::Param; 1]>) {
195         "function parameter"; many fn flat_map_param; fn visit_param(); fn make_params;
196     }
197     StructFields(SmallVec<[ast::StructField; 1]>) {
198         "field";
199         many fn flat_map_struct_field;
200         fn visit_struct_field();
201         fn make_struct_fields;
202     }
203     Variants(SmallVec<[ast::Variant; 1]>) {
204         "variant"; many fn flat_map_variant; fn visit_variant(); fn make_variants;
205     }
206 }
207
208 impl AstFragmentKind {
209     crate fn dummy(self, span: Span) -> AstFragment {
210         self.make_from(DummyResult::any(span)).expect("couldn't create a dummy AST fragment")
211     }
212
213     fn expect_from_annotatables<I: IntoIterator<Item = Annotatable>>(
214         self,
215         items: I,
216     ) -> AstFragment {
217         let mut items = items.into_iter();
218         match self {
219             AstFragmentKind::Arms => {
220                 AstFragment::Arms(items.map(Annotatable::expect_arm).collect())
221             }
222             AstFragmentKind::Fields => {
223                 AstFragment::Fields(items.map(Annotatable::expect_field).collect())
224             }
225             AstFragmentKind::FieldPats => {
226                 AstFragment::FieldPats(items.map(Annotatable::expect_field_pattern).collect())
227             }
228             AstFragmentKind::GenericParams => {
229                 AstFragment::GenericParams(items.map(Annotatable::expect_generic_param).collect())
230             }
231             AstFragmentKind::Params => {
232                 AstFragment::Params(items.map(Annotatable::expect_param).collect())
233             }
234             AstFragmentKind::StructFields => {
235                 AstFragment::StructFields(items.map(Annotatable::expect_struct_field).collect())
236             }
237             AstFragmentKind::Variants => {
238                 AstFragment::Variants(items.map(Annotatable::expect_variant).collect())
239             }
240             AstFragmentKind::Items => {
241                 AstFragment::Items(items.map(Annotatable::expect_item).collect())
242             }
243             AstFragmentKind::ImplItems => {
244                 AstFragment::ImplItems(items.map(Annotatable::expect_impl_item).collect())
245             }
246             AstFragmentKind::TraitItems => {
247                 AstFragment::TraitItems(items.map(Annotatable::expect_trait_item).collect())
248             }
249             AstFragmentKind::ForeignItems => {
250                 AstFragment::ForeignItems(items.map(Annotatable::expect_foreign_item).collect())
251             }
252             AstFragmentKind::Stmts => {
253                 AstFragment::Stmts(items.map(Annotatable::expect_stmt).collect())
254             }
255             AstFragmentKind::Expr => AstFragment::Expr(
256                 items.next().expect("expected exactly one expression").expect_expr(),
257             ),
258             AstFragmentKind::OptExpr => {
259                 AstFragment::OptExpr(items.next().map(Annotatable::expect_expr))
260             }
261             AstFragmentKind::Pat | AstFragmentKind::Ty => {
262                 panic!("patterns and types aren't annotatable")
263             }
264         }
265     }
266 }
267
268 pub struct Invocation {
269     pub kind: InvocationKind,
270     pub fragment_kind: AstFragmentKind,
271     pub expansion_data: ExpansionData,
272 }
273
274 pub enum InvocationKind {
275     Bang {
276         mac: ast::MacCall,
277         span: Span,
278     },
279     Attr {
280         attr: ast::Attribute,
281         item: Annotatable,
282         // Required for resolving derive helper attributes.
283         derives: Vec<Path>,
284         // We temporarily report errors for attribute macros placed after derives
285         after_derive: bool,
286     },
287     Derive {
288         path: Path,
289         item: Annotatable,
290     },
291     /// "Invocation" that contains all derives from an item,
292     /// broken into multiple `Derive` invocations when expanded.
293     /// FIXME: Find a way to remove it.
294     DeriveContainer {
295         derives: Vec<Path>,
296         item: Annotatable,
297     },
298 }
299
300 impl InvocationKind {
301     fn placeholder_visibility(&self) -> Option<ast::Visibility> {
302         // HACK: For unnamed fields placeholders should have the same visibility as the actual
303         // fields because for tuple structs/variants resolve determines visibilities of their
304         // constructor using these field visibilities before attributes on them are are expanded.
305         // The assumption is that the attribute expansion cannot change field visibilities,
306         // and it holds because only inert attributes are supported in this position.
307         match self {
308             InvocationKind::Attr { item: Annotatable::StructField(field), .. }
309             | InvocationKind::Derive { item: Annotatable::StructField(field), .. }
310             | InvocationKind::DeriveContainer { item: Annotatable::StructField(field), .. }
311                 if field.ident.is_none() =>
312             {
313                 Some(field.vis.clone())
314             }
315             _ => None,
316         }
317     }
318 }
319
320 impl Invocation {
321     pub fn span(&self) -> Span {
322         match &self.kind {
323             InvocationKind::Bang { span, .. } => *span,
324             InvocationKind::Attr { attr, .. } => attr.span,
325             InvocationKind::Derive { path, .. } => path.span,
326             InvocationKind::DeriveContainer { item, .. } => item.span(),
327         }
328     }
329 }
330
331 pub struct MacroExpander<'a, 'b> {
332     pub cx: &'a mut ExtCtxt<'b>,
333     monotonic: bool, // cf. `cx.monotonic_expander()`
334 }
335
336 impl<'a, 'b> MacroExpander<'a, 'b> {
337     pub fn new(cx: &'a mut ExtCtxt<'b>, monotonic: bool) -> Self {
338         MacroExpander { cx, monotonic }
339     }
340
341     pub fn expand_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
342         let mut module = ModuleData {
343             mod_path: vec![Ident::from_str(&self.cx.ecfg.crate_name)],
344             directory: match self.cx.source_map().span_to_unmapped_path(krate.span) {
345                 FileName::Real(name) => name.into_local_path(),
346                 other => PathBuf::from(other.to_string()),
347             },
348         };
349         module.directory.pop();
350         self.cx.root_path = module.directory.clone();
351         self.cx.current_expansion.module = Rc::new(module);
352
353         let orig_mod_span = krate.module.inner;
354
355         let krate_item = AstFragment::Items(smallvec![P(ast::Item {
356             attrs: krate.attrs,
357             span: krate.span,
358             kind: ast::ItemKind::Mod(krate.module),
359             ident: Ident::invalid(),
360             id: ast::DUMMY_NODE_ID,
361             vis: respan(krate.span.shrink_to_lo(), ast::VisibilityKind::Public),
362             tokens: None,
363         })]);
364
365         match self.fully_expand_fragment(krate_item).make_items().pop().map(P::into_inner) {
366             Some(ast::Item { attrs, kind: ast::ItemKind::Mod(module), .. }) => {
367                 krate.attrs = attrs;
368                 krate.module = module;
369             }
370             None => {
371                 // Resolution failed so we return an empty expansion
372                 krate.attrs = vec![];
373                 krate.module = ast::Mod { inner: orig_mod_span, items: vec![], inline: true };
374             }
375             Some(ast::Item { span, kind, .. }) => {
376                 krate.attrs = vec![];
377                 krate.module = ast::Mod { inner: orig_mod_span, items: vec![], inline: true };
378                 self.cx.span_err(
379                     span,
380                     &format!(
381                         "expected crate top-level item to be a module after macro expansion, found {} {}",
382                         kind.article(), kind.descr()
383                     ),
384                 );
385             }
386         };
387         self.cx.trace_macros_diag();
388         krate
389     }
390
391     // Recursively expand all macro invocations in this AST fragment.
392     pub fn fully_expand_fragment(&mut self, input_fragment: AstFragment) -> AstFragment {
393         let orig_expansion_data = self.cx.current_expansion.clone();
394         self.cx.current_expansion.depth = 0;
395
396         // Collect all macro invocations and replace them with placeholders.
397         let (mut fragment_with_placeholders, mut invocations) =
398             self.collect_invocations(input_fragment, &[]);
399
400         // Optimization: if we resolve all imports now,
401         // we'll be able to immediately resolve most of imported macros.
402         self.resolve_imports();
403
404         // Resolve paths in all invocations and produce output expanded fragments for them, but
405         // do not insert them into our input AST fragment yet, only store in `expanded_fragments`.
406         // The output fragments also go through expansion recursively until no invocations are left.
407         // Unresolved macros produce dummy outputs as a recovery measure.
408         invocations.reverse();
409         let mut expanded_fragments = Vec::new();
410         let mut undetermined_invocations = Vec::new();
411         let (mut progress, mut force) = (false, !self.monotonic);
412         loop {
413             let (invoc, res) = if let Some(invoc) = invocations.pop() {
414                 invoc
415             } else {
416                 self.resolve_imports();
417                 if undetermined_invocations.is_empty() {
418                     break;
419                 }
420                 invocations = mem::take(&mut undetermined_invocations);
421                 force = !mem::replace(&mut progress, false);
422                 continue;
423             };
424
425             let res = match res {
426                 Some(res) => res,
427                 None => {
428                     let eager_expansion_root = if self.monotonic {
429                         invoc.expansion_data.id
430                     } else {
431                         orig_expansion_data.id
432                     };
433                     match self.cx.resolver.resolve_macro_invocation(
434                         &invoc,
435                         eager_expansion_root,
436                         force,
437                     ) {
438                         Ok(res) => res,
439                         Err(Indeterminate) => {
440                             // Cannot resolve, will retry this invocation later.
441                             undetermined_invocations.push((invoc, None));
442                             continue;
443                         }
444                     }
445                 }
446             };
447
448             let ExpansionData { depth, id: expn_id, .. } = invoc.expansion_data;
449             self.cx.current_expansion = invoc.expansion_data.clone();
450
451             // FIXME(jseyfried): Refactor out the following logic
452             let (expanded_fragment, new_invocations) = match res {
453                 InvocationRes::Single(ext) => match self.expand_invoc(invoc, &ext.kind) {
454                     ExpandResult::Ready(fragment) => self.collect_invocations(fragment, &[]),
455                     ExpandResult::Retry(invoc, explanation) => {
456                         if force {
457                             // We are stuck, stop retrying and produce a dummy fragment.
458                             let span = invoc.span();
459                             self.cx.span_err(span, &explanation);
460                             let fragment = invoc.fragment_kind.dummy(span);
461                             self.collect_invocations(fragment, &[])
462                         } else {
463                             // Cannot expand, will retry this invocation later.
464                             undetermined_invocations
465                                 .push((invoc, Some(InvocationRes::Single(ext))));
466                             continue;
467                         }
468                     }
469                 },
470                 InvocationRes::DeriveContainer(_exts) => {
471                     // FIXME: Consider using the derive resolutions (`_exts`) immediately,
472                     // instead of enqueuing the derives to be resolved again later.
473                     let (derives, item) = match invoc.kind {
474                         InvocationKind::DeriveContainer { derives, item } => (derives, item),
475                         _ => unreachable!(),
476                     };
477                     if !item.derive_allowed() {
478                         self.error_derive_forbidden_on_non_adt(&derives, &item);
479                     }
480
481                     let mut item = self.fully_configure(item);
482                     item.visit_attrs(|attrs| attrs.retain(|a| !a.has_name(sym::derive)));
483
484                     let mut derive_placeholders = Vec::with_capacity(derives.len());
485                     invocations.reserve(derives.len());
486                     for path in derives {
487                         let expn_id = ExpnId::fresh(None);
488                         derive_placeholders.push(NodeId::placeholder_from_expn_id(expn_id));
489                         invocations.push((
490                             Invocation {
491                                 kind: InvocationKind::Derive { path, item: item.clone() },
492                                 fragment_kind: invoc.fragment_kind,
493                                 expansion_data: ExpansionData {
494                                     id: expn_id,
495                                     ..invoc.expansion_data.clone()
496                                 },
497                             },
498                             None,
499                         ));
500                     }
501                     let fragment =
502                         invoc.fragment_kind.expect_from_annotatables(::std::iter::once(item));
503                     self.collect_invocations(fragment, &derive_placeholders)
504                 }
505             };
506
507             progress = true;
508             if expanded_fragments.len() < depth {
509                 expanded_fragments.push(Vec::new());
510             }
511             expanded_fragments[depth - 1].push((expn_id, expanded_fragment));
512             invocations.extend(new_invocations.into_iter().rev());
513         }
514
515         self.cx.current_expansion = orig_expansion_data;
516
517         // Finally incorporate all the expanded macros into the input AST fragment.
518         let mut placeholder_expander = PlaceholderExpander::new(self.cx, self.monotonic);
519         while let Some(expanded_fragments) = expanded_fragments.pop() {
520             for (expn_id, expanded_fragment) in expanded_fragments.into_iter().rev() {
521                 placeholder_expander
522                     .add(NodeId::placeholder_from_expn_id(expn_id), expanded_fragment);
523             }
524         }
525         fragment_with_placeholders.mut_visit_with(&mut placeholder_expander);
526         fragment_with_placeholders
527     }
528
529     fn error_derive_forbidden_on_non_adt(&self, derives: &[Path], item: &Annotatable) {
530         let attr = attr::find_by_name(item.attrs(), sym::derive);
531         let span = attr.map_or(item.span(), |attr| attr.span);
532         let mut err = self
533             .cx
534             .struct_span_err(span, "`derive` may only be applied to structs, enums and unions");
535         if let Some(ast::Attribute { style: ast::AttrStyle::Inner, .. }) = attr {
536             let trait_list = derives.iter().map(|t| pprust::path_to_string(t)).collect::<Vec<_>>();
537             let suggestion = format!("#[derive({})]", trait_list.join(", "));
538             err.span_suggestion(
539                 span,
540                 "try an outer attribute",
541                 suggestion,
542                 // We don't 𝑘𝑛𝑜𝑤 that the following item is an ADT
543                 Applicability::MaybeIncorrect,
544             );
545         }
546         err.emit();
547     }
548
549     fn resolve_imports(&mut self) {
550         if self.monotonic {
551             self.cx.resolver.resolve_imports();
552         }
553     }
554
555     /// Collects all macro invocations reachable at this time in this AST fragment, and replace
556     /// them with "placeholders" - dummy macro invocations with specially crafted `NodeId`s.
557     /// Then call into resolver that builds a skeleton ("reduced graph") of the fragment and
558     /// prepares data for resolving paths of macro invocations.
559     fn collect_invocations(
560         &mut self,
561         mut fragment: AstFragment,
562         extra_placeholders: &[NodeId],
563     ) -> (AstFragment, Vec<(Invocation, Option<InvocationRes>)>) {
564         // Resolve `$crate`s in the fragment for pretty-printing.
565         self.cx.resolver.resolve_dollar_crates();
566
567         let invocations = {
568             let mut collector = InvocationCollector {
569                 cfg: StripUnconfigured {
570                     sess: self.cx.parse_sess,
571                     features: self.cx.ecfg.features,
572                 },
573                 cx: self.cx,
574                 invocations: Vec::new(),
575                 monotonic: self.monotonic,
576             };
577             fragment.mut_visit_with(&mut collector);
578             fragment.add_placeholders(extra_placeholders);
579             collector.invocations
580         };
581
582         if self.monotonic {
583             self.cx
584                 .resolver
585                 .visit_ast_fragment_with_placeholders(self.cx.current_expansion.id, &fragment);
586         }
587
588         (fragment, invocations)
589     }
590
591     fn fully_configure(&mut self, item: Annotatable) -> Annotatable {
592         let mut cfg =
593             StripUnconfigured { sess: self.cx.parse_sess, features: self.cx.ecfg.features };
594         // Since the item itself has already been configured by the InvocationCollector,
595         // we know that fold result vector will contain exactly one element
596         match item {
597             Annotatable::Item(item) => Annotatable::Item(cfg.flat_map_item(item).pop().unwrap()),
598             Annotatable::TraitItem(item) => {
599                 Annotatable::TraitItem(cfg.flat_map_trait_item(item).pop().unwrap())
600             }
601             Annotatable::ImplItem(item) => {
602                 Annotatable::ImplItem(cfg.flat_map_impl_item(item).pop().unwrap())
603             }
604             Annotatable::ForeignItem(item) => {
605                 Annotatable::ForeignItem(cfg.flat_map_foreign_item(item).pop().unwrap())
606             }
607             Annotatable::Stmt(stmt) => {
608                 Annotatable::Stmt(stmt.map(|stmt| cfg.flat_map_stmt(stmt).pop().unwrap()))
609             }
610             Annotatable::Expr(mut expr) => Annotatable::Expr({
611                 cfg.visit_expr(&mut expr);
612                 expr
613             }),
614             Annotatable::Arm(arm) => Annotatable::Arm(cfg.flat_map_arm(arm).pop().unwrap()),
615             Annotatable::Field(field) => {
616                 Annotatable::Field(cfg.flat_map_field(field).pop().unwrap())
617             }
618             Annotatable::FieldPat(fp) => {
619                 Annotatable::FieldPat(cfg.flat_map_field_pattern(fp).pop().unwrap())
620             }
621             Annotatable::GenericParam(param) => {
622                 Annotatable::GenericParam(cfg.flat_map_generic_param(param).pop().unwrap())
623             }
624             Annotatable::Param(param) => {
625                 Annotatable::Param(cfg.flat_map_param(param).pop().unwrap())
626             }
627             Annotatable::StructField(sf) => {
628                 Annotatable::StructField(cfg.flat_map_struct_field(sf).pop().unwrap())
629             }
630             Annotatable::Variant(v) => Annotatable::Variant(cfg.flat_map_variant(v).pop().unwrap()),
631         }
632     }
633
634     fn error_recursion_limit_reached(&mut self) {
635         let expn_data = self.cx.current_expansion.id.expn_data();
636         let suggested_limit = self.cx.ecfg.recursion_limit * 2;
637         self.cx
638             .struct_span_err(
639                 expn_data.call_site,
640                 &format!("recursion limit reached while expanding `{}`", expn_data.kind.descr()),
641             )
642             .help(&format!(
643                 "consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate (`{}`)",
644                 suggested_limit, self.cx.ecfg.crate_name,
645             ))
646             .emit();
647         self.cx.trace_macros_diag();
648     }
649
650     /// A macro's expansion does not fit in this fragment kind.
651     /// For example, a non-type macro in a type position.
652     fn error_wrong_fragment_kind(&mut self, kind: AstFragmentKind, mac: &ast::MacCall, span: Span) {
653         let msg = format!(
654             "non-{kind} macro in {kind} position: {path}",
655             kind = kind.name(),
656             path = pprust::path_to_string(&mac.path),
657         );
658         self.cx.span_err(span, &msg);
659         self.cx.trace_macros_diag();
660     }
661
662     fn expand_invoc(
663         &mut self,
664         invoc: Invocation,
665         ext: &SyntaxExtensionKind,
666     ) -> ExpandResult<AstFragment, Invocation> {
667         let recursion_limit =
668             self.cx.reduced_recursion_limit.unwrap_or(self.cx.ecfg.recursion_limit);
669         if !recursion_limit.value_within_limit(self.cx.current_expansion.depth) {
670             if self.cx.reduced_recursion_limit.is_none() {
671                 self.error_recursion_limit_reached();
672             }
673
674             // Reduce the recursion limit by half each time it triggers.
675             self.cx.reduced_recursion_limit = Some(recursion_limit / 2);
676
677             return ExpandResult::Ready(invoc.fragment_kind.dummy(invoc.span()));
678         }
679
680         let (fragment_kind, span) = (invoc.fragment_kind, invoc.span());
681         ExpandResult::Ready(match invoc.kind {
682             InvocationKind::Bang { mac, .. } => match ext {
683                 SyntaxExtensionKind::Bang(expander) => {
684                     let tok_result = match expander.expand(self.cx, span, mac.args.inner_tokens()) {
685                         Err(_) => return ExpandResult::Ready(fragment_kind.dummy(span)),
686                         Ok(ts) => ts,
687                     };
688                     self.parse_ast_fragment(tok_result, fragment_kind, &mac.path, span)
689                 }
690                 SyntaxExtensionKind::LegacyBang(expander) => {
691                     let prev = self.cx.current_expansion.prior_type_ascription;
692                     self.cx.current_expansion.prior_type_ascription = mac.prior_type_ascription;
693                     let tok_result = expander.expand(self.cx, span, mac.args.inner_tokens());
694                     let result = if let Some(result) = fragment_kind.make_from(tok_result) {
695                         result
696                     } else {
697                         self.error_wrong_fragment_kind(fragment_kind, &mac, span);
698                         fragment_kind.dummy(span)
699                     };
700                     self.cx.current_expansion.prior_type_ascription = prev;
701                     result
702                 }
703                 _ => unreachable!(),
704             },
705             InvocationKind::Attr { attr, mut item, derives, after_derive } => match ext {
706                 SyntaxExtensionKind::Attr(expander) => {
707                     self.gate_proc_macro_input(&item);
708                     self.gate_proc_macro_attr_item(span, &item);
709                     let tokens = item.into_tokens(self.cx.parse_sess);
710                     let attr_item = attr.unwrap_normal_item();
711                     if let MacArgs::Eq(..) = attr_item.args {
712                         self.cx.span_err(span, "key-value macro attributes are not supported");
713                     }
714                     let inner_tokens = attr_item.args.inner_tokens();
715                     let tok_result = match expander.expand(self.cx, span, inner_tokens, tokens) {
716                         Err(_) => return ExpandResult::Ready(fragment_kind.dummy(span)),
717                         Ok(ts) => ts,
718                     };
719                     self.parse_ast_fragment(tok_result, fragment_kind, &attr_item.path, span)
720                 }
721                 SyntaxExtensionKind::LegacyAttr(expander) => {
722                     match validate_attr::parse_meta(self.cx.parse_sess, &attr) {
723                         Ok(meta) => {
724                             let items = match expander.expand(self.cx, span, &meta, item) {
725                                 ExpandResult::Ready(items) => items,
726                                 ExpandResult::Retry(item, explanation) => {
727                                     // Reassemble the original invocation for retrying.
728                                     return ExpandResult::Retry(
729                                         Invocation {
730                                             kind: InvocationKind::Attr {
731                                                 attr,
732                                                 item,
733                                                 derives,
734                                                 after_derive,
735                                             },
736                                             ..invoc
737                                         },
738                                         explanation,
739                                     );
740                                 }
741                             };
742                             fragment_kind.expect_from_annotatables(items)
743                         }
744                         Err(mut err) => {
745                             err.emit();
746                             fragment_kind.dummy(span)
747                         }
748                     }
749                 }
750                 SyntaxExtensionKind::NonMacroAttr { mark_used } => {
751                     attr::mark_known(&attr);
752                     if *mark_used {
753                         attr::mark_used(&attr);
754                     }
755                     item.visit_attrs(|attrs| attrs.push(attr));
756                     fragment_kind.expect_from_annotatables(iter::once(item))
757                 }
758                 _ => unreachable!(),
759             },
760             InvocationKind::Derive { path, item } => match ext {
761                 SyntaxExtensionKind::Derive(expander)
762                 | SyntaxExtensionKind::LegacyDerive(expander) => {
763                     if !item.derive_allowed() {
764                         return ExpandResult::Ready(fragment_kind.dummy(span));
765                     }
766                     if let SyntaxExtensionKind::Derive(..) = ext {
767                         self.gate_proc_macro_input(&item);
768                     }
769                     let meta = ast::MetaItem { kind: ast::MetaItemKind::Word, span, path };
770                     let items = match expander.expand(self.cx, span, &meta, item) {
771                         ExpandResult::Ready(items) => items,
772                         ExpandResult::Retry(item, explanation) => {
773                             // Reassemble the original invocation for retrying.
774                             return ExpandResult::Retry(
775                                 Invocation {
776                                     kind: InvocationKind::Derive { path: meta.path, item },
777                                     ..invoc
778                                 },
779                                 explanation,
780                             );
781                         }
782                     };
783                     fragment_kind.expect_from_annotatables(items)
784                 }
785                 _ => unreachable!(),
786             },
787             InvocationKind::DeriveContainer { .. } => unreachable!(),
788         })
789     }
790
791     fn gate_proc_macro_attr_item(&self, span: Span, item: &Annotatable) {
792         let kind = match item {
793             Annotatable::Item(_)
794             | Annotatable::TraitItem(_)
795             | Annotatable::ImplItem(_)
796             | Annotatable::ForeignItem(_) => return,
797             Annotatable::Stmt(_) => "statements",
798             Annotatable::Expr(_) => "expressions",
799             Annotatable::Arm(..)
800             | Annotatable::Field(..)
801             | Annotatable::FieldPat(..)
802             | Annotatable::GenericParam(..)
803             | Annotatable::Param(..)
804             | Annotatable::StructField(..)
805             | Annotatable::Variant(..) => panic!("unexpected annotatable"),
806         };
807         if self.cx.ecfg.proc_macro_hygiene() {
808             return;
809         }
810         feature_err(
811             self.cx.parse_sess,
812             sym::proc_macro_hygiene,
813             span,
814             &format!("custom attributes cannot be applied to {}", kind),
815         )
816         .emit();
817     }
818
819     fn gate_proc_macro_input(&self, annotatable: &Annotatable) {
820         struct GateProcMacroInput<'a> {
821             parse_sess: &'a ParseSess,
822         }
823
824         impl<'ast, 'a> Visitor<'ast> for GateProcMacroInput<'a> {
825             fn visit_item(&mut self, item: &'ast ast::Item) {
826                 match &item.kind {
827                     ast::ItemKind::Mod(module) if !module.inline => {
828                         feature_err(
829                             self.parse_sess,
830                             sym::proc_macro_hygiene,
831                             item.span,
832                             "non-inline modules in proc macro input are unstable",
833                         )
834                         .emit();
835                     }
836                     _ => {}
837                 }
838
839                 visit::walk_item(self, item);
840             }
841
842             fn visit_mac(&mut self, _: &'ast ast::MacCall) {}
843         }
844
845         if !self.cx.ecfg.proc_macro_hygiene() {
846             annotatable.visit_with(&mut GateProcMacroInput { parse_sess: self.cx.parse_sess });
847         }
848     }
849
850     fn parse_ast_fragment(
851         &mut self,
852         toks: TokenStream,
853         kind: AstFragmentKind,
854         path: &Path,
855         span: Span,
856     ) -> AstFragment {
857         let mut parser = self.cx.new_parser_from_tts(toks);
858         match parse_ast_fragment(&mut parser, kind) {
859             Ok(fragment) => {
860                 ensure_complete_parse(&mut parser, path, kind.name(), span);
861                 fragment
862             }
863             Err(mut err) => {
864                 err.set_span(span);
865                 annotate_err_with_kind(&mut err, kind, span);
866                 err.emit();
867                 self.cx.trace_macros_diag();
868                 kind.dummy(span)
869             }
870         }
871     }
872 }
873
874 pub fn parse_ast_fragment<'a>(
875     this: &mut Parser<'a>,
876     kind: AstFragmentKind,
877 ) -> PResult<'a, AstFragment> {
878     Ok(match kind {
879         AstFragmentKind::Items => {
880             let mut items = SmallVec::new();
881             while let Some(item) = this.parse_item()? {
882                 items.push(item);
883             }
884             AstFragment::Items(items)
885         }
886         AstFragmentKind::TraitItems => {
887             let mut items = SmallVec::new();
888             while let Some(item) = this.parse_trait_item()? {
889                 items.extend(item);
890             }
891             AstFragment::TraitItems(items)
892         }
893         AstFragmentKind::ImplItems => {
894             let mut items = SmallVec::new();
895             while let Some(item) = this.parse_impl_item()? {
896                 items.extend(item);
897             }
898             AstFragment::ImplItems(items)
899         }
900         AstFragmentKind::ForeignItems => {
901             let mut items = SmallVec::new();
902             while let Some(item) = this.parse_foreign_item()? {
903                 items.extend(item);
904             }
905             AstFragment::ForeignItems(items)
906         }
907         AstFragmentKind::Stmts => {
908             let mut stmts = SmallVec::new();
909             // Won't make progress on a `}`.
910             while this.token != token::Eof && this.token != token::CloseDelim(token::Brace) {
911                 if let Some(stmt) = this.parse_full_stmt()? {
912                     stmts.push(stmt);
913                 }
914             }
915             AstFragment::Stmts(stmts)
916         }
917         AstFragmentKind::Expr => AstFragment::Expr(this.parse_expr()?),
918         AstFragmentKind::OptExpr => {
919             if this.token != token::Eof {
920                 AstFragment::OptExpr(Some(this.parse_expr()?))
921             } else {
922                 AstFragment::OptExpr(None)
923             }
924         }
925         AstFragmentKind::Ty => AstFragment::Ty(this.parse_ty()?),
926         AstFragmentKind::Pat => AstFragment::Pat(this.parse_pat(None)?),
927         AstFragmentKind::Arms
928         | AstFragmentKind::Fields
929         | AstFragmentKind::FieldPats
930         | AstFragmentKind::GenericParams
931         | AstFragmentKind::Params
932         | AstFragmentKind::StructFields
933         | AstFragmentKind::Variants => panic!("unexpected AST fragment kind"),
934     })
935 }
936
937 pub fn ensure_complete_parse<'a>(
938     this: &mut Parser<'a>,
939     macro_path: &Path,
940     kind_name: &str,
941     span: Span,
942 ) {
943     if this.token != token::Eof {
944         let token = pprust::token_to_string(&this.token);
945         let msg = format!("macro expansion ignores token `{}` and any following", token);
946         // Avoid emitting backtrace info twice.
947         let def_site_span = this.token.span.with_ctxt(SyntaxContext::root());
948         let mut err = this.struct_span_err(def_site_span, &msg);
949         err.span_label(span, "caused by the macro expansion here");
950         let msg = format!(
951             "the usage of `{}!` is likely invalid in {} context",
952             pprust::path_to_string(macro_path),
953             kind_name,
954         );
955         err.note(&msg);
956         let semi_span = this.sess.source_map().next_point(span);
957
958         let semi_full_span = semi_span.to(this.sess.source_map().next_point(semi_span));
959         match this.sess.source_map().span_to_snippet(semi_full_span) {
960             Ok(ref snippet) if &snippet[..] != ";" && kind_name == "expression" => {
961                 err.span_suggestion(
962                     semi_span,
963                     "you might be missing a semicolon here",
964                     ";".to_owned(),
965                     Applicability::MaybeIncorrect,
966                 );
967             }
968             _ => {}
969         }
970         err.emit();
971     }
972 }
973
974 struct InvocationCollector<'a, 'b> {
975     cx: &'a mut ExtCtxt<'b>,
976     cfg: StripUnconfigured<'a>,
977     invocations: Vec<(Invocation, Option<InvocationRes>)>,
978     monotonic: bool,
979 }
980
981 impl<'a, 'b> InvocationCollector<'a, 'b> {
982     fn collect(&mut self, fragment_kind: AstFragmentKind, kind: InvocationKind) -> AstFragment {
983         // Expansion data for all the collected invocations is set upon their resolution,
984         // with exception of the derive container case which is not resolved and can get
985         // its expansion data immediately.
986         let expn_data = match &kind {
987             InvocationKind::DeriveContainer { item, .. } => Some(ExpnData {
988                 parent: self.cx.current_expansion.id,
989                 ..ExpnData::default(
990                     ExpnKind::Macro(MacroKind::Attr, sym::derive),
991                     item.span(),
992                     self.cx.parse_sess.edition,
993                     None,
994                 )
995             }),
996             _ => None,
997         };
998         let expn_id = ExpnId::fresh(expn_data);
999         let vis = kind.placeholder_visibility();
1000         self.invocations.push((
1001             Invocation {
1002                 kind,
1003                 fragment_kind,
1004                 expansion_data: ExpansionData {
1005                     id: expn_id,
1006                     depth: self.cx.current_expansion.depth + 1,
1007                     ..self.cx.current_expansion.clone()
1008                 },
1009             },
1010             None,
1011         ));
1012         placeholder(fragment_kind, NodeId::placeholder_from_expn_id(expn_id), vis)
1013     }
1014
1015     fn collect_bang(
1016         &mut self,
1017         mac: ast::MacCall,
1018         span: Span,
1019         kind: AstFragmentKind,
1020     ) -> AstFragment {
1021         self.collect(kind, InvocationKind::Bang { mac, span })
1022     }
1023
1024     fn collect_attr(
1025         &mut self,
1026         attr: Option<ast::Attribute>,
1027         derives: Vec<Path>,
1028         item: Annotatable,
1029         kind: AstFragmentKind,
1030         after_derive: bool,
1031     ) -> AstFragment {
1032         self.collect(
1033             kind,
1034             match attr {
1035                 Some(attr) => InvocationKind::Attr { attr, item, derives, after_derive },
1036                 None => InvocationKind::DeriveContainer { derives, item },
1037             },
1038         )
1039     }
1040
1041     fn find_attr_invoc(
1042         &self,
1043         attrs: &mut Vec<ast::Attribute>,
1044         after_derive: &mut bool,
1045     ) -> Option<ast::Attribute> {
1046         let attr = attrs
1047             .iter()
1048             .position(|a| {
1049                 if a.has_name(sym::derive) {
1050                     *after_derive = true;
1051                 }
1052                 !attr::is_known(a) && !is_builtin_attr(a)
1053             })
1054             .map(|i| attrs.remove(i));
1055         if let Some(attr) = &attr {
1056             if !self.cx.ecfg.custom_inner_attributes()
1057                 && attr.style == ast::AttrStyle::Inner
1058                 && !attr.has_name(sym::test)
1059             {
1060                 feature_err(
1061                     &self.cx.parse_sess,
1062                     sym::custom_inner_attributes,
1063                     attr.span,
1064                     "non-builtin inner attributes are unstable",
1065                 )
1066                 .emit();
1067             }
1068         }
1069         attr
1070     }
1071
1072     /// If `item` is an attr invocation, remove and return the macro attribute and derive traits.
1073     fn classify_item(
1074         &mut self,
1075         item: &mut impl HasAttrs,
1076     ) -> (Option<ast::Attribute>, Vec<Path>, /* after_derive */ bool) {
1077         let (mut attr, mut traits, mut after_derive) = (None, Vec::new(), false);
1078
1079         item.visit_attrs(|mut attrs| {
1080             attr = self.find_attr_invoc(&mut attrs, &mut after_derive);
1081             traits = collect_derives(&mut self.cx, &mut attrs);
1082         });
1083
1084         (attr, traits, after_derive)
1085     }
1086
1087     /// Alternative to `classify_item()` that ignores `#[derive]` so invocations fallthrough
1088     /// to the unused-attributes lint (making it an error on statements and expressions
1089     /// is a breaking change)
1090     fn classify_nonitem(
1091         &mut self,
1092         nonitem: &mut impl HasAttrs,
1093     ) -> (Option<ast::Attribute>, /* after_derive */ bool) {
1094         let (mut attr, mut after_derive) = (None, false);
1095
1096         nonitem.visit_attrs(|mut attrs| {
1097             attr = self.find_attr_invoc(&mut attrs, &mut after_derive);
1098         });
1099
1100         (attr, after_derive)
1101     }
1102
1103     fn configure<T: HasAttrs>(&mut self, node: T) -> Option<T> {
1104         self.cfg.configure(node)
1105     }
1106
1107     // Detect use of feature-gated or invalid attributes on macro invocations
1108     // since they will not be detected after macro expansion.
1109     fn check_attributes(&mut self, attrs: &[ast::Attribute]) {
1110         let features = self.cx.ecfg.features.unwrap();
1111         for attr in attrs.iter() {
1112             rustc_ast_passes::feature_gate::check_attribute(attr, self.cx.parse_sess, features);
1113             validate_attr::check_meta(self.cx.parse_sess, attr);
1114
1115             // macros are expanded before any lint passes so this warning has to be hardcoded
1116             if attr.has_name(sym::derive) {
1117                 self.cx
1118                     .parse_sess()
1119                     .span_diagnostic
1120                     .struct_span_warn(attr.span, "`#[derive]` does nothing on macro invocations")
1121                     .note("this may become a hard error in a future release")
1122                     .emit();
1123             }
1124
1125             if attr.doc_str().is_some() {
1126                 self.cx.parse_sess.buffer_lint_with_diagnostic(
1127                     &UNUSED_DOC_COMMENTS,
1128                     attr.span,
1129                     ast::CRATE_NODE_ID,
1130                     "unused doc comment",
1131                     BuiltinLintDiagnostics::UnusedDocComment(attr.span),
1132                 );
1133             }
1134         }
1135     }
1136 }
1137
1138 impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
1139     fn visit_expr(&mut self, expr: &mut P<ast::Expr>) {
1140         self.cfg.configure_expr(expr);
1141         visit_clobber(expr.deref_mut(), |mut expr| {
1142             self.cfg.configure_expr_kind(&mut expr.kind);
1143
1144             // ignore derives so they remain unused
1145             let (attr, after_derive) = self.classify_nonitem(&mut expr);
1146
1147             if let Some(ref attr_value) = attr {
1148                 // Collect the invoc regardless of whether or not attributes are permitted here
1149                 // expansion will eat the attribute so it won't error later.
1150                 self.cfg.maybe_emit_expr_attr_err(attr_value);
1151
1152                 // AstFragmentKind::Expr requires the macro to emit an expression.
1153                 return self
1154                     .collect_attr(
1155                         attr,
1156                         vec![],
1157                         Annotatable::Expr(P(expr)),
1158                         AstFragmentKind::Expr,
1159                         after_derive,
1160                     )
1161                     .make_expr()
1162                     .into_inner();
1163             }
1164
1165             if let ast::ExprKind::MacCall(mac) = expr.kind {
1166                 self.check_attributes(&expr.attrs);
1167                 self.collect_bang(mac, expr.span, AstFragmentKind::Expr).make_expr().into_inner()
1168             } else {
1169                 ensure_sufficient_stack(|| noop_visit_expr(&mut expr, self));
1170                 expr
1171             }
1172         });
1173     }
1174
1175     fn flat_map_arm(&mut self, arm: ast::Arm) -> SmallVec<[ast::Arm; 1]> {
1176         let mut arm = configure!(self, arm);
1177
1178         let (attr, traits, after_derive) = self.classify_item(&mut arm);
1179         if attr.is_some() || !traits.is_empty() {
1180             return self
1181                 .collect_attr(
1182                     attr,
1183                     traits,
1184                     Annotatable::Arm(arm),
1185                     AstFragmentKind::Arms,
1186                     after_derive,
1187                 )
1188                 .make_arms();
1189         }
1190
1191         noop_flat_map_arm(arm, self)
1192     }
1193
1194     fn flat_map_field(&mut self, field: ast::Field) -> SmallVec<[ast::Field; 1]> {
1195         let mut field = configure!(self, field);
1196
1197         let (attr, traits, after_derive) = self.classify_item(&mut field);
1198         if attr.is_some() || !traits.is_empty() {
1199             return self
1200                 .collect_attr(
1201                     attr,
1202                     traits,
1203                     Annotatable::Field(field),
1204                     AstFragmentKind::Fields,
1205                     after_derive,
1206                 )
1207                 .make_fields();
1208         }
1209
1210         noop_flat_map_field(field, self)
1211     }
1212
1213     fn flat_map_field_pattern(&mut self, fp: ast::FieldPat) -> SmallVec<[ast::FieldPat; 1]> {
1214         let mut fp = configure!(self, fp);
1215
1216         let (attr, traits, after_derive) = self.classify_item(&mut fp);
1217         if attr.is_some() || !traits.is_empty() {
1218             return self
1219                 .collect_attr(
1220                     attr,
1221                     traits,
1222                     Annotatable::FieldPat(fp),
1223                     AstFragmentKind::FieldPats,
1224                     after_derive,
1225                 )
1226                 .make_field_patterns();
1227         }
1228
1229         noop_flat_map_field_pattern(fp, self)
1230     }
1231
1232     fn flat_map_param(&mut self, p: ast::Param) -> SmallVec<[ast::Param; 1]> {
1233         let mut p = configure!(self, p);
1234
1235         let (attr, traits, after_derive) = self.classify_item(&mut p);
1236         if attr.is_some() || !traits.is_empty() {
1237             return self
1238                 .collect_attr(
1239                     attr,
1240                     traits,
1241                     Annotatable::Param(p),
1242                     AstFragmentKind::Params,
1243                     after_derive,
1244                 )
1245                 .make_params();
1246         }
1247
1248         noop_flat_map_param(p, self)
1249     }
1250
1251     fn flat_map_struct_field(&mut self, sf: ast::StructField) -> SmallVec<[ast::StructField; 1]> {
1252         let mut sf = configure!(self, sf);
1253
1254         let (attr, traits, after_derive) = self.classify_item(&mut sf);
1255         if attr.is_some() || !traits.is_empty() {
1256             return self
1257                 .collect_attr(
1258                     attr,
1259                     traits,
1260                     Annotatable::StructField(sf),
1261                     AstFragmentKind::StructFields,
1262                     after_derive,
1263                 )
1264                 .make_struct_fields();
1265         }
1266
1267         noop_flat_map_struct_field(sf, self)
1268     }
1269
1270     fn flat_map_variant(&mut self, variant: ast::Variant) -> SmallVec<[ast::Variant; 1]> {
1271         let mut variant = configure!(self, variant);
1272
1273         let (attr, traits, after_derive) = self.classify_item(&mut variant);
1274         if attr.is_some() || !traits.is_empty() {
1275             return self
1276                 .collect_attr(
1277                     attr,
1278                     traits,
1279                     Annotatable::Variant(variant),
1280                     AstFragmentKind::Variants,
1281                     after_derive,
1282                 )
1283                 .make_variants();
1284         }
1285
1286         noop_flat_map_variant(variant, self)
1287     }
1288
1289     fn filter_map_expr(&mut self, expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
1290         let expr = configure!(self, expr);
1291         expr.filter_map(|mut expr| {
1292             self.cfg.configure_expr_kind(&mut expr.kind);
1293
1294             // Ignore derives so they remain unused.
1295             let (attr, after_derive) = self.classify_nonitem(&mut expr);
1296
1297             if let Some(ref attr_value) = attr {
1298                 self.cfg.maybe_emit_expr_attr_err(attr_value);
1299
1300                 return self
1301                     .collect_attr(
1302                         attr,
1303                         vec![],
1304                         Annotatable::Expr(P(expr)),
1305                         AstFragmentKind::OptExpr,
1306                         after_derive,
1307                     )
1308                     .make_opt_expr()
1309                     .map(|expr| expr.into_inner());
1310             }
1311
1312             if let ast::ExprKind::MacCall(mac) = expr.kind {
1313                 self.check_attributes(&expr.attrs);
1314                 self.collect_bang(mac, expr.span, AstFragmentKind::OptExpr)
1315                     .make_opt_expr()
1316                     .map(|expr| expr.into_inner())
1317             } else {
1318                 Some({
1319                     noop_visit_expr(&mut expr, self);
1320                     expr
1321                 })
1322             }
1323         })
1324     }
1325
1326     fn visit_pat(&mut self, pat: &mut P<ast::Pat>) {
1327         self.cfg.configure_pat(pat);
1328         match pat.kind {
1329             PatKind::MacCall(_) => {}
1330             _ => return noop_visit_pat(pat, self),
1331         }
1332
1333         visit_clobber(pat, |mut pat| match mem::replace(&mut pat.kind, PatKind::Wild) {
1334             PatKind::MacCall(mac) => {
1335                 self.collect_bang(mac, pat.span, AstFragmentKind::Pat).make_pat()
1336             }
1337             _ => unreachable!(),
1338         });
1339     }
1340
1341     fn flat_map_stmt(&mut self, stmt: ast::Stmt) -> SmallVec<[ast::Stmt; 1]> {
1342         let mut stmt = configure!(self, stmt);
1343
1344         // we'll expand attributes on expressions separately
1345         if !stmt.is_expr() {
1346             let (attr, derives, after_derive) = if stmt.is_item() {
1347                 self.classify_item(&mut stmt)
1348             } else {
1349                 // ignore derives on non-item statements so it falls through
1350                 // to the unused-attributes lint
1351                 let (attr, after_derive) = self.classify_nonitem(&mut stmt);
1352                 (attr, vec![], after_derive)
1353             };
1354
1355             if attr.is_some() || !derives.is_empty() {
1356                 return self
1357                     .collect_attr(
1358                         attr,
1359                         derives,
1360                         Annotatable::Stmt(P(stmt)),
1361                         AstFragmentKind::Stmts,
1362                         after_derive,
1363                     )
1364                     .make_stmts();
1365             }
1366         }
1367
1368         if let StmtKind::MacCall(mac) = stmt.kind {
1369             let (mac, style, attrs) = mac.into_inner();
1370             self.check_attributes(&attrs);
1371             let mut placeholder =
1372                 self.collect_bang(mac, stmt.span, AstFragmentKind::Stmts).make_stmts();
1373
1374             // If this is a macro invocation with a semicolon, then apply that
1375             // semicolon to the final statement produced by expansion.
1376             if style == MacStmtStyle::Semicolon {
1377                 if let Some(stmt) = placeholder.pop() {
1378                     placeholder.push(stmt.add_trailing_semicolon());
1379                 }
1380             }
1381
1382             return placeholder;
1383         }
1384
1385         // The placeholder expander gives ids to statements, so we avoid folding the id here.
1386         let ast::Stmt { id, kind, span } = stmt;
1387         noop_flat_map_stmt_kind(kind, self)
1388             .into_iter()
1389             .map(|kind| ast::Stmt { id, kind, span })
1390             .collect()
1391     }
1392
1393     fn visit_block(&mut self, block: &mut P<Block>) {
1394         let old_directory_ownership = self.cx.current_expansion.directory_ownership;
1395         self.cx.current_expansion.directory_ownership = DirectoryOwnership::UnownedViaBlock;
1396         noop_visit_block(block, self);
1397         self.cx.current_expansion.directory_ownership = old_directory_ownership;
1398     }
1399
1400     fn flat_map_item(&mut self, item: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
1401         let mut item = configure!(self, item);
1402
1403         let (attr, traits, after_derive) = self.classify_item(&mut item);
1404         if attr.is_some() || !traits.is_empty() {
1405             return self
1406                 .collect_attr(
1407                     attr,
1408                     traits,
1409                     Annotatable::Item(item),
1410                     AstFragmentKind::Items,
1411                     after_derive,
1412                 )
1413                 .make_items();
1414         }
1415
1416         let mut attrs = mem::take(&mut item.attrs); // We do this to please borrowck.
1417         let ident = item.ident;
1418         let span = item.span;
1419
1420         match item.kind {
1421             ast::ItemKind::MacCall(..) => {
1422                 item.attrs = attrs;
1423                 self.check_attributes(&item.attrs);
1424                 item.and_then(|item| match item.kind {
1425                     ItemKind::MacCall(mac) => self
1426                         .collect(AstFragmentKind::Items, InvocationKind::Bang { mac, span })
1427                         .make_items(),
1428                     _ => unreachable!(),
1429                 })
1430             }
1431             ast::ItemKind::Mod(ref mut old_mod @ ast::Mod { .. }) if ident != Ident::invalid() => {
1432                 let sess = self.cx.parse_sess;
1433                 let orig_ownership = self.cx.current_expansion.directory_ownership;
1434                 let mut module = (*self.cx.current_expansion.module).clone();
1435
1436                 let pushed = &mut false; // Record `parse_external_mod` pushing so we can pop.
1437                 let dir = Directory { ownership: orig_ownership, path: module.directory };
1438                 let Directory { ownership, path } = if old_mod.inline {
1439                     // Inline `mod foo { ... }`, but we still need to push directories.
1440                     item.attrs = attrs;
1441                     push_directory(ident, &item.attrs, dir)
1442                 } else {
1443                     // We have an outline `mod foo;` so we need to parse the file.
1444                     let (new_mod, dir) =
1445                         parse_external_mod(sess, ident, span, dir, &mut attrs, pushed);
1446
1447                     let krate = ast::Crate {
1448                         span: new_mod.inner,
1449                         module: new_mod,
1450                         attrs,
1451                         proc_macros: vec![],
1452                     };
1453                     if let Some(extern_mod_loaded) = self.cx.extern_mod_loaded {
1454                         extern_mod_loaded(&krate);
1455                     }
1456
1457                     *old_mod = krate.module;
1458                     item.attrs = krate.attrs;
1459                     // File can have inline attributes, e.g., `#![cfg(...)]` & co. => Reconfigure.
1460                     item = match self.configure(item) {
1461                         Some(node) => node,
1462                         None => {
1463                             if *pushed {
1464                                 sess.included_mod_stack.borrow_mut().pop();
1465                             }
1466                             return Default::default();
1467                         }
1468                     };
1469                     dir
1470                 };
1471
1472                 // Set the module info before we flat map.
1473                 self.cx.current_expansion.directory_ownership = ownership;
1474                 module.directory = path;
1475                 module.mod_path.push(ident);
1476                 let orig_module =
1477                     mem::replace(&mut self.cx.current_expansion.module, Rc::new(module));
1478
1479                 let result = noop_flat_map_item(item, self);
1480
1481                 // Restore the module info.
1482                 self.cx.current_expansion.module = orig_module;
1483                 self.cx.current_expansion.directory_ownership = orig_ownership;
1484                 if *pushed {
1485                     sess.included_mod_stack.borrow_mut().pop();
1486                 }
1487                 result
1488             }
1489             _ => {
1490                 item.attrs = attrs;
1491                 noop_flat_map_item(item, self)
1492             }
1493         }
1494     }
1495
1496     fn flat_map_trait_item(&mut self, item: P<ast::AssocItem>) -> SmallVec<[P<ast::AssocItem>; 1]> {
1497         let mut item = configure!(self, item);
1498
1499         let (attr, traits, after_derive) = self.classify_item(&mut item);
1500         if attr.is_some() || !traits.is_empty() {
1501             return self
1502                 .collect_attr(
1503                     attr,
1504                     traits,
1505                     Annotatable::TraitItem(item),
1506                     AstFragmentKind::TraitItems,
1507                     after_derive,
1508                 )
1509                 .make_trait_items();
1510         }
1511
1512         match item.kind {
1513             ast::AssocItemKind::MacCall(..) => {
1514                 self.check_attributes(&item.attrs);
1515                 item.and_then(|item| match item.kind {
1516                     ast::AssocItemKind::MacCall(mac) => self
1517                         .collect_bang(mac, item.span, AstFragmentKind::TraitItems)
1518                         .make_trait_items(),
1519                     _ => unreachable!(),
1520                 })
1521             }
1522             _ => noop_flat_map_assoc_item(item, self),
1523         }
1524     }
1525
1526     fn flat_map_impl_item(&mut self, item: P<ast::AssocItem>) -> SmallVec<[P<ast::AssocItem>; 1]> {
1527         let mut item = configure!(self, item);
1528
1529         let (attr, traits, after_derive) = self.classify_item(&mut item);
1530         if attr.is_some() || !traits.is_empty() {
1531             return self
1532                 .collect_attr(
1533                     attr,
1534                     traits,
1535                     Annotatable::ImplItem(item),
1536                     AstFragmentKind::ImplItems,
1537                     after_derive,
1538                 )
1539                 .make_impl_items();
1540         }
1541
1542         match item.kind {
1543             ast::AssocItemKind::MacCall(..) => {
1544                 self.check_attributes(&item.attrs);
1545                 item.and_then(|item| match item.kind {
1546                     ast::AssocItemKind::MacCall(mac) => self
1547                         .collect_bang(mac, item.span, AstFragmentKind::ImplItems)
1548                         .make_impl_items(),
1549                     _ => unreachable!(),
1550                 })
1551             }
1552             _ => noop_flat_map_assoc_item(item, self),
1553         }
1554     }
1555
1556     fn visit_ty(&mut self, ty: &mut P<ast::Ty>) {
1557         match ty.kind {
1558             ast::TyKind::MacCall(_) => {}
1559             _ => return noop_visit_ty(ty, self),
1560         };
1561
1562         visit_clobber(ty, |mut ty| match mem::replace(&mut ty.kind, ast::TyKind::Err) {
1563             ast::TyKind::MacCall(mac) => {
1564                 self.collect_bang(mac, ty.span, AstFragmentKind::Ty).make_ty()
1565             }
1566             _ => unreachable!(),
1567         });
1568     }
1569
1570     fn visit_foreign_mod(&mut self, foreign_mod: &mut ast::ForeignMod) {
1571         self.cfg.configure_foreign_mod(foreign_mod);
1572         noop_visit_foreign_mod(foreign_mod, self);
1573     }
1574
1575     fn flat_map_foreign_item(
1576         &mut self,
1577         mut foreign_item: P<ast::ForeignItem>,
1578     ) -> SmallVec<[P<ast::ForeignItem>; 1]> {
1579         let (attr, traits, after_derive) = self.classify_item(&mut foreign_item);
1580
1581         if attr.is_some() || !traits.is_empty() {
1582             return self
1583                 .collect_attr(
1584                     attr,
1585                     traits,
1586                     Annotatable::ForeignItem(foreign_item),
1587                     AstFragmentKind::ForeignItems,
1588                     after_derive,
1589                 )
1590                 .make_foreign_items();
1591         }
1592
1593         match foreign_item.kind {
1594             ast::ForeignItemKind::MacCall(..) => {
1595                 self.check_attributes(&foreign_item.attrs);
1596                 foreign_item.and_then(|item| match item.kind {
1597                     ast::ForeignItemKind::MacCall(mac) => self
1598                         .collect_bang(mac, item.span, AstFragmentKind::ForeignItems)
1599                         .make_foreign_items(),
1600                     _ => unreachable!(),
1601                 })
1602             }
1603             _ => noop_flat_map_foreign_item(foreign_item, self),
1604         }
1605     }
1606
1607     fn visit_item_kind(&mut self, item: &mut ast::ItemKind) {
1608         match item {
1609             ast::ItemKind::MacroDef(..) => {}
1610             _ => {
1611                 self.cfg.configure_item_kind(item);
1612                 noop_visit_item_kind(item, self);
1613             }
1614         }
1615     }
1616
1617     fn flat_map_generic_param(
1618         &mut self,
1619         param: ast::GenericParam,
1620     ) -> SmallVec<[ast::GenericParam; 1]> {
1621         let mut param = configure!(self, param);
1622
1623         let (attr, traits, after_derive) = self.classify_item(&mut param);
1624         if attr.is_some() || !traits.is_empty() {
1625             return self
1626                 .collect_attr(
1627                     attr,
1628                     traits,
1629                     Annotatable::GenericParam(param),
1630                     AstFragmentKind::GenericParams,
1631                     after_derive,
1632                 )
1633                 .make_generic_params();
1634         }
1635
1636         noop_flat_map_generic_param(param, self)
1637     }
1638
1639     fn visit_attribute(&mut self, at: &mut ast::Attribute) {
1640         // turn `#[doc(include="filename")]` attributes into `#[doc(include(file="filename",
1641         // contents="file contents")]` attributes
1642         if !at.check_name(sym::doc) {
1643             return noop_visit_attribute(at, self);
1644         }
1645
1646         if let Some(list) = at.meta_item_list() {
1647             if !list.iter().any(|it| it.check_name(sym::include)) {
1648                 return noop_visit_attribute(at, self);
1649             }
1650
1651             let mut items = vec![];
1652
1653             for mut it in list {
1654                 if !it.check_name(sym::include) {
1655                     items.push({
1656                         noop_visit_meta_list_item(&mut it, self);
1657                         it
1658                     });
1659                     continue;
1660                 }
1661
1662                 if let Some(file) = it.value_str() {
1663                     let err_count = self.cx.parse_sess.span_diagnostic.err_count();
1664                     self.check_attributes(slice::from_ref(at));
1665                     if self.cx.parse_sess.span_diagnostic.err_count() > err_count {
1666                         // avoid loading the file if they haven't enabled the feature
1667                         return noop_visit_attribute(at, self);
1668                     }
1669
1670                     let filename = match self.cx.resolve_path(&*file.as_str(), it.span()) {
1671                         Ok(filename) => filename,
1672                         Err(mut err) => {
1673                             err.emit();
1674                             continue;
1675                         }
1676                     };
1677
1678                     match self.cx.source_map().load_file(&filename) {
1679                         Ok(source_file) => {
1680                             let src = source_file
1681                                 .src
1682                                 .as_ref()
1683                                 .expect("freshly loaded file should have a source");
1684                             let src_interned = Symbol::intern(src.as_str());
1685
1686                             let include_info = vec![
1687                                 ast::NestedMetaItem::MetaItem(attr::mk_name_value_item_str(
1688                                     Ident::with_dummy_span(sym::file),
1689                                     file,
1690                                     DUMMY_SP,
1691                                 )),
1692                                 ast::NestedMetaItem::MetaItem(attr::mk_name_value_item_str(
1693                                     Ident::with_dummy_span(sym::contents),
1694                                     src_interned,
1695                                     DUMMY_SP,
1696                                 )),
1697                             ];
1698
1699                             let include_ident = Ident::with_dummy_span(sym::include);
1700                             let item = attr::mk_list_item(include_ident, include_info);
1701                             items.push(ast::NestedMetaItem::MetaItem(item));
1702                         }
1703                         Err(e) => {
1704                             let lit =
1705                                 it.meta_item().and_then(|item| item.name_value_literal()).unwrap();
1706
1707                             if e.kind() == ErrorKind::InvalidData {
1708                                 self.cx
1709                                     .struct_span_err(
1710                                         lit.span,
1711                                         &format!("{} wasn't a utf-8 file", filename.display()),
1712                                     )
1713                                     .span_label(lit.span, "contains invalid utf-8")
1714                                     .emit();
1715                             } else {
1716                                 let mut err = self.cx.struct_span_err(
1717                                     lit.span,
1718                                     &format!("couldn't read {}: {}", filename.display(), e),
1719                                 );
1720                                 err.span_label(lit.span, "couldn't read file");
1721
1722                                 err.emit();
1723                             }
1724                         }
1725                     }
1726                 } else {
1727                     let mut err = self
1728                         .cx
1729                         .struct_span_err(it.span(), "expected path to external documentation");
1730
1731                     // Check if the user erroneously used `doc(include(...))` syntax.
1732                     let literal = it.meta_item_list().and_then(|list| {
1733                         if list.len() == 1 {
1734                             list[0].literal().map(|literal| &literal.kind)
1735                         } else {
1736                             None
1737                         }
1738                     });
1739
1740                     let (path, applicability) = match &literal {
1741                         Some(LitKind::Str(path, ..)) => {
1742                             (path.to_string(), Applicability::MachineApplicable)
1743                         }
1744                         _ => (String::from("<path>"), Applicability::HasPlaceholders),
1745                     };
1746
1747                     err.span_suggestion(
1748                         it.span(),
1749                         "provide a file path with `=`",
1750                         format!("include = \"{}\"", path),
1751                         applicability,
1752                     );
1753
1754                     err.emit();
1755                 }
1756             }
1757
1758             let meta = attr::mk_list_item(Ident::with_dummy_span(sym::doc), items);
1759             *at = ast::Attribute {
1760                 kind: ast::AttrKind::Normal(AttrItem {
1761                     path: meta.path,
1762                     args: meta.kind.mac_args(meta.span),
1763                 }),
1764                 span: at.span,
1765                 id: at.id,
1766                 style: at.style,
1767             };
1768         } else {
1769             noop_visit_attribute(at, self)
1770         }
1771     }
1772
1773     fn visit_id(&mut self, id: &mut ast::NodeId) {
1774         if self.monotonic {
1775             debug_assert_eq!(*id, ast::DUMMY_NODE_ID);
1776             *id = self.cx.resolver.next_node_id()
1777         }
1778     }
1779
1780     fn visit_fn_decl(&mut self, mut fn_decl: &mut P<ast::FnDecl>) {
1781         self.cfg.configure_fn_decl(&mut fn_decl);
1782         noop_visit_fn_decl(fn_decl, self);
1783     }
1784 }
1785
1786 pub struct ExpansionConfig<'feat> {
1787     pub crate_name: String,
1788     pub features: Option<&'feat Features>,
1789     pub recursion_limit: Limit,
1790     pub trace_mac: bool,
1791     pub should_test: bool, // If false, strip `#[test]` nodes
1792     pub keep_macs: bool,
1793     pub span_debug: bool, // If true, use verbose debugging for `proc_macro::Span`
1794 }
1795
1796 impl<'feat> ExpansionConfig<'feat> {
1797     pub fn default(crate_name: String) -> ExpansionConfig<'static> {
1798         ExpansionConfig {
1799             crate_name,
1800             features: None,
1801             recursion_limit: Limit::new(1024),
1802             trace_mac: false,
1803             should_test: false,
1804             keep_macs: false,
1805             span_debug: false,
1806         }
1807     }
1808
1809     fn proc_macro_hygiene(&self) -> bool {
1810         self.features.map_or(false, |features| features.proc_macro_hygiene)
1811     }
1812     fn custom_inner_attributes(&self) -> bool {
1813         self.features.map_or(false, |features| features.custom_inner_attributes)
1814     }
1815 }