aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_db/src/fixture.rs11
-rw-r--r--crates/ra_db/src/input.rs129
-rw-r--r--crates/ra_hir/src/code_model.rs37
-rw-r--r--crates/ra_hir_def/src/find_path.rs2
-rw-r--r--crates/ra_hir_def/src/lang_item.rs4
-rw-r--r--crates/ra_hir_def/src/nameres.rs3
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs7
-rw-r--r--crates/ra_hir_ty/src/traits.rs2
-rw-r--r--crates/ra_ide/src/display.rs14
-rw-r--r--crates/ra_ide/src/hover.rs114
-rw-r--r--crates/ra_ide/src/lib.rs12
-rw-r--r--crates/ra_ide/src/mock_analysis.rs10
-rw-r--r--crates/ra_ide/src/parent_module.rs1
-rw-r--r--crates/ra_ide_db/src/change.rs6
-rw-r--r--crates/ra_ide_db/src/lib.rs2
-rw-r--r--crates/ra_project_model/src/lib.rs13
-rw-r--r--crates/rust-analyzer/src/cli/load_cargo.rs11
-rw-r--r--crates/rust-analyzer/src/world.rs13
18 files changed, 270 insertions, 121 deletions
diff --git a/crates/ra_db/src/fixture.rs b/crates/ra_db/src/fixture.rs
index da7af110c..947d6ad56 100644
--- a/crates/ra_db/src/fixture.rs
+++ b/crates/ra_db/src/fixture.rs
@@ -56,6 +56,7 @@ fn with_single_file(db: &mut dyn SourceDatabaseExt, text: &str) -> FileId {
56 crate_graph.add_crate_root( 56 crate_graph.add_crate_root(
57 file_id, 57 file_id,
58 Edition::Edition2018, 58 Edition::Edition2018,
59 None,
59 CfgOptions::default(), 60 CfgOptions::default(),
60 Env::default(), 61 Env::default(),
61 ); 62 );
@@ -98,8 +99,13 @@ fn with_files(db: &mut dyn SourceDatabaseExt, fixture: &str) -> Option<FilePosit
98 assert!(meta.path.starts_with(&source_root_prefix)); 99 assert!(meta.path.starts_with(&source_root_prefix));
99 100
100 if let Some(krate) = meta.krate { 101 if let Some(krate) = meta.krate {
101 let crate_id = 102 let crate_id = crate_graph.add_crate_root(
102 crate_graph.add_crate_root(file_id, meta.edition, meta.cfg, Env::default()); 103 file_id,
104 meta.edition,
105 Some(krate.clone()),
106 meta.cfg,
107 Env::default(),
108 );
103 let prev = crates.insert(krate.clone(), crate_id); 109 let prev = crates.insert(krate.clone(), crate_id);
104 assert!(prev.is_none()); 110 assert!(prev.is_none());
105 for dep in meta.deps { 111 for dep in meta.deps {
@@ -132,6 +138,7 @@ fn with_files(db: &mut dyn SourceDatabaseExt, fixture: &str) -> Option<FilePosit
132 crate_graph.add_crate_root( 138 crate_graph.add_crate_root(
133 crate_root, 139 crate_root,
134 Edition::Edition2018, 140 Edition::Edition2018,
141 None,
135 CfgOptions::default(), 142 CfgOptions::default(),
136 Env::default(), 143 Env::default(),
137 ); 144 );
diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs
index eaff99fd3..4069c0fed 100644
--- a/crates/ra_db/src/input.rs
+++ b/crates/ra_db/src/input.rs
@@ -86,7 +86,7 @@ pub struct CrateId(pub u32);
86pub struct CrateName(SmolStr); 86pub struct CrateName(SmolStr);
87 87
88impl CrateName { 88impl CrateName {
89 /// Crates a crate name, checking for dashes in the string provided. 89 /// Creates a crate name, checking for dashes in the string provided.
90 /// Dashes are not allowed in the crate names, 90 /// Dashes are not allowed in the crate names,
91 /// hence the input string is returned as `Err` for those cases. 91 /// hence the input string is returned as `Err` for those cases.
92 pub fn new(name: &str) -> Result<CrateName, &str> { 92 pub fn new(name: &str) -> Result<CrateName, &str> {
@@ -97,19 +97,23 @@ impl CrateName {
97 } 97 }
98 } 98 }
99 99
100 /// Crates a crate name, unconditionally replacing the dashes with underscores. 100 /// Creates a crate name, unconditionally replacing the dashes with underscores.
101 pub fn normalize_dashes(name: &str) -> CrateName { 101 pub fn normalize_dashes(name: &str) -> CrateName {
102 Self(SmolStr::new(name.replace('-', "_"))) 102 Self(SmolStr::new(name.replace('-', "_")))
103 } 103 }
104} 104}
105 105
106#[derive(Debug, Clone, PartialEq, Eq)] 106#[derive(Debug, Clone, PartialEq, Eq)]
107struct CrateData { 107pub struct CrateData {
108 file_id: FileId, 108 pub root_file_id: FileId,
109 edition: Edition, 109 pub edition: Edition,
110 /// The name to display to the end user.
111 /// This actual crate name can be different in a particular dependent crate
112 /// or may even be missing for some cases, such as a dummy crate for the code snippet.
113 pub display_name: Option<String>,
110 cfg_options: CfgOptions, 114 cfg_options: CfgOptions,
111 env: Env, 115 env: Env,
112 dependencies: Vec<Dependency>, 116 pub dependencies: Vec<Dependency>,
113} 117}
114 118
115#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 119#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -134,10 +138,11 @@ impl CrateGraph {
134 &mut self, 138 &mut self,
135 file_id: FileId, 139 file_id: FileId,
136 edition: Edition, 140 edition: Edition,
141 display_name: Option<String>,
137 cfg_options: CfgOptions, 142 cfg_options: CfgOptions,
138 env: Env, 143 env: Env,
139 ) -> CrateId { 144 ) -> CrateId {
140 let data = CrateData::new(file_id, edition, cfg_options, env); 145 let data = CrateData::new(file_id, edition, display_name, cfg_options, env);
141 let crate_id = CrateId(self.arena.len() as u32); 146 let crate_id = CrateId(self.arena.len() as u32);
142 let prev = self.arena.insert(crate_id, data); 147 let prev = self.arena.insert(crate_id, data);
143 assert!(prev.is_none()); 148 assert!(prev.is_none());
@@ -169,24 +174,17 @@ impl CrateGraph {
169 self.arena.keys().copied() 174 self.arena.keys().copied()
170 } 175 }
171 176
172 pub fn crate_root(&self, crate_id: CrateId) -> FileId { 177 pub fn crate_data(&self, crate_id: &CrateId) -> &CrateData {
173 self.arena[&crate_id].file_id 178 &self.arena[crate_id]
174 }
175
176 pub fn edition(&self, crate_id: CrateId) -> Edition {
177 self.arena[&crate_id].edition
178 } 179 }
179 180
180 // FIXME: this only finds one crate with the given root; we could have multiple 181 // FIXME: this only finds one crate with the given root; we could have multiple
181 pub fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> { 182 pub fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> {
182 let (&crate_id, _) = self.arena.iter().find(|(_crate_id, data)| data.file_id == file_id)?; 183 let (&crate_id, _) =
184 self.arena.iter().find(|(_crate_id, data)| data.root_file_id == file_id)?;
183 Some(crate_id) 185 Some(crate_id)
184 } 186 }
185 187
186 pub fn dependencies(&self, crate_id: CrateId) -> impl Iterator<Item = &Dependency> {
187 self.arena[&crate_id].dependencies.iter()
188 }
189
190 /// Extends this crate graph by adding a complete disjoint second crate 188 /// Extends this crate graph by adding a complete disjoint second crate
191 /// graph. 189 /// graph.
192 /// 190 ///
@@ -209,7 +207,7 @@ impl CrateGraph {
209 return false; 207 return false;
210 } 208 }
211 209
212 for dep in self.dependencies(from) { 210 for dep in &self.crate_data(&from).dependencies {
213 let crate_id = dep.crate_id(); 211 let crate_id = dep.crate_id();
214 if crate_id == target { 212 if crate_id == target {
215 return true; 213 return true;
@@ -230,8 +228,21 @@ impl CrateId {
230} 228}
231 229
232impl CrateData { 230impl CrateData {
233 fn new(file_id: FileId, edition: Edition, cfg_options: CfgOptions, env: Env) -> CrateData { 231 fn new(
234 CrateData { file_id, edition, dependencies: Vec::new(), cfg_options, env } 232 root_file_id: FileId,
233 edition: Edition,
234 display_name: Option<String>,
235 cfg_options: CfgOptions,
236 env: Env,
237 ) -> CrateData {
238 CrateData {
239 root_file_id,
240 edition,
241 display_name,
242 dependencies: Vec::new(),
243 cfg_options,
244 env,
245 }
235 } 246 }
236 247
237 fn add_dep(&mut self, name: SmolStr, crate_id: CrateId) { 248 fn add_dep(&mut self, name: SmolStr, crate_id: CrateId) {
@@ -290,12 +301,27 @@ mod tests {
290 #[test] 301 #[test]
291 fn it_should_panic_because_of_cycle_dependencies() { 302 fn it_should_panic_because_of_cycle_dependencies() {
292 let mut graph = CrateGraph::default(); 303 let mut graph = CrateGraph::default();
293 let crate1 = 304 let crate1 = graph.add_crate_root(
294 graph.add_crate_root(FileId(1u32), Edition2018, CfgOptions::default(), Env::default()); 305 FileId(1u32),
295 let crate2 = 306 Edition2018,
296 graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default(), Env::default()); 307 None,
297 let crate3 = 308 CfgOptions::default(),
298 graph.add_crate_root(FileId(3u32), Edition2018, CfgOptions::default(), Env::default()); 309 Env::default(),
310 );
311 let crate2 = graph.add_crate_root(
312 FileId(2u32),
313 Edition2018,
314 None,
315 CfgOptions::default(),
316 Env::default(),
317 );
318 let crate3 = graph.add_crate_root(
319 FileId(3u32),
320 Edition2018,
321 None,
322 CfgOptions::default(),
323 Env::default(),
324 );
299 assert!(graph.add_dep(crate1, CrateName::new("crate2").unwrap(), crate2).is_ok()); 325 assert!(graph.add_dep(crate1, CrateName::new("crate2").unwrap(), crate2).is_ok());
300 assert!(graph.add_dep(crate2, CrateName::new("crate3").unwrap(), crate3).is_ok()); 326 assert!(graph.add_dep(crate2, CrateName::new("crate3").unwrap(), crate3).is_ok());
301 assert!(graph.add_dep(crate3, CrateName::new("crate1").unwrap(), crate1).is_err()); 327 assert!(graph.add_dep(crate3, CrateName::new("crate1").unwrap(), crate1).is_err());
@@ -304,12 +330,27 @@ mod tests {
304 #[test] 330 #[test]
305 fn it_works() { 331 fn it_works() {
306 let mut graph = CrateGraph::default(); 332 let mut graph = CrateGraph::default();
307 let crate1 = 333 let crate1 = graph.add_crate_root(
308 graph.add_crate_root(FileId(1u32), Edition2018, CfgOptions::default(), Env::default()); 334 FileId(1u32),
309 let crate2 = 335 Edition2018,
310 graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default(), Env::default()); 336 None,
311 let crate3 = 337 CfgOptions::default(),
312 graph.add_crate_root(FileId(3u32), Edition2018, CfgOptions::default(), Env::default()); 338 Env::default(),
339 );
340 let crate2 = graph.add_crate_root(
341 FileId(2u32),
342 Edition2018,
343 None,
344 CfgOptions::default(),
345 Env::default(),
346 );
347 let crate3 = graph.add_crate_root(
348 FileId(3u32),
349 Edition2018,
350 None,
351 CfgOptions::default(),
352 Env::default(),
353 );
313 assert!(graph.add_dep(crate1, CrateName::new("crate2").unwrap(), crate2).is_ok()); 354 assert!(graph.add_dep(crate1, CrateName::new("crate2").unwrap(), crate2).is_ok());
314 assert!(graph.add_dep(crate2, CrateName::new("crate3").unwrap(), crate3).is_ok()); 355 assert!(graph.add_dep(crate2, CrateName::new("crate3").unwrap(), crate3).is_ok());
315 } 356 }
@@ -317,16 +358,26 @@ mod tests {
317 #[test] 358 #[test]
318 fn dashes_are_normalized() { 359 fn dashes_are_normalized() {
319 let mut graph = CrateGraph::default(); 360 let mut graph = CrateGraph::default();
320 let crate1 = 361 let crate1 = graph.add_crate_root(
321 graph.add_crate_root(FileId(1u32), Edition2018, CfgOptions::default(), Env::default()); 362 FileId(1u32),
322 let crate2 = 363 Edition2018,
323 graph.add_crate_root(FileId(2u32), Edition2018, CfgOptions::default(), Env::default()); 364 None,
365 CfgOptions::default(),
366 Env::default(),
367 );
368 let crate2 = graph.add_crate_root(
369 FileId(2u32),
370 Edition2018,
371 None,
372 CfgOptions::default(),
373 Env::default(),
374 );
324 assert!(graph 375 assert!(graph
325 .add_dep(crate1, CrateName::normalize_dashes("crate-name-with-dashes"), crate2) 376 .add_dep(crate1, CrateName::normalize_dashes("crate-name-with-dashes"), crate2)
326 .is_ok()); 377 .is_ok());
327 assert_eq!( 378 assert_eq!(
328 graph.dependencies(crate1).collect::<Vec<_>>(), 379 graph.crate_data(&crate1).dependencies,
329 vec![&Dependency { crate_id: crate2, name: "crate_name_with_dashes".into() }] 380 vec![Dependency { crate_id: crate2, name: "crate_name_with_dashes".into() }]
330 ); 381 );
331 } 382 }
332} 383}
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 911c809fd..78c444037 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -55,7 +55,9 @@ pub struct CrateDependency {
55impl Crate { 55impl Crate {
56 pub fn dependencies(self, db: &impl DefDatabase) -> Vec<CrateDependency> { 56 pub fn dependencies(self, db: &impl DefDatabase) -> Vec<CrateDependency> {
57 db.crate_graph() 57 db.crate_graph()
58 .dependencies(self.id) 58 .crate_data(&self.id)
59 .dependencies
60 .iter()
59 .map(|dep| { 61 .map(|dep| {
60 let krate = Crate { id: dep.crate_id() }; 62 let krate = Crate { id: dep.crate_id() };
61 let name = dep.as_name(); 63 let name = dep.as_name();
@@ -69,7 +71,9 @@ impl Crate {
69 let crate_graph = db.crate_graph(); 71 let crate_graph = db.crate_graph();
70 crate_graph 72 crate_graph
71 .iter() 73 .iter()
72 .filter(|&krate| crate_graph.dependencies(krate).any(|it| it.crate_id == self.id)) 74 .filter(|&krate| {
75 crate_graph.crate_data(&krate).dependencies.iter().any(|it| it.crate_id == self.id)
76 })
73 .map(|id| Crate { id }) 77 .map(|id| Crate { id })
74 .collect() 78 .collect()
75 } 79 }
@@ -80,12 +84,11 @@ impl Crate {
80 } 84 }
81 85
82 pub fn root_file(self, db: &impl DefDatabase) -> FileId { 86 pub fn root_file(self, db: &impl DefDatabase) -> FileId {
83 db.crate_graph().crate_root(self.id) 87 db.crate_graph().crate_data(&self.id).root_file_id
84 } 88 }
85 89
86 pub fn edition(self, db: &impl DefDatabase) -> Edition { 90 pub fn edition(self, db: &impl DefDatabase) -> Edition {
87 let crate_graph = db.crate_graph(); 91 db.crate_graph().crate_data(&self.id).edition
88 crate_graph.edition(self.id)
89 } 92 }
90 93
91 pub fn all(db: &impl DefDatabase) -> Vec<Crate> { 94 pub fn all(db: &impl DefDatabase) -> Vec<Crate> {
@@ -496,6 +499,14 @@ impl Adt {
496 pub fn krate(self, db: &impl HirDatabase) -> Option<Crate> { 499 pub fn krate(self, db: &impl HirDatabase) -> Option<Crate> {
497 Some(self.module(db).krate()) 500 Some(self.module(db).krate())
498 } 501 }
502
503 pub fn name(&self, db: &impl HirDatabase) -> Name {
504 match self {
505 Adt::Struct(s) => s.name(db),
506 Adt::Union(u) => u.name(db),
507 Adt::Enum(e) => e.name(db),
508 }
509 }
499} 510}
500 511
501#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 512#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
@@ -523,6 +534,14 @@ impl VariantDef {
523 } 534 }
524 } 535 }
525 536
537 pub fn name(&self, db: &impl HirDatabase) -> Name {
538 match self {
539 VariantDef::Struct(s) => s.name(db),
540 VariantDef::Union(u) => u.name(db),
541 VariantDef::EnumVariant(e) => e.name(db),
542 }
543 }
544
526 pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { 545 pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
527 match self { 546 match self {
528 VariantDef::Struct(it) => it.variant_data(db), 547 VariantDef::Struct(it) => it.variant_data(db),
@@ -550,6 +569,14 @@ impl DefWithBody {
550 DefWithBody::Static(s) => s.module(db), 569 DefWithBody::Static(s) => s.module(db),
551 } 570 }
552 } 571 }
572
573 pub fn name(self, db: &impl HirDatabase) -> Option<Name> {
574 match self {
575 DefWithBody::Function(f) => Some(f.name(db)),
576 DefWithBody::Static(s) => s.name(db),
577 DefWithBody::Const(c) => c.name(db),
578 }
579 }
553} 580}
554 581
555#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 582#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
diff --git a/crates/ra_hir_def/src/find_path.rs b/crates/ra_hir_def/src/find_path.rs
index 43b9b124a..217e19b01 100644
--- a/crates/ra_hir_def/src/find_path.rs
+++ b/crates/ra_hir_def/src/find_path.rs
@@ -176,7 +176,7 @@ fn find_importable_locations(
176 // directly (only through reexports in direct dependencies). 176 // directly (only through reexports in direct dependencies).
177 for krate in Some(from.krate) 177 for krate in Some(from.krate)
178 .into_iter() 178 .into_iter()
179 .chain(crate_graph.dependencies(from.krate).map(|dep| dep.crate_id)) 179 .chain(crate_graph.crate_data(&from.krate).dependencies.iter().map(|dep| dep.crate_id))
180 { 180 {
181 result.extend( 181 result.extend(
182 importable_locations_in_crate(db, item, krate) 182 importable_locations_in_crate(db, item, krate)
diff --git a/crates/ra_hir_def/src/lang_item.rs b/crates/ra_hir_def/src/lang_item.rs
index 5a336ea1f..79e8d8038 100644
--- a/crates/ra_hir_def/src/lang_item.rs
+++ b/crates/ra_hir_def/src/lang_item.rs
@@ -117,7 +117,9 @@ impl LangItems {
117 return Some(*target); 117 return Some(*target);
118 } 118 }
119 db.crate_graph() 119 db.crate_graph()
120 .dependencies(start_crate) 120 .crate_data(&start_crate)
121 .dependencies
122 .iter()
121 .find_map(|dep| db.lang_item(dep.crate_id, item.clone())) 123 .find_map(|dep| db.lang_item(dep.crate_id, item.clone()))
122 } 124 }
123 125
diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs
index 628c44c99..6af0f4a8e 100644
--- a/crates/ra_hir_def/src/nameres.rs
+++ b/crates/ra_hir_def/src/nameres.rs
@@ -179,8 +179,7 @@ impl CrateDefMap {
179 pub(crate) fn crate_def_map_query(db: &impl DefDatabase, krate: CrateId) -> Arc<CrateDefMap> { 179 pub(crate) fn crate_def_map_query(db: &impl DefDatabase, krate: CrateId) -> Arc<CrateDefMap> {
180 let _p = profile("crate_def_map_query"); 180 let _p = profile("crate_def_map_query");
181 let def_map = { 181 let def_map = {
182 let crate_graph = db.crate_graph(); 182 let edition = db.crate_graph().crate_data(&krate).edition;
183 let edition = crate_graph.edition(krate);
184 let mut modules: Arena<LocalModuleId, ModuleData> = Arena::default(); 183 let mut modules: Arena<LocalModuleId, ModuleData> = Arena::default();
185 let root = modules.alloc(ModuleData::default()); 184 let root = modules.alloc(ModuleData::default());
186 CrateDefMap { 185 CrateDefMap {
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index 51c65a5d7..e69f89b80 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -34,7 +34,7 @@ pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> C
34 let crate_graph = db.crate_graph(); 34 let crate_graph = db.crate_graph();
35 35
36 // populate external prelude 36 // populate external prelude
37 for dep in crate_graph.dependencies(def_map.krate) { 37 for dep in &crate_graph.crate_data(&def_map.krate).dependencies {
38 let dep_def_map = db.crate_def_map(dep.crate_id); 38 let dep_def_map = db.crate_def_map(dep.crate_id);
39 log::debug!("crate dep {:?} -> {:?}", dep.name, dep.crate_id); 39 log::debug!("crate dep {:?} -> {:?}", dep.name, dep.crate_id);
40 def_map.extern_prelude.insert( 40 def_map.extern_prelude.insert(
@@ -128,8 +128,7 @@ where
128 DB: DefDatabase, 128 DB: DefDatabase,
129{ 129{
130 fn collect(&mut self) { 130 fn collect(&mut self) {
131 let crate_graph = self.db.crate_graph(); 131 let file_id = self.db.crate_graph().crate_data(&self.def_map.krate).root_file_id;
132 let file_id = crate_graph.crate_root(self.def_map.krate);
133 let raw_items = self.db.raw_items(file_id.into()); 132 let raw_items = self.db.raw_items(file_id.into());
134 let module_id = self.def_map.root; 133 let module_id = self.def_map.root;
135 self.def_map.modules[module_id].origin = ModuleOrigin::CrateRoot { definition: file_id }; 134 self.def_map.modules[module_id].origin = ModuleOrigin::CrateRoot { definition: file_id };
@@ -955,7 +954,7 @@ mod tests {
955 let krate = db.test_crate(); 954 let krate = db.test_crate();
956 955
957 let def_map = { 956 let def_map = {
958 let edition = db.crate_graph().edition(krate); 957 let edition = db.crate_graph().crate_data(&krate).edition;
959 let mut modules: Arena<LocalModuleId, ModuleData> = Arena::default(); 958 let mut modules: Arena<LocalModuleId, ModuleData> = Arena::default();
960 let root = modules.alloc(ModuleData::default()); 959 let root = modules.alloc(ModuleData::default());
961 CrateDefMap { 960 CrateDefMap {
diff --git a/crates/ra_hir_ty/src/traits.rs b/crates/ra_hir_ty/src/traits.rs
index 8de588790..6c653c4f5 100644
--- a/crates/ra_hir_ty/src/traits.rs
+++ b/crates/ra_hir_ty/src/traits.rs
@@ -47,7 +47,7 @@ pub(crate) fn impls_for_trait_query(
47 // will only ever get called for a few crates near the root of the tree (the 47 // will only ever get called for a few crates near the root of the tree (the
48 // ones the user is editing), so this may actually be a waste of memory. I'm 48 // ones the user is editing), so this may actually be a waste of memory. I'm
49 // doing it like this mainly for simplicity for now. 49 // doing it like this mainly for simplicity for now.
50 for dep in db.crate_graph().dependencies(krate) { 50 for dep in &db.crate_graph().crate_data(&krate).dependencies {
51 impls.extend(db.impls_for_trait(dep.crate_id, trait_).iter()); 51 impls.extend(db.impls_for_trait(dep.crate_id, trait_).iter());
52 } 52 }
53 let crate_impl_defs = db.impls_in_crate(krate); 53 let crate_impl_defs = db.impls_in_crate(krate);
diff --git a/crates/ra_ide/src/display.rs b/crates/ra_ide/src/display.rs
index 1c26a8697..eaeaaa2b4 100644
--- a/crates/ra_ide/src/display.rs
+++ b/crates/ra_ide/src/display.rs
@@ -68,17 +68,23 @@ pub(crate) fn macro_label(node: &ast::MacroCall) -> String {
68} 68}
69 69
70pub(crate) fn rust_code_markup<CODE: AsRef<str>>(val: CODE) -> String { 70pub(crate) fn rust_code_markup<CODE: AsRef<str>>(val: CODE) -> String {
71 rust_code_markup_with_doc::<_, &str>(val, None) 71 rust_code_markup_with_doc::<_, &str>(val, None, None)
72} 72}
73 73
74pub(crate) fn rust_code_markup_with_doc<CODE, DOC>(val: CODE, doc: Option<DOC>) -> String 74pub(crate) fn rust_code_markup_with_doc<CODE, DOC>(
75 val: CODE,
76 doc: Option<DOC>,
77 mod_path: Option<String>,
78) -> String
75where 79where
76 CODE: AsRef<str>, 80 CODE: AsRef<str>,
77 DOC: AsRef<str>, 81 DOC: AsRef<str>,
78{ 82{
83 let mod_path =
84 mod_path.filter(|path| !path.is_empty()).map(|path| path + "\n").unwrap_or_default();
79 if let Some(doc) = doc { 85 if let Some(doc) = doc {
80 format!("```rust\n{}\n```\n\n{}", val.as_ref(), doc.as_ref()) 86 format!("```rust\n{}{}\n```\n\n{}", mod_path, val.as_ref(), doc.as_ref())
81 } else { 87 } else {
82 format!("```rust\n{}\n```", val.as_ref()) 88 format!("```rust\n{}{}\n```", mod_path, val.as_ref())
83 } 89 }
84} 90}
diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs
index e9c682557..8b8af35fc 100644
--- a/crates/ra_ide/src/hover.rs
+++ b/crates/ra_ide/src/hover.rs
@@ -1,6 +1,10 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use hir::{Adt, HasSource, HirDisplay, Semantics}; 3use hir::{
4 Adt, AsAssocItem, AssocItemContainer, FieldSource, HasSource, HirDisplay, ModuleDef,
5 ModuleSource, Semantics,
6};
7use ra_db::SourceDatabase;
4use ra_ide_db::{ 8use ra_ide_db::{
5 defs::{classify_name, classify_name_ref, Definition}, 9 defs::{classify_name, classify_name_ref, Definition},
6 RootDatabase, 10 RootDatabase,
@@ -16,6 +20,8 @@ use crate::{
16 display::{macro_label, rust_code_markup, rust_code_markup_with_doc, ShortLabel}, 20 display::{macro_label, rust_code_markup, rust_code_markup_with_doc, ShortLabel},
17 FilePosition, RangeInfo, 21 FilePosition, RangeInfo,
18}; 22};
23use itertools::Itertools;
24use std::iter::once;
19 25
20/// Contains the results when hovering over an item 26/// Contains the results when hovering over an item
21#[derive(Debug, Clone)] 27#[derive(Debug, Clone)]
@@ -83,44 +89,86 @@ impl HoverResult {
83 } 89 }
84} 90}
85 91
86fn hover_text(docs: Option<String>, desc: Option<String>) -> Option<String> { 92fn hover_text(
87 match (desc, docs) { 93 docs: Option<String>,
88 (Some(desc), docs) => Some(rust_code_markup_with_doc(desc, docs)), 94 desc: Option<String>,
89 (None, Some(docs)) => Some(docs), 95 mod_path: Option<String>,
96) -> Option<String> {
97 match (desc, docs, mod_path) {
98 (Some(desc), docs, mod_path) => Some(rust_code_markup_with_doc(desc, docs, mod_path)),
99 (None, Some(docs), _) => Some(docs),
100 _ => None,
101 }
102}
103
104fn definition_owner_name(db: &RootDatabase, def: &Definition) -> Option<String> {
105 match def {
106 Definition::StructField(f) => Some(f.parent_def(db).name(db)),
107 Definition::Local(l) => l.parent(db).name(db),
108 Definition::ModuleDef(md) => match md {
109 ModuleDef::Function(f) => match f.as_assoc_item(db)?.container(db) {
110 AssocItemContainer::Trait(t) => Some(t.name(db)),
111 AssocItemContainer::ImplDef(i) => i.target_ty(db).as_adt().map(|adt| adt.name(db)),
112 },
113 ModuleDef::EnumVariant(e) => Some(e.parent_enum(db).name(db)),
114 _ => None,
115 },
116 Definition::SelfType(i) => i.target_ty(db).as_adt().map(|adt| adt.name(db)),
90 _ => None, 117 _ => None,
91 } 118 }
119 .map(|name| name.to_string())
120}
121
122fn determine_mod_path(db: &RootDatabase, def: &Definition) -> Option<String> {
123 let mod_path = def.module(db).map(|module| {
124 once(db.crate_graph().crate_data(&module.krate().into()).display_name.clone())
125 .chain(
126 module
127 .path_to_root(db)
128 .into_iter()
129 .rev()
130 .map(|it| it.name(db).map(|name| name.to_string())),
131 )
132 .chain(once(definition_owner_name(db, def)))
133 .flatten()
134 .join("::")
135 });
136 mod_path
92} 137}
93 138
94fn hover_text_from_name_kind(db: &RootDatabase, def: Definition) -> Option<String> { 139fn hover_text_from_name_kind(db: &RootDatabase, def: Definition) -> Option<String> {
140 let mod_path = determine_mod_path(db, &def);
95 return match def { 141 return match def {
96 Definition::Macro(it) => { 142 Definition::Macro(it) => {
97 let src = it.source(db); 143 let src = it.source(db);
98 hover_text(src.value.doc_comment_text(), Some(macro_label(&src.value))) 144 hover_text(src.value.doc_comment_text(), Some(macro_label(&src.value)), mod_path)
99 } 145 }
100 Definition::StructField(it) => { 146 Definition::StructField(it) => {
101 let src = it.source(db); 147 let src = it.source(db);
102 match src.value { 148 match src.value {
103 hir::FieldSource::Named(it) => hover_text(it.doc_comment_text(), it.short_label()), 149 FieldSource::Named(it) => {
150 hover_text(it.doc_comment_text(), it.short_label(), mod_path)
151 }
104 _ => None, 152 _ => None,
105 } 153 }
106 } 154 }
107 Definition::ModuleDef(it) => match it { 155 Definition::ModuleDef(it) => match it {
108 hir::ModuleDef::Module(it) => match it.definition_source(db).value { 156 ModuleDef::Module(it) => match it.definition_source(db).value {
109 hir::ModuleSource::Module(it) => { 157 ModuleSource::Module(it) => {
110 hover_text(it.doc_comment_text(), it.short_label()) 158 hover_text(it.doc_comment_text(), it.short_label(), mod_path)
111 } 159 }
112 _ => None, 160 _ => None,
113 }, 161 },
114 hir::ModuleDef::Function(it) => from_def_source(db, it), 162 ModuleDef::Function(it) => from_def_source(db, it, mod_path),
115 hir::ModuleDef::Adt(Adt::Struct(it)) => from_def_source(db, it), 163 ModuleDef::Adt(Adt::Struct(it)) => from_def_source(db, it, mod_path),
116 hir::ModuleDef::Adt(Adt::Union(it)) => from_def_source(db, it), 164 ModuleDef::Adt(Adt::Union(it)) => from_def_source(db, it, mod_path),
117 hir::ModuleDef::Adt(Adt::Enum(it)) => from_def_source(db, it), 165 ModuleDef::Adt(Adt::Enum(it)) => from_def_source(db, it, mod_path),
118 hir::ModuleDef::EnumVariant(it) => from_def_source(db, it), 166 ModuleDef::EnumVariant(it) => from_def_source(db, it, mod_path),
119 hir::ModuleDef::Const(it) => from_def_source(db, it), 167 ModuleDef::Const(it) => from_def_source(db, it, mod_path),
120 hir::ModuleDef::Static(it) => from_def_source(db, it), 168 ModuleDef::Static(it) => from_def_source(db, it, mod_path),
121 hir::ModuleDef::Trait(it) => from_def_source(db, it), 169 ModuleDef::Trait(it) => from_def_source(db, it, mod_path),
122 hir::ModuleDef::TypeAlias(it) => from_def_source(db, it), 170 ModuleDef::TypeAlias(it) => from_def_source(db, it, mod_path),
123 hir::ModuleDef::BuiltinType(it) => Some(it.to_string()), 171 ModuleDef::BuiltinType(it) => Some(it.to_string()),
124 }, 172 },
125 Definition::Local(it) => { 173 Definition::Local(it) => {
126 Some(rust_code_markup(it.ty(db).display_truncated(db, None).to_string())) 174 Some(rust_code_markup(it.ty(db).display_truncated(db, None).to_string()))
@@ -131,13 +179,13 @@ fn hover_text_from_name_kind(db: &RootDatabase, def: Definition) -> Option<Strin
131 } 179 }
132 }; 180 };
133 181
134 fn from_def_source<A, D>(db: &RootDatabase, def: D) -> Option<String> 182 fn from_def_source<A, D>(db: &RootDatabase, def: D, mod_path: Option<String>) -> Option<String>
135 where 183 where
136 D: HasSource<Ast = A>, 184 D: HasSource<Ast = A>,
137 A: ast::DocCommentsOwner + ast::NameOwner + ShortLabel, 185 A: ast::DocCommentsOwner + ast::NameOwner + ShortLabel,
138 { 186 {
139 let src = def.source(db); 187 let src = def.source(db);
140 hover_text(src.value.doc_comment_text(), src.value.short_label()) 188 hover_text(src.value.doc_comment_text(), src.value.short_label(), mod_path)
141 } 189 }
142} 190}
143 191
@@ -345,7 +393,7 @@ mod tests {
345 }; 393 };
346 } 394 }
347 "#, 395 "#,
348 &["field_a: u32"], 396 &["Foo\nfield_a: u32"],
349 ); 397 );
350 398
351 // Hovering over the field in the definition 399 // Hovering over the field in the definition
@@ -362,7 +410,7 @@ mod tests {
362 }; 410 };
363 } 411 }
364 "#, 412 "#,
365 &["field_a: u32"], 413 &["Foo\nfield_a: u32"],
366 ); 414 );
367 } 415 }
368 416
@@ -415,7 +463,7 @@ fn main() {
415 ", 463 ",
416 ); 464 );
417 let hover = analysis.hover(position).unwrap().unwrap(); 465 let hover = analysis.hover(position).unwrap().unwrap();
418 assert_eq!(trim_markup_opt(hover.info.first()), Some("Some")); 466 assert_eq!(trim_markup_opt(hover.info.first()), Some("Option\nSome"));
419 467
420 let (analysis, position) = single_file_with_position( 468 let (analysis, position) = single_file_with_position(
421 " 469 "
@@ -442,6 +490,7 @@ fn main() {
442 } 490 }
443 "#, 491 "#,
444 &[" 492 &["
493Option
445None 494None
446``` 495```
447 496
@@ -462,6 +511,7 @@ The None variant
462 } 511 }
463 "#, 512 "#,
464 &[" 513 &["
514Option
465Some 515Some
466``` 516```
467 517
@@ -528,21 +578,23 @@ fn func(foo: i32) { if true { <|>foo; }; }
528 fn test_hover_infer_associated_method_exact() { 578 fn test_hover_infer_associated_method_exact() {
529 let (analysis, position) = single_file_with_position( 579 let (analysis, position) = single_file_with_position(
530 " 580 "
531 struct Thing { x: u32 } 581 mod wrapper {
582 struct Thing { x: u32 }
532 583
533 impl Thing { 584 impl Thing {
534 fn new() -> Thing { 585 fn new() -> Thing {
535 Thing { x: 0 } 586 Thing { x: 0 }
587 }
536 } 588 }
537 } 589 }
538 590
539 fn main() { 591 fn main() {
540 let foo_test = Thing::new<|>(); 592 let foo_test = wrapper::Thing::new<|>();
541 } 593 }
542 ", 594 ",
543 ); 595 );
544 let hover = analysis.hover(position).unwrap().unwrap(); 596 let hover = analysis.hover(position).unwrap().unwrap();
545 assert_eq!(trim_markup_opt(hover.info.first()), Some("fn new() -> Thing")); 597 assert_eq!(trim_markup_opt(hover.info.first()), Some("wrapper::Thing\nfn new() -> Thing"));
546 assert_eq!(hover.info.is_exact(), true); 598 assert_eq!(hover.info.is_exact(), true);
547 } 599 }
548 600
diff --git a/crates/ra_ide/src/lib.rs b/crates/ra_ide/src/lib.rs
index 4dfe0553e..903624381 100644
--- a/crates/ra_ide/src/lib.rs
+++ b/crates/ra_ide/src/lib.rs
@@ -211,7 +211,13 @@ impl Analysis {
211 // Default to enable test for single file. 211 // Default to enable test for single file.
212 let mut cfg_options = CfgOptions::default(); 212 let mut cfg_options = CfgOptions::default();
213 cfg_options.insert_atom("test".into()); 213 cfg_options.insert_atom("test".into());
214 crate_graph.add_crate_root(file_id, Edition::Edition2018, cfg_options, Env::default()); 214 crate_graph.add_crate_root(
215 file_id,
216 Edition::Edition2018,
217 None,
218 cfg_options,
219 Env::default(),
220 );
215 change.add_file(source_root, file_id, "main.rs".into(), Arc::new(text)); 221 change.add_file(source_root, file_id, "main.rs".into(), Arc::new(text));
216 change.set_crate_graph(crate_graph); 222 change.set_crate_graph(crate_graph);
217 host.apply_change(change); 223 host.apply_change(change);
@@ -415,12 +421,12 @@ impl Analysis {
415 421
416 /// Returns the edition of the given crate. 422 /// Returns the edition of the given crate.
417 pub fn crate_edition(&self, crate_id: CrateId) -> Cancelable<Edition> { 423 pub fn crate_edition(&self, crate_id: CrateId) -> Cancelable<Edition> {
418 self.with_db(|db| db.crate_graph().edition(crate_id)) 424 self.with_db(|db| db.crate_graph().crate_data(&crate_id).edition)
419 } 425 }
420 426
421 /// Returns the root file of the given crate. 427 /// Returns the root file of the given crate.
422 pub fn crate_root(&self, crate_id: CrateId) -> Cancelable<FileId> { 428 pub fn crate_root(&self, crate_id: CrateId) -> Cancelable<FileId> {
423 self.with_db(|db| db.crate_graph().crate_root(crate_id)) 429 self.with_db(|db| db.crate_graph().crate_data(&crate_id).root_file_id)
424 } 430 }
425 431
426 /// Returns the set of possible targets to run for the current file. 432 /// Returns the set of possible targets to run for the current file.
diff --git a/crates/ra_ide/src/mock_analysis.rs b/crates/ra_ide/src/mock_analysis.rs
index f4cd6deb7..90f84b052 100644
--- a/crates/ra_ide/src/mock_analysis.rs
+++ b/crates/ra_ide/src/mock_analysis.rs
@@ -99,13 +99,19 @@ impl MockAnalysis {
99 root_crate = Some(crate_graph.add_crate_root( 99 root_crate = Some(crate_graph.add_crate_root(
100 file_id, 100 file_id,
101 Edition2018, 101 Edition2018,
102 None,
102 cfg_options, 103 cfg_options,
103 Env::default(), 104 Env::default(),
104 )); 105 ));
105 } else if path.ends_with("/lib.rs") { 106 } else if path.ends_with("/lib.rs") {
106 let other_crate =
107 crate_graph.add_crate_root(file_id, Edition2018, cfg_options, Env::default());
108 let crate_name = path.parent().unwrap().file_name().unwrap(); 107 let crate_name = path.parent().unwrap().file_name().unwrap();
108 let other_crate = crate_graph.add_crate_root(
109 file_id,
110 Edition2018,
111 Some(crate_name.to_owned()),
112 cfg_options,
113 Env::default(),
114 );
109 if let Some(root_crate) = root_crate { 115 if let Some(root_crate) = root_crate {
110 crate_graph 116 crate_graph
111 .add_dep(root_crate, CrateName::new(crate_name).unwrap(), other_crate) 117 .add_dep(root_crate, CrateName::new(crate_name).unwrap(), other_crate)
diff --git a/crates/ra_ide/src/parent_module.rs b/crates/ra_ide/src/parent_module.rs
index 2c4bdb039..b73cefd97 100644
--- a/crates/ra_ide/src/parent_module.rs
+++ b/crates/ra_ide/src/parent_module.rs
@@ -133,6 +133,7 @@ mod tests {
133 let crate_id = crate_graph.add_crate_root( 133 let crate_id = crate_graph.add_crate_root(
134 root_file, 134 root_file,
135 Edition2018, 135 Edition2018,
136 None,
136 CfgOptions::default(), 137 CfgOptions::default(),
137 Env::default(), 138 Env::default(),
138 ); 139 );
diff --git a/crates/ra_ide_db/src/change.rs b/crates/ra_ide_db/src/change.rs
index 8b5be9d21..628cf6416 100644
--- a/crates/ra_ide_db/src/change.rs
+++ b/crates/ra_ide_db/src/change.rs
@@ -5,7 +5,7 @@ use std::{fmt, sync::Arc, time};
5 5
6use ra_db::{ 6use ra_db::{
7 salsa::{Database, Durability, SweepStrategy}, 7 salsa::{Database, Durability, SweepStrategy},
8 CrateGraph, CrateId, FileId, RelativePathBuf, SourceDatabase, SourceDatabaseExt, SourceRoot, 8 CrateGraph, FileId, RelativePathBuf, SourceDatabase, SourceDatabaseExt, SourceRoot,
9 SourceRootId, 9 SourceRootId,
10}; 10};
11use ra_prof::{memory_usage, profile, Bytes}; 11use ra_prof::{memory_usage, profile, Bytes};
@@ -88,10 +88,6 @@ impl AnalysisChange {
88 self.crate_graph = Some(graph); 88 self.crate_graph = Some(graph);
89 } 89 }
90 90
91 pub fn set_debug_crate_name(&mut self, crate_id: CrateId, name: String) {
92 self.debug_data.crate_names.insert(crate_id, name);
93 }
94
95 pub fn set_debug_root_path(&mut self, source_root_id: SourceRootId, path: String) { 91 pub fn set_debug_root_path(&mut self, source_root_id: SourceRootId, path: String) {
96 self.debug_data.root_paths.insert(source_root_id, path); 92 self.debug_data.root_paths.insert(source_root_id, path);
97 } 93 }
diff --git a/crates/ra_ide_db/src/lib.rs b/crates/ra_ide_db/src/lib.rs
index 79f48c9e3..a105c7556 100644
--- a/crates/ra_ide_db/src/lib.rs
+++ b/crates/ra_ide_db/src/lib.rs
@@ -131,12 +131,10 @@ fn line_index(db: &impl LineIndexDatabase, file_id: FileId) -> Arc<LineIndex> {
131#[derive(Debug, Default, Clone)] 131#[derive(Debug, Default, Clone)]
132pub(crate) struct DebugData { 132pub(crate) struct DebugData {
133 pub(crate) root_paths: FxHashMap<SourceRootId, String>, 133 pub(crate) root_paths: FxHashMap<SourceRootId, String>,
134 pub(crate) crate_names: FxHashMap<CrateId, String>,
135} 134}
136 135
137impl DebugData { 136impl DebugData {
138 pub(crate) fn merge(&mut self, other: DebugData) { 137 pub(crate) fn merge(&mut self, other: DebugData) {
139 self.root_paths.extend(other.root_paths.into_iter()); 138 self.root_paths.extend(other.root_paths.into_iter());
140 self.crate_names.extend(other.crate_names.into_iter());
141 } 139 }
142} 140}
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs
index bcf12460d..37845ca56 100644
--- a/crates/ra_project_model/src/lib.rs
+++ b/crates/ra_project_model/src/lib.rs
@@ -14,7 +14,7 @@ use std::{
14 14
15use anyhow::{bail, Context, Result}; 15use anyhow::{bail, Context, Result};
16use ra_cfg::CfgOptions; 16use ra_cfg::CfgOptions;
17use ra_db::{CrateGraph, CrateId, CrateName, Edition, Env, FileId}; 17use ra_db::{CrateGraph, CrateName, Edition, Env, FileId};
18use rustc_hash::FxHashMap; 18use rustc_hash::FxHashMap;
19use serde_json::from_reader; 19use serde_json::from_reader;
20 20
@@ -163,9 +163,8 @@ impl ProjectWorkspace {
163 &self, 163 &self,
164 default_cfg_options: &CfgOptions, 164 default_cfg_options: &CfgOptions,
165 load: &mut dyn FnMut(&Path) -> Option<FileId>, 165 load: &mut dyn FnMut(&Path) -> Option<FileId>,
166 ) -> (CrateGraph, FxHashMap<CrateId, String>) { 166 ) -> CrateGraph {
167 let mut crate_graph = CrateGraph::default(); 167 let mut crate_graph = CrateGraph::default();
168 let mut names = FxHashMap::default();
169 match self { 168 match self {
170 ProjectWorkspace::Json { project } => { 169 ProjectWorkspace::Json { project } => {
171 let mut crates = FxHashMap::default(); 170 let mut crates = FxHashMap::default();
@@ -191,6 +190,8 @@ impl ProjectWorkspace {
191 crate_graph.add_crate_root( 190 crate_graph.add_crate_root(
192 file_id, 191 file_id,
193 edition, 192 edition,
193 // FIXME json definitions can store the crate name
194 None,
194 cfg_options, 195 cfg_options,
195 Env::default(), 196 Env::default(),
196 ), 197 ),
@@ -233,11 +234,11 @@ impl ProjectWorkspace {
233 let crate_id = crate_graph.add_crate_root( 234 let crate_id = crate_graph.add_crate_root(
234 file_id, 235 file_id,
235 Edition::Edition2018, 236 Edition::Edition2018,
237 Some(krate.name(&sysroot).to_string()),
236 cfg_options, 238 cfg_options,
237 Env::default(), 239 Env::default(),
238 ); 240 );
239 sysroot_crates.insert(krate, crate_id); 241 sysroot_crates.insert(krate, crate_id);
240 names.insert(crate_id, krate.name(&sysroot).to_string());
241 } 242 }
242 } 243 }
243 for from in sysroot.crates() { 244 for from in sysroot.crates() {
@@ -277,10 +278,10 @@ impl ProjectWorkspace {
277 let crate_id = crate_graph.add_crate_root( 278 let crate_id = crate_graph.add_crate_root(
278 file_id, 279 file_id,
279 edition, 280 edition,
281 Some(pkg.name(&cargo).to_string()),
280 cfg_options, 282 cfg_options,
281 Env::default(), 283 Env::default(),
282 ); 284 );
283 names.insert(crate_id, pkg.name(&cargo).to_string());
284 if tgt.kind(&cargo) == TargetKind::Lib { 285 if tgt.kind(&cargo) == TargetKind::Lib {
285 lib_tgt = Some(crate_id); 286 lib_tgt = Some(crate_id);
286 pkg_to_lib_crate.insert(pkg, crate_id); 287 pkg_to_lib_crate.insert(pkg, crate_id);
@@ -381,7 +382,7 @@ impl ProjectWorkspace {
381 } 382 }
382 } 383 }
383 } 384 }
384 (crate_graph, names) 385 crate_graph
385 } 386 }
386 387
387 pub fn workspace_root_for(&self, path: &Path) -> Option<&Path> { 388 pub fn workspace_root_for(&self, path: &Path) -> Option<&Path> {
diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs
index 8cd08ecb6..4be987860 100644
--- a/crates/rust-analyzer/src/cli/load_cargo.rs
+++ b/crates/rust-analyzer/src/cli/load_cargo.rs
@@ -52,12 +52,11 @@ pub(crate) fn load_cargo(
52 opts 52 opts
53 }; 53 };
54 54
55 let (crate_graph, _crate_names) = 55 let crate_graph = ws.to_crate_graph(&default_cfg_options, &mut |path: &Path| {
56 ws.to_crate_graph(&default_cfg_options, &mut |path: &Path| { 56 let vfs_file = vfs.load(path);
57 let vfs_file = vfs.load(path); 57 log::debug!("vfs file {:?} -> {:?}", path, vfs_file);
58 log::debug!("vfs file {:?} -> {:?}", path, vfs_file); 58 vfs_file.map(vfs_file_to_id)
59 vfs_file.map(vfs_file_to_id) 59 });
60 });
61 log::debug!("crate graph: {:?}", crate_graph); 60 log::debug!("crate graph: {:?}", crate_graph);
62 61
63 let source_roots = roots 62 let source_roots = roots
diff --git a/crates/rust-analyzer/src/world.rs b/crates/rust-analyzer/src/world.rs
index 96efab844..c92cf137c 100644
--- a/crates/rust-analyzer/src/world.rs
+++ b/crates/rust-analyzer/src/world.rs
@@ -123,13 +123,12 @@ impl WorldState {
123 let vfs_file = vfs.load(path); 123 let vfs_file = vfs.load(path);
124 vfs_file.map(|f| FileId(f.0)) 124 vfs_file.map(|f| FileId(f.0))
125 }; 125 };
126 for ws in workspaces.iter() { 126
127 let (graph, crate_names) = ws.to_crate_graph(&default_cfg_options, &mut load); 127 workspaces.iter().map(|ws| ws.to_crate_graph(&default_cfg_options, &mut load)).for_each(
128 let shift = crate_graph.extend(graph); 128 |graph| {
129 for (crate_id, name) in crate_names { 129 crate_graph.extend(graph);
130 change.set_debug_crate_name(crate_id.shift(shift), name) 130 },
131 } 131 );
132 }
133 change.set_crate_graph(crate_graph); 132 change.set_crate_graph(crate_graph);
134 133
135 // FIXME: Figure out the multi-workspace situation 134 // FIXME: Figure out the multi-workspace situation