Auto merge of #14091 - Veykril:workspace-sysroot, r=Veykril
Support sysroot library source being defined inside the workspace With this you can now specify `cargo.sysrootSrc`. This is required for the rust workspace such that the `library` folder inside the workspace can be used as the sysroot library sources. We now also recognize if these sources are inside the workspace, tagging the as workspace members. This does duplicate the sysroot crates still, but I don't think that causes too many problems.
This commit is contained in:
commit
62523024d3
@ -96,6 +96,7 @@ pub struct CargoConfig {
|
||||
pub target: Option<String>,
|
||||
/// Sysroot loading behavior
|
||||
pub sysroot: Option<RustcSource>,
|
||||
pub sysroot_src: Option<AbsPathBuf>,
|
||||
/// rustc private crate source
|
||||
pub rustc_source: Option<RustcSource>,
|
||||
/// crates to disable `#[cfg(test)]` on
|
||||
|
@ -76,6 +76,7 @@ impl Sysroot {
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Expose a builder api as loading the sysroot got way too modular and complicated.
|
||||
impl Sysroot {
|
||||
/// Attempts to discover the toolchain's sysroot from the given `dir`.
|
||||
pub fn discover(dir: &AbsPath, extra_env: &FxHashMap<String, String>) -> Result<Sysroot> {
|
||||
@ -86,6 +87,16 @@ impl Sysroot {
|
||||
Ok(Sysroot::load(sysroot_dir, sysroot_src_dir))
|
||||
}
|
||||
|
||||
pub fn discover_with_src_override(
|
||||
dir: &AbsPath,
|
||||
extra_env: &FxHashMap<String, String>,
|
||||
src: AbsPathBuf,
|
||||
) -> Result<Sysroot> {
|
||||
tracing::debug!("discovering sysroot for {}", dir.display());
|
||||
let sysroot_dir = discover_sysroot_dir(dir, extra_env)?;
|
||||
Ok(Sysroot::load(sysroot_dir, src))
|
||||
}
|
||||
|
||||
pub fn discover_rustc(
|
||||
cargo_toml: &ManifestPath,
|
||||
extra_env: &FxHashMap<String, String>,
|
||||
|
@ -190,8 +190,8 @@ impl ProjectWorkspace {
|
||||
})?;
|
||||
let cargo = CargoWorkspace::new(meta);
|
||||
|
||||
let sysroot = match &config.sysroot {
|
||||
Some(RustcSource::Path(path)) => {
|
||||
let sysroot = match (&config.sysroot, &config.sysroot_src) {
|
||||
(Some(RustcSource::Path(path)), None) => {
|
||||
match Sysroot::with_sysroot_dir(path.clone()) {
|
||||
Ok(it) => Some(it),
|
||||
Err(e) => {
|
||||
@ -200,7 +200,7 @@ impl ProjectWorkspace {
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(RustcSource::Discover) => {
|
||||
(Some(RustcSource::Discover), None) => {
|
||||
match Sysroot::discover(cargo_toml.parent(), &config.extra_env) {
|
||||
Ok(it) => Some(it),
|
||||
Err(e) => {
|
||||
@ -213,8 +213,29 @@ impl ProjectWorkspace {
|
||||
}
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
(Some(RustcSource::Path(sysroot)), Some(sysroot_src)) => {
|
||||
Some(Sysroot::load(sysroot.clone(), sysroot_src.clone()))
|
||||
}
|
||||
(Some(RustcSource::Discover), Some(sysroot_src)) => {
|
||||
match Sysroot::discover_with_src_override(
|
||||
cargo_toml.parent(),
|
||||
&config.extra_env,
|
||||
sysroot_src.clone(),
|
||||
) {
|
||||
Ok(it) => Some(it),
|
||||
Err(e) => {
|
||||
tracing::error!(
|
||||
%e,
|
||||
"Failed to find sysroot for Cargo.toml file {}. Is rust-src installed?",
|
||||
cargo_toml.display()
|
||||
);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
(None, _) => None,
|
||||
};
|
||||
|
||||
if let Some(sysroot) = &sysroot {
|
||||
tracing::info!(src_root = %sysroot.src_root().display(), root = %sysroot.root().display(), "Using sysroot");
|
||||
}
|
||||
@ -440,9 +461,11 @@ impl ProjectWorkspace {
|
||||
/// The return type contains the path and whether or not
|
||||
/// the root is a member of the current workspace
|
||||
pub fn to_roots(&self) -> Vec<PackageRoot> {
|
||||
let mk_sysroot = |sysroot: Option<&Sysroot>| {
|
||||
let mk_sysroot = |sysroot: Option<&Sysroot>, project_root: Option<&AbsPath>| {
|
||||
sysroot.map(|sysroot| PackageRoot {
|
||||
is_local: false,
|
||||
// mark the sysroot as mutable if it is located inside of the project
|
||||
is_local: project_root
|
||||
.map_or(false, |project_root| sysroot.src_root().starts_with(project_root)),
|
||||
include: vec![sysroot.src_root().to_path_buf()],
|
||||
exclude: Vec::new(),
|
||||
})
|
||||
@ -457,7 +480,7 @@ impl ProjectWorkspace {
|
||||
})
|
||||
.collect::<FxHashSet<_>>()
|
||||
.into_iter()
|
||||
.chain(mk_sysroot(sysroot.as_ref()))
|
||||
.chain(mk_sysroot(sysroot.as_ref(), Some(project.path())))
|
||||
.collect::<Vec<_>>(),
|
||||
ProjectWorkspace::Cargo {
|
||||
cargo,
|
||||
@ -507,7 +530,7 @@ impl ProjectWorkspace {
|
||||
}
|
||||
PackageRoot { is_local, include, exclude }
|
||||
})
|
||||
.chain(mk_sysroot(sysroot.as_ref()))
|
||||
.chain(mk_sysroot(sysroot.as_ref(), Some(cargo.workspace_root())))
|
||||
.chain(rustc.iter().flat_map(|rustc| {
|
||||
rustc.packages().map(move |krate| PackageRoot {
|
||||
is_local: false,
|
||||
@ -524,7 +547,7 @@ impl ProjectWorkspace {
|
||||
include: vec![detached_file.clone()],
|
||||
exclude: Vec::new(),
|
||||
})
|
||||
.chain(mk_sysroot(sysroot.as_ref()))
|
||||
.chain(mk_sysroot(sysroot.as_ref(), None))
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
@ -117,6 +117,11 @@ config_data! {
|
||||
///
|
||||
/// This option does not take effect until rust-analyzer is restarted.
|
||||
cargo_sysroot: Option<String> = "\"discover\"",
|
||||
/// Relative path to the sysroot library sources. If left unset, this will default to
|
||||
/// `{cargo.sysroot}/lib/rustlib/src/rust/library`.
|
||||
///
|
||||
/// This option does not take effect until rust-analyzer is restarted.
|
||||
cargo_sysrootSrc: Option<String> = "null",
|
||||
/// Compilation target override (target triple).
|
||||
// FIXME(@poliorcetics): move to multiple targets here too, but this will need more work
|
||||
// than `checkOnSave_target`
|
||||
@ -1103,6 +1108,8 @@ impl Config {
|
||||
RustcSource::Path(self.root_path.join(sysroot))
|
||||
}
|
||||
});
|
||||
let sysroot_src =
|
||||
self.data.cargo_sysrootSrc.as_ref().map(|sysroot| self.root_path.join(sysroot));
|
||||
|
||||
CargoConfig {
|
||||
features: match &self.data.cargo_features {
|
||||
@ -1114,6 +1121,7 @@ impl Config {
|
||||
},
|
||||
target: self.data.cargo_target.clone(),
|
||||
sysroot,
|
||||
sysroot_src,
|
||||
rustc_source,
|
||||
unset_test_crates: UnsetTestCrates::Only(self.data.cargo_unsetTest.clone()),
|
||||
wrap_rustc_in_build_scripts: self.data.cargo_buildScripts_useRustcWrapper,
|
||||
|
@ -97,6 +97,14 @@ Relative path to the sysroot, or "discover" to try to automatically find it via
|
||||
|
||||
Unsetting this disables sysroot loading.
|
||||
|
||||
This option does not take effect until rust-analyzer is restarted.
|
||||
--
|
||||
[[rust-analyzer.cargo.sysrootSrc]]rust-analyzer.cargo.sysrootSrc (default: `null`)::
|
||||
+
|
||||
--
|
||||
Relative path to the sysroot library sources. If left unset, this will default to
|
||||
`{cargo.sysroot}/lib/rustlib/src/rust/library`.
|
||||
|
||||
This option does not take effect until rust-analyzer is restarted.
|
||||
--
|
||||
[[rust-analyzer.cargo.target]]rust-analyzer.cargo.target (default: `null`)::
|
||||
|
@ -539,6 +539,14 @@
|
||||
"string"
|
||||
]
|
||||
},
|
||||
"rust-analyzer.cargo.sysrootSrc": {
|
||||
"markdownDescription": "Relative path to the sysroot library sources. If left unset, this will default to\n`{cargo.sysroot}/lib/rustlib/src/rust/library`.\n\nThis option does not take effect until rust-analyzer is restarted.",
|
||||
"default": null,
|
||||
"type": [
|
||||
"null",
|
||||
"string"
|
||||
]
|
||||
},
|
||||
"rust-analyzer.cargo.target": {
|
||||
"markdownDescription": "Compilation target override (target triple).",
|
||||
"default": null,
|
||||
|
Loading…
x
Reference in New Issue
Block a user