about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-03-31 13:01:20 +0000
committerbors <bors@rust-lang.org>2023-03-31 13:01:20 +0000
commit853fb44a24b8d3341f52747caa949013121b24b4 (patch)
treecf803f99807d83f83600dd4ba2b62832e836f77d
parent419d59f6e77a88773c90481bbfb8a0cee237ba9a (diff)
parentb3919ea80de5dff9f4c58ad6b66a936477f7f014 (diff)
downloadrust-853fb44a24b8d3341f52747caa949013121b24b4.tar.gz
rust-853fb44a24b8d3341f52747caa949013121b24b4.zip
Auto merge of #14458 - Veykril:crate-origins, r=Veykril
Cleanup crate_graph construction
-rw-r--r--crates/base-db/src/fixture.rs12
-rw-r--r--crates/base-db/src/input.rs47
-rw-r--r--crates/hir/src/lib.rs3
-rw-r--r--crates/ide/src/lib.rs2
-rw-r--r--crates/project-model/src/cfg_flag.rs8
-rw-r--r--crates/project-model/src/tests.rs304
-rw-r--r--crates/project-model/src/workspace.rs292
7 files changed, 335 insertions, 333 deletions
diff --git a/crates/base-db/src/fixture.rs b/crates/base-db/src/fixture.rs
index 0ce8ec864be..3339580bfe2 100644
--- a/crates/base-db/src/fixture.rs
+++ b/crates/base-db/src/fixture.rs
@@ -157,8 +157,8 @@ impl ChangeFixture {
                     meta.edition,
                     Some(crate_name.clone().into()),
                     version,
-                    meta.cfg.clone(),
                     meta.cfg,
+                    Default::default(),
                     meta.env,
                     false,
                     origin,
@@ -197,8 +197,8 @@ impl ChangeFixture {
                 Edition::CURRENT,
                 Some(CrateName::new("test").unwrap().into()),
                 None,
-                default_cfg.clone(),
                 default_cfg,
+                Default::default(),
                 Env::default(),
                 false,
                 CrateOrigin::Local { repo: None, name: None },
@@ -241,8 +241,8 @@ impl ChangeFixture {
                 Edition::Edition2021,
                 Some(CrateDisplayName::from_canonical_name("core".to_string())),
                 None,
-                CfgOptions::default(),
-                CfgOptions::default(),
+                Default::default(),
+                Default::default(),
                 Env::default(),
                 false,
                 CrateOrigin::Lang(LangCrateOrigin::Core),
@@ -280,8 +280,8 @@ impl ChangeFixture {
                 Edition::Edition2021,
                 Some(CrateDisplayName::from_canonical_name("proc_macros".to_string())),
                 None,
-                CfgOptions::default(),
-                CfgOptions::default(),
+                Default::default(),
+                Default::default(),
                 Env::default(),
                 true,
                 CrateOrigin::Local { repo: None, name: None },
diff --git a/crates/base-db/src/input.rs b/crates/base-db/src/input.rs
index e65568bb8ef..ca09963aef4 100644
--- a/crates/base-db/src/input.rs
+++ b/crates/base-db/src/input.rs
@@ -300,7 +300,8 @@ pub struct CrateData {
     /// `Dependency` matters), this name should only be used for UI.
     pub display_name: Option<CrateDisplayName>,
     pub cfg_options: CfgOptions,
-    pub potential_cfg_options: CfgOptions,
+    /// The cfg options that could be used by the crate
+    pub potential_cfg_options: Option<CfgOptions>,
     pub env: Env,
     pub dependencies: Vec<Dependency>,
     pub origin: CrateOrigin,
@@ -356,7 +357,7 @@ impl CrateGraph {
         display_name: Option<CrateDisplayName>,
         version: Option<String>,
         cfg_options: CfgOptions,
-        potential_cfg_options: CfgOptions,
+        potential_cfg_options: Option<CfgOptions>,
         env: Env,
         is_proc_macro: bool,
         origin: CrateOrigin,
@@ -673,7 +674,7 @@ impl fmt::Display for CyclicDependenciesError {
 mod tests {
     use crate::CrateOrigin;
 
-    use super::{CfgOptions, CrateGraph, CrateName, Dependency, Edition::Edition2018, Env, FileId};
+    use super::{CrateGraph, CrateName, Dependency, Edition::Edition2018, Env, FileId};
 
     #[test]
     fn detect_cyclic_dependency_indirect() {
@@ -683,8 +684,8 @@ mod tests {
             Edition2018,
             None,
             None,
-            CfgOptions::default(),
-            CfgOptions::default(),
+            Default::default(),
+            Default::default(),
             Env::default(),
             false,
             CrateOrigin::Local { repo: None, name: None },
@@ -696,8 +697,8 @@ mod tests {
             Edition2018,
             None,
             None,
-            CfgOptions::default(),
-            CfgOptions::default(),
+            Default::default(),
+            Default::default(),
             Env::default(),
             false,
             CrateOrigin::Local { repo: None, name: None },
@@ -709,8 +710,8 @@ mod tests {
             Edition2018,
             None,
             None,
-            CfgOptions::default(),
-            CfgOptions::default(),
+            Default::default(),
+            Default::default(),
             Env::default(),
             false,
             CrateOrigin::Local { repo: None, name: None },
@@ -736,8 +737,8 @@ mod tests {
             Edition2018,
             None,
             None,
-            CfgOptions::default(),
-            CfgOptions::default(),
+            Default::default(),
+            Default::default(),
             Env::default(),
             false,
             CrateOrigin::Local { repo: None, name: None },
@@ -749,8 +750,8 @@ mod tests {
             Edition2018,
             None,
             None,
-            CfgOptions::default(),
-            CfgOptions::default(),
+            Default::default(),
+            Default::default(),
             Env::default(),
             false,
             CrateOrigin::Local { repo: None, name: None },
@@ -773,8 +774,8 @@ mod tests {
             Edition2018,
             None,
             None,
-            CfgOptions::default(),
-            CfgOptions::default(),
+            Default::default(),
+            Default::default(),
             Env::default(),
             false,
             CrateOrigin::Local { repo: None, name: None },
@@ -786,8 +787,8 @@ mod tests {
             Edition2018,
             None,
             None,
-            CfgOptions::default(),
-            CfgOptions::default(),
+            Default::default(),
+            Default::default(),
             Env::default(),
             false,
             CrateOrigin::Local { repo: None, name: None },
@@ -799,8 +800,8 @@ mod tests {
             Edition2018,
             None,
             None,
-            CfgOptions::default(),
-            CfgOptions::default(),
+            Default::default(),
+            Default::default(),
             Env::default(),
             false,
             CrateOrigin::Local { repo: None, name: None },
@@ -823,8 +824,8 @@ mod tests {
             Edition2018,
             None,
             None,
-            CfgOptions::default(),
-            CfgOptions::default(),
+            Default::default(),
+            Default::default(),
             Env::default(),
             false,
             CrateOrigin::Local { repo: None, name: None },
@@ -836,8 +837,8 @@ mod tests {
             Edition2018,
             None,
             None,
-            CfgOptions::default(),
-            CfgOptions::default(),
+            Default::default(),
+            Default::default(),
             Env::default(),
             false,
             CrateOrigin::Local { repo: None, name: None },
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 648ae00a5fa..624ee1fd30a 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -253,7 +253,8 @@ impl Crate {
     }
 
     pub fn potential_cfg(&self, db: &dyn HirDatabase) -> CfgOptions {
-        db.crate_graph()[self.id].potential_cfg_options.clone()
+        let data = &db.crate_graph()[self.id];
+        data.potential_cfg_options.clone().unwrap_or_else(|| data.cfg_options.clone())
     }
 }
 
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs
index 22ddf91ab33..b227addc4c2 100644
--- a/crates/ide/src/lib.rs
+++ b/crates/ide/src/lib.rs
@@ -237,7 +237,7 @@ impl Analysis {
             None,
             None,
             cfg_options.clone(),
-            cfg_options,
+            None,
             Env::default(),
             false,
             CrateOrigin::Local { repo: None, name: None },
diff --git a/crates/project-model/src/cfg_flag.rs b/crates/project-model/src/cfg_flag.rs
index c134b78ab3a..e366d441c1b 100644
--- a/crates/project-model/src/cfg_flag.rs
+++ b/crates/project-model/src/cfg_flag.rs
@@ -49,6 +49,14 @@ impl Extend<CfgFlag> for CfgOptions {
     }
 }
 
+impl FromIterator<CfgFlag> for CfgOptions {
+    fn from_iter<T: IntoIterator<Item = CfgFlag>>(iter: T) -> Self {
+        let mut this = CfgOptions::default();
+        this.extend(iter);
+        this
+    }
+}
+
 impl fmt::Display for CfgFlag {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
diff --git a/crates/project-model/src/tests.rs b/crates/project-model/src/tests.rs
index ea238ad5985..e31269aeadd 100644
--- a/crates/project-model/src/tests.rs
+++ b/crates/project-model/src/tests.rs
@@ -150,11 +150,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
                                 "debug_assertions",
                             ],
                         ),
-                        potential_cfg_options: CfgOptions(
-                            [
-                                "debug_assertions",
-                            ],
-                        ),
+                        potential_cfg_options: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -185,8 +181,11 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
                                 prelude: true,
                             },
                         ],
-                        origin: Rustc {
-                            name: "hello-world",
+                        origin: Local {
+                            repo: None,
+                            name: Some(
+                                "hello-world",
+                            ),
                         },
                         is_proc_macro: false,
                         target_layout: Err(
@@ -217,11 +216,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
                                 "debug_assertions",
                             ],
                         ),
-                        potential_cfg_options: CfgOptions(
-                            [
-                                "debug_assertions",
-                            ],
-                        ),
+                        potential_cfg_options: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -261,8 +256,11 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
                                 prelude: true,
                             },
                         ],
-                        origin: Rustc {
-                            name: "hello-world",
+                        origin: Local {
+                            repo: None,
+                            name: Some(
+                                "hello-world",
+                            ),
                         },
                         is_proc_macro: false,
                         target_layout: Err(
@@ -293,11 +291,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
                                 "debug_assertions",
                             ],
                         ),
-                        potential_cfg_options: CfgOptions(
-                            [
-                                "debug_assertions",
-                            ],
-                        ),
+                        potential_cfg_options: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -337,8 +331,11 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
                                 prelude: true,
                             },
                         ],
-                        origin: Rustc {
-                            name: "hello-world",
+                        origin: Local {
+                            repo: None,
+                            name: Some(
+                                "hello-world",
+                            ),
                         },
                         is_proc_macro: false,
                         target_layout: Err(
@@ -369,11 +366,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
                                 "debug_assertions",
                             ],
                         ),
-                        potential_cfg_options: CfgOptions(
-                            [
-                                "debug_assertions",
-                            ],
-                        ),
+                        potential_cfg_options: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -413,8 +406,11 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
                                 prelude: true,
                             },
                         ],
-                        origin: Rustc {
-                            name: "hello-world",
+                        origin: Local {
+                            repo: None,
+                            name: Some(
+                                "hello-world",
+                            ),
                         },
                         is_proc_macro: false,
                         target_layout: Err(
@@ -447,17 +443,19 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
                                 "feature=std",
                             ],
                         ),
-                        potential_cfg_options: CfgOptions(
-                            [
-                                "debug_assertions",
-                                "feature=align",
-                                "feature=const-extern-fn",
-                                "feature=default",
-                                "feature=extra_traits",
-                                "feature=rustc-dep-of-std",
-                                "feature=std",
-                                "feature=use_std",
-                            ],
+                        potential_cfg_options: Some(
+                            CfgOptions(
+                                [
+                                    "debug_assertions",
+                                    "feature=align",
+                                    "feature=const-extern-fn",
+                                    "feature=default",
+                                    "feature=extra_traits",
+                                    "feature=rustc-dep-of-std",
+                                    "feature=std",
+                                    "feature=use_std",
+                                ],
+                            ),
                         ),
                         env: Env {
                             entries: {
@@ -479,7 +477,10 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
                             },
                         },
                         dependencies: [],
-                        origin: Rustc {
+                        origin: Library {
+                            repo: Some(
+                                "https://github.com/rust-lang/libc",
+                            ),
                             name: "libc",
                         },
                         is_proc_macro: false,
@@ -535,12 +536,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
                                 "test",
                             ],
                         ),
-                        potential_cfg_options: CfgOptions(
-                            [
-                                "debug_assertions",
-                                "test",
-                            ],
-                        ),
+                        potential_cfg_options: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -571,8 +567,11 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
                                 prelude: true,
                             },
                         ],
-                        origin: Rustc {
-                            name: "hello-world",
+                        origin: Local {
+                            repo: None,
+                            name: Some(
+                                "hello-world",
+                            ),
                         },
                         is_proc_macro: false,
                         target_layout: Err(
@@ -604,12 +603,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
                                 "test",
                             ],
                         ),
-                        potential_cfg_options: CfgOptions(
-                            [
-                                "debug_assertions",
-                                "test",
-                            ],
-                        ),
+                        potential_cfg_options: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -649,8 +643,11 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
                                 prelude: true,
                             },
                         ],
-                        origin: Rustc {
-                            name: "hello-world",
+                        origin: Local {
+                            repo: None,
+                            name: Some(
+                                "hello-world",
+                            ),
                         },
                         is_proc_macro: false,
                         target_layout: Err(
@@ -682,12 +679,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
                                 "test",
                             ],
                         ),
-                        potential_cfg_options: CfgOptions(
-                            [
-                                "debug_assertions",
-                                "test",
-                            ],
-                        ),
+                        potential_cfg_options: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -727,8 +719,11 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
                                 prelude: true,
                             },
                         ],
-                        origin: Rustc {
-                            name: "hello-world",
+                        origin: Local {
+                            repo: None,
+                            name: Some(
+                                "hello-world",
+                            ),
                         },
                         is_proc_macro: false,
                         target_layout: Err(
@@ -760,12 +755,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
                                 "test",
                             ],
                         ),
-                        potential_cfg_options: CfgOptions(
-                            [
-                                "debug_assertions",
-                                "test",
-                            ],
-                        ),
+                        potential_cfg_options: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -805,8 +795,11 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
                                 prelude: true,
                             },
                         ],
-                        origin: Rustc {
-                            name: "hello-world",
+                        origin: Local {
+                            repo: None,
+                            name: Some(
+                                "hello-world",
+                            ),
                         },
                         is_proc_macro: false,
                         target_layout: Err(
@@ -839,17 +832,19 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
                                 "feature=std",
                             ],
                         ),
-                        potential_cfg_options: CfgOptions(
-                            [
-                                "debug_assertions",
-                                "feature=align",
-                                "feature=const-extern-fn",
-                                "feature=default",
-                                "feature=extra_traits",
-                                "feature=rustc-dep-of-std",
-                                "feature=std",
-                                "feature=use_std",
-                            ],
+                        potential_cfg_options: Some(
+                            CfgOptions(
+                                [
+                                    "debug_assertions",
+                                    "feature=align",
+                                    "feature=const-extern-fn",
+                                    "feature=default",
+                                    "feature=extra_traits",
+                                    "feature=rustc-dep-of-std",
+                                    "feature=std",
+                                    "feature=use_std",
+                                ],
+                            ),
                         ),
                         env: Env {
                             entries: {
@@ -871,7 +866,10 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
                             },
                         },
                         dependencies: [],
-                        origin: Rustc {
+                        origin: Library {
+                            repo: Some(
+                                "https://github.com/rust-lang/libc",
+                            ),
                             name: "libc",
                         },
                         is_proc_macro: false,
@@ -917,12 +915,7 @@ fn cargo_hello_world_project_model() {
                                 "test",
                             ],
                         ),
-                        potential_cfg_options: CfgOptions(
-                            [
-                                "debug_assertions",
-                                "test",
-                            ],
-                        ),
+                        potential_cfg_options: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -953,8 +946,11 @@ fn cargo_hello_world_project_model() {
                                 prelude: true,
                             },
                         ],
-                        origin: Rustc {
-                            name: "hello-world",
+                        origin: Local {
+                            repo: None,
+                            name: Some(
+                                "hello-world",
+                            ),
                         },
                         is_proc_macro: false,
                         target_layout: Err(
@@ -986,12 +982,7 @@ fn cargo_hello_world_project_model() {
                                 "test",
                             ],
                         ),
-                        potential_cfg_options: CfgOptions(
-                            [
-                                "debug_assertions",
-                                "test",
-                            ],
-                        ),
+                        potential_cfg_options: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -1031,8 +1022,11 @@ fn cargo_hello_world_project_model() {
                                 prelude: true,
                             },
                         ],
-                        origin: Rustc {
-                            name: "hello-world",
+                        origin: Local {
+                            repo: None,
+                            name: Some(
+                                "hello-world",
+                            ),
                         },
                         is_proc_macro: false,
                         target_layout: Err(
@@ -1064,12 +1058,7 @@ fn cargo_hello_world_project_model() {
                                 "test",
                             ],
                         ),
-                        potential_cfg_options: CfgOptions(
-                            [
-                                "debug_assertions",
-                                "test",
-                            ],
-                        ),
+                        potential_cfg_options: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -1109,8 +1098,11 @@ fn cargo_hello_world_project_model() {
                                 prelude: true,
                             },
                         ],
-                        origin: Rustc {
-                            name: "hello-world",
+                        origin: Local {
+                            repo: None,
+                            name: Some(
+                                "hello-world",
+                            ),
                         },
                         is_proc_macro: false,
                         target_layout: Err(
@@ -1142,12 +1134,7 @@ fn cargo_hello_world_project_model() {
                                 "test",
                             ],
                         ),
-                        potential_cfg_options: CfgOptions(
-                            [
-                                "debug_assertions",
-                                "test",
-                            ],
-                        ),
+                        potential_cfg_options: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -1187,8 +1174,11 @@ fn cargo_hello_world_project_model() {
                                 prelude: true,
                             },
                         ],
-                        origin: Rustc {
-                            name: "hello-world",
+                        origin: Local {
+                            repo: None,
+                            name: Some(
+                                "hello-world",
+                            ),
                         },
                         is_proc_macro: false,
                         target_layout: Err(
@@ -1221,17 +1211,19 @@ fn cargo_hello_world_project_model() {
                                 "feature=std",
                             ],
                         ),
-                        potential_cfg_options: CfgOptions(
-                            [
-                                "debug_assertions",
-                                "feature=align",
-                                "feature=const-extern-fn",
-                                "feature=default",
-                                "feature=extra_traits",
-                                "feature=rustc-dep-of-std",
-                                "feature=std",
-                                "feature=use_std",
-                            ],
+                        potential_cfg_options: Some(
+                            CfgOptions(
+                                [
+                                    "debug_assertions",
+                                    "feature=align",
+                                    "feature=const-extern-fn",
+                                    "feature=default",
+                                    "feature=extra_traits",
+                                    "feature=rustc-dep-of-std",
+                                    "feature=std",
+                                    "feature=use_std",
+                                ],
+                            ),
                         ),
                         env: Env {
                             entries: {
@@ -1253,7 +1245,10 @@ fn cargo_hello_world_project_model() {
                             },
                         },
                         dependencies: [],
-                        origin: Rustc {
+                        origin: Library {
+                            repo: Some(
+                                "https://github.com/rust-lang/libc",
+                            ),
                             name: "libc",
                         },
                         is_proc_macro: false,
@@ -1294,9 +1289,7 @@ fn rust_project_hello_world_project_model() {
                         cfg_options: CfgOptions(
                             [],
                         ),
-                        potential_cfg_options: CfgOptions(
-                            [],
-                        ),
+                        potential_cfg_options: None,
                         env: Env {
                             entries: {},
                         },
@@ -1339,9 +1332,7 @@ fn rust_project_hello_world_project_model() {
                         cfg_options: CfgOptions(
                             [],
                         ),
-                        potential_cfg_options: CfgOptions(
-                            [],
-                        ),
+                        potential_cfg_options: None,
                         env: Env {
                             entries: {},
                         },
@@ -1374,9 +1365,7 @@ fn rust_project_hello_world_project_model() {
                         cfg_options: CfgOptions(
                             [],
                         ),
-                        potential_cfg_options: CfgOptions(
-                            [],
-                        ),
+                        potential_cfg_options: None,
                         env: Env {
                             entries: {},
                         },
@@ -1409,9 +1398,7 @@ fn rust_project_hello_world_project_model() {
                         cfg_options: CfgOptions(
                             [],
                         ),
-                        potential_cfg_options: CfgOptions(
-                            [],
-                        ),
+                        potential_cfg_options: None,
                         env: Env {
                             entries: {},
                         },
@@ -1444,9 +1431,7 @@ fn rust_project_hello_world_project_model() {
                         cfg_options: CfgOptions(
                             [],
                         ),
-                        potential_cfg_options: CfgOptions(
-                            [],
-                        ),
+                        potential_cfg_options: None,
                         env: Env {
                             entries: {},
                         },
@@ -1498,9 +1483,7 @@ fn rust_project_hello_world_project_model() {
                         cfg_options: CfgOptions(
                             [],
                         ),
-                        potential_cfg_options: CfgOptions(
-                            [],
-                        ),
+                        potential_cfg_options: None,
                         env: Env {
                             entries: {},
                         },
@@ -1533,9 +1516,7 @@ fn rust_project_hello_world_project_model() {
                         cfg_options: CfgOptions(
                             [],
                         ),
-                        potential_cfg_options: CfgOptions(
-                            [],
-                        ),
+                        potential_cfg_options: None,
                         env: Env {
                             entries: {},
                         },
@@ -1641,9 +1622,7 @@ fn rust_project_hello_world_project_model() {
                         cfg_options: CfgOptions(
                             [],
                         ),
-                        potential_cfg_options: CfgOptions(
-                            [],
-                        ),
+                        potential_cfg_options: None,
                         env: Env {
                             entries: {},
                         },
@@ -1676,9 +1655,7 @@ fn rust_project_hello_world_project_model() {
                         cfg_options: CfgOptions(
                             [],
                         ),
-                        potential_cfg_options: CfgOptions(
-                            [],
-                        ),
+                        potential_cfg_options: None,
                         env: Env {
                             entries: {},
                         },
@@ -1711,9 +1688,7 @@ fn rust_project_hello_world_project_model() {
                         cfg_options: CfgOptions(
                             [],
                         ),
-                        potential_cfg_options: CfgOptions(
-                            [],
-                        ),
+                        potential_cfg_options: None,
                         env: Env {
                             entries: {},
                         },
@@ -1746,9 +1721,7 @@ fn rust_project_hello_world_project_model() {
                         cfg_options: CfgOptions(
                             [],
                         ),
-                        potential_cfg_options: CfgOptions(
-                            [],
-                        ),
+                        potential_cfg_options: None,
                         env: Env {
                             entries: {},
                         },
@@ -1789,6 +1762,15 @@ fn rust_project_hello_world_project_model() {
                                 ),
                                 prelude: false,
                             },
+                            Dependency {
+                                crate_id: CrateId(
+                                    4,
+                                ),
+                                name: CrateName(
+                                    "proc_macro",
+                                ),
+                                prelude: false,
+                            },
                         ],
                         origin: Local {
                             repo: None,
diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs
index aac5f428b57..418696a3610 100644
--- a/crates/project-model/src/workspace.rs
+++ b/crates/project-model/src/workspace.rs
@@ -19,6 +19,7 @@ use crate::{
     build_scripts::BuildScriptOutput,
     cargo_workspace::{DepKind, PackageData, RustLibSource},
     cfg_flag::CfgFlag,
+    project_json::Crate,
     rustc_cfg,
     sysroot::SysrootCrate,
     target_data_layout, utf8_stdout, CargoConfig, CargoWorkspace, InvocationStrategy, ManifestPath,
@@ -717,11 +718,11 @@ fn project_json_to_crate_graph(
     target_layout: TargetLayoutLoadResult,
     channel: Option<ReleaseChannel>,
 ) -> (CrateGraph, ProcMacroPaths) {
-    let mut crate_graph = CrateGraph::default();
-    let mut proc_macros: ProcMacroPaths = FxHashMap::default();
+    let mut res = (CrateGraph::default(), ProcMacroPaths::default());
+    let (crate_graph, proc_macros) = &mut res;
     let sysroot_deps = sysroot.as_ref().map(|sysroot| {
         sysroot_to_crate_graph(
-            &mut crate_graph,
+            crate_graph,
             sysroot,
             rustc_cfg.clone(),
             target_layout.clone(),
@@ -733,80 +734,84 @@ fn project_json_to_crate_graph(
     let mut cfg_cache: FxHashMap<&str, Vec<CfgFlag>> = FxHashMap::default();
     let crates: NoHashHashMap<CrateId, CrateId> = project
         .crates()
-        .filter_map(|(crate_id, krate)| {
-            let file_path = &krate.root_module;
-            let file_id = load(file_path)?;
-            Some((crate_id, krate, file_id))
-        })
-        .map(|(crate_id, krate, file_id)| {
-            let env = krate.env.clone().into_iter().collect();
-
-            let target_cfgs = match krate.target.as_deref() {
-                Some(target) => cfg_cache
-                    .entry(target)
-                    .or_insert_with(|| rustc_cfg::get(None, Some(target), extra_env)),
-                None => &rustc_cfg,
-            };
-
-            let mut cfg_options = CfgOptions::default();
-            cfg_options.extend(target_cfgs.iter().chain(krate.cfg.iter()).cloned());
-            let crate_graph_crate_id = crate_graph.add_crate_root(
+        .filter_map(|(crate_id, krate)| Some((crate_id, krate, load(&krate.root_module)?)))
+        .map(
+            |(
+                crate_id,
+                Crate {
+                    display_name,
+                    edition,
+                    version,
+                    cfg,
+                    target,
+                    env,
+                    proc_macro_dylib_path,
+                    is_proc_macro,
+                    repository,
+                    ..
+                },
                 file_id,
-                krate.edition,
-                krate.display_name.clone(),
-                krate.version.clone(),
-                cfg_options.clone(),
-                cfg_options,
-                env,
-                krate.is_proc_macro,
-                if let Some(name) = krate.display_name.clone() {
-                    CrateOrigin::Local {
-                        repo: krate.repository.clone(),
-                        name: Some(name.canonical_name().to_string()),
+            )| {
+                let env = env.clone().into_iter().collect();
+
+                let target_cfgs = match target.as_deref() {
+                    Some(target) => cfg_cache
+                        .entry(target)
+                        .or_insert_with(|| rustc_cfg::get(None, Some(target), extra_env)),
+                    None => &rustc_cfg,
+                };
+
+                let crate_graph_crate_id = crate_graph.add_crate_root(
+                    file_id,
+                    *edition,
+                    display_name.clone(),
+                    version.clone(),
+                    target_cfgs.iter().chain(cfg.iter()).cloned().collect(),
+                    None,
+                    env,
+                    *is_proc_macro,
+                    if let Some(name) = display_name.clone() {
+                        CrateOrigin::Local {
+                            repo: repository.clone(),
+                            name: Some(name.canonical_name().to_string()),
+                        }
+                    } else {
+                        CrateOrigin::Local { repo: None, name: None }
+                    },
+                    target_layout.clone(),
+                    None,
+                );
+                if *is_proc_macro {
+                    if let Some(path) = proc_macro_dylib_path.clone() {
+                        let node = Ok((
+                            display_name.as_ref().map(|it| it.canonical_name().to_owned()),
+                            path,
+                        ));
+                        proc_macros.insert(crate_graph_crate_id, node);
                     }
-                } else {
-                    CrateOrigin::Local { repo: None, name: None }
-                },
-                target_layout.clone(),
-                None,
-            );
-            if krate.is_proc_macro {
-                if let Some(path) = krate.proc_macro_dylib_path.clone() {
-                    let node = Ok((
-                        krate.display_name.as_ref().map(|it| it.canonical_name().to_owned()),
-                        path,
-                    ));
-                    proc_macros.insert(crate_graph_crate_id, node);
                 }
-            }
-            (crate_id, crate_graph_crate_id)
-        })
+                (crate_id, crate_graph_crate_id)
+            },
+        )
         .collect();
 
     for (from, krate) in project.crates() {
         if let Some(&from) = crates.get(&from) {
             if let Some((public_deps, libproc_macro)) = &sysroot_deps {
-                public_deps.add_to_crate_graph(&mut crate_graph, from);
-                if krate.is_proc_macro {
-                    if let Some(proc_macro) = libproc_macro {
-                        add_dep(
-                            &mut crate_graph,
-                            from,
-                            CrateName::new("proc_macro").unwrap(),
-                            *proc_macro,
-                        );
-                    }
+                public_deps.add_to_crate_graph(crate_graph, from);
+                if let Some(proc_macro) = libproc_macro {
+                    add_proc_macro_dep(crate_graph, from, *proc_macro, krate.is_proc_macro);
                 }
             }
 
             for dep in &krate.deps {
                 if let Some(&to) = crates.get(&dep.crate_id) {
-                    add_dep(&mut crate_graph, from, dep.name.clone(), to)
+                    add_dep(crate_graph, from, dep.name.clone(), to)
                 }
             }
         }
     }
-    (crate_graph, proc_macros)
+    res
 }
 
 fn cargo_to_crate_graph(
@@ -821,11 +826,12 @@ fn cargo_to_crate_graph(
     channel: Option<ReleaseChannel>,
 ) -> (CrateGraph, ProcMacroPaths) {
     let _p = profile::span("cargo_to_crate_graph");
-    let mut crate_graph = CrateGraph::default();
-    let mut proc_macros = FxHashMap::default();
+    let mut res = (CrateGraph::default(), ProcMacroPaths::default());
+    let crate_graph = &mut res.0;
+    let proc_macros = &mut res.1;
     let (public_deps, libproc_macro) = match sysroot {
         Some(sysroot) => sysroot_to_crate_graph(
-            &mut crate_graph,
+            crate_graph,
             sysroot,
             rustc_cfg.clone(),
             target_layout.clone(),
@@ -842,37 +848,42 @@ fn cargo_to_crate_graph(
         cfg_options
     };
 
+    // Mapping of a package to its library target
     let mut pkg_to_lib_crate = FxHashMap::default();
-
     let mut pkg_crates = FxHashMap::default();
     // Does any crate signal to rust-analyzer that they need the rustc_private crates?
     let mut has_private = false;
+
     // Next, create crates for each package, target pair
     for pkg in cargo.packages() {
-        let mut cfg_options = cfg_options.clone();
+        has_private |= cargo[pkg].metadata.rustc_private;
 
-        let overrides = match override_cfg {
-            CfgOverrides::Wildcard(cfg_diff) => Some(cfg_diff),
-            CfgOverrides::Selective(cfg_overrides) => cfg_overrides.get(&cargo[pkg].name),
-        };
+        let cfg_options = {
+            let mut cfg_options = cfg_options.clone();
 
-        // Add test cfg for local crates
-        if cargo[pkg].is_local {
-            cfg_options.insert_atom("test".into());
-        }
+            // Add test cfg for local crates
+            if cargo[pkg].is_local {
+                cfg_options.insert_atom("test".into());
+            }
 
-        if let Some(overrides) = overrides {
-            // FIXME: this is sort of a hack to deal with #![cfg(not(test))] vanishing such as seen
-            // in ed25519_dalek (#7243), and libcore (#9203) (although you only hit that one while
-            // working on rust-lang/rust as that's the only time it appears outside sysroot).
-            //
-            // A more ideal solution might be to reanalyze crates based on where the cursor is and
-            // figure out the set of cfgs that would have to apply to make it active.
+            let overrides = match override_cfg {
+                CfgOverrides::Wildcard(cfg_diff) => Some(cfg_diff),
+                CfgOverrides::Selective(cfg_overrides) => cfg_overrides.get(&cargo[pkg].name),
+            };
 
-            cfg_options.apply_diff(overrides.clone());
+            if let Some(overrides) = overrides {
+                // FIXME: this is sort of a hack to deal with #![cfg(not(test))] vanishing such as seen
+                // in ed25519_dalek (#7243), and libcore (#9203) (although you only hit that one while
+                // working on rust-lang/rust as that's the only time it appears outside sysroot).
+                //
+                // A more ideal solution might be to reanalyze crates based on where the cursor is and
+                // figure out the set of cfgs that would have to apply to make it active.
+
+                cfg_options.apply_diff(overrides.clone());
+            };
+            cfg_options
         };
 
-        has_private |= cargo[pkg].metadata.rustc_private;
         let mut lib_tgt = None;
         for &tgt in cargo[pkg].targets.iter() {
             if cargo[tgt].kind != TargetKind::Lib && !cargo[pkg].is_member {
@@ -883,46 +894,40 @@ fn cargo_to_crate_graph(
                 // https://github.com/rust-lang/rust-analyzer/issues/11300
                 continue;
             }
+            let Some(file_id) =  load(&cargo[tgt].root) else { continue };
 
-            if let Some(file_id) = load(&cargo[tgt].root) {
-                let crate_id = add_target_crate_root(
-                    &mut crate_graph,
-                    &mut proc_macros,
-                    &cargo[pkg],
-                    build_scripts.get_output(pkg),
-                    cfg_options.clone(),
-                    file_id,
-                    &cargo[tgt].name,
-                    cargo[tgt].is_proc_macro,
-                    target_layout.clone(),
-                    true,
-                    channel,
-                );
-                if cargo[tgt].kind == TargetKind::Lib {
-                    lib_tgt = Some((crate_id, cargo[tgt].name.clone()));
-                    pkg_to_lib_crate.insert(pkg, crate_id);
-                }
-                // Even crates that don't set proc-macro = true are allowed to depend on proc_macro
-                // (just none of the APIs work when called outside of a proc macro).
-                if let Some(proc_macro) = libproc_macro {
-                    add_dep_with_prelude(
-                        &mut crate_graph,
-                        crate_id,
-                        CrateName::new("proc_macro").unwrap(),
-                        proc_macro,
-                        cargo[tgt].is_proc_macro,
-                    );
-                }
-
-                pkg_crates.entry(pkg).or_insert_with(Vec::new).push((crate_id, cargo[tgt].kind));
+            let crate_id = add_target_crate_root(
+                crate_graph,
+                proc_macros,
+                &cargo[pkg],
+                build_scripts.get_output(pkg),
+                cfg_options.clone(),
+                file_id,
+                &cargo[tgt].name,
+                cargo[tgt].is_proc_macro,
+                target_layout.clone(),
+                false,
+                channel,
+            );
+            if cargo[tgt].kind == TargetKind::Lib {
+                lib_tgt = Some((crate_id, cargo[tgt].name.clone()));
+                pkg_to_lib_crate.insert(pkg, crate_id);
+            }
+            // Even crates that don't set proc-macro = true are allowed to depend on proc_macro
+            // (just none of the APIs work when called outside of a proc macro).
+            if let Some(proc_macro) = libproc_macro {
+                add_proc_macro_dep(crate_graph, crate_id, proc_macro, cargo[tgt].is_proc_macro);
             }
+
+            pkg_crates.entry(pkg).or_insert_with(Vec::new).push((crate_id, cargo[tgt].kind));
         }
 
         // Set deps to the core, std and to the lib target of the current package
         for &(from, kind) in pkg_crates.get(&pkg).into_iter().flatten() {
             // Add sysroot deps first so that a lib target named `core` etc. can overwrite them.
-            public_deps.add_to_crate_graph(&mut crate_graph, from);
+            public_deps.add_to_crate_graph(crate_graph, from);
 
+            // Add dep edge of all targets to the package's lib target
             if let Some((to, name)) = lib_tgt.clone() {
                 if to != from && kind != TargetKind::BuildScript {
                     // (build script can not depend on its library target)
@@ -931,7 +936,7 @@ fn cargo_to_crate_graph(
                     // cargo metadata does not do any normalization,
                     // so we do it ourselves currently
                     let name = CrateName::normalize_dashes(&name);
-                    add_dep(&mut crate_graph, from, name, to);
+                    add_dep(crate_graph, from, name, to);
                 }
             }
         }
@@ -940,21 +945,18 @@ fn cargo_to_crate_graph(
     // Now add a dep edge from all targets of upstream to the lib
     // target of downstream.
     for pkg in cargo.packages() {
-        for dep in cargo[pkg].dependencies.iter() {
-            let name = CrateName::new(&dep.name).unwrap();
-            if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) {
-                for &(from, kind) in pkg_crates.get(&pkg).into_iter().flatten() {
-                    if dep.kind == DepKind::Build && kind != TargetKind::BuildScript {
-                        // Only build scripts may depend on build dependencies.
-                        continue;
-                    }
-                    if dep.kind != DepKind::Build && kind == TargetKind::BuildScript {
-                        // Build scripts may only depend on build dependencies.
-                        continue;
-                    }
+        for dep in &cargo[pkg].dependencies {
+            let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) else { continue };
+            let Some(targets) = pkg_crates.get(&pkg) else { continue };
 
-                    add_dep(&mut crate_graph, from, name.clone(), to)
+            let name = CrateName::new(&dep.name).unwrap();
+            for &(from, kind) in targets {
+                // Build scripts may only depend on build dependencies.
+                if (dep.kind == DepKind::Build) != (kind == TargetKind::BuildScript) {
+                    continue;
                 }
+
+                add_dep(crate_graph, from, name.clone(), to)
             }
         }
     }
@@ -964,8 +966,8 @@ fn cargo_to_crate_graph(
         // and create dependencies on them for the crates which opt-in to that
         if let Some((rustc_workspace, rustc_build_scripts)) = rustc {
             handle_rustc_crates(
-                &mut crate_graph,
-                &mut proc_macros,
+                crate_graph,
+                proc_macros,
                 &mut pkg_to_lib_crate,
                 load,
                 rustc_workspace,
@@ -987,7 +989,7 @@ fn cargo_to_crate_graph(
             );
         }
     }
-    (crate_graph, proc_macros)
+    res
 }
 
 fn detached_files_to_crate_graph(
@@ -1032,7 +1034,7 @@ fn detached_files_to_crate_graph(
             display_name.clone(),
             None,
             cfg_options.clone(),
-            cfg_options.clone(),
+            None,
             Env::default(),
             false,
             CrateOrigin::Local {
@@ -1127,10 +1129,9 @@ fn handle_rustc_crates(
                     // Add dependencies on core / std / alloc for this crate
                     public_deps.add_to_crate_graph(crate_graph, crate_id);
                     if let Some(proc_macro) = libproc_macro {
-                        add_dep_with_prelude(
+                        add_proc_macro_dep(
                             crate_graph,
                             crate_id,
-                            CrateName::new("proc_macro").unwrap(),
                             proc_macro,
                             rustc_workspace[tgt].is_proc_macro,
                         );
@@ -1191,12 +1192,17 @@ fn add_target_crate_root(
     channel: Option<ReleaseChannel>,
 ) -> CrateId {
     let edition = pkg.edition;
-    let mut potential_cfg_options = cfg_options.clone();
-    potential_cfg_options.extend(
-        pkg.features
-            .iter()
-            .map(|feat| CfgFlag::KeyValue { key: "feature".into(), value: feat.0.into() }),
-    );
+    let potential_cfg_options = if pkg.features.is_empty() {
+        None
+    } else {
+        let mut potential_cfg_options = cfg_options.clone();
+        potential_cfg_options.extend(
+            pkg.features
+                .iter()
+                .map(|feat| CfgFlag::KeyValue { key: "feature".into(), value: feat.0.into() }),
+        );
+        Some(potential_cfg_options)
+    };
     let cfg_options = {
         let mut opts = cfg_options;
         for feature in pkg.active_features.iter() {
@@ -1288,7 +1294,7 @@ fn sysroot_to_crate_graph(
                 Some(display_name),
                 None,
                 cfg_options.clone(),
-                cfg_options.clone(),
+                None,
                 env,
                 false,
                 CrateOrigin::Lang(LangCrateOrigin::from(&*sysroot[krate].name)),
@@ -1333,6 +1339,10 @@ fn add_dep_with_prelude(
     add_dep_inner(graph, from, Dependency::with_prelude(name, to, prelude))
 }
 
+fn add_proc_macro_dep(crate_graph: &mut CrateGraph, from: CrateId, to: CrateId, prelude: bool) {
+    add_dep_with_prelude(crate_graph, from, CrateName::new("proc_macro").unwrap(), to, prelude);
+}
+
 fn add_dep_inner(graph: &mut CrateGraph, from: CrateId, dep: Dependency) {
     if let Err(err) = graph.add_dep(from, dep) {
         tracing::error!("{}", err)