aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-03-13 09:18:47 +0000
committerGitHub <[email protected]>2020-03-13 09:18:47 +0000
commitb0ed808266e346b0f9330822f874e930710df4ec (patch)
tree5fec1ee6c1af3e3763c3a694a34789e856fc9d13 /crates
parent56590097ed71374902f1e1c44cde487db4e3ab4f (diff)
parent7208498d54b9f3d386b58f901c911a35170057ce (diff)
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]>
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir/Cargo.toml1
-rw-r--r--crates/ra_hir/src/code_model.rs48
-rw-r--r--crates/ra_hir/src/semantics.rs8
-rw-r--r--crates/ra_hir_def/src/nameres/tests.rs22
-rw-r--r--crates/ra_ide/src/completion/complete_path.rs39
5 files changed, 107 insertions, 11 deletions
diff --git a/crates/ra_hir/Cargo.toml b/crates/ra_hir/Cargo.toml
index 266c4cff3..42193b492 100644
--- a/crates/ra_hir/Cargo.toml
+++ b/crates/ra_hir/Cargo.toml
@@ -11,6 +11,7 @@ doctest = false
11log = "0.4.8" 11log = "0.4.8"
12rustc-hash = "1.1.0" 12rustc-hash = "1.1.0"
13either = "1.5.3" 13either = "1.5.3"
14arrayvec = "0.5.1"
14 15
15itertools = "0.8.2" 16itertools = "0.8.2"
16 17
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 41d4e2ed3..9e2fa03f8 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -1,6 +1,7 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2use std::sync::Arc; 2use std::sync::Arc;
3 3
4use arrayvec::ArrayVec;
4use either::Either; 5use either::Either;
5use hir_def::{ 6use hir_def::{
6 adt::StructKind, 7 adt::StructKind,
@@ -226,7 +227,11 @@ impl Module {
226 Some((name, def)) 227 Some((name, def))
227 } 228 }
228 }) 229 })
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 )
230 .collect() 235 .collect()
231 } 236 }
232 237
@@ -1288,15 +1293,38 @@ pub enum ScopeDef {
1288 Unknown, 1293 Unknown,
1289} 1294}
1290 1295
1291impl From<PerNs> for ScopeDef { 1296impl ScopeDef {
1292 fn from(def: PerNs) -> Self { 1297 pub fn all_items(def: PerNs) -> ArrayVec<[Self; 3]> {
1293 def.take_types() 1298 let mut items = ArrayVec::new();
1294 .or_else(|| def.take_values()) 1299
1295 .map(|module_def_id| ScopeDef::ModuleDef(module_def_id.into())) 1300 match (def.take_types(), def.take_values()) {
1296 .or_else(|| { 1301 (Some(m1), None) =>
1297 def.take_macros().map(|macro_def_id| ScopeDef::MacroDef(macro_def_id.into())) 1302 items.push(ScopeDef::ModuleDef(m1.into())),
1298 }) 1303 (None, Some(m2)) =>
1299 .unwrap_or(ScopeDef::Unknown) 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
1300 } 1328 }
1301} 1329}
1302 1330
diff --git a/crates/ra_hir/src/semantics.rs b/crates/ra_hir/src/semantics.rs
index 3782a9984..e83eb1fdc 100644
--- a/crates/ra_hir/src/semantics.rs
+++ b/crates/ra_hir/src/semantics.rs
@@ -344,7 +344,13 @@ impl<'a, DB: HirDatabase> SemanticsScope<'a, DB> {
344 344
345 resolver.process_all_names(self.db, &mut |name, def| { 345 resolver.process_all_names(self.db, &mut |name, def| {
346 let def = match def { 346 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 },
348 resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()), 354 resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()),
349 resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()), 355 resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()),
350 resolver::ScopeDef::GenericParam(id) => ScopeDef::GenericParam(TypeParam { id }), 356 resolver::ScopeDef::GenericParam(id) => ScopeDef::GenericParam(TypeParam { id }),
diff --git a/crates/ra_hir_def/src/nameres/tests.rs b/crates/ra_hir_def/src/nameres/tests.rs
index dda5ed699..3f33a75b9 100644
--- a/crates/ra_hir_def/src/nameres/tests.rs
+++ b/crates/ra_hir_def/src/nameres/tests.rs
@@ -102,6 +102,28 @@ fn crate_def_map_super_super() {
102} 102}
103 103
104#[test] 104#[test]
105fn 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
126#[test]
105fn bogus_paths() { 127fn bogus_paths() {
106 covers!(bogus_paths); 128 covers!(bogus_paths);
107 let map = def_map( 129 let map = def_map(
diff --git a/crates/ra_ide/src/completion/complete_path.rs b/crates/ra_ide/src/completion/complete_path.rs
index d588ee364..648c1d39b 100644
--- a/crates/ra_ide/src/completion/complete_path.rs
+++ b/crates/ra_ide/src/completion/complete_path.rs
@@ -967,4 +967,43 @@ mod tests {
967 ] 967 ]
968 "###); 968 "###);
969 } 969 }
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
970} 1009}