diff options
| author | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2021-10-17 19:32:34 +0300 |
|---|---|---|
| committer | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2021-11-28 15:48:55 +0800 |
| commit | 141c6cc78ece04fb8330b2c28a42c025500d2d0e (patch) | |
| tree | e018a0cf0be39dee3946397bef2ea965210a72f8 /compiler/rustc_ast/src | |
| parent | 4919988fe1765e51232558647f2260fff3544658 (diff) | |
| download | rust-141c6cc78ece04fb8330b2c28a42c025500d2d0e.tar.gz rust-141c6cc78ece04fb8330b2c28a42c025500d2d0e.zip | |
expand: Turn `ast::Crate` into a first class expansion target
And stop creating a fake `mod` item for the crate root when expanding a crate.
Diffstat (limited to 'compiler/rustc_ast/src')
| -rw-r--r-- | compiler/rustc_ast/src/ast.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/ast_like.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/mut_visit.rs | 37 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/visit.rs | 3 |
4 files changed, 15 insertions, 31 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 55b243a84a9..4d4c6217ad0 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -517,6 +517,8 @@ pub struct Crate { pub attrs: Vec<Attribute>, pub items: Vec<P<Item>>, pub span: Span, + // Placeholder ID if the crate node is a macro placeholder. + pub is_placeholder: Option<NodeId>, } /// Possible values inside of compile-time attribute lists. diff --git a/compiler/rustc_ast/src/ast_like.rs b/compiler/rustc_ast/src/ast_like.rs index d586426d70e..b9c397974a1 100644 --- a/compiler/rustc_ast/src/ast_like.rs +++ b/compiler/rustc_ast/src/ast_like.rs @@ -1,7 +1,7 @@ use super::ptr::P; use super::token::Nonterminal; use super::tokenstream::LazyTokenStream; -use super::{Arm, ExprField, FieldDef, GenericParam, Param, PatField, Variant}; +use super::{Arm, Crate, ExprField, FieldDef, GenericParam, Param, PatField, Variant}; use super::{AssocItem, Expr, ForeignItem, Item, Local, MacCallStmt}; use super::{AttrItem, AttrKind, Block, Pat, Path, Ty, Visibility}; use super::{AttrVec, Attribute, Stmt, StmtKind}; @@ -276,7 +276,7 @@ derive_has_tokens_and_attrs! { // These ast nodes only support inert attributes, so they don't // store tokens (since nothing can observe them) derive_has_attrs_no_tokens! { - FieldDef, Arm, ExprField, PatField, Variant, Param, GenericParam + FieldDef, Arm, ExprField, PatField, Variant, Param, GenericParam, Crate } // These AST nodes don't support attributes, but can diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index fc5cc963992..205625573a6 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -284,6 +284,10 @@ pub trait MutVisitor: Sized { /// Use a map-style function (`FnOnce(T) -> T`) to overwrite a `&mut T`. Useful /// when using a `flat_map_*` or `filter_map_*` method within a `visit_` /// method. Abort the program if the closure panics. +/// +/// FIXME: Abort on panic means that any fatal error inside `visit_clobber` will abort the compiler. +/// Instead of aborting on catching a panic we need to reset the visited node to some valid but +/// possibly meaningless value and rethrow the panic. // // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. pub fn visit_clobber<T, F>(t: &mut T, f: F) @@ -1105,36 +1109,11 @@ pub fn noop_visit_fn_header<T: MutVisitor>(header: &mut FnHeader, vis: &mut T) { visit_unsafety(unsafety, vis); } -// FIXME: Avoid visiting the crate as a `Mod` item, flat map only the inner items if possible, -// or make crate visiting first class if necessary. pub fn noop_visit_crate<T: MutVisitor>(krate: &mut Crate, vis: &mut T) { - visit_clobber(krate, |Crate { attrs, items, span }| { - let item_vis = - Visibility { kind: VisibilityKind::Public, span: span.shrink_to_lo(), tokens: None }; - let item = P(Item { - ident: Ident::empty(), - attrs, - id: DUMMY_NODE_ID, - vis: item_vis, - span, - kind: ItemKind::Mod(Unsafe::No, ModKind::Loaded(items, Inline::Yes, span)), - tokens: None, - }); - let items = vis.flat_map_item(item); - - let len = items.len(); - if len == 0 { - Crate { attrs: vec![], items: vec![], span } - } else if len == 1 { - let Item { attrs, span, kind, .. } = items.into_iter().next().unwrap().into_inner(); - match kind { - ItemKind::Mod(_, ModKind::Loaded(items, ..)) => Crate { attrs, items, span }, - _ => panic!("visitor converted a module to not a module"), - } - } else { - panic!("a crate cannot expand to more than one item"); - } - }); + let Crate { attrs, items, span, is_placeholder: _ } = krate; + visit_attrs(attrs, vis); + items.flat_map_in_place(|item| vis.flat_map_item(item)); + vis.visit_span(span); } // Mutates one item into possibly many items. diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index be794ed221a..6840f092da6 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -211,6 +211,9 @@ pub trait Visitor<'ast>: Sized { fn visit_pat_field(&mut self, fp: &'ast PatField) { walk_pat_field(self, fp) } + fn visit_crate(&mut self, krate: &'ast Crate) { + walk_crate(self, krate) + } } #[macro_export] |
