1
Fork 0

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:
Vadim Petrochenkov 2021-02-14 21:14:12 +03:00
parent d1462d8558
commit eb65f15c78
23 changed files with 114 additions and 179 deletions

View file

@ -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) => {

View file

@ -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) {

View file

@ -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(|_| {

View file

@ -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()
);
})