From 4924c24d91c768a232c159d884c0947e847a6bad Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 20 Aug 2021 16:56:02 +0300 Subject: [PATCH] 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 --- crates/project_model/src/sysroot.rs | 17 +++++++++------ crates/project_model/src/tests.rs | 8 +++---- crates/project_model/src/workspace.rs | 31 +++++++++++++++------------ 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/crates/project_model/src/sysroot.rs b/crates/project_model/src/sysroot.rs index fec606e729..946b79d176 100644 --- a/crates/project_model/src/sysroot.rs +++ b/crates/project_model/src/sysroot.rs @@ -12,8 +12,9 @@ use paths::{AbsPath, AbsPathBuf}; use crate::{utf8_stdout, ManifestPath}; -#[derive(Default, Debug, Clone, Eq, PartialEq)] +#[derive(Debug, Clone, Eq, PartialEq)] pub struct Sysroot { + root: AbsPathBuf, crates: Arena, } @@ -34,6 +35,10 @@ impl ops::Index for Sysroot { } impl Sysroot { + pub fn root(&self) -> &AbsPath { + &self.root + } + pub fn public_deps(&self) -> impl Iterator + '_ { // core is added as a dependency before std in order to // mimic rustcs dependency order @@ -52,7 +57,7 @@ impl Sysroot { log::debug!("Discovering sysroot for {}", dir.display()); let sysroot_dir = discover_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) } @@ -62,14 +67,14 @@ impl Sysroot { discover_sysroot_dir(current_dir).ok().and_then(|sysroot_dir| get_rustc_src(&sysroot_dir)) } - pub fn load(sysroot_src_dir: &AbsPath) -> Result { - let mut sysroot = Sysroot { crates: Arena::default() }; + pub fn load(sysroot_src_dir: AbsPathBuf) -> Result { + let mut sysroot = Sysroot { root: sysroot_src_dir, crates: Arena::default() }; for path in SYSROOT_CRATES.trim().lines() { let name = path.split('/').last().unwrap(); let root = [format!("{}/src/lib.rs", path), format!("lib{}/lib.rs", path)] .iter() - .map(|it| sysroot_src_dir.join(it)) + .map(|it| sysroot.root.join(it)) .filter_map(|it| ManifestPath::try_from(it).ok()) .find(|it| fs::metadata(it).is_ok()); @@ -110,7 +115,7 @@ impl Sysroot { }; anyhow::bail!( "could not find libcore in sysroot path `{}`{}", - sysroot_src_dir.as_ref().display(), + sysroot.root.as_path().display(), var_note, ); } diff --git a/crates/project_model/src/tests.rs b/crates/project_model/src/tests.rs index b50db6f3b8..d13b968cc1 100644 --- a/crates/project_model/src/tests.rs +++ b/crates/project_model/src/tests.rs @@ -5,7 +5,7 @@ use std::{ use base_db::{CrateGraph, FileId}; use expect_test::{expect, Expect}; -use paths::AbsPath; +use paths::{AbsPath, AbsPathBuf}; use serde::de::DeserializeOwned; use crate::{ @@ -19,7 +19,7 @@ fn load_cargo(file: &str) -> CrateGraph { let project_workspace = ProjectWorkspace::Cargo { cargo: cargo_workspace, build_scripts: WorkspaceBuildScripts::default(), - sysroot: Sysroot::default(), + sysroot: None, rustc: None, rustc_cfg: Vec::new(), cfg_overrides: CfgOverrides::default(), @@ -71,8 +71,8 @@ fn get_test_path(file: &str) -> PathBuf { fn get_fake_sysroot() -> Sysroot { let sysroot_path = get_test_path("fake-sysroot"); - let sysroot_src_dir = AbsPath::assert(&sysroot_path); - Sysroot::load(&sysroot_src_dir).unwrap() + let sysroot_src_dir = AbsPathBuf::assert(sysroot_path); + Sysroot::load(sysroot_src_dir).unwrap() } fn rooted_project_json(data: ProjectJsonData) -> ProjectJson { diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs index 898df83d62..e11ca61afa 100644 --- a/crates/project_model/src/workspace.rs +++ b/crates/project_model/src/workspace.rs @@ -41,7 +41,7 @@ pub enum ProjectWorkspace { Cargo { cargo: CargoWorkspace, build_scripts: WorkspaceBuildScripts, - sysroot: Sysroot, + sysroot: Option, rustc: Option, /// Holds cfg flags for the current target. We get those by running /// `rustc --print cfg`. @@ -82,7 +82,7 @@ impl fmt::Debug for ProjectWorkspace { .debug_struct("Cargo") .field("root", &cargo.workspace_root().file_name()) .field("n_packages", &cargo.packages().len()) - .field("n_sysroot_crates", &sysroot.crates().len()) + .field("sysroot", &sysroot.is_some()) .field( "n_rustc_compiler_crates", &rustc.as_ref().map_or(0, |rc| rc.packages().len()), @@ -145,14 +145,14 @@ impl ProjectWorkspace { let cargo = CargoWorkspace::new(meta); let sysroot = if config.no_sysroot { - Sysroot::default() + None } else { - Sysroot::discover(cargo_toml.parent()).with_context(|| { + Some(Sysroot::discover(cargo_toml.parent()).with_context(|| { format!( "Failed to find sysroot for Cargo.toml file {}. Is rust-src installed?", cargo_toml.display() ) - })? + })?) }; let rustc_dir = match &config.rustc_source { @@ -194,7 +194,7 @@ impl ProjectWorkspace { target: Option<&str>, ) -> Result { let sysroot = match &project_json.sysroot_src { - Some(path) => Some(Sysroot::load(path)?), + Some(path) => Some(Sysroot::load(path.clone())?), None => None, }; let rustc_cfg = rustc_cfg::get(None, target); @@ -304,9 +304,9 @@ impl ProjectWorkspace { } PackageRoot { is_member, include, exclude } }) - .chain(sysroot.crates().map(|krate| PackageRoot { + .chain(sysroot.into_iter().map(|sysroot| PackageRoot { is_member: false, - include: vec![sysroot[krate].root.parent().to_path_buf()], + include: vec![sysroot.root().to_path_buf()], exclude: Vec::new(), })) .chain(rustc.into_iter().flat_map(|rustc| { @@ -338,8 +338,9 @@ impl ProjectWorkspace { match self { ProjectWorkspace::Json { project, .. } => project.n_crates(), ProjectWorkspace::Cargo { cargo, sysroot, rustc, .. } => { - let rustc_package_len = rustc.as_ref().map_or(0, |rc| rc.packages().len()); - cargo.packages().len() + sysroot.crates().len() + rustc_package_len + let rustc_package_len = rustc.as_ref().map_or(0, |it| it.packages().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, .. } => { sysroot.crates().len() + files.len() @@ -380,7 +381,7 @@ impl ProjectWorkspace { load, cargo, build_scripts, - sysroot, + sysroot.as_ref(), rustc, ), ProjectWorkspace::DetachedFiles { files, sysroot, rustc_cfg } => { @@ -479,13 +480,15 @@ fn cargo_to_crate_graph( load: &mut dyn FnMut(&AbsPath) -> Option, cargo: &CargoWorkspace, build_scripts: &WorkspaceBuildScripts, - sysroot: &Sysroot, + sysroot: Option<&Sysroot>, rustc: &Option, ) -> CrateGraph { let _p = profile::span("cargo_to_crate_graph"); let mut crate_graph = CrateGraph::default(); - let (public_deps, libproc_macro) = - sysroot_to_crate_graph(&mut crate_graph, sysroot, rustc_cfg.clone(), load); + let (public_deps, libproc_macro) = match sysroot { + Some(sysroot) => sysroot_to_crate_graph(&mut crate_graph, sysroot, rustc_cfg.clone(), load), + None => (Vec::new(), None), + }; let mut cfg_options = CfgOptions::default(); cfg_options.extend(rustc_cfg);