Unnamed repository; edit this file 'description' to name the repository.
-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 0ce8ec864b..3339580bfe 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 e65568bb8e..ca09963aef 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 648ae00a5f..624ee1fd30 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 22ddf91ab3..b227addc4c 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 c134b78ab3..e366d441c1 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 ea238ad598..e31269aead 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 aac5f428b5..418696a361 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)