Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 828196b

Browse files
committed
fix: Fix runnables trying to add doc tests in the crate root from #[macro_export] macros
1 parent bd17933 commit 828196b

File tree

6 files changed

+98
-3
lines changed

6 files changed

+98
-3
lines changed

crates/hir/src/lib.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,12 @@ impl Module {
570570
.collect()
571571
}
572572

573+
pub fn legacy_macros(self, db: &dyn HirDatabase) -> Vec<Macro> {
574+
let def_map = self.id.def_map(db.upcast());
575+
let scope = &def_map[self.id.local_id].scope;
576+
scope.legacy_macros().map(|(_, it)| MacroId::from(it).into()).collect()
577+
}
578+
573579
pub fn impl_defs(self, db: &dyn HirDatabase) -> Vec<Impl> {
574580
let def_map = self.id.def_map(db.upcast());
575581
def_map[self.id.local_id].scope.impls().map(Impl::from).collect()
@@ -1789,6 +1795,10 @@ impl Macro {
17891795
}
17901796
}
17911797

1798+
pub fn is_macro_export(self, db: &dyn HirDatabase) -> bool {
1799+
matches!(self.id, MacroId::MacroRulesId(id) if db.macro_rules_data(id).macro_export)
1800+
}
1801+
17921802
pub fn kind(&self, db: &dyn HirDatabase) -> MacroKind {
17931803
match self.id {
17941804
MacroId::Macro2Id(it) => match it.lookup(db.upcast()).expander {

crates/hir_def/src/data.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ impl Macro2Data {
315315
#[derive(Debug, Clone, PartialEq, Eq)]
316316
pub struct MacroRulesData {
317317
pub name: Name,
318+
pub macro_export: bool,
318319
}
319320

320321
impl MacroRulesData {
@@ -326,7 +327,12 @@ impl MacroRulesData {
326327
let item_tree = loc.id.item_tree(db);
327328
let makro = &item_tree[loc.id.value];
328329

329-
Arc::new(MacroRulesData { name: makro.name.clone() })
330+
let macro_export = item_tree
331+
.attrs(db, loc.container.krate(), ModItem::from(loc.id.value).into())
332+
.by_key("macro_export")
333+
.exists();
334+
335+
Arc::new(MacroRulesData { name: makro.name.clone(), macro_export })
330336
}
331337
}
332338
#[derive(Debug, Clone, PartialEq, Eq)]

crates/hir_def/src/item_scope.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ pub struct ItemScope {
6363
// FIXME: Macro shadowing in one module is not properly handled. Non-item place macros will
6464
// be all resolved to the last one defined if shadowing happens.
6565
legacy_macros: FxHashMap<Name, MacroRulesId>,
66+
/// The derive macro invocations in this scope.
6667
attr_macros: FxHashMap<AstId<ast::Item>, MacroCallId>,
6768
/// The derive macro invocations in this scope, keyed by the owner item over the actual derive attributes
6869
/// paired with the derive macro invocations for the specific attribute.

crates/ide/src/runnables.rs

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,13 @@ pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> {
157157
Definition::SelfType(impl_) => runnable_impl(&sema, &impl_),
158158
_ => None,
159159
};
160-
add_opt(runnable.or_else(|| module_def_doctest(sema.db, def)), Some(def));
160+
add_opt(
161+
runnable
162+
.or_else(|| module_def_doctest(sema.db, def))
163+
// #[macro_export] mbe macros are declared in the root, while their definition may reside in a different module
164+
.filter(|it| it.nav.file_id == file_id),
165+
Some(def),
166+
);
161167
if let Definition::SelfType(impl_) = def {
162168
impl_.items(db).into_iter().for_each(|assoc| {
163169
let runnable = match assoc {
@@ -2074,4 +2080,68 @@ impl<T, U> Foo<T, U> {
20742080
"#]],
20752081
);
20762082
}
2083+
2084+
#[test]
2085+
fn doc_test_macro_export_mbe() {
2086+
check(
2087+
r#"
2088+
//- /lib.rs
2089+
$0
2090+
mod foo;
2091+
2092+
//- /foo.rs
2093+
/// ```
2094+
/// fn foo() {
2095+
/// }
2096+
/// ```
2097+
#[macro_export]
2098+
macro_rules! foo {
2099+
() => {
2100+
2101+
};
2102+
}
2103+
"#,
2104+
&[],
2105+
expect![[r#"
2106+
[]
2107+
"#]],
2108+
);
2109+
check(
2110+
r#"
2111+
//- /lib.rs
2112+
$0
2113+
/// ```
2114+
/// fn foo() {
2115+
/// }
2116+
/// ```
2117+
#[macro_export]
2118+
macro_rules! foo {
2119+
() => {
2120+
2121+
};
2122+
}
2123+
"#,
2124+
&[DocTest],
2125+
expect![[r#"
2126+
[
2127+
Runnable {
2128+
use_name_in_title: false,
2129+
nav: NavigationTarget {
2130+
file_id: FileId(
2131+
0,
2132+
),
2133+
full_range: 1..94,
2134+
name: "foo",
2135+
},
2136+
kind: DocTest {
2137+
test_id: Path(
2138+
"foo",
2139+
),
2140+
},
2141+
cfg: None,
2142+
},
2143+
]
2144+
"#]],
2145+
);
2146+
}
20772147
}

crates/ide_db/src/defs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ impl NameRefClass {
447447

448448
impl_from!(
449449
Field, Module, Function, Adt, Variant, Const, Static, Trait, TypeAlias, BuiltinType, Local,
450-
GenericParam, Label
450+
GenericParam, Label, Macro
451451
for Definition
452452
);
453453

crates/ide_db/src/helpers.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,14 @@ pub fn visit_file_defs(
7676
cb(def.into());
7777
}
7878
module.impl_defs(db).into_iter().for_each(|impl_| cb(impl_.into()));
79+
80+
let is_root = module.is_crate_root(db);
81+
module
82+
.legacy_macros(db)
83+
.into_iter()
84+
// don't show legacy macros declared in the crate-root that were already covered in declarations earlier
85+
.filter(|it| !(is_root && it.is_macro_export(db)))
86+
.for_each(|mac| cb(mac.into()));
7987
}
8088

8189
/// Checks if the given lint is equal or is contained by the other lint which may or may not be a group.

0 commit comments

Comments
 (0)