fix: resolve core::arch module

See https://users.rust-lang.org/t/rust-analyzer-unable-to-resolve-target-specific-module/63797/4?u=matklad

The fix is to put all sysroot crates into the same source root
This commit is contained in:
Aleksey Kladov 2021-08-20 16:56:02 +03:00
parent 3004f2ec90
commit 4924c24d91
3 changed files with 32 additions and 24 deletions

View file

@ -12,8 +12,9 @@ use paths::{AbsPath, AbsPathBuf};
use crate::{utf8_stdout, ManifestPath}; use crate::{utf8_stdout, ManifestPath};
#[derive(Default, Debug, Clone, Eq, PartialEq)] #[derive(Debug, Clone, Eq, PartialEq)]
pub struct Sysroot { pub struct Sysroot {
root: AbsPathBuf,
crates: Arena<SysrootCrateData>, crates: Arena<SysrootCrateData>,
} }
@ -34,6 +35,10 @@ impl ops::Index<SysrootCrate> for Sysroot {
} }
impl Sysroot { impl Sysroot {
pub fn root(&self) -> &AbsPath {
&self.root
}
pub fn public_deps(&self) -> impl Iterator<Item = (&'static str, SysrootCrate)> + '_ { pub fn public_deps(&self) -> impl Iterator<Item = (&'static str, SysrootCrate)> + '_ {
// core is added as a dependency before std in order to // core is added as a dependency before std in order to
// mimic rustcs dependency order // mimic rustcs dependency order
@ -52,7 +57,7 @@ impl Sysroot {
log::debug!("Discovering sysroot for {}", dir.display()); log::debug!("Discovering sysroot for {}", dir.display());
let sysroot_dir = discover_sysroot_dir(dir)?; let sysroot_dir = discover_sysroot_dir(dir)?;
let sysroot_src_dir = discover_sysroot_src_dir(&sysroot_dir, dir)?; let sysroot_src_dir = discover_sysroot_src_dir(&sysroot_dir, dir)?;
let res = Sysroot::load(&sysroot_src_dir)?; let res = Sysroot::load(sysroot_src_dir)?;
Ok(res) Ok(res)
} }
@ -62,14 +67,14 @@ impl Sysroot {
discover_sysroot_dir(current_dir).ok().and_then(|sysroot_dir| get_rustc_src(&sysroot_dir)) discover_sysroot_dir(current_dir).ok().and_then(|sysroot_dir| get_rustc_src(&sysroot_dir))
} }
pub fn load(sysroot_src_dir: &AbsPath) -> Result<Sysroot> { pub fn load(sysroot_src_dir: AbsPathBuf) -> Result<Sysroot> {
let mut sysroot = Sysroot { crates: Arena::default() }; let mut sysroot = Sysroot { root: sysroot_src_dir, crates: Arena::default() };
for path in SYSROOT_CRATES.trim().lines() { for path in SYSROOT_CRATES.trim().lines() {
let name = path.split('/').last().unwrap(); let name = path.split('/').last().unwrap();
let root = [format!("{}/src/lib.rs", path), format!("lib{}/lib.rs", path)] let root = [format!("{}/src/lib.rs", path), format!("lib{}/lib.rs", path)]
.iter() .iter()
.map(|it| sysroot_src_dir.join(it)) .map(|it| sysroot.root.join(it))
.filter_map(|it| ManifestPath::try_from(it).ok()) .filter_map(|it| ManifestPath::try_from(it).ok())
.find(|it| fs::metadata(it).is_ok()); .find(|it| fs::metadata(it).is_ok());
@ -110,7 +115,7 @@ impl Sysroot {
}; };
anyhow::bail!( anyhow::bail!(
"could not find libcore in sysroot path `{}`{}", "could not find libcore in sysroot path `{}`{}",
sysroot_src_dir.as_ref().display(), sysroot.root.as_path().display(),
var_note, var_note,
); );
} }

View file

@ -5,7 +5,7 @@ use std::{
use base_db::{CrateGraph, FileId}; use base_db::{CrateGraph, FileId};
use expect_test::{expect, Expect}; use expect_test::{expect, Expect};
use paths::AbsPath; use paths::{AbsPath, AbsPathBuf};
use serde::de::DeserializeOwned; use serde::de::DeserializeOwned;
use crate::{ use crate::{
@ -19,7 +19,7 @@ fn load_cargo(file: &str) -> CrateGraph {
let project_workspace = ProjectWorkspace::Cargo { let project_workspace = ProjectWorkspace::Cargo {
cargo: cargo_workspace, cargo: cargo_workspace,
build_scripts: WorkspaceBuildScripts::default(), build_scripts: WorkspaceBuildScripts::default(),
sysroot: Sysroot::default(), sysroot: None,
rustc: None, rustc: None,
rustc_cfg: Vec::new(), rustc_cfg: Vec::new(),
cfg_overrides: CfgOverrides::default(), cfg_overrides: CfgOverrides::default(),
@ -71,8 +71,8 @@ fn get_test_path(file: &str) -> PathBuf {
fn get_fake_sysroot() -> Sysroot { fn get_fake_sysroot() -> Sysroot {
let sysroot_path = get_test_path("fake-sysroot"); let sysroot_path = get_test_path("fake-sysroot");
let sysroot_src_dir = AbsPath::assert(&sysroot_path); let sysroot_src_dir = AbsPathBuf::assert(sysroot_path);
Sysroot::load(&sysroot_src_dir).unwrap() Sysroot::load(sysroot_src_dir).unwrap()
} }
fn rooted_project_json(data: ProjectJsonData) -> ProjectJson { fn rooted_project_json(data: ProjectJsonData) -> ProjectJson {

View file

@ -41,7 +41,7 @@ pub enum ProjectWorkspace {
Cargo { Cargo {
cargo: CargoWorkspace, cargo: CargoWorkspace,
build_scripts: WorkspaceBuildScripts, build_scripts: WorkspaceBuildScripts,
sysroot: Sysroot, sysroot: Option<Sysroot>,
rustc: Option<CargoWorkspace>, rustc: Option<CargoWorkspace>,
/// Holds cfg flags for the current target. We get those by running /// Holds cfg flags for the current target. We get those by running
/// `rustc --print cfg`. /// `rustc --print cfg`.
@ -82,7 +82,7 @@ impl fmt::Debug for ProjectWorkspace {
.debug_struct("Cargo") .debug_struct("Cargo")
.field("root", &cargo.workspace_root().file_name()) .field("root", &cargo.workspace_root().file_name())
.field("n_packages", &cargo.packages().len()) .field("n_packages", &cargo.packages().len())
.field("n_sysroot_crates", &sysroot.crates().len()) .field("sysroot", &sysroot.is_some())
.field( .field(
"n_rustc_compiler_crates", "n_rustc_compiler_crates",
&rustc.as_ref().map_or(0, |rc| rc.packages().len()), &rustc.as_ref().map_or(0, |rc| rc.packages().len()),
@ -145,14 +145,14 @@ impl ProjectWorkspace {
let cargo = CargoWorkspace::new(meta); let cargo = CargoWorkspace::new(meta);
let sysroot = if config.no_sysroot { let sysroot = if config.no_sysroot {
Sysroot::default() None
} else { } else {
Sysroot::discover(cargo_toml.parent()).with_context(|| { Some(Sysroot::discover(cargo_toml.parent()).with_context(|| {
format!( format!(
"Failed to find sysroot for Cargo.toml file {}. Is rust-src installed?", "Failed to find sysroot for Cargo.toml file {}. Is rust-src installed?",
cargo_toml.display() cargo_toml.display()
) )
})? })?)
}; };
let rustc_dir = match &config.rustc_source { let rustc_dir = match &config.rustc_source {
@ -194,7 +194,7 @@ impl ProjectWorkspace {
target: Option<&str>, target: Option<&str>,
) -> Result<ProjectWorkspace> { ) -> Result<ProjectWorkspace> {
let sysroot = match &project_json.sysroot_src { let sysroot = match &project_json.sysroot_src {
Some(path) => Some(Sysroot::load(path)?), Some(path) => Some(Sysroot::load(path.clone())?),
None => None, None => None,
}; };
let rustc_cfg = rustc_cfg::get(None, target); let rustc_cfg = rustc_cfg::get(None, target);
@ -304,9 +304,9 @@ impl ProjectWorkspace {
} }
PackageRoot { is_member, include, exclude } PackageRoot { is_member, include, exclude }
}) })
.chain(sysroot.crates().map(|krate| PackageRoot { .chain(sysroot.into_iter().map(|sysroot| PackageRoot {
is_member: false, is_member: false,
include: vec![sysroot[krate].root.parent().to_path_buf()], include: vec![sysroot.root().to_path_buf()],
exclude: Vec::new(), exclude: Vec::new(),
})) }))
.chain(rustc.into_iter().flat_map(|rustc| { .chain(rustc.into_iter().flat_map(|rustc| {
@ -338,8 +338,9 @@ impl ProjectWorkspace {
match self { match self {
ProjectWorkspace::Json { project, .. } => project.n_crates(), ProjectWorkspace::Json { project, .. } => project.n_crates(),
ProjectWorkspace::Cargo { cargo, sysroot, rustc, .. } => { ProjectWorkspace::Cargo { cargo, sysroot, rustc, .. } => {
let rustc_package_len = rustc.as_ref().map_or(0, |rc| rc.packages().len()); let rustc_package_len = rustc.as_ref().map_or(0, |it| it.packages().len());
cargo.packages().len() + sysroot.crates().len() + rustc_package_len let sysroot_package_len = sysroot.as_ref().map_or(0, |it| it.crates().len());
cargo.packages().len() + sysroot_package_len + rustc_package_len
} }
ProjectWorkspace::DetachedFiles { sysroot, files, .. } => { ProjectWorkspace::DetachedFiles { sysroot, files, .. } => {
sysroot.crates().len() + files.len() sysroot.crates().len() + files.len()
@ -380,7 +381,7 @@ impl ProjectWorkspace {
load, load,
cargo, cargo,
build_scripts, build_scripts,
sysroot, sysroot.as_ref(),
rustc, rustc,
), ),
ProjectWorkspace::DetachedFiles { files, sysroot, rustc_cfg } => { ProjectWorkspace::DetachedFiles { files, sysroot, rustc_cfg } => {
@ -479,13 +480,15 @@ fn cargo_to_crate_graph(
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>, load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
cargo: &CargoWorkspace, cargo: &CargoWorkspace,
build_scripts: &WorkspaceBuildScripts, build_scripts: &WorkspaceBuildScripts,
sysroot: &Sysroot, sysroot: Option<&Sysroot>,
rustc: &Option<CargoWorkspace>, rustc: &Option<CargoWorkspace>,
) -> CrateGraph { ) -> CrateGraph {
let _p = profile::span("cargo_to_crate_graph"); let _p = profile::span("cargo_to_crate_graph");
let mut crate_graph = CrateGraph::default(); let mut crate_graph = CrateGraph::default();
let (public_deps, libproc_macro) = let (public_deps, libproc_macro) = match sysroot {
sysroot_to_crate_graph(&mut crate_graph, sysroot, rustc_cfg.clone(), load); Some(sysroot) => sysroot_to_crate_graph(&mut crate_graph, sysroot, rustc_cfg.clone(), load),
None => (Vec::new(), None),
};
let mut cfg_options = CfgOptions::default(); let mut cfg_options = CfgOptions::default();
cfg_options.extend(rustc_cfg); cfg_options.extend(rustc_cfg);