ast: Keep expansion status for out-of-line module items
Also remove `ast::Mod` which is mostly redundant now
This commit is contained in:
parent
eb65f15c78
commit
4a88165124
14 changed files with 147 additions and 125 deletions
|
@ -12,8 +12,8 @@ use rustc_ast::ptr::P;
|
|||
use rustc_ast::token;
|
||||
use rustc_ast::tokenstream::TokenStream;
|
||||
use rustc_ast::visit::{self, AssocCtxt, Visitor};
|
||||
use rustc_ast::{AttrItem, AttrStyle, Block, ItemKind, LitKind, MacArgs};
|
||||
use rustc_ast::{MacCallStmt, MacStmtStyle, MetaItemKind, NestedMetaItem};
|
||||
use rustc_ast::{AttrItem, AttrStyle, Block, Inline, ItemKind, LitKind, MacArgs};
|
||||
use rustc_ast::{MacCallStmt, MacStmtStyle, MetaItemKind, ModKind, NestedMetaItem};
|
||||
use rustc_ast::{NodeId, PatKind, Path, StmtKind, Unsafe};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_attr::{self as attr, is_builtin_attr, HasAttrs};
|
||||
|
@ -367,12 +367,10 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||
let krate_item = AstFragment::Items(smallvec![P(ast::Item {
|
||||
attrs: krate.attrs,
|
||||
span: krate.span,
|
||||
kind: ast::ItemKind::Mod(ast::Mod {
|
||||
inner: krate.span,
|
||||
unsafety: Unsafe::No,
|
||||
items: krate.items,
|
||||
inline: true
|
||||
}),
|
||||
kind: ast::ItemKind::Mod(
|
||||
Unsafe::No,
|
||||
ModKind::Loaded(krate.items, Inline::Yes, krate.span)
|
||||
),
|
||||
ident: Ident::invalid(),
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
vis: ast::Visibility {
|
||||
|
@ -384,9 +382,13 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||
})]);
|
||||
|
||||
match self.fully_expand_fragment(krate_item).make_items().pop().map(P::into_inner) {
|
||||
Some(ast::Item { attrs, kind: ast::ItemKind::Mod(module), .. }) => {
|
||||
Some(ast::Item {
|
||||
attrs,
|
||||
kind: ast::ItemKind::Mod(_, ModKind::Loaded(items, ..)),
|
||||
..
|
||||
}) => {
|
||||
krate.attrs = attrs;
|
||||
krate.items = module.items;
|
||||
krate.items = items;
|
||||
}
|
||||
None => {
|
||||
// Resolution failed so we return an empty expansion
|
||||
|
@ -809,7 +811,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||
impl<'ast, 'a> Visitor<'ast> for GateProcMacroInput<'a> {
|
||||
fn visit_item(&mut self, item: &'ast ast::Item) {
|
||||
match &item.kind {
|
||||
ast::ItemKind::Mod(module) if !module.inline => {
|
||||
ast::ItemKind::Mod(_, mod_kind)
|
||||
if !matches!(mod_kind, ModKind::Loaded(_, Inline::Yes, _)) =>
|
||||
{
|
||||
feature_err(
|
||||
self.parse_sess,
|
||||
sym::proc_macro_hygiene,
|
||||
|
@ -1266,47 +1270,47 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
|
|||
_ => unreachable!(),
|
||||
})
|
||||
}
|
||||
ast::ItemKind::Mod(ref mut old_mod @ ast::Mod { .. }) if ident != Ident::invalid() => {
|
||||
ast::ItemKind::Mod(_, ref mut mod_kind) if ident != Ident::invalid() => {
|
||||
let sess = &self.cx.sess.parse_sess;
|
||||
let orig_ownership = self.cx.current_expansion.directory_ownership;
|
||||
let mut module = (*self.cx.current_expansion.module).clone();
|
||||
|
||||
let pushed = &mut false; // Record `parse_external_mod` pushing so we can pop.
|
||||
let dir = Directory { ownership: orig_ownership, path: module.directory };
|
||||
let Directory { ownership, path } = if old_mod.inline {
|
||||
// Inline `mod foo { ... }`, but we still need to push directories.
|
||||
item.attrs = attrs;
|
||||
push_directory(&self.cx.sess, ident, &item.attrs, dir)
|
||||
} else {
|
||||
// We have an outline `mod foo;` so we need to parse the file.
|
||||
let (ast::Mod { unsafety, inline, items, inner }, dir) = parse_external_mod(
|
||||
&self.cx.sess,
|
||||
ident,
|
||||
span,
|
||||
old_mod.unsafety,
|
||||
dir,
|
||||
&mut attrs,
|
||||
pushed,
|
||||
);
|
||||
|
||||
let krate = ast::Crate { attrs, items, span: inner, proc_macros: vec![] };
|
||||
if let Some(extern_mod_loaded) = self.cx.extern_mod_loaded {
|
||||
extern_mod_loaded(&krate, ident);
|
||||
let Directory { ownership, path } = match mod_kind {
|
||||
ModKind::Loaded(_, Inline::Yes, _) => {
|
||||
// Inline `mod foo { ... }`, but we still need to push directories.
|
||||
item.attrs = attrs;
|
||||
push_directory(&self.cx.sess, ident, &item.attrs, dir)
|
||||
}
|
||||
ModKind::Loaded(_, Inline::No, _) => {
|
||||
panic!("`mod` item is loaded from a file for the second time")
|
||||
}
|
||||
ModKind::Unloaded => {
|
||||
// We have an outline `mod foo;` so we need to parse the file.
|
||||
let (items, inner_span, dir) =
|
||||
parse_external_mod(&self.cx.sess, ident, span, dir, &mut attrs, pushed);
|
||||
|
||||
*old_mod = ast::Mod { unsafety, inline, items: krate.items, inner };
|
||||
item.attrs = krate.attrs;
|
||||
// File can have inline attributes, e.g., `#![cfg(...)]` & co. => Reconfigure.
|
||||
item = match self.configure(item) {
|
||||
Some(node) => node,
|
||||
None => {
|
||||
if *pushed {
|
||||
sess.included_mod_stack.borrow_mut().pop();
|
||||
}
|
||||
return Default::default();
|
||||
let krate =
|
||||
ast::Crate { attrs, items, span: inner_span, proc_macros: vec![] };
|
||||
if let Some(extern_mod_loaded) = self.cx.extern_mod_loaded {
|
||||
extern_mod_loaded(&krate, ident);
|
||||
}
|
||||
};
|
||||
dir
|
||||
|
||||
*mod_kind = ModKind::Loaded(krate.items, Inline::No, inner_span);
|
||||
item.attrs = krate.attrs;
|
||||
// File can have inline attributes, e.g., `#![cfg(...)]` & co. => Reconfigure.
|
||||
item = match self.configure(item) {
|
||||
Some(node) => node,
|
||||
None => {
|
||||
if *pushed {
|
||||
sess.included_mod_stack.borrow_mut().pop();
|
||||
}
|
||||
return Default::default();
|
||||
}
|
||||
};
|
||||
dir
|
||||
}
|
||||
};
|
||||
|
||||
// Set the module info before we flat map.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue