mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 13:03:31 +00:00
Cleanup crate_graph construction
This commit is contained in:
parent
31db1fc75f
commit
b3919ea80d
7 changed files with 341 additions and 339 deletions
|
@ -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 },
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -237,7 +237,7 @@ impl Analysis {
|
|||
None,
|
||||
None,
|
||||
cfg_options.clone(),
|
||||
cfg_options,
|
||||
None,
|
||||
Env::default(),
|
||||
false,
|
||||
CrateOrigin::Local { repo: None, name: None },
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(
|
||||
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()),
|
||||
}
|
||||
} else {
|
||||
CrateOrigin::Local { repo: None, name: None }
|
||||
.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,
|
||||
..
|
||||
},
|
||||
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);
|
||||
file_id,
|
||||
)| {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
(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();
|
||||
|
||||
let overrides = match override_cfg {
|
||||
CfgOverrides::Wildcard(cfg_diff) => Some(cfg_diff),
|
||||
CfgOverrides::Selective(cfg_overrides) => cfg_overrides.get(&cargo[pkg].name),
|
||||
};
|
||||
|
||||
// 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.
|
||||
|
||||
cfg_options.apply_diff(overrides.clone());
|
||||
};
|
||||
|
||||
has_private |= cargo[pkg].metadata.rustc_private;
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
let overrides = match override_cfg {
|
||||
CfgOverrides::Wildcard(cfg_diff) => Some(cfg_diff),
|
||||
CfgOverrides::Selective(cfg_overrides) => cfg_overrides.get(&cargo[pkg].name),
|
||||
};
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
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)
|
||||
|
|
Loading…
Reference in a new issue