ast: Stop using Mod
in Crate
Crate root is sufficiently different from `mod` items, at least at syntactic level. Also remove customization point for "`mod` item or crate root" from AST visitors.
This commit is contained in:
parent
d1462d8558
commit
eb65f15c78
23 changed files with 114 additions and 179 deletions
|
@ -209,7 +209,7 @@ pub fn features(sess: &Session, mut krate: ast::Crate) -> (ast::Crate, Features)
|
|||
None => {
|
||||
// The entire crate is unconfigured.
|
||||
krate.attrs = Vec::new();
|
||||
krate.module.items = Vec::new();
|
||||
krate.items = Vec::new();
|
||||
Features::default()
|
||||
}
|
||||
Some(attrs) => {
|
||||
|
|
|
@ -350,6 +350,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||
MacroExpander { cx, monotonic }
|
||||
}
|
||||
|
||||
// FIXME: Avoid visiting the crate as a `Mod` item,
|
||||
// make crate a first class expansion target instead.
|
||||
pub fn expand_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
|
||||
let mut module = ModuleData {
|
||||
mod_path: vec![Ident::from_str(&self.cx.ecfg.crate_name)],
|
||||
|
@ -362,12 +364,15 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||
self.cx.root_path = module.directory.clone();
|
||||
self.cx.current_expansion.module = Rc::new(module);
|
||||
|
||||
let orig_mod_span = krate.module.inner;
|
||||
|
||||
let krate_item = AstFragment::Items(smallvec![P(ast::Item {
|
||||
attrs: krate.attrs,
|
||||
span: krate.span,
|
||||
kind: ast::ItemKind::Mod(krate.module),
|
||||
kind: ast::ItemKind::Mod(ast::Mod {
|
||||
inner: krate.span,
|
||||
unsafety: Unsafe::No,
|
||||
items: krate.items,
|
||||
inline: true
|
||||
}),
|
||||
ident: Ident::invalid(),
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
vis: ast::Visibility {
|
||||
|
@ -381,26 +386,16 @@ 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), .. }) => {
|
||||
krate.attrs = attrs;
|
||||
krate.module = module;
|
||||
krate.items = module.items;
|
||||
}
|
||||
None => {
|
||||
// Resolution failed so we return an empty expansion
|
||||
krate.attrs = vec![];
|
||||
krate.module = ast::Mod {
|
||||
inner: orig_mod_span,
|
||||
unsafety: Unsafe::No,
|
||||
items: vec![],
|
||||
inline: true,
|
||||
};
|
||||
krate.items = vec![];
|
||||
}
|
||||
Some(ast::Item { span, kind, .. }) => {
|
||||
krate.attrs = vec![];
|
||||
krate.module = ast::Mod {
|
||||
inner: orig_mod_span,
|
||||
unsafety: Unsafe::No,
|
||||
items: vec![],
|
||||
inline: true,
|
||||
};
|
||||
krate.items = vec![];
|
||||
self.cx.span_err(
|
||||
span,
|
||||
&format!(
|
||||
|
@ -1284,7 +1279,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
|
|||
push_directory(&self.cx.sess, ident, &item.attrs, dir)
|
||||
} else {
|
||||
// We have an outline `mod foo;` so we need to parse the file.
|
||||
let (new_mod, dir) = parse_external_mod(
|
||||
let (ast::Mod { unsafety, inline, items, inner }, dir) = parse_external_mod(
|
||||
&self.cx.sess,
|
||||
ident,
|
||||
span,
|
||||
|
@ -1294,17 +1289,12 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
|
|||
pushed,
|
||||
);
|
||||
|
||||
let krate = ast::Crate {
|
||||
span: new_mod.inner,
|
||||
module: new_mod,
|
||||
attrs,
|
||||
proc_macros: vec![],
|
||||
};
|
||||
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);
|
||||
}
|
||||
|
||||
*old_mod = krate.module;
|
||||
*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) {
|
||||
|
|
|
@ -62,9 +62,8 @@ crate fn parse_external_mod(
|
|||
|
||||
// Actually parse the external file as a module.
|
||||
let mut parser = new_parser_from_file(&sess.parse_sess, &mp.path, Some(span));
|
||||
let mut module = parser.parse_mod(&token::Eof, unsafety)?;
|
||||
module.0.inline = false;
|
||||
module
|
||||
let (inner_attrs, items, inner) = parser.parse_mod(&token::Eof)?;
|
||||
(Mod { unsafety, inline: false, items, inner }, inner_attrs)
|
||||
};
|
||||
// (1) ...instead, we return a dummy module.
|
||||
let (module, mut new_attrs) = result.map_err(|mut err| err.emit()).unwrap_or_else(|_| {
|
||||
|
|
|
@ -7,8 +7,8 @@ use rustc_span::symbol::Ident;
|
|||
use rustc_span::with_default_session_globals;
|
||||
|
||||
// This version doesn't care about getting comments or doc-strings in.
|
||||
fn fake_print_crate(s: &mut pprust::State<'_>, krate: &ast::Crate) {
|
||||
s.print_mod(&krate.module, &krate.attrs)
|
||||
fn print_crate_items(krate: &ast::Crate) -> String {
|
||||
krate.items.iter().map(|i| pprust::item_to_string(i)).collect::<Vec<_>>().join(" ")
|
||||
}
|
||||
|
||||
// Change every identifier to "zz".
|
||||
|
@ -46,7 +46,7 @@ fn ident_transformation() {
|
|||
assert_pred!(
|
||||
matches_codepattern,
|
||||
"matches_codepattern",
|
||||
pprust::to_string(|s| fake_print_crate(s, &krate)),
|
||||
print_crate_items(&krate),
|
||||
"#[zz]mod zz{fn zz(zz:zz,zz:zz){zz!(zz,zz,zz);zz;zz}}".to_string()
|
||||
);
|
||||
})
|
||||
|
@ -66,7 +66,7 @@ fn ident_transformation_in_defs() {
|
|||
assert_pred!(
|
||||
matches_codepattern,
|
||||
"matches_codepattern",
|
||||
pprust::to_string(|s| fake_print_crate(s, &krate)),
|
||||
print_crate_items(&krate),
|
||||
"macro_rules! zz{(zz$zz:zz$(zz $zz:zz)zz+=>(zz$(zz$zz$zz)+))}".to_string()
|
||||
);
|
||||
})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue