Skip to content

Commit 58ed8ee

Browse files
committed
use extern prelude in Resolver
This fixes two bugs: - completion for paths works again - we handle extern prelude shadowing more correctly
1 parent 2babbbb commit 58ed8ee

File tree

5 files changed

+81
-18
lines changed

5 files changed

+81
-18
lines changed

crates/ra_hir/src/nameres.rs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,14 @@ impl ItemMap {
434434
self.resolve_path_fp(db, original_module, path).0
435435
}
436436

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+
437445
// Returns Yes if we are sure that additions to `ItemMap` wouldn't change
438446
// the result.
439447
fn resolve_path_fp(
@@ -451,19 +459,7 @@ impl ItemMap {
451459
Some((_, segment)) => segment,
452460
None => return (PerNs::none(), ReachedFixedPoint::Yes),
453461
};
454-
// Resolve in:
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-
}
462+
self.resolve_name_in_module(original_module, &segment.name)
467463
}
468464
PathKind::Super => {
469465
if let Some(p) = original_module.parent(db) {

crates/ra_hir/src/nameres/tests.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,38 @@ fn reexport_across_crates() {
536536
);
537537
}
538538

539+
#[test]
540+
fn 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+
539571
fn check_item_map_is_not_recomputed(initial: &str, file_change: &str) {
540572
let (mut db, pos) = MockDatabase::with_position(initial);
541573
let module = crate::source_binder::module_from_file_id(&db, pos.file_id).unwrap();

crates/ra_hir/src/resolve.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,7 @@ impl Scope {
149149
if let Some(KnownName::SelfParam) = name.as_known_name() {
150150
PerNs::types(Resolution::Def(m.module.into()))
151151
} else {
152-
match m.item_map[m.module.module_id].get(name) {
153-
Some(res) => res.def.map(Resolution::Def),
154-
None => PerNs::none(),
155-
}
152+
m.item_map.resolve_name_in_module(m.module, name).map(Resolution::Def)
156153
}
157154
}
158155
Scope::GenericParams(gp) => match gp.find_by_name(name) {
@@ -177,7 +174,7 @@ impl Scope {
177174
}
178175
}
179176

180-
fn collect_names(&self, f: &mut FnMut(Name, PerNs<Resolution>)) {
177+
fn collect_names(&self, f: &mut dyn FnMut(Name, PerNs<Resolution>)) {
181178
match self {
182179
Scope::ModuleScope(m) => {
183180
// TODO: should we provide `self` here?

crates/ra_ide_api/src/completion/complete_path.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,4 +186,20 @@ mod tests {
186186
",
187187
);
188188
}
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+
}
189205
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
created: "2019-02-11T11:53:02.410665254Z"
3+
creator: insta@0.6.1
4+
source: crates/ra_ide_api/src/completion/completion_item.rs
5+
expression: 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+
]

0 commit comments

Comments
 (0)