summaryrefslogtreecommitdiffstats
path: root/src/tools/rust-analyzer/crates/project-model
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:32 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:32 +0000
commit4547b622d8d29df964fa2914213088b148c498fc (patch)
tree9fc6b25f3c3add6b745be9a2400a6e96140046e9 /src/tools/rust-analyzer/crates/project-model
parentReleasing progress-linux version 1.66.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-4547b622d8d29df964fa2914213088b148c498fc.tar.xz
rustc-4547b622d8d29df964fa2914213088b148c498fc.zip
Merging upstream version 1.67.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/tools/rust-analyzer/crates/project-model')
-rw-r--r--src/tools/rust-analyzer/crates/project-model/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/build_scripts.rs2
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs50
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/sysroot.rs27
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/tests.rs71
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/workspace.rs84
6 files changed, 125 insertions, 111 deletions
diff --git a/src/tools/rust-analyzer/crates/project-model/Cargo.toml b/src/tools/rust-analyzer/crates/project-model/Cargo.toml
index cf9868740..39902a532 100644
--- a/src/tools/rust-analyzer/crates/project-model/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/project-model/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
description = "TBD"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[lib]
doctest = false
diff --git a/src/tools/rust-analyzer/crates/project-model/src/build_scripts.rs b/src/tools/rust-analyzer/crates/project-model/src/build_scripts.rs
index a26a7c57a..ae2b41f27 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/build_scripts.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/build_scripts.rs
@@ -69,7 +69,7 @@ impl WorkspaceBuildScripts {
cmd.args(&["check", "--quiet", "--workspace", "--message-format=json"]);
// --all-targets includes tests, benches and examples in addition to the
- // default lib and bins. This is an independent concept from the --targets
+ // default lib and bins. This is an independent concept from the --target
// flag below.
cmd.arg("--all-targets");
diff --git a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs
index b4c2ba436..02ec7a4f6 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs
@@ -270,11 +270,7 @@ impl CargoWorkspace {
config: &CargoConfig,
progress: &dyn Fn(String),
) -> Result<cargo_metadata::Metadata> {
- let target = config
- .target
- .clone()
- .or_else(|| cargo_config_build_target(cargo_toml, &config.extra_env))
- .or_else(|| rustc_discover_host_triple(cargo_toml, &config.extra_env));
+ let targets = find_list_of_build_targets(config, cargo_toml);
let mut meta = MetadataCommand::new();
meta.cargo_path(toolchain::cargo());
@@ -294,8 +290,12 @@ impl CargoWorkspace {
}
meta.current_dir(current_dir.as_os_str());
- if let Some(target) = target {
- meta.other_options(vec![String::from("--filter-platform"), target]);
+ if !targets.is_empty() {
+ let other_options: Vec<_> = targets
+ .into_iter()
+ .flat_map(|target| ["--filter-platform".to_string(), target])
+ .collect();
+ meta.other_options(other_options);
}
// FIXME: Fetching metadata is a slow process, as it might require
@@ -469,6 +469,19 @@ impl CargoWorkspace {
}
}
+fn find_list_of_build_targets(config: &CargoConfig, cargo_toml: &ManifestPath) -> Vec<String> {
+ if let Some(target) = &config.target {
+ return [target.into()].to_vec();
+ }
+
+ let build_targets = cargo_config_build_target(cargo_toml, &config.extra_env);
+ if !build_targets.is_empty() {
+ return build_targets;
+ }
+
+ rustc_discover_host_triple(cargo_toml, &config.extra_env).into_iter().collect()
+}
+
fn rustc_discover_host_triple(
cargo_toml: &ManifestPath,
extra_env: &FxHashMap<String, String>,
@@ -499,7 +512,7 @@ fn rustc_discover_host_triple(
fn cargo_config_build_target(
cargo_toml: &ManifestPath,
extra_env: &FxHashMap<String, String>,
-) -> Option<String> {
+) -> Vec<String> {
let mut cargo_config = Command::new(toolchain::cargo());
cargo_config.envs(extra_env);
cargo_config
@@ -507,12 +520,21 @@ fn cargo_config_build_target(
.args(&["-Z", "unstable-options", "config", "get", "build.target"])
.env("RUSTC_BOOTSTRAP", "1");
// if successful we receive `build.target = "target-triple"`
+ // or `build.target = ["<target 1>", ..]`
tracing::debug!("Discovering cargo config target by {:?}", cargo_config);
- match utf8_stdout(cargo_config) {
- Ok(stdout) => stdout
- .strip_prefix("build.target = \"")
- .and_then(|stdout| stdout.strip_suffix('"'))
- .map(ToOwned::to_owned),
- Err(_) => None,
+ utf8_stdout(cargo_config).map(parse_output_cargo_config_build_target).unwrap_or_default()
+}
+
+fn parse_output_cargo_config_build_target(stdout: String) -> Vec<String> {
+ let trimmed = stdout.trim_start_matches("build.target = ").trim_matches('"');
+
+ if !trimmed.starts_with('[') {
+ return [trimmed.to_string()].to_vec();
+ }
+
+ let res = serde_json::from_str(trimmed);
+ if let Err(e) = &res {
+ tracing::warn!("Failed to parse `build.target` as an array of target: {}`", e);
}
+ res.unwrap_or_default()
}
diff --git a/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs b/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs
index fa8d76f3f..f6c09a27c 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs
@@ -128,14 +128,18 @@ impl Sysroot {
}
if let Some(alloc) = sysroot.by_name("alloc") {
- if let Some(core) = sysroot.by_name("core") {
- sysroot.crates[alloc].deps.push(core);
+ for dep in ALLOC_DEPS.trim().lines() {
+ if let Some(dep) = sysroot.by_name(dep) {
+ sysroot.crates[alloc].deps.push(dep)
+ }
}
}
if let Some(proc_macro) = sysroot.by_name("proc_macro") {
- if let Some(std) = sysroot.by_name("std") {
- sysroot.crates[proc_macro].deps.push(std);
+ for dep in PROC_MACRO_DEPS.trim().lines() {
+ if let Some(dep) = sysroot.by_name(dep) {
+ sysroot.crates[proc_macro].deps.push(dep)
+ }
}
}
@@ -239,6 +243,7 @@ fn get_rust_src(sysroot_path: &AbsPath) -> Option<AbsPathBuf> {
const SYSROOT_CRATES: &str = "
alloc
+backtrace
core
panic_abort
panic_unwind
@@ -246,17 +251,19 @@ proc_macro
profiler_builtins
std
stdarch/crates/std_detect
-term
test
unwind";
+const ALLOC_DEPS: &str = "core";
+
const STD_DEPS: &str = "
alloc
-core
-panic_abort
panic_unwind
+panic_abort
+core
profiler_builtins
+unwind
std_detect
-term
-test
-unwind";
+test";
+
+const PROC_MACRO_DEPS: &str = "std";
diff --git a/src/tools/rust-analyzer/crates/project-model/src/tests.rs b/src/tools/rust-analyzer/crates/project-model/src/tests.rs
index e2444e249..a1cb438bd 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/tests.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/tests.rs
@@ -1566,10 +1566,10 @@ fn rust_project_hello_world_project_model() {
},
Dependency {
crate_id: CrateId(
- 1,
+ 3,
),
name: CrateName(
- "core",
+ "panic_unwind",
),
prelude: true,
},
@@ -1584,10 +1584,10 @@ fn rust_project_hello_world_project_model() {
},
Dependency {
crate_id: CrateId(
- 3,
+ 1,
),
name: CrateName(
- "panic_unwind",
+ "core",
),
prelude: true,
},
@@ -1602,40 +1602,31 @@ fn rust_project_hello_world_project_model() {
},
Dependency {
crate_id: CrateId(
- 7,
+ 9,
),
name: CrateName(
- "std_detect",
+ "unwind",
),
prelude: true,
},
Dependency {
crate_id: CrateId(
- 8,
+ 7,
),
name: CrateName(
- "term",
+ "std_detect",
),
prelude: true,
},
Dependency {
crate_id: CrateId(
- 9,
+ 8,
),
name: CrateName(
"test",
),
prelude: true,
},
- Dependency {
- crate_id: CrateId(
- 10,
- ),
- name: CrateName(
- "unwind",
- ),
- prelude: true,
- },
],
proc_macro: Err(
"no proc macro loaded for sysroot crate",
@@ -1690,40 +1681,6 @@ fn rust_project_hello_world_project_model() {
display_name: Some(
CrateDisplayName {
crate_name: CrateName(
- "term",
- ),
- canonical_name: "term",
- },
- ),
- cfg_options: CfgOptions(
- [],
- ),
- potential_cfg_options: CfgOptions(
- [],
- ),
- env: Env {
- entries: {},
- },
- dependencies: [],
- proc_macro: Err(
- "no proc macro loaded for sysroot crate",
- ),
- origin: Lang(
- Other,
- ),
- is_proc_macro: false,
- },
- CrateId(
- 9,
- ): CrateData {
- root_file_id: FileId(
- 10,
- ),
- edition: Edition2018,
- version: None,
- display_name: Some(
- CrateDisplayName {
- crate_name: CrateName(
"test",
),
canonical_name: "test",
@@ -1748,10 +1705,10 @@ fn rust_project_hello_world_project_model() {
is_proc_macro: false,
},
CrateId(
- 10,
+ 9,
): CrateData {
root_file_id: FileId(
- 11,
+ 10,
),
edition: Edition2018,
version: None,
@@ -1782,10 +1739,10 @@ fn rust_project_hello_world_project_model() {
is_proc_macro: false,
},
CrateId(
- 11,
+ 10,
): CrateData {
root_file_id: FileId(
- 12,
+ 11,
),
edition: Edition2018,
version: None,
@@ -1836,7 +1793,7 @@ fn rust_project_hello_world_project_model() {
},
Dependency {
crate_id: CrateId(
- 9,
+ 8,
),
name: CrateName(
"test",
diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
index 2780c62ed..3d199ed24 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
@@ -377,6 +377,21 @@ impl ProjectWorkspace {
}
}
+ pub fn find_sysroot_proc_macro_srv(&self) -> Option<AbsPathBuf> {
+ match self {
+ ProjectWorkspace::Cargo { sysroot: Some(sysroot), .. }
+ | ProjectWorkspace::Json { sysroot: Some(sysroot), .. } => {
+ let standalone_server_name =
+ format!("rust-analyzer-proc-macro-srv{}", std::env::consts::EXE_SUFFIX);
+ ["libexec", "lib"]
+ .into_iter()
+ .map(|segment| sysroot.root().join(segment).join(&standalone_server_name))
+ .find(|server_path| std::fs::metadata(&server_path).is_ok())
+ }
+ _ => None,
+ }
+ }
+
/// Returns the roots for the current `ProjectWorkspace`
/// The return type contains the path and whether or not
/// the root is a member of the current workspace
@@ -509,14 +524,14 @@ impl ProjectWorkspace {
build_scripts,
toolchain: _,
} => cargo_to_crate_graph(
- rustc_cfg.clone(),
- cfg_overrides,
load_proc_macro,
load,
+ rustc,
cargo,
- build_scripts,
sysroot.as_ref(),
- rustc,
+ rustc_cfg.clone(),
+ cfg_overrides,
+ build_scripts,
),
ProjectWorkspace::DetachedFiles { files, sysroot, rustc_cfg } => {
detached_files_to_crate_graph(rustc_cfg.clone(), load, files, sysroot)
@@ -602,7 +617,7 @@ fn project_json_to_crate_graph(
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(from, &mut crate_graph);
+ public_deps.add_to_crate_graph(&mut crate_graph, from);
if krate.is_proc_macro {
if let Some(proc_macro) = libproc_macro {
add_dep(
@@ -626,14 +641,14 @@ fn project_json_to_crate_graph(
}
fn cargo_to_crate_graph(
- rustc_cfg: Vec<CfgFlag>,
- override_cfg: &CfgOverrides,
load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> ProcMacroLoadResult,
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
+ rustc: &Option<CargoWorkspace>,
cargo: &CargoWorkspace,
- build_scripts: &WorkspaceBuildScripts,
sysroot: Option<&Sysroot>,
- rustc: &Option<CargoWorkspace>,
+ rustc_cfg: Vec<CfgFlag>,
+ override_cfg: &CfgOverrides,
+ build_scripts: &WorkspaceBuildScripts,
) -> CrateGraph {
let _p = profile::span("cargo_to_crate_graph");
let mut crate_graph = CrateGraph::default();
@@ -642,13 +657,15 @@ fn cargo_to_crate_graph(
None => (SysrootPublicDeps::default(), None),
};
- let mut cfg_options = CfgOptions::default();
- cfg_options.extend(rustc_cfg);
+ let cfg_options = {
+ let mut cfg_options = CfgOptions::default();
+ cfg_options.extend(rustc_cfg);
+ cfg_options.insert_atom("debug_assertions".into());
+ cfg_options
+ };
let mut pkg_to_lib_crate = FxHashMap::default();
- cfg_options.insert_atom("debug_assertions".into());
-
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;
@@ -723,7 +740,7 @@ fn cargo_to_crate_graph(
// 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(from, &mut crate_graph);
+ public_deps.add_to_crate_graph(&mut crate_graph, from);
if let Some((to, name)) = lib_tgt.clone() {
if to != from && kind != TargetKind::BuildScript {
@@ -767,15 +784,16 @@ fn cargo_to_crate_graph(
if let Some(rustc_workspace) = rustc {
handle_rustc_crates(
&mut crate_graph,
- rustc_workspace,
+ &mut pkg_to_lib_crate,
load,
- &cfg_options,
- override_cfg,
load_proc_macro,
- &mut pkg_to_lib_crate,
- &public_deps,
+ rustc_workspace,
cargo,
+ &public_deps,
+ libproc_macro,
&pkg_crates,
+ &cfg_options,
+ override_cfg,
build_scripts,
);
}
@@ -825,28 +843,29 @@ fn detached_files_to_crate_graph(
},
);
- public_deps.add(detached_file_crate, &mut crate_graph);
+ public_deps.add_to_crate_graph(&mut crate_graph, detached_file_crate);
}
crate_graph
}
fn handle_rustc_crates(
crate_graph: &mut CrateGraph,
- rustc_workspace: &CargoWorkspace,
+ pkg_to_lib_crate: &mut FxHashMap<Package, CrateId>,
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
- cfg_options: &CfgOptions,
- override_cfg: &CfgOverrides,
load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> ProcMacroLoadResult,
- pkg_to_lib_crate: &mut FxHashMap<Package, CrateId>,
- public_deps: &SysrootPublicDeps,
+ rustc_workspace: &CargoWorkspace,
cargo: &CargoWorkspace,
+ public_deps: &SysrootPublicDeps,
+ libproc_macro: Option<CrateId>,
pkg_crates: &FxHashMap<Package, Vec<(CrateId, TargetKind)>>,
+ cfg_options: &CfgOptions,
+ override_cfg: &CfgOverrides,
build_scripts: &WorkspaceBuildScripts,
) {
let mut rustc_pkg_crates = FxHashMap::default();
// The root package of the rustc-dev component is rustc_driver, so we match that
let root_pkg =
- rustc_workspace.packages().find(|package| rustc_workspace[*package].name == "rustc_driver");
+ rustc_workspace.packages().find(|&package| rustc_workspace[package].name == "rustc_driver");
// The rustc workspace might be incomplete (such as if rustc-dev is not
// installed for the current toolchain) and `rustc_source` is set to discover.
if let Some(root_pkg) = root_pkg {
@@ -901,7 +920,16 @@ fn handle_rustc_crates(
);
pkg_to_lib_crate.insert(pkg, crate_id);
// Add dependencies on core / std / alloc for this crate
- public_deps.add(crate_id, crate_graph);
+ public_deps.add_to_crate_graph(crate_graph, crate_id);
+ if let Some(proc_macro) = libproc_macro {
+ add_dep_with_prelude(
+ crate_graph,
+ crate_id,
+ CrateName::new("proc_macro").unwrap(),
+ proc_macro,
+ rustc_workspace[tgt].is_proc_macro,
+ );
+ }
rustc_pkg_crates.entry(pkg).or_insert_with(Vec::new).push(crate_id);
}
}
@@ -1009,7 +1037,7 @@ struct SysrootPublicDeps {
impl SysrootPublicDeps {
/// Makes `from` depend on the public sysroot crates.
- fn add(&self, from: CrateId, crate_graph: &mut CrateGraph) {
+ fn add_to_crate_graph(&self, crate_graph: &mut CrateGraph, from: CrateId) {
for (name, krate, prelude) in &self.deps {
add_dep_with_prelude(crate_graph, from, name.clone(), *krate, *prelude);
}