about summary refs log tree commit diff
path: root/src/tools/rust-analyzer/crates/project-model
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/rust-analyzer/crates/project-model')
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs18
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/project_json.rs2
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/sysroot.rs137
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/tests.rs4
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/workspace.rs64
-rw-r--r--src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt501
-rw-r--r--src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt454
7 files changed, 1166 insertions, 14 deletions
diff --git a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs
index 40ab8c53fae..014028a0b63 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs
@@ -288,7 +288,23 @@ impl CargoWorkspace {
         locked: bool,
         progress: &dyn Fn(String),
     ) -> anyhow::Result<(cargo_metadata::Metadata, Option<anyhow::Error>)> {
-        Self::fetch_metadata_(cargo_toml, current_dir, config, sysroot, locked, false, progress)
+        let res = Self::fetch_metadata_(
+            cargo_toml,
+            current_dir,
+            config,
+            sysroot,
+            locked,
+            false,
+            progress,
+        );
+        if let Ok((_, Some(ref e))) = res {
+            tracing::warn!(
+                %cargo_toml,
+                ?e,
+                "`cargo metadata` failed, but retry with `--no-deps` succeeded"
+            );
+        }
+        res
     }
 
     fn fetch_metadata_(
diff --git a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs
index 0282a714645..b2df8e4703a 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs
@@ -86,7 +86,7 @@ impl ProjectJson {
     /// * `manifest` - The path to the `rust-project.json`.
     /// * `base` - The path to the workspace root (i.e. the folder containing `rust-project.json`)
     /// * `data` - The parsed contents of `rust-project.json`, or project json that's passed via
-    ///            configuration.
+    ///   configuration.
     pub fn new(
         manifest: Option<ManifestPath>,
         base: &AbsPath,
diff --git a/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs b/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs
index 1e3c5a94786..13812e96fe7 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs
@@ -30,6 +30,7 @@ pub struct Sysroot {
 pub enum RustLibSrcWorkspace {
     Workspace(CargoWorkspace),
     Json(ProjectJson),
+    Stitched(stitched::Stitched),
     Empty,
 }
 
@@ -60,6 +61,7 @@ impl Sysroot {
         match &self.workspace {
             RustLibSrcWorkspace::Workspace(ws) => ws.packages().next().is_none(),
             RustLibSrcWorkspace::Json(project_json) => project_json.n_crates() == 0,
+            RustLibSrcWorkspace::Stitched(stitched) => stitched.crates.is_empty(),
             RustLibSrcWorkspace::Empty => true,
         }
     }
@@ -72,6 +74,7 @@ impl Sysroot {
         match &self.workspace {
             RustLibSrcWorkspace::Workspace(ws) => ws.packages().count(),
             RustLibSrcWorkspace::Json(project_json) => project_json.n_crates(),
+            RustLibSrcWorkspace::Stitched(stitched) => stitched.crates.len(),
             RustLibSrcWorkspace::Empty => 0,
         }
     }
@@ -197,6 +200,51 @@ impl Sysroot {
                     return Some(loaded);
                 }
             }
+            tracing::debug!("Stitching sysroot library: {src_root}");
+
+            let mut stitched = stitched::Stitched { crates: Default::default() };
+
+            for path in stitched::SYSROOT_CRATES.trim().lines() {
+                let name = path.split('/').next_back().unwrap();
+                let root = [format!("{path}/src/lib.rs"), format!("lib{path}/lib.rs")]
+                    .into_iter()
+                    .map(|it| src_root.join(it))
+                    .filter_map(|it| ManifestPath::try_from(it).ok())
+                    .find(|it| fs::metadata(it).is_ok());
+
+                if let Some(root) = root {
+                    stitched.crates.alloc(stitched::RustLibSrcCrateData {
+                        name: name.into(),
+                        root,
+                        deps: Vec::new(),
+                    });
+                }
+            }
+
+            if let Some(std) = stitched.by_name("std") {
+                for dep in stitched::STD_DEPS.trim().lines() {
+                    if let Some(dep) = stitched.by_name(dep) {
+                        stitched.crates[std].deps.push(dep)
+                    }
+                }
+            }
+
+            if let Some(alloc) = stitched.by_name("alloc") {
+                for dep in stitched::ALLOC_DEPS.trim().lines() {
+                    if let Some(dep) = stitched.by_name(dep) {
+                        stitched.crates[alloc].deps.push(dep)
+                    }
+                }
+            }
+
+            if let Some(proc_macro) = stitched.by_name("proc_macro") {
+                for dep in stitched::PROC_MACRO_DEPS.trim().lines() {
+                    if let Some(dep) = stitched.by_name(dep) {
+                        stitched.crates[proc_macro].deps.push(dep)
+                    }
+                }
+            }
+            return Some(RustLibSrcWorkspace::Stitched(stitched));
         } else if let RustSourceWorkspaceConfig::Json(project_json) = sysroot_source_config {
             return Some(RustLibSrcWorkspace::Json(project_json.clone()));
         }
@@ -216,6 +264,7 @@ impl Sysroot {
                         .crates()
                         .filter_map(|(_, krate)| krate.display_name.clone())
                         .any(|name| name.canonical_name().as_str() == "core"),
+                    RustLibSrcWorkspace::Stitched(stitched) => stitched.by_name("core").is_some(),
                     RustLibSrcWorkspace::Empty => true,
                 };
                 if !has_core {
@@ -391,3 +440,91 @@ fn get_rust_lib_src(sysroot_path: &AbsPath) -> Option<AbsPathBuf> {
         None
     }
 }
+
+// FIXME: Remove this, that will bump our project MSRV to 1.82
+pub(crate) mod stitched {
+    use std::ops;
+
+    use base_db::CrateName;
+    use la_arena::{Arena, Idx};
+
+    use crate::ManifestPath;
+
+    #[derive(Debug, Clone, Eq, PartialEq)]
+    pub struct Stitched {
+        pub(super) crates: Arena<RustLibSrcCrateData>,
+    }
+
+    impl ops::Index<RustLibSrcCrate> for Stitched {
+        type Output = RustLibSrcCrateData;
+        fn index(&self, index: RustLibSrcCrate) -> &RustLibSrcCrateData {
+            &self.crates[index]
+        }
+    }
+
+    impl Stitched {
+        pub(crate) fn public_deps(
+            &self,
+        ) -> impl Iterator<Item = (CrateName, RustLibSrcCrate, bool)> + '_ {
+            // core is added as a dependency before std in order to
+            // mimic rustcs dependency order
+            [("core", true), ("alloc", false), ("std", true), ("test", false)]
+                .into_iter()
+                .filter_map(move |(name, prelude)| {
+                    Some((CrateName::new(name).unwrap(), self.by_name(name)?, prelude))
+                })
+        }
+
+        pub(crate) fn proc_macro(&self) -> Option<RustLibSrcCrate> {
+            self.by_name("proc_macro")
+        }
+
+        pub(crate) fn crates(&self) -> impl ExactSizeIterator<Item = RustLibSrcCrate> + '_ {
+            self.crates.iter().map(|(id, _data)| id)
+        }
+
+        pub(super) fn by_name(&self, name: &str) -> Option<RustLibSrcCrate> {
+            let (id, _data) = self.crates.iter().find(|(_id, data)| data.name == name)?;
+            Some(id)
+        }
+    }
+
+    pub(crate) type RustLibSrcCrate = Idx<RustLibSrcCrateData>;
+
+    #[derive(Debug, Clone, Eq, PartialEq)]
+    pub(crate) struct RustLibSrcCrateData {
+        pub(crate) name: String,
+        pub(crate) root: ManifestPath,
+        pub(crate) deps: Vec<RustLibSrcCrate>,
+    }
+
+    pub(super) const SYSROOT_CRATES: &str = "
+alloc
+backtrace
+core
+panic_abort
+panic_unwind
+proc_macro
+profiler_builtins
+std
+stdarch/crates/std_detect
+test
+unwind";
+
+    pub(super) const ALLOC_DEPS: &str = "core";
+
+    pub(super) const STD_DEPS: &str = "
+alloc
+panic_unwind
+panic_abort
+core
+profiler_builtins
+unwind
+std_detect
+test";
+
+    // core is required for our builtin derives to work in the proc_macro lib currently
+    pub(super) const PROC_MACRO_DEPS: &str = "
+std
+core";
+}
diff --git a/src/tools/rust-analyzer/crates/project-model/src/tests.rs b/src/tools/rust-analyzer/crates/project-model/src/tests.rs
index cfc666970bd..83740622732 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/tests.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/tests.rs
@@ -166,7 +166,7 @@ fn check_crate_graph(crate_graph: CrateGraph, expect: ExpectFile) {
 #[test]
 fn cargo_hello_world_project_model_with_wildcard_overrides() {
     let cfg_overrides = CfgOverrides {
-        global: CfgDiff::new(Vec::new(), vec![CfgAtom::Flag(sym::test.clone())]).unwrap(),
+        global: CfgDiff::new(Vec::new(), vec![CfgAtom::Flag(sym::test.clone())]),
         selective: Default::default(),
     };
     let (crate_graph, _proc_macros) =
@@ -185,7 +185,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
         global: Default::default(),
         selective: std::iter::once((
             "libc".to_owned(),
-            CfgDiff::new(Vec::new(), vec![CfgAtom::Flag(sym::test.clone())]).unwrap(),
+            CfgDiff::new(Vec::new(), vec![CfgAtom::Flag(sym::test.clone())]),
         ))
         .collect(),
     };
diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
index 2c9f41e828e..62c13c7d9ec 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
@@ -692,6 +692,7 @@ impl ProjectWorkspace {
                         exclude: krate.exclude.clone(),
                     })
                     .collect(),
