mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-25 12:33:33 +00:00
fix: Fix runnables trying to add doc tests in the crate root from #[macro_export] macros
This commit is contained in:
parent
bd17933c31
commit
828196be3b
6 changed files with 98 additions and 3 deletions
|
@ -570,6 +570,12 @@ impl Module {
|
|||
.collect()
|
||||
}
|
||||
|
||||
pub fn legacy_macros(self, db: &dyn HirDatabase) -> Vec<Macro> {
|
||||
let def_map = self.id.def_map(db.upcast());
|
||||
let scope = &def_map[self.id.local_id].scope;
|
||||
scope.legacy_macros().map(|(_, it)| MacroId::from(it).into()).collect()
|
||||
}
|
||||
|
||||
pub fn impl_defs(self, db: &dyn HirDatabase) -> Vec<Impl> {
|
||||
let def_map = self.id.def_map(db.upcast());
|
||||
def_map[self.id.local_id].scope.impls().map(Impl::from).collect()
|
||||
|
@ -1789,6 +1795,10 @@ impl Macro {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn is_macro_export(self, db: &dyn HirDatabase) -> bool {
|
||||
matches!(self.id, MacroId::MacroRulesId(id) if db.macro_rules_data(id).macro_export)
|
||||
}
|
||||
|
||||
pub fn kind(&self, db: &dyn HirDatabase) -> MacroKind {
|
||||
match self.id {
|
||||
MacroId::Macro2Id(it) => match it.lookup(db.upcast()).expander {
|
||||
|
|
|
@ -315,6 +315,7 @@ impl Macro2Data {
|
|||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct MacroRulesData {
|
||||
pub name: Name,
|
||||
pub macro_export: bool,
|
||||
}
|
||||
|
||||
impl MacroRulesData {
|
||||
|
@ -326,7 +327,12 @@ impl MacroRulesData {
|
|||
let item_tree = loc.id.item_tree(db);
|
||||
let makro = &item_tree[loc.id.value];
|
||||
|
||||
Arc::new(MacroRulesData { name: makro.name.clone() })
|
||||
let macro_export = item_tree
|
||||
.attrs(db, loc.container.krate(), ModItem::from(loc.id.value).into())
|
||||
.by_key("macro_export")
|
||||
.exists();
|
||||
|
||||
Arc::new(MacroRulesData { name: makro.name.clone(), macro_export })
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
|
|
|
@ -63,6 +63,7 @@ pub struct ItemScope {
|
|||
// FIXME: Macro shadowing in one module is not properly handled. Non-item place macros will
|
||||
// be all resolved to the last one defined if shadowing happens.
|
||||
legacy_macros: FxHashMap<Name, MacroRulesId>,
|
||||
/// The derive macro invocations in this scope.
|
||||
attr_macros: FxHashMap<AstId<ast::Item>, MacroCallId>,
|
||||
/// The derive macro invocations in this scope, keyed by the owner item over the actual derive attributes
|
||||
/// paired with the derive macro invocations for the specific attribute.
|
||||
|
|
|
@ -157,7 +157,13 @@ pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> {
|
|||
Definition::SelfType(impl_) => runnable_impl(&sema, &impl_),
|
||||
_ => None,
|
||||
};
|
||||
add_opt(runnable.or_else(|| module_def_doctest(sema.db, def)), Some(def));
|
||||
add_opt(
|
||||
runnable
|
||||
.or_else(|| module_def_doctest(sema.db, def))
|
||||
// #[macro_export] mbe macros are declared in the root, while their definition may reside in a different module
|
||||
.filter(|it| it.nav.file_id == file_id),
|
||||
Some(def),
|
||||
);
|
||||
if let Definition::SelfType(impl_) = def {
|
||||
impl_.items(db).into_iter().for_each(|assoc| {
|
||||
let runnable = match assoc {
|
||||
|
@ -2074,4 +2080,68 @@ impl<T, U> Foo<T, U> {
|
|||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn doc_test_macro_export_mbe() {
|
||||
check(
|
||||
r#"
|
||||
//- /lib.rs
|
||||
$0
|
||||
mod foo;
|
||||
|
||||
//- /foo.rs
|
||||
/// ```
|
||||
/// fn foo() {
|
||||
/// }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! foo {
|
||||
() => {
|
||||
|
||||
};
|
||||
}
|
||||
"#,
|
||||
&[],
|
||||
expect![[r#"
|
||||
[]
|
||||
"#]],
|
||||
);
|
||||
check(
|
||||
r#"
|
||||
//- /lib.rs
|
||||
$0
|
||||
/// ```
|
||||
/// fn foo() {
|
||||
/// }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! foo {
|
||||
() => {
|
||||
|
||||
};
|
||||
}
|
||||
"#,
|
||||
&[DocTest],
|
||||
expect![[r#"
|
||||
[
|
||||
Runnable {
|
||||
use_name_in_title: false,
|
||||
nav: NavigationTarget {
|
||||
file_id: FileId(
|
||||
0,
|
||||
),
|
||||
full_range: 1..94,
|
||||
name: "foo",
|
||||
},
|
||||
kind: DocTest {
|
||||
test_id: Path(
|
||||
"foo",
|
||||
),
|
||||
},
|
||||
cfg: None,
|
||||
},
|
||||
]
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -447,7 +447,7 @@ impl NameRefClass {
|
|||
|
||||
impl_from!(
|
||||
Field, Module, Function, Adt, Variant, Const, Static, Trait, TypeAlias, BuiltinType, Local,
|
||||
GenericParam, Label
|
||||
GenericParam, Label, Macro
|
||||
for Definition
|
||||
);
|
||||
|
||||
|
|
|
@ -76,6 +76,14 @@ pub fn visit_file_defs(
|
|||
cb(def.into());
|
||||
}
|
||||
module.impl_defs(db).into_iter().for_each(|impl_| cb(impl_.into()));
|
||||
|
||||
let is_root = module.is_crate_root(db);
|
||||
module
|
||||
.legacy_macros(db)
|
||||
.into_iter()
|
||||
// don't show legacy macros declared in the crate-root that were already covered in declarations earlier
|
||||
.filter(|it| !(is_root && it.is_macro_export(db)))
|
||||
.for_each(|mac| cb(mac.into()));
|
||||
}
|
||||
|
||||
/// Checks if the given lint is equal or is contained by the other lint which may or may not be a group.
|
||||
|
|
Loading…
Reference in a new issue