self.resolve_path_fp(db, original_module, path).0
}
+ pub(crate) fn resolve_name_in_module(&self, module: Module, name: &Name) -> PerNs<ModuleDef> {
+ let from_scope = self[module.module_id].items.get(name).map_or(PerNs::none(), |it| it.def);
+ let from_extern_prelude =
+ self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it));
+
+ from_scope.combine(from_extern_prelude)
+ }
+
// Returns Yes if we are sure that additions to `ItemMap` wouldn't change
// the result.
fn resolve_path_fp(
Some((_, segment)) => segment,
None => return (PerNs::none(), ReachedFixedPoint::Yes),
};
- // Resolve in:
- // - current module / scope
- // - extern prelude
- match self[original_module.module_id].items.get(&segment.name) {
- Some(res) if !res.def.is_none() => res.def,
- _ => {
- if let Some(def) = self.extern_prelude.get(&segment.name) {
- PerNs::types(*def)
- } else {
- return (PerNs::none(), ReachedFixedPoint::No);
- }
- }
- }
+ self.resolve_name_in_module(original_module, &segment.name)
}
PathKind::Super => {
if let Some(p) = original_module.parent(db) {
);
}
+#[test]
+fn values_dont_shadow_extern_crates() {
+ let mut db = MockDatabase::with_files(
+ "
+ //- /main.rs
+ fn foo() {}
+ use foo::Bar;
+
+ //- /foo/lib.rs
+ pub struct Bar;
+ ",
+ );
+ db.set_crate_graph_from_fixture(crate_graph! {
+ "main": ("/main.rs", ["foo"]),
+ "foo": ("/foo/lib.rs", []),
+ });
+ let main_id = db.file_id_of("/main.rs");
+
+ let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap();
+ let krate = module.krate(&db).unwrap();
+ let item_map = db.item_map(krate);
+
+ check_module_item_map(
+ &item_map,
+ module.module_id,
+ "
+ Bar: t v
+ foo: v
+ ",
+ );
+}
+
fn check_item_map_is_not_recomputed(initial: &str, file_change: &str) {
let (mut db, pos) = MockDatabase::with_position(initial);
let module = crate::source_binder::module_from_file_id(&db, pos.file_id).unwrap();
if let Some(KnownName::SelfParam) = name.as_known_name() {
PerNs::types(Resolution::Def(m.module.into()))
} else {
- match m.item_map[m.module.module_id].get(name) {
- Some(res) => res.def.map(Resolution::Def),
- None => PerNs::none(),
- }
+ m.item_map.resolve_name_in_module(m.module, name).map(Resolution::Def)
}
}
Scope::GenericParams(gp) => match gp.find_by_name(name) {
}
}
- fn collect_names(&self, f: &mut FnMut(Name, PerNs<Resolution>)) {
+ fn collect_names(&self, f: &mut dyn FnMut(Name, PerNs<Resolution>)) {
match self {
Scope::ModuleScope(m) => {
// TODO: should we provide `self` here?
",
);
}
+
+ #[test]
+ fn completes_use_paths_across_crates() {
+ check_reference_completion(
+ "completes_use_paths_across_crates",
+ "
+ //- /main.rs
+ use foo::<|>;
+
+ //- /foo/lib.rs
+ pub mod bar {
+ pub struct S;
+ }
+ ",
+ );
+ }
}
--- /dev/null
+---
+created: "2019-02-11T11:53:02.410665254Z"
+creator: insta@0.6.1
+source: crates/ra_ide_api/src/completion/completion_item.rs
+expression: kind_completions
+---
+[
+ CompletionItem {
+ completion_kind: Reference,
+ label: "bar",
+ kind: Some(
+ Module
+ ),
+ detail: None,
+ documentation: None,
+ lookup: None,
+ insert_text: None,
+ insert_text_format: PlainText,
+ source_range: [9; 9),
+ text_edit: None
+ }
+]