+                RustLibSrcWorkspace::Stitched(_) => vec![],
                 RustLibSrcWorkspace::Empty => vec![],
             };
 
@@ -1521,7 +1522,7 @@ fn extend_crate_graph_with_sysroot(
 ) -> (SysrootPublicDeps, Option<CrateId>) {
     let mut pub_deps = vec![];
     let mut libproc_macro = None;
-    let diff = CfgDiff::new(vec![], vec![CfgAtom::Flag(sym::test.clone())]).unwrap();
+    let diff = CfgDiff::new(vec![], vec![CfgAtom::Flag(sym::test.clone())]);
     for (cid, c) in sysroot_crate_graph.iter_mut() {
         // uninject `test` flag so `core` keeps working.
         Arc::make_mut(&mut c.cfg_options).apply_diff(diff.clone());
@@ -1599,8 +1600,7 @@ fn sysroot_to_crate_graph(
                             CfgAtom::Flag(sym::miri.clone()),
                         ],
                         vec![],
-                    )
-                    .unwrap(),
+                    ),
                     ..Default::default()
                 },
                 &WorkspaceBuildScripts::default(),
@@ -1623,8 +1623,7 @@ fn sysroot_to_crate_graph(
                             CfgAtom::Flag(sym::miri.clone()),
                         ],
                         vec![],
