This commit is contained in:
Lukas Wirth 2022-09-20 14:33:18 +02:00
parent a6c067c06d
commit 7e8eac3fd7
2 changed files with 31 additions and 36 deletions

View File

@ -115,7 +115,7 @@ pub(super) struct SourceToDefCtx<'a, 'b> {
} }
impl SourceToDefCtx<'_, '_> { impl SourceToDefCtx<'_, '_> {
pub(super) fn file_to_def(&mut self, file: FileId) -> SmallVec<[ModuleId; 1]> { pub(super) fn file_to_def(&self, file: FileId) -> SmallVec<[ModuleId; 1]> {
let _p = profile::span("SourceBinder::to_module_def"); let _p = profile::span("SourceBinder::to_module_def");
let mut mods = SmallVec::new(); let mut mods = SmallVec::new();
for &crate_id in self.db.relevant_crates(file).iter() { for &crate_id in self.db.relevant_crates(file).iter() {
@ -130,7 +130,7 @@ impl SourceToDefCtx<'_, '_> {
mods mods
} }
pub(super) fn module_to_def(&mut self, src: InFile<ast::Module>) -> Option<ModuleId> { pub(super) fn module_to_def(&self, src: InFile<ast::Module>) -> Option<ModuleId> {
let _p = profile::span("module_to_def"); let _p = profile::span("module_to_def");
let parent_declaration = src let parent_declaration = src
.syntax() .syntax()
@ -151,7 +151,7 @@ pub(super) fn module_to_def(&mut self, src: InFile<ast::Module>) -> Option<Modul
Some(def_map.module_id(child_id)) Some(def_map.module_id(child_id))
} }
pub(super) fn source_file_to_def(&mut self, src: InFile<ast::SourceFile>) -> Option<ModuleId> { pub(super) fn source_file_to_def(&self, src: InFile<ast::SourceFile>) -> Option<ModuleId> {
let _p = profile::span("source_file_to_def"); let _p = profile::span("source_file_to_def");
let file_id = src.file_id.original_file(self.db.upcast()); let file_id = src.file_id.original_file(self.db.upcast());
self.file_to_def(file_id).get(0).copied() self.file_to_def(file_id).get(0).copied()

View File

@ -21,8 +21,8 @@
cfg_flag::CfgFlag, cfg_flag::CfgFlag,
rustc_cfg, rustc_cfg,
sysroot::SysrootCrate, sysroot::SysrootCrate,
utf8_stdout, CargoConfig, CargoWorkspace, ManifestPath, ProjectJson, ProjectManifest, Sysroot, utf8_stdout, CargoConfig, CargoWorkspace, ManifestPath, Package, ProjectJson, ProjectManifest,
TargetKind, WorkspaceBuildScripts, Sysroot, TargetKind, WorkspaceBuildScripts,
}; };
/// A set of cfg-overrides per crate. /// A set of cfg-overrides per crate.
@ -315,6 +315,13 @@ pub fn set_build_scripts(&mut self, bs: WorkspaceBuildScripts) {
/// The return type contains the path and whether or not /// The return type contains the path and whether or not
/// the root is a member of the current workspace /// the root is a member of the current workspace
pub fn to_roots(&self) -> Vec<PackageRoot> { pub fn to_roots(&self) -> Vec<PackageRoot> {
let mk_sysroot = |sysroot: Option<&Sysroot>| {
sysroot.map(|sysroot| PackageRoot {
is_local: false,
include: vec![sysroot.src_root().to_path_buf()],
exclude: Vec::new(),
})
};
match self { match self {
ProjectWorkspace::Json { project, sysroot, rustc_cfg: _ } => project ProjectWorkspace::Json { project, sysroot, rustc_cfg: _ } => project
.crates() .crates()
@ -325,13 +332,7 @@ pub fn to_roots(&self) -> Vec<PackageRoot> {
}) })
.collect::<FxHashSet<_>>() .collect::<FxHashSet<_>>()
.into_iter() .into_iter()
.chain(sysroot.as_ref().into_iter().flat_map(|sysroot| { .chain(mk_sysroot(sysroot.as_ref()))
sysroot.crates().map(move |krate| PackageRoot {
is_local: false,
include: vec![sysroot[krate].root.parent().to_path_buf()],
exclude: Vec::new(),
})
}))
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
ProjectWorkspace::Cargo { ProjectWorkspace::Cargo {
cargo, cargo,
@ -380,11 +381,7 @@ pub fn to_roots(&self) -> Vec<PackageRoot> {
} }
PackageRoot { is_local, include, exclude } PackageRoot { is_local, include, exclude }
}) })
.chain(sysroot.iter().map(|sysroot| PackageRoot { .chain(mk_sysroot(sysroot.as_ref()))
is_local: false,
include: vec![sysroot.src_root().to_path_buf()],
exclude: Vec::new(),
}))
.chain(rustc.iter().flat_map(|rustc| { .chain(rustc.iter().flat_map(|rustc| {
rustc.packages().map(move |krate| PackageRoot { rustc.packages().map(move |krate| PackageRoot {
is_local: false, is_local: false,
@ -401,11 +398,7 @@ pub fn to_roots(&self) -> Vec<PackageRoot> {
include: vec![detached_file.clone()], include: vec![detached_file.clone()],
exclude: Vec::new(), exclude: Vec::new(),
}) })
.chain(sysroot.crates().map(|krate| PackageRoot { .chain(mk_sysroot(Some(sysroot)))
is_local: false,
include: vec![sysroot[krate].root.parent().to_path_buf()],
exclude: Vec::new(),
}))
.collect(), .collect(),
} }
} }
@ -639,6 +632,8 @@ fn cargo_to_crate_graph(
lib_tgt = Some((crate_id, cargo[tgt].name.clone())); lib_tgt = Some((crate_id, cargo[tgt].name.clone()));
pkg_to_lib_crate.insert(pkg, crate_id); pkg_to_lib_crate.insert(pkg, crate_id);
} }
// Even crates that don't set proc-macro = true are allowed to depend on proc_macro
// (just none of the APIs work when called outside of a proc macro).
if let Some(proc_macro) = libproc_macro { if let Some(proc_macro) = libproc_macro {
add_dep_with_prelude( add_dep_with_prelude(
&mut crate_graph, &mut crate_graph,
@ -654,19 +649,19 @@ fn cargo_to_crate_graph(
} }
// Set deps to the core, std and to the lib target of the current package // Set deps to the core, std and to the lib target of the current package
for (from, kind) in pkg_crates.get(&pkg).into_iter().flatten() { for &(from, kind) in pkg_crates.get(&pkg).into_iter().flatten() {
// Add sysroot deps first so that a lib target named `core` etc. can overwrite them. // Add sysroot deps first so that a lib target named `core` etc. can overwrite them.
public_deps.add(*from, &mut crate_graph); public_deps.add(from, &mut crate_graph);
if let Some((to, name)) = lib_tgt.clone() { if let Some((to, name)) = lib_tgt.clone() {
if to != *from && *kind != TargetKind::BuildScript { if to != from && kind != TargetKind::BuildScript {
// (build script can not depend on its library target) // (build script can not depend on its library target)
// For root projects with dashes in their name, // For root projects with dashes in their name,
// cargo metadata does not do any normalization, // cargo metadata does not do any normalization,
// so we do it ourselves currently // so we do it ourselves currently
let name = CrateName::normalize_dashes(&name); let name = CrateName::normalize_dashes(&name);
add_dep(&mut crate_graph, *from, name, to); add_dep(&mut crate_graph, from, name, to);
} }
} }
} }
@ -678,17 +673,17 @@ fn cargo_to_crate_graph(
for dep in cargo[pkg].dependencies.iter() { for dep in cargo[pkg].dependencies.iter() {
let name = CrateName::new(&dep.name).unwrap(); let name = CrateName::new(&dep.name).unwrap();
if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) { if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) {
for (from, kind) in pkg_crates.get(&pkg).into_iter().flatten() { for &(from, kind) in pkg_crates.get(&pkg).into_iter().flatten() {
if dep.kind == DepKind::Build && *kind != TargetKind::BuildScript { if dep.kind == DepKind::Build && kind != TargetKind::BuildScript {
// Only build scripts may depend on build dependencies. // Only build scripts may depend on build dependencies.
continue; continue;
} }
if dep.kind != DepKind::Build && *kind == TargetKind::BuildScript { if dep.kind != DepKind::Build && kind == TargetKind::BuildScript {
// Build scripts may only depend on build dependencies. // Build scripts may only depend on build dependencies.
continue; continue;
} }
add_dep(&mut crate_graph, *from, name.clone(), to) add_dep(&mut crate_graph, from, name.clone(), to)
} }
} }
} }
@ -699,9 +694,9 @@ fn cargo_to_crate_graph(
// and create dependencies on them for the crates which opt-in to that // and create dependencies on them for the crates which opt-in to that
if let Some(rustc_workspace) = rustc { if let Some(rustc_workspace) = rustc {
handle_rustc_crates( handle_rustc_crates(
&mut crate_graph,
rustc_workspace, rustc_workspace,
load, load,
&mut crate_graph,
&cfg_options, &cfg_options,
override_cfg, override_cfg,
load_proc_macro, load_proc_macro,
@ -761,16 +756,16 @@ fn detached_files_to_crate_graph(
} }
fn handle_rustc_crates( fn handle_rustc_crates(
crate_graph: &mut CrateGraph,
rustc_workspace: &CargoWorkspace, rustc_workspace: &CargoWorkspace,
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>, load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
crate_graph: &mut CrateGraph,
cfg_options: &CfgOptions, cfg_options: &CfgOptions,
override_cfg: &CfgOverrides, override_cfg: &CfgOverrides,
load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> ProcMacroLoadResult, load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> ProcMacroLoadResult,
pkg_to_lib_crate: &mut FxHashMap<la_arena::Idx<crate::PackageData>, CrateId>, pkg_to_lib_crate: &mut FxHashMap<Package, CrateId>,
public_deps: &SysrootPublicDeps, public_deps: &SysrootPublicDeps,
cargo: &CargoWorkspace, cargo: &CargoWorkspace,
pkg_crates: &FxHashMap<la_arena::Idx<crate::PackageData>, Vec<(CrateId, TargetKind)>>, pkg_crates: &FxHashMap<Package, Vec<(CrateId, TargetKind)>>,
build_scripts: &WorkspaceBuildScripts, build_scripts: &WorkspaceBuildScripts,
) { ) {
let mut rustc_pkg_crates = FxHashMap::default(); let mut rustc_pkg_crates = FxHashMap::default();
@ -784,8 +779,8 @@ fn handle_rustc_crates(
let mut queue = VecDeque::new(); let mut queue = VecDeque::new();
queue.push_back(root_pkg); queue.push_back(root_pkg);
while let Some(pkg) = queue.pop_front() { while let Some(pkg) = queue.pop_front() {
// Don't duplicate packages if they are dependended on a diamond pattern // Don't duplicate packages if they are dependent on a diamond pattern
// N.B. if this line is omitted, we try to analyse over 4_800_000 crates // N.B. if this line is omitted, we try to analyze over 4_800_000 crates
// which is not ideal // which is not ideal
if rustc_pkg_crates.contains_key(&pkg) { if rustc_pkg_crates.contains_key(&pkg) {
continue; continue;