Skip to content

Commit b0ed808

Browse files
Merge #3553
3553: Completions do not show for function with same name as mod r=matklad a=JoshMcguigan fixes #3444 I've added a test case in `crates/ra_ide/src/completion/complete_path.rs` which verifies the described behavior in #3444. Digging in, I found that [the module scope iterator](https://github.com/JoshMcguigan/rust-analyzer/blob/ba62d8bd1ce8a68b8d21aaf89ae1ea6787f18366/crates/ra_ide/src/completion/complete_path.rs#L22) only provides the module `z`, and does not provide the function `z` (although if I name the function something else then it does show up here). I thought perhaps the name wasn't being properly resolved, but I added a test in `crates/ra_hir_def/src/nameres/tests.rs` which seems to suggest that it is? I've tried to figure out how to bridge the gap between these two tests (one passing, one failing) to see where the function `z` is being dropped, but to this point I haven't been able to track it down. Any pointers on where I might look for this? Co-authored-by: Josh Mcguigan <[email protected]>
2 parents 5659009 + 7208498 commit b0ed808

File tree

6 files changed

+108
-11
lines changed

6 files changed

+108
-11
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/ra_hir/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ doctest = false
1111
log = "0.4.8"
1212
rustc-hash = "1.1.0"
1313
either = "1.5.3"
14+
arrayvec = "0.5.1"
1415

1516
itertools = "0.8.2"
1617

crates/ra_hir/src/code_model.rs

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! FIXME: write short doc here
22
use std::sync::Arc;
33

4+
use arrayvec::ArrayVec;
45
use either::Either;
56
use hir_def::{
67
adt::StructKind,
@@ -226,7 +227,11 @@ impl Module {
226227
Some((name, def))
227228
}
228229
})
229-
.map(|(name, def)| (name.clone(), def.into()))
230+
.flat_map(|(name, def)|
231+
ScopeDef::all_items(def)
232+
.into_iter()
233+
.map(move |item| (name.clone(), item))
234+
)
230235
.collect()
231236
}
232237

@@ -1288,15 +1293,38 @@ pub enum ScopeDef {
12881293
Unknown,
12891294
}
12901295

1291-
impl From<PerNs> for ScopeDef {
1292-
fn from(def: PerNs) -> Self {
1293-
def.take_types()
1294-
.or_else(|| def.take_values())
1295-
.map(|module_def_id| ScopeDef::ModuleDef(module_def_id.into()))
1296-
.or_else(|| {
1297-
def.take_macros().map(|macro_def_id| ScopeDef::MacroDef(macro_def_id.into()))
1298-
})
1299-
.unwrap_or(ScopeDef::Unknown)
1296+
impl ScopeDef {
1297+
pub fn all_items(def: PerNs) -> ArrayVec<[Self; 3]> {
1298+
let mut items = ArrayVec::new();
1299+
1300+
match (def.take_types(), def.take_values()) {
1301+
(Some(m1), None) =>
1302+
items.push(ScopeDef::ModuleDef(m1.into())),
1303+
(None, Some(m2)) =>
1304+
items.push(ScopeDef::ModuleDef(m2.into())),
1305+
(Some(m1), Some(m2)) => {
1306+
// Some items, like unit structs and enum variants, are
1307+
// returned as both a type and a value. Here we want
1308+
// to de-duplicate them.
1309+
if m1 != m2 {
1310+
items.push(ScopeDef::ModuleDef(m1.into()));
1311+
items.push(ScopeDef::ModuleDef(m2.into()));
1312+
} else {
1313+
items.push(ScopeDef::ModuleDef(m1.into()));
1314+
}
1315+
},
1316+
(None, None) => {},
1317+
};
1318+
1319+
if let Some(macro_def_id) = def.take_macros() {
1320+
items.push(ScopeDef::MacroDef(macro_def_id.into()));
1321+
}
1322+
1323+
if items.is_empty() {
1324+
items.push(ScopeDef::Unknown);
1325+
}
1326+
1327+
items
13001328
}
13011329
}
13021330

crates/ra_hir/src/semantics.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,13 @@ impl<'a, DB: HirDatabase> SemanticsScope<'a, DB> {
344344

345345
resolver.process_all_names(self.db, &mut |name, def| {
346346
let def = match def {
347-
resolver::ScopeDef::PerNs(it) => it.into(),
347+
resolver::ScopeDef::PerNs(it) => {
348+
let items = ScopeDef::all_items(it);
349+
for item in items {
350+
f(name.clone(), item);
351+
}
352+
return
353+
},
348354
resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()),
349355
resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()),
350356
resolver::ScopeDef::GenericParam(id) => ScopeDef::GenericParam(TypeParam { id }),

crates/ra_hir_def/src/nameres/tests.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,28 @@ fn crate_def_map_super_super() {
101101
"###)
102102
}
103103

104+
#[test]
105+
fn crate_def_map_fn_mod_same_name() {
106+
let map = def_map(
107+
"
108+
//- /lib.rs
109+
mod m {
110+
pub mod z {}
111+
pub fn z() {}
112+
}
113+
",
114+
);
115+
assert_snapshot!(map, @r###"
116+
⋮crate
117+
⋮m: t
118+
119+
⋮crate::m
120+
⋮z: t v
121+
122+
⋮crate::m::z
123+
"###)
124+
}
125+
104126
#[test]
105127
fn bogus_paths() {
106128
covers!(bogus_paths);

crates/ra_ide/src/completion/complete_path.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -967,4 +967,43 @@ mod tests {
967967
]
968968
"###);
969969
}
970+
971+
#[test]
972+
fn function_mod_share_name() {
973+
assert_debug_snapshot!(
974+
do_reference_completion(
975+
r"
976+
fn foo() {
977+
self::m::<|>
978+
}
979+
980+
mod m {
981+
pub mod z {}
982+
pub fn z() {}
983+
}
984+
",
985+
),
986+
@r###"
987+
[
988+
CompletionItem {
989+
label: "z",
990+
source_range: [57; 57),
991+
delete: [57; 57),
992+
insert: "z",
993+
kind: Module,
994+
},
995+
CompletionItem {
996+
label: "z()",
997+
source_range: [57; 57),
998+
delete: [57; 57),
999+
insert: "z()$0",
1000+
kind: Function,
1001+
lookup: "z",
1002+
detail: "pub fn z()",
1003+
},
1004+
]
1005+
"###
1006+
);
1007+
}
1008+
9701009
}

0 commit comments

Comments
 (0)