-                    )
-                    .unwrap(),
+                    ),
                     ..Default::default()
                 },
                 false,
@@ -1632,7 +1631,62 @@ fn sysroot_to_crate_graph(
 
             extend_crate_graph_with_sysroot(crate_graph, cg, pm)
         }
+        RustLibSrcWorkspace::Stitched(stitched) => {
+            let cfg_options = Arc::new({
+                let mut cfg_options = CfgOptions::default();
+                cfg_options.extend(rustc_cfg);
+                cfg_options.insert_atom(sym::debug_assertions.clone());
+                cfg_options.insert_atom(sym::miri.clone());
+                cfg_options
+            });
+            let sysroot_crates: FxHashMap<crate::sysroot::stitched::RustLibSrcCrate, CrateId> =
+                stitched
+                    .crates()
+                    .filter_map(|krate| {
+                        let file_id = load(&stitched[krate].root)?;
+
+                        let display_name =
+                            CrateDisplayName::from_canonical_name(&stitched[krate].name);
+                        let crate_id = crate_graph.add_crate_root(
+                            file_id,
+                            Edition::CURRENT_FIXME,
+                            Some(display_name),
+                            None,
+                            cfg_options.clone(),
+                            None,
+                            Env::default(),
+                            CrateOrigin::Lang(LangCrateOrigin::from(&*stitched[krate].name)),
+                            false,
+                            None,
+                        );
+                        Some((krate, crate_id))
+                    })
+                    .collect();
+
+            for from in stitched.crates() {
+                for &to in stitched[from].deps.iter() {
+                    let name = CrateName::new(&stitched[to].name).unwrap();
+                    if let (Some(&from), Some(&to)) =
+                        (sysroot_crates.get(&from), sysroot_crates.get(&to))
+                    {
+                        add_dep(crate_graph, from, name, to);
+                    }
+                }
+            }
+
+            let public_deps = SysrootPublicDeps {
+                deps: stitched
+                    .public_deps()
+                    .filter_map(|(name, idx, prelude)| {
+                        Some((name, *sysroot_crates.get(&idx)?, prelude))
+                    })
+                    .collect::<Vec<_>>(),
+            };
 
+            let libproc_macro =
+                stitched.proc_macro().and_then(|it| sysroot_crates.get(&it).copied());
+            (public_deps, libproc_macro)
+        }
         RustLibSrcWorkspace::Empty => (SysrootPublicDeps { deps: vec![] }, None),
     }
 }
diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt
index 28ca4eb5348..9b4be19c41c 100644
--- a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt
+++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt
@@ -3,6 +3,417 @@
         root_file_id: FileId(
             1,
         ),
+        edition: Edition2021,
+        version: None,
+        display_name: Some(
+            CrateDisplayName {
+                crate_name: CrateName(
+                    "alloc",
+                ),
+                canonical_name: "alloc",
+            },
+        ),
+        cfg_options: CfgOptions(
+            [
+                "debug_assertions",
+                "miri",
+                "true",
+            ],
+        ),
+        potential_cfg_options: None,
+        env: Env {
+            entries: {},
+        },
+        dependencies: [
+            Dependency {
+                crate_id: Idx::<CrateData>(1),
+                name: CrateName(
+                    "core",
+                ),
+                prelude: true,
+                sysroot: false,
+            },
+        ],
+        origin: Lang(
+            Alloc,
+        ),
+        is_proc_macro: false,
+        proc_macro_cwd: None,
+    },
+    1: CrateData {
+        root_file_id: FileId(
+            2,
+        ),
+        edition: Edition2021,
+        version: None,
+        display_name: Some(
+            CrateDisplayName {
+                crate_name: CrateName(
+                    "core",
+                ),
+                canonical_name: "core",
+            },
+        ),
+        cfg_options: CfgOptions(
+            [
+                "debug_assertions",
+                "miri",
+                "true",
+            ],
+        ),
+        potential_cfg_options: None,
+        env: Env {
+            entries: {},
+        },
+        dependencies: [],
+        origin: Lang(
+            Core,
+        ),
+        is_proc_macro: false,
+        proc_macro_cwd: None,
+    },
+    2: CrateData {
+        root_file_id: FileId(
+            3,
+        ),
+        edition: Edition2021,
+        version: None,
+        display_name: Some(
+            CrateDisplayName {
+                crate_name: CrateName(
+                    "panic_abort",
+                ),
+                canonical_name: "panic_abort",
+            },
+        ),
+        cfg_options: CfgOptions(
+            [
+                "debug_assertions",
+                "miri",
+                "true",
+            ],
+        ),
+        potential_cfg_options: None,
+        env: Env {
+            entries: {},
+        },
+        dependencies: [],
+        origin: Lang(
+            Other,
+        ),
+        is_proc_macro: false,
+        proc_macro_cwd: None,
+    },
+    3: CrateData {
+        root_file_id: FileId(
+            4,
+        ),
+        edition: Edition2021,
+        version: None,
+        display_name: Some(
+            CrateDisplayName {
+                crate_name: CrateName(
+                    "panic_unwind",
+                ),
+                canonical_name: "panic_unwind",
+            },
+        ),
+        cfg_options: CfgOptions(
+            [
+                "debug_assertions",
+                "miri",
+                "true",
+            ],
+        ),
+        potential_cfg_options: None,
+        env: Env {
+            entries: {},
+        },
+        dependencies: [],
+        origin: Lang(
+            Other,
+        ),
+        is_proc_macro: false,
+        proc_macro_cwd: None,
+    },
+    4: CrateData {
+        root_file_id: FileId(
+            5,
+        ),
+        edition: Edition2021,
+        version: None,
+        display_name: Some(
+            CrateDisplayName {
+                crate_name: CrateName(
+                    "proc_macro",
+                ),
+                canonical_name: "proc_macro",
+            },
+        ),
+        cfg_options: CfgOptions(
+            [
+                "debug_assertions",
+                "miri",
+                "true",
+            ],
+        ),
+        potential_cfg_options: None,
+        env: Env {
+            entries: {},
+        },
+        dependencies: [
+            Dependency {
+                crate_id: Idx::<CrateData>(6),
+                name: CrateName(
+                    "std",
+                ),
+                prelude: true,
+                sysroot: false,
+            },
+            Dependency {
+                crate_id: Idx::<CrateData>(1),
+                name: CrateName(
+                    "core",
+                ),
+                prelude: true,
+                sysroot: false,
+            },
+        ],
+        origin: Lang(
+            ProcMacro,
+        ),
+        is_proc_macro: false,
+        proc_macro_cwd: None,
+    },
+    5: CrateData {
+        root_file_id: FileId(
+            6,
+        ),
+        edition: Edition2021,
+        version: None,
+        display_name: Some(
+            CrateDisplayName {
+                crate_name: CrateName(
+                    "profiler_builtins",
+                ),
+                canonical_name: "profiler_builtins",
+            },
+        ),
+        cfg_options: CfgOptions(
+            [
+                "debug_assertions",
+                "miri",
+                "true",
+            ],
+        ),
+        potential_cfg_options: None,
+        env: Env {
+            entries: {},
+        },
+        dependencies: [],
+        origin: Lang(
+            Other,
+        ),
+        is_proc_macro: false,
+        proc_macro_cwd: None,
+    },
+    6: CrateData {
+        root_file_id: FileId(
+            7,
+        ),
+        edition: Edition2021,
+        version: None,
+        display_name: Some(
+            CrateDisplayName {
+                crate_name: CrateName(
+                    "std",
+                ),
+                canonical_name: "std",
+            },
+        ),
+        cfg_options: CfgOptions(
+            [
+                "debug_assertions",
+                "miri",
+                "true",
+            ],
+        ),
+        potential_cfg_options: None,
+        env: Env {
+            entries: {},
+        },
+        dependencies: [
+            Dependency {
+                crate_id: Idx::<CrateData>(0),
+                name: CrateName(
+                    "alloc",
+                ),
+                prelude: true,
+                sysroot: false,
+            },
+            Dependency {
+                crate_id: Idx::<CrateData>(3),
+                name: CrateName(
+                    "panic_unwind",
+                ),
+                prelude: true,
+                sysroot: false,
+            },
+            Dependency {
+                crate_id: Idx::<CrateData>(2),
+                name: CrateName(
+                    "panic_abort",
+                ),
+                prelude: true,
+                sysroot: false,
+            },
+            Dependency {
+                crate_id: Idx::<CrateData>(1),
+                name: CrateName(
+                    "core",
+                ),
+                prelude: true,
+                sysroot: false,
+            },
+            Dependency {
+                crate_id: Idx::<CrateData>(5),
+                name: CrateName(
+                    "profiler_builtins",
+                ),
+                prelude: true,
+                sysroot: false,
+            },
+            Dependency {
+                crate_id: Idx::<CrateData>(9),
+                name: CrateName(
+                    "unwind",
+                ),
+                prelude: true,
+                sysroot: false,
+            },
+            Dependency {
+                crate_id: Idx::<CrateData>(7),
+                name: CrateName(
+                    "std_detect",
+                ),
+                prelude: true,
+                sysroot: false,
+            },
+            Dependency {
+                crate_id: Idx::<CrateData>(8),
+                name: CrateName(
+                    "test",
+                ),
+                prelude: true,
+                sysroot: false,
+            },
+        ],
+        origin: Lang(
+            Std,
+        ),
+        is_proc_macro: false,
+        proc_macro_cwd: None,
+    },
+    7: CrateData {
+        root_file_id: FileId(
+            8,
+        ),
+        edition: Edition2021,
+        version: None,
+        display_name: Some(
+            CrateDisplayName {
+                crate_name: CrateName(
+                    "std_detect",
+                ),
+                canonical_name: "std_detect",
+            },
+        ),
+        cfg_options: CfgOptions(
+            [
+                "debug_assertions",
+                "miri",
+                "true",
+            ],
+        ),
+        potential_cfg_options: None,
+        env: Env {
+            entries: {},
+        },
+        dependencies: [],
+        origin: Lang(
+            Other,
+        ),
+        is_proc_macro: false,
+        proc_macro_cwd: None,
+    },
+    8: CrateData {
+        root_file_id: FileId(
+            9,
+        ),
+        edition: Edition2021,
+        version: None,
+        display_name: Some(
+            CrateDisplayName {
+                crate_name: CrateName(
+                    "test",
+                ),
+                canonical_name: "test",
+            },
+        ),
+        cfg_options: CfgOptions(
+            [
+                "debug_assertions",
+                "miri",
+                "true",
+            ],
+        ),
+        potential_cfg_options: None,
+        env: Env {
+            entries: {},
+        },
+        dependencies: [],
+        origin: Lang(
+            Test,
+        ),
+        is_proc_macro: false,
+        proc_macro_cwd: None,
+    },
+    9: CrateData {
+        root_file_id: FileId(
+            10,
+        ),
+        edition: Edition2021,
+        version: None,
+        display_name: Some(
+            CrateDisplayName {
+                crate_name: CrateName(
+                    "unwind",
+                ),
+                canonical_name: "unwind",
+            },
+        ),
+        cfg_options: CfgOptions(
+            [
+                "debug_assertions",
+                "miri",
+                "true",
+            ],
+        ),
+        potential_cfg_options: None,
+        env: Env {
+            entries: {},
+        },
+        dependencies: [],
+        origin: Lang(
+            Other,
+        ),
+        is_proc_macro: false,
+        proc_macro_cwd: None,
+    },
+    10: CrateData {
+        root_file_id: FileId(
+            11,
+        ),
         edition: Edition2018,
         version: None,
         display_name: Some(
@@ -27,7 +438,48 @@
         env: Env {
             entries: {},
         },
-        dependencies: [],
+        dependencies: [
+            Dependency {
+                crate_id: Idx::<CrateData>(1),
+                name: CrateName(
+                    "core",
+                ),
+                prelude: true,
+                sysroot: true,
+            },
+            Dependency {
+                crate_id: Idx::<CrateData>(0),
+                name: CrateName(
+                    "alloc",
+                ),
+                prelude: false,
+                sysroot: true,
+            },
+            Dependency {
+                crate_id: Idx::<CrateData>(6),
+                name: CrateName(
+                    "std",
+                ),
+                prelude: true,
+                sysroot: true,
+            },
+            Dependency {
+                crate_id: Idx::<CrateData>(8),
+                name: CrateName(
+                    "test",
+                ),
+                prelude: false,
+                sysroot: true,
+            },
+            Dependency {
+                crate_id: Idx::<CrateData>(4),
+                name: CrateName(
+                    "proc_macro",
+                ),
+                prelude: false,
+                sysroot: true,
+            },
+        ],
         origin: Local {
             repo: None,
             name: Some(
@@ -37,9 +489,9 @@
         is_proc_macro: false,
         proc_macro_cwd: None,
     },
-    1: CrateData {
+    11: CrateData {
         root_file_id: FileId(
-            1,
+            11,
         ),
         edition: Edition2018,
         version: None,
@@ -65,7 +517,48 @@
         env: Env {
             entries: {},
         },
-        dependencies: [],
+        dependencies: [
+            Dependency {
+                crate_id: Idx::<CrateData>(1),
+                name: CrateName(
+                    "core",
+                ),
+                prelude: true,
+                sysroot: true,
+            },
+            Dependency {
+                crate_id: Idx::<CrateData>(0),
+                name: CrateName(
+                    "alloc",
+                ),
+                prelude: false,
+                sysroot: true,
+            },
+            Dependency {
+                crate_id: Idx::<CrateData>(6),
+                name: CrateName(
+                    "std",
+                ),
+                prelude: true,
+                sysroot: true,
+            },
+            Dependency {
+                crate_id: Idx::<CrateData>(8),
+                name: CrateName(
+                    "test",
+                ),
+                prelude: false,
+                sysroot: true,
+            },
+            Dependency {
+                crate_id: Idx::<CrateData>(4),
+                name: CrateName(
+                    "proc_macro",
+                ),
+                prelude: false,
+                sysroot: true,
+            },
+        ],
         origin: Local {
             repo: None,
             name: Some(
diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt
index dde8d3023dc..4c8e66e8e96 100644
--- a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt
+++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt
@@ -3,6 +3,417 @@
         root_file_id: FileId(
             1,
         ),
+        edition: Edition2021,
+        version: None,
+        display_name: Some(
+            CrateDisplayName {
+                crate_name: CrateName(
+                    "alloc",
+                ),
+                canonical_name: "alloc",
+            },
+        ),
+        cfg_options: CfgOptions(
+            [
+                "debug_assertions",
+                "miri",
+                "true",
+            ],
+        ),
+        potential_cfg_options: None,
+        env: Env {
+            entries: {},
+        },
+        dependencies: [
+            Dependency {
+                crate_id: Idx::<CrateData>(1),
+                name: CrateName(
+                    "core",
+                ),
+                prelude: true,
+                sysroot: false,
+            },
+        ],
+        origin: Lang(
+            Alloc,
+        ),
+        is_proc_macro: false,
+        proc_macro_cwd: None,
+    },
+    1: CrateData {
+        root_file_id: FileId(
+            2,
+        ),
+        edition: Edition2021,
+        version: None,
+        display_name: Some(
+            CrateDisplayName {
+                crate_name: CrateName(
+                    "core",
+                ),
+                canonical_name: "core",
+            },
+        ),
+        cfg_options: CfgOptions(
+            [
+                "debug_assertions",
+                "miri",
+                "true",
+            ],
+        ),
+        potential_cfg_options: None,
+        env: Env {
+            entries: {},
+        },
+        dependencies: [],
+        origin: Lang(
+            Core,
+        ),
+        is_proc_macro: false,
+        proc_macro_cwd: None,
+    },
+    2: CrateData {
+        root_file_id: FileId(
+            3,
+        ),
+        edition: Edition2021,
+        version: None,
+        display_name: Some(
+            CrateDisplayName {
+                crate_name: CrateName(
+                    "panic_abort",
+                ),
+                canonical_name: "panic_abort",
+            },
+        ),
+        cfg_options: CfgOptions(
+            [
+                "debug_assertions",
+                "miri",
+                "true",
+            ],
+        ),
+        potential_cfg_options: None,
+        env: Env {
+            entries: {},
+        },
+        dependencies: [],
+        origin: Lang(
+            Other,
+        ),
+        is_proc_macro: false,
+        proc_macro_cwd: None,
+    },
+    3: CrateData {
+        root_file_id: FileId(
+            4,
+        ),
+        edition: Edition2021,
+        version: None,
+        display_name: Some(
+            CrateDisplayName {
+                crate_name: CrateName(
+                    "panic_unwind",
+                ),
+                canonical_name: "panic_unwind",
+            },
+        ),
+        cfg_options: CfgOptions(
+            [
+                "debug_assertions",
+                "miri",
+                "true",
+            ],
+        ),
+        potential_cfg_options: None,
+        env: Env {
+            entries: {},
+        },
+        dependencies: [],
+        origin: Lang(
+            Other,
+        ),
+        is_proc_macro: false,
+        proc_macro_cwd: None,
+    },
+    4: CrateData {
+        root_file_id: FileId(
+            5,
+        ),
+        edition: Edition2021,
+        version: None,
+        display_name: Some(
+            CrateDisplayName {
+                crate_name: CrateName(
+                    "proc_macro",
+                ),
+                canonical_name: "proc_macro",
+            },
+        ),
+        cfg_options: CfgOptions(
+            [
+                "debug_assertions",
+                "miri",
+                "true",
+            ],
+        ),
+        potential_cfg_options: None,
+        env: Env {
+            entries: {},
+        },
+        dependencies: [
+            Dependency {
+                crate_id: Idx::<CrateData>(6),
+                name: CrateName(
+                    "std",
+                ),
+                prelude: true,
+                sysroot: false,
+            },
+            Dependency {
+                crate_id: Idx::<CrateData>(1),
+                name: CrateName(
+                    "core",
+                ),
+                prelude: true,
+                sysroot: false,
+            },
+        ],
+        origin: Lang(
+            ProcMacro,
+        ),
+        is_proc_macro: false,
+        proc_macro_cwd: None,
+    },
+    5: CrateData {
+        root_file_id: FileId(
+            6,
+        ),
+        edition: Edition2021,
+        version: None,
+        display_name: Some(
+            CrateDisplayName {
+                crate_name: CrateName(
+                    "profiler_builtins",
+                ),
+                canonical_name: "profiler_builtins",
+            },
+        ),
+        cfg_options: CfgOptions(
+            [
+                "debug_assertions",
+                "miri",
+                "true",
+            ],
+        ),
+        potential_cfg_options: None,
+        env: Env {
+            entries: {},
+        },
+        dependencies: [],
+        origin: Lang(
+            Other,
+        ),
+        is_proc_macro: false,
+        proc_macro_cwd: None,
+    },
+    6: CrateData {
+        root_file_id: FileId(
+            7,
+        ),
+        edition: Edition2021,
+        version: None,
+        display_name: Some(
+            CrateDisplayName {
+                crate_name: CrateName(
+                    "std",
+                ),
+                canonical_name: "std",
+            },
+        ),
+        cfg_options: CfgOptions(
+            [
+                "debug_assertions",
+                "miri",
+                "true",
+            ],
+        ),
+        potential_cfg_options: None,
+        env: Env {
+            entries: {},
+        },
+        dependencies: [
+            Dependency {
+                crate_id: Idx::<CrateData>(0),
+                name: CrateName(
+                    "alloc",
+                ),
+                prelude: true,
+                sysroot: false,
+            },
+            Dependency {
+                crate_id: Idx::<CrateData>(3),
+                name: CrateName(
+                    "panic_unwind",
+                ),
+                prelude: true,
+                sysroot: false,
+            },
+            Dependency {
+                crate_id: Idx::<CrateData>(2),
+                name: CrateName(
+                    "panic_abort",
+                ),
+                prelude: true,
+                sysroot: false,
+            },
+            Dependency {
+                crate_id: Idx::<CrateData>(1),
+                name: CrateName(
+                    "core",
+                ),
+                prelude: true,
+                sysroot: false,
+            },
+            Dependency {
+                crate_id: Idx::<CrateData>(5),
+                name: CrateName(
+                    "profiler_builtins",
+                ),
+                prelude: true,
+                sysroot: false,
+            },
+            Dependency {
+                crate_id: Idx::<CrateData>(9),
+                name: CrateName(
+                    "unwind",
+                ),
+                prelude: true,
+                sysroot: false,
+            },
+            Dependency {
+                crate_id: Idx::<CrateData>(7),
+                name: CrateName(
+                    "std_detect",
+                ),
+                prelude: true,
+                sysroot: false,
+            },
+            Dependency {
+                crate_id: Idx::<CrateData>(8),
+                name: CrateName(
+                    "test",
+                ),
+                prelude: true,
+                sysroot: false,
+            },
+        ],
+        origin: Lang(
+            Std,
+        ),
+        is_proc_macro: false,
+        proc_macro_cwd: None,
+    },
+    7: CrateData {
+        root_file_id: FileId(
+            8,
+        ),
+        edition: Edition2021,
+        version: None,
+        display_name: Some(
+            CrateDisplayName {
+                crate_name: CrateName(
+                    "std_detect",
+                ),
+                canonical_name: "std_detect",
+            },
+        ),
+        cfg_options: CfgOptions(
+            [
+                "debug_assertions",
+                "miri",
+                "true",
+            ],
+        ),
+        potential_cfg_options: None,
+        env: Env {
+            entries: {},
+        },
+        dependencies: [],
+        origin: Lang(
+            Other,
+        ),
+        is_proc_macro: false,
+        proc_macro_cwd: None,
+    },
+    8: CrateData {
+        root_file_id: FileId(
+            9,
+        ),
+        edition: Edition2021,
+        version: None,
+        display_name: Some(
+            CrateDisplayName {
+                crate_name: CrateName(
+                    "test",
+                ),
+                canonical_name: "test",
+            },
+        ),
+        cfg_options: CfgOptions(
+            [
+                "debug_assertions",
+                "miri",
+                "true",
+            ],
+        ),
+        potential_cfg_options: None,
+        env: Env {
+            entries: {},
+        },
+        dependencies: [],
+        origin: Lang(
+            Test,
+        ),
+        is_proc_macro: false,
+        proc_macro_cwd: None,
+    },
+    9: CrateData {
+        root_file_id: FileId(
+            10,
+        ),
+        edition: Edition2021,
+        version: None,
+        display_name: Some(
+            CrateDisplayName {
+                crate_name: CrateName(
+                    "unwind",
+                ),
+                canonical_name: "unwind",
+            },
+        ),
+        cfg_options: CfgOptions(
+            [
+                "debug_assertions",
+                "miri",
+                "true",
+            ],
+        ),
+        potential_cfg_options: None,
+        env: Env {
+            entries: {},
+        },
+        dependencies: [],
+        origin: Lang(
+            Other,
+        ),
+        is_proc_macro: false,
+        proc_macro_cwd: None,
+    },
+    10: CrateData {
+        root_file_id: FileId(
+            11,
+        ),
         edition: Edition2018,
         version: None,
         display_name: Some(
@@ -24,7 +435,48 @@
         env: Env {
             entries: {},
         },
-        dependencies: [],
+        dependencies: [
+            Dependency {
+                crate_id: Idx::<CrateData>(1),
+                name: CrateName(
+                    "core",
+                ),
+                prelude: true,
+                sysroot: true,
+            },
+            Dependency {
+                crate_id: Idx::<CrateData>(0),
+                name: CrateName(
+                    "alloc",
+                ),
+                prelude: false,
+                sysroot: true,
+            },
+            Dependency {
+                crate_id: Idx::<CrateData>(6),
+                name: CrateName(
+                    "std",
+                ),
+                prelude: true,
+                sysroot: true,
+            },
+            Dependency {
+                crate_id: Idx::<CrateData>(8),
+                name: CrateName(
+                    "test",
+                ),
+                prelude: false,
+                sysroot: true,
+            },
+            Dependency {
+                crate_id: Idx::<CrateData>(4),
+                name: CrateName(
+                    "proc_macro",
+                ),
+                prelude: false,
+                sysroot: true,
+            },
+        ],
         origin: Local {
             repo: None,
             name: Some(