aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/nameres.rs22
-rw-r--r--crates/ra_hir/src/nameres/tests.rs32
-rw-r--r--crates/ra_hir/src/resolve.rs7
-rw-r--r--crates/ra_ide_api/src/completion/complete_path.rs16
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__completes_use_paths_across_crates.snap22
5 files changed, 81 insertions, 18 deletions
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs
index 94f7db024..4b8097235 100644
--- a/crates/ra_hir/src/nameres.rs
+++ b/crates/ra_hir/src/nameres.rs
@@ -434,6 +434,14 @@ impl ItemMap {
434 self.resolve_path_fp(db, original_module, path).0 434 self.resolve_path_fp(db, original_module, path).0
435 } 435 }
436 436
437 pub(crate) fn resolve_name_in_module(&self, module: Module, name: &Name) -> PerNs<ModuleDef> {
438 let from_scope = self[module.module_id].items.get(name).map_or(PerNs::none(), |it| it.def);
439 let from_extern_prelude =
440 self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it));
441
442 from_scope.combine(from_extern_prelude)
443 }
444
437 // Returns Yes if we are sure that additions to `ItemMap` wouldn't change 445 // Returns Yes if we are sure that additions to `ItemMap` wouldn't change
438 // the result. 446 // the result.
439 fn resolve_path_fp( 447 fn resolve_path_fp(
@@ -451,19 +459,7 @@ impl ItemMap {
451 Some((_, segment)) => segment, 459 Some((_, segment)) => segment,
452 None => return (PerNs::none(), ReachedFixedPoint::Yes), 460 None => return (PerNs::none(), ReachedFixedPoint::Yes),
453 }; 461 };
454 // Resolve in: 462 self.resolve_name_in_module(original_module, &segment.name)
455 // - current module / scope
456 // - extern prelude
457 match self[original_module.module_id].items.get(&segment.name) {
458 Some(res) if !res.def.is_none() => res.def,
459 _ => {
460 if let Some(def) = self.extern_prelude.get(&segment.name) {
461 PerNs::types(*def)
462 } else {
463 return (PerNs::none(), ReachedFixedPoint::No);
464 }
465 }
466 }
467 } 463 }
468 PathKind::Super => { 464 PathKind::Super => {
469 if let Some(p) = original_module.parent(db) { 465 if let Some(p) = original_module.parent(db) {
diff --git a/crates/ra_hir/src/nameres/tests.rs b/crates/ra_hir/src/nameres/tests.rs
index 9b621fbc2..f1a1f5b76 100644
--- a/crates/ra_hir/src/nameres/tests.rs
+++ b/crates/ra_hir/src/nameres/tests.rs
@@ -536,6 +536,38 @@ fn reexport_across_crates() {
536 ); 536 );
537} 537}
538 538
539#[test]
540fn values_dont_shadow_extern_crates() {
541 let mut db = MockDatabase::with_files(
542 "
543 //- /main.rs
544 fn foo() {}
545 use foo::Bar;
546
547 //- /foo/lib.rs
548 pub struct Bar;
549 ",
550 );
551 db.set_crate_graph_from_fixture(crate_graph! {
552 "main": ("/main.rs", ["foo"]),
553 "foo": ("/foo/lib.rs", []),
554 });
555 let main_id = db.file_id_of("/main.rs");
556
557 let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap();
558 let krate = module.krate(&db).unwrap();
559 let item_map = db.item_map(krate);
560
561 check_module_item_map(
562 &item_map,
563 module.module_id,
564 "
565 Bar: t v
566 foo: v
567 ",
568 );
569}
570
539fn check_item_map_is_not_recomputed(initial: &str, file_change: &str) { 571fn check_item_map_is_not_recomputed(initial: &str, file_change: &str) {
540 let (mut db, pos) = MockDatabase::with_position(initial); 572 let (mut db, pos) = MockDatabase::with_position(initial);
541 let module = crate::source_binder::module_from_file_id(&db, pos.file_id).unwrap(); 573 let module = crate::source_binder::module_from_file_id(&db, pos.file_id).unwrap();
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs
index 3d7ec5683..e8abac5bc 100644
--- a/crates/ra_hir/src/resolve.rs
+++ b/crates/ra_hir/src/resolve.rs
@@ -149,10 +149,7 @@ impl Scope {
149 if let Some(KnownName::SelfParam) = name.as_known_name() { 149 if let Some(KnownName::SelfParam) = name.as_known_name() {
150 PerNs::types(Resolution::Def(m.module.into())) 150 PerNs::types(Resolution::Def(m.module.into()))
151 } else { 151 } else {
152 match m.item_map[m.module.module_id].get(name) { 152 m.item_map.resolve_name_in_module(m.module, name).map(Resolution::Def)
153 Some(res) => res.def.map(Resolution::Def),
154 None => PerNs::none(),
155 }
156 } 153 }
157 } 154 }
158 Scope::GenericParams(gp) => match gp.find_by_name(name) { 155 Scope::GenericParams(gp) => match gp.find_by_name(name) {
@@ -177,7 +174,7 @@ impl Scope {
177 } 174 }
178 } 175 }
179 176
180 fn collect_names(&self, f: &mut FnMut(Name, PerNs<Resolution>)) { 177 fn collect_names(&self, f: &mut dyn FnMut(Name, PerNs<Resolution>)) {
181 match self { 178 match self {
182 Scope::ModuleScope(m) => { 179 Scope::ModuleScope(m) => {
183 // TODO: should we provide `self` here? 180 // TODO: should we provide `self` here?
diff --git a/crates/ra_ide_api/src/completion/complete_path.rs b/crates/ra_ide_api/src/completion/complete_path.rs
index c47a14e9f..39aefdb13 100644
--- a/crates/ra_ide_api/src/completion/complete_path.rs
+++ b/crates/ra_ide_api/src/completion/complete_path.rs
@@ -186,4 +186,20 @@ mod tests {
186 ", 186 ",
187 ); 187 );
188 } 188 }
189
190 #[test]
191 fn completes_use_paths_across_crates() {
192 check_reference_completion(
193 "completes_use_paths_across_crates",
194 "
195 //- /main.rs
196 use foo::<|>;
197
198 //- /foo/lib.rs
199 pub mod bar {
200 pub struct S;
201 }
202 ",
203 );
204 }
189} 205}
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__completes_use_paths_across_crates.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__completes_use_paths_across_crates.snap
new file mode 100644
index 000000000..4b40fcf27
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__completes_use_paths_across_crates.snap
@@ -0,0 +1,22 @@
1---
2created: "2019-02-11T11:53:02.410665254Z"
3creator: [email protected]
4source: crates/ra_ide_api/src/completion/completion_item.rs
5expression: kind_completions
6---
7[
8 CompletionItem {
9 completion_kind: Reference,
10 label: "bar",
11 kind: Some(
12 Module
13 ),
14 detail: None,
15 documentation: None,
16 lookup: None,
17 insert_text: None,
18 insert_text_format: PlainText,
19 source_range: [9; 9),
20 text_edit: None
21 }
22]