Fix import strategy of macro_use and its test

This commit is contained in:
uHOOCCOOHu 2019-09-02 14:36:20 +08:00
parent dfa758f6a9
commit a66214b34e
No known key found for this signature in database
GPG Key ID: CED392DE0C483D00
4 changed files with 26 additions and 9 deletions

View File

@ -11,4 +11,5 @@ test_utils::marks!(
match_ergonomics_ref
trait_resolution_on_fn_type
infer_while_let
macro_rules_from_other_crates_are_visible_with_macro_use
);

View File

@ -101,6 +101,8 @@ pub struct CrateDefMap {
/// However, do we want to put it as a global variable?
poison_macros: FxHashSet<MacroDefId>,
exported_macros: FxHashMap<Name, MacroDefId>,
diagnostics: Vec<DefDiagnostic>,
}
@ -245,6 +247,7 @@ impl CrateDefMap {
root,
modules,
poison_macros: FxHashSet::default(),
exported_macros: FxHashMap::default(),
diagnostics: Vec::new(),
}
};

View File

@ -157,6 +157,10 @@ where
// crate root, even if the parent modules is **not** visible.
if export {
self.update(self.def_map.root, None, &[(name.clone(), def.clone())]);
// Exported macros are collected in crate level ready for
// glob import with `#[macro_use]`.
self.def_map.exported_macros.insert(name.clone(), macro_id);
}
self.update(module_id, None, &[(name.clone(), def)]);
self.global_macro_scope.insert(name, macro_id);
@ -295,20 +299,18 @@ where
}
}
// `#[macro_use] extern crate` glob import macros
// `#[macro_use] extern crate` glob imports all macros exported,
// ignoring their scopes
if import.is_extern_crate && import.is_macro_use {
if let Some(ModuleDef::Module(m)) =
def.a().and_then(|item| item.take_types())
{
let item_map = self.db.crate_def_map(m.krate);
let scope = &item_map[m.module_id].scope;
let macros = scope
.macros
.iter()
.map(|(name, res)| (name.clone(), Either::B(*res)))
.collect::<Vec<_>>();
tested_by!(macro_rules_from_other_crates_are_visible_with_macro_use);
self.update(module_id, Some(import_id), &macros);
let item_map = self.db.crate_def_map(m.krate);
for (name, &macro_id) in &item_map.exported_macros {
self.define_macro(module_id, name.clone(), macro_id, false);
}
}
}
@ -877,6 +879,7 @@ mod tests {
root,
modules,
poison_macros: FxHashSet::default(),
exported_macros: FxHashMap::default(),
diagnostics: Vec::new(),
}
};

View File

@ -140,6 +140,7 @@ fn unexpanded_macro_should_expand_by_fixedpoint_loop() {
#[test]
fn macro_rules_from_other_crates_are_visible_with_macro_use() {
covers!(macro_rules_from_other_crates_are_visible_with_macro_use);
let map = def_map_with_crate_graph(
"
//- /main.rs
@ -160,6 +161,13 @@ fn macro_rules_from_other_crates_are_visible_with_macro_use() {
$(struct $i { field: u32 } )*
}
}
mod priv_mod {
#[macro_export]
macro_rules! baz {
() => {};
}
}
",
crate_graph! {
"main": ("/main.rs", ["foo"]),
@ -171,6 +179,7 @@ fn macro_rules_from_other_crates_are_visible_with_macro_use() {
Bar: t v
Foo: t v
bar: t
baz: m
foo: t
structs: m
@ -178,6 +187,7 @@ fn macro_rules_from_other_crates_are_visible_with_macro_use() {
Bar: t v
Foo: t v
bar: t
baz: m
foo: t
structs: m
"###);