aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Einwag <[email protected]>2019-11-09 23:22:19 +0000
committerMatthias Einwag <[email protected]>2019-11-09 23:22:19 +0000
commit799903ba16dd0d80ca975a2e0e58e81f71ddc023 (patch)
tree798af5ece778c1630f903753805f163ba6043fd5
parent9d786ea221b27fbdf7c7f7beea0290db448e0611 (diff)
Resolve core types
This adds support for completion and goto definition of types defined within the "core" crate. The core crate is added as a dependency to each crate in the project. The core crate exported it's own prelude. This caused now all crates to inherit the core crates prelude instead of the std crates. In order to avoid the problem the prelude resolution has been changed to overwrite an already resolved prelude if this was set to a crate named core - in order to pick a better prelude like std. Fixes #2199
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs6
-rw-r--r--crates/ra_project_model/src/lib.rs8
-rw-r--r--crates/ra_project_model/src/sysroot.rs4
3 files changed, 16 insertions, 2 deletions
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index 7e6083961..36a61dc3d 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -27,6 +27,7 @@ pub(super) fn collect_defs(db: &impl DefDatabase2, mut def_map: CrateDefMap) ->
27 let crate_graph = db.crate_graph(); 27 let crate_graph = db.crate_graph();
28 28
29 // populate external prelude 29 // populate external prelude
30 let mut prelude_is_core = false;
30 for dep in crate_graph.dependencies(def_map.krate) { 31 for dep in crate_graph.dependencies(def_map.krate) {
31 let dep_def_map = db.crate_def_map(dep.crate_id); 32 let dep_def_map = db.crate_def_map(dep.crate_id);
32 log::debug!("crate dep {:?} -> {:?}", dep.name, dep.crate_id); 33 log::debug!("crate dep {:?} -> {:?}", dep.name, dep.crate_id);
@@ -36,10 +37,13 @@ pub(super) fn collect_defs(db: &impl DefDatabase2, mut def_map: CrateDefMap) ->
36 ); 37 );
37 38
38 // look for the prelude 39 // look for the prelude
39 if def_map.prelude.is_none() { 40 // If the prelude is the "core" prelude, try to replace it with a higher
41 // level prelude (e.g. "std") if available.
42 if def_map.prelude.is_none() || prelude_is_core {
40 let map = db.crate_def_map(dep.crate_id); 43 let map = db.crate_def_map(dep.crate_id);
41 if map.prelude.is_some() { 44 if map.prelude.is_some() {
42 def_map.prelude = map.prelude; 45 def_map.prelude = map.prelude;
46 prelude_is_core = dep.name == "core";
43 } 47 }
44 } 48 }
45 } 49 }
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs
index 8b8663a78..b1268f29b 100644
--- a/crates/ra_project_model/src/lib.rs
+++ b/crates/ra_project_model/src/lib.rs
@@ -199,6 +199,7 @@ impl ProjectWorkspace {
199 } 199 }
200 } 200 }
201 201
202 let libcore = sysroot.core().and_then(|it| sysroot_crates.get(&it).copied());
202 let libstd = sysroot.std().and_then(|it| sysroot_crates.get(&it).copied()); 203 let libstd = sysroot.std().and_then(|it| sysroot_crates.get(&it).copied());
203 204
204 let mut pkg_to_lib_crate = FxHashMap::default(); 205 let mut pkg_to_lib_crate = FxHashMap::default();
@@ -226,7 +227,7 @@ impl ProjectWorkspace {
226 } 227 }
227 } 228 }
228 229
229 // Set deps to the std and to the lib target of the current package 230 // Set deps to the core, std and to the lib target of the current package
230 for &from in pkg_crates.get(&pkg).into_iter().flatten() { 231 for &from in pkg_crates.get(&pkg).into_iter().flatten() {
231 if let Some(to) = lib_tgt { 232 if let Some(to) = lib_tgt {
232 if to != from { 233 if to != from {
@@ -240,6 +241,11 @@ impl ProjectWorkspace {
240 } 241 }
241 } 242 }
242 } 243 }
244 if let Some(core) = libcore {
245 if let Err(_) = crate_graph.add_dep(from, "core".into(), core) {
246 log::error!("cyclic dependency on core for {}", pkg.name(&cargo))
247 }
248 }
243 if let Some(std) = libstd { 249 if let Some(std) = libstd {
244 if let Err(_) = crate_graph.add_dep(from, "std".into(), std) { 250 if let Err(_) = crate_graph.add_dep(from, "std".into(), std) {
245 log::error!("cyclic dependency on std for {}", pkg.name(&cargo)) 251 log::error!("cyclic dependency on std for {}", pkg.name(&cargo))
diff --git a/crates/ra_project_model/src/sysroot.rs b/crates/ra_project_model/src/sysroot.rs
index 35d6df5cb..3d827809e 100644
--- a/crates/ra_project_model/src/sysroot.rs
+++ b/crates/ra_project_model/src/sysroot.rs
@@ -27,6 +27,10 @@ struct SysrootCrateData {
27} 27}
28 28
29impl Sysroot { 29impl Sysroot {
30 pub fn core(&self) -> Option<SysrootCrate> {
31 self.by_name("core")
32 }
33
30 pub fn std(&self) -> Option<SysrootCrate> { 34 pub fn std(&self) -> Option<SysrootCrate> {
31 self.by_name("std") 35 self.by_name("std")
32 } 36 }