Handle sysroot config in detached-files workspaces

This commit is contained in:
Lukas Wirth 2022-11-24 10:21:19 +01:00
parent e162d5800a
commit 2300c9de83
2 changed files with 42 additions and 22 deletions

View file

@ -93,7 +93,7 @@ pub enum ProjectWorkspace {
// // // //
/// Project with a set of disjoint files, not belonging to any particular workspace. /// Project with a set of disjoint files, not belonging to any particular workspace.
/// Backed by basic sysroot crates for basic completion and highlighting. /// Backed by basic sysroot crates for basic completion and highlighting.
DetachedFiles { files: Vec<AbsPathBuf>, sysroot: Sysroot, rustc_cfg: Vec<CfgFlag> }, DetachedFiles { files: Vec<AbsPathBuf>, sysroot: Option<Sysroot>, rustc_cfg: Vec<CfgFlag> },
} }
impl fmt::Debug for ProjectWorkspace { impl fmt::Debug for ProjectWorkspace {
@ -133,7 +133,7 @@ impl fmt::Debug for ProjectWorkspace {
ProjectWorkspace::DetachedFiles { files, sysroot, rustc_cfg } => f ProjectWorkspace::DetachedFiles { files, sysroot, rustc_cfg } => f
.debug_struct("DetachedFiles") .debug_struct("DetachedFiles")
.field("n_files", &files.len()) .field("n_files", &files.len())
.field("n_sysroot_crates", &sysroot.crates().len()) .field("sysroot", &sysroot.is_some())
.field("n_rustc_cfg", &rustc_cfg.len()) .field("n_rustc_cfg", &rustc_cfg.len())
.finish(), .finish(),
} }
@ -191,10 +191,7 @@ impl ProjectWorkspace {
let sysroot = match &config.sysroot { let sysroot = match &config.sysroot {
Some(RustcSource::Path(path)) => { Some(RustcSource::Path(path)) => {
Some(Sysroot::with_sysroot_dir(path.clone()).with_context(|| { Some(Sysroot::with_sysroot_dir(path.clone()).with_context(|| {
format!( format!("Failed to find sysroot at {}.", path.display())
"Failed to find sysroot for Cargo.toml file {}.",
cargo_toml.display()
)
})?) })?)
} }
Some(RustcSource::Discover) => Some( Some(RustcSource::Discover) => Some(
@ -291,14 +288,29 @@ impl ProjectWorkspace {
Ok(ProjectWorkspace::Json { project: project_json, sysroot, rustc_cfg }) Ok(ProjectWorkspace::Json { project: project_json, sysroot, rustc_cfg })
} }
pub fn load_detached_files(detached_files: Vec<AbsPathBuf>) -> Result<ProjectWorkspace> { pub fn load_detached_files(
let sysroot = Sysroot::discover( detached_files: Vec<AbsPathBuf>,
detached_files config: &CargoConfig,
.first() ) -> Result<ProjectWorkspace> {
.and_then(|it| it.parent()) let sysroot = match &config.sysroot {
.ok_or_else(|| format_err!("No detached files to load"))?, Some(RustcSource::Path(path)) => Some(
&Default::default(), Sysroot::with_sysroot_dir(path.clone())
)?; .with_context(|| format!("Failed to find sysroot at {}.", path.display()))?,
),
Some(RustcSource::Discover) => {
let dir = &detached_files
.first()
.and_then(|it| it.parent())
.ok_or_else(|| format_err!("No detached files to load"))?;
Some(Sysroot::discover(dir, &config.extra_env).with_context(|| {
format!("Failed to find sysroot in {}. Is rust-src installed?", dir.display())
})?)
}
None => None,
};
if let Some(sysroot) = &sysroot {
tracing::info!(src_root = %sysroot.src_root().display(), root = %sysroot.root().display(), "Using sysroot");
}
let rustc_cfg = rustc_cfg::get(None, None, &Default::default()); let rustc_cfg = rustc_cfg::get(None, None, &Default::default());
Ok(ProjectWorkspace::DetachedFiles { files: detached_files, sysroot, rustc_cfg }) Ok(ProjectWorkspace::DetachedFiles { files: detached_files, sysroot, rustc_cfg })
} }
@ -464,21 +476,25 @@ impl ProjectWorkspace {
include: vec![detached_file.clone()], include: vec![detached_file.clone()],
exclude: Vec::new(), exclude: Vec::new(),
}) })
.chain(mk_sysroot(Some(sysroot))) .chain(mk_sysroot(sysroot.as_ref()))
.collect(), .collect(),
} }
} }
pub fn n_packages(&self) -> usize { pub fn n_packages(&self) -> usize {
match self { match self {
ProjectWorkspace::Json { project, .. } => project.n_crates(), ProjectWorkspace::Json { project, sysroot, .. } => {
let sysroot_package_len = sysroot.as_ref().map_or(0, |it| it.crates().len());
sysroot_package_len + project.n_crates()
}
ProjectWorkspace::Cargo { cargo, sysroot, rustc, .. } => { ProjectWorkspace::Cargo { cargo, sysroot, rustc, .. } => {
let rustc_package_len = rustc.as_ref().map_or(0, |it| it.packages().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()); let sysroot_package_len = sysroot.as_ref().map_or(0, |it| it.crates().len());
cargo.packages().len() + sysroot_package_len + rustc_package_len cargo.packages().len() + sysroot_package_len + rustc_package_len
} }
ProjectWorkspace::DetachedFiles { sysroot, files, .. } => { ProjectWorkspace::DetachedFiles { sysroot, files, .. } => {
sysroot.crates().len() + files.len() let sysroot_package_len = sysroot.as_ref().map_or(0, |it| it.crates().len());
sysroot_package_len + files.len()
} }
} }
} }
@ -790,12 +806,14 @@ fn detached_files_to_crate_graph(
rustc_cfg: Vec<CfgFlag>, rustc_cfg: Vec<CfgFlag>,
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>, load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
detached_files: &[AbsPathBuf], detached_files: &[AbsPathBuf],
sysroot: &Sysroot, sysroot: &Option<Sysroot>,
) -> CrateGraph { ) -> CrateGraph {
let _p = profile::span("detached_files_to_crate_graph"); let _p = profile::span("detached_files_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 => (SysrootPublicDeps::default(), None),
};
let mut cfg_options = CfgOptions::default(); let mut cfg_options = CfgOptions::default();
cfg_options.extend(rustc_cfg); cfg_options.extend(rustc_cfg);

View file

@ -158,8 +158,10 @@ impl GlobalState {
.collect::<Vec<_>>(); .collect::<Vec<_>>();
if !detached_files.is_empty() { if !detached_files.is_empty() {
workspaces workspaces.push(project_model::ProjectWorkspace::load_detached_files(
.push(project_model::ProjectWorkspace::load_detached_files(detached_files)); detached_files,
&cargo_config,
));
} }
tracing::info!("did fetch workspaces {:?}", workspaces); tracing::info!("did fetch workspaces {:?}", workspaces);