mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-26 20:09:19 +00:00
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:
parent
3004f2ec90
commit
4924c24d91
3 changed files with 32 additions and 24 deletions
|
@ -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,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue