mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 05:23:24 +00:00
Merge #5878
5878: Prepare to share sysroot lowering code between Cargo & ProjectJSON
r=matklad a=matklad
bors r+
🤖
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
3f721683de
2 changed files with 73 additions and 105 deletions
|
@ -335,45 +335,8 @@ impl ProjectWorkspace {
|
||||||
let mut cfg_options = CfgOptions::default();
|
let mut cfg_options = CfgOptions::default();
|
||||||
cfg_options.extend(get_rustc_cfg_options(target));
|
cfg_options.extend(get_rustc_cfg_options(target));
|
||||||
|
|
||||||
let sysroot_crates: FxHashMap<_, _> = sysroot
|
let (public_deps, libproc_macro) =
|
||||||
.crates()
|
sysroot_to_crate_graph(&mut crate_graph, sysroot, &cfg_options, load);
|
||||||
.filter_map(|krate| {
|
|
||||||
let file_id = load(&sysroot[krate].root)?;
|
|
||||||
|
|
||||||
let env = Env::default();
|
|
||||||
let proc_macro = vec![];
|
|
||||||
let name = sysroot[krate].name.clone();
|
|
||||||
let crate_id = crate_graph.add_crate_root(
|
|
||||||
file_id,
|
|
||||||
Edition::Edition2018,
|
|
||||||
Some(name),
|
|
||||||
cfg_options.clone(),
|
|
||||||
env,
|
|
||||||
proc_macro,
|
|
||||||
);
|
|
||||||
Some((krate, crate_id))
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
for from in sysroot.crates() {
|
|
||||||
for &to in sysroot[from].deps.iter() {
|
|
||||||
let name = &sysroot[to].name;
|
|
||||||
if let (Some(&from), Some(&to)) =
|
|
||||||
(sysroot_crates.get(&from), sysroot_crates.get(&to))
|
|
||||||
{
|
|
||||||
if crate_graph.add_dep(from, CrateName::new(name).unwrap(), to).is_err()
|
|
||||||
{
|
|
||||||
log::error!("cyclic dependency between sysroot crates")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let libcore = sysroot.core().and_then(|it| sysroot_crates.get(&it).copied());
|
|
||||||
let liballoc = sysroot.alloc().and_then(|it| sysroot_crates.get(&it).copied());
|
|
||||||
let libstd = sysroot.std().and_then(|it| sysroot_crates.get(&it).copied());
|
|
||||||
let libproc_macro =
|
|
||||||
sysroot.proc_macro().and_then(|it| sysroot_crates.get(&it).copied());
|
|
||||||
|
|
||||||
let mut pkg_to_lib_crate = FxHashMap::default();
|
let mut pkg_to_lib_crate = FxHashMap::default();
|
||||||
let mut pkg_crates = FxHashMap::default();
|
let mut pkg_crates = FxHashMap::default();
|
||||||
|
@ -424,14 +387,11 @@ impl ProjectWorkspace {
|
||||||
}
|
}
|
||||||
if cargo[tgt].is_proc_macro {
|
if cargo[tgt].is_proc_macro {
|
||||||
if let Some(proc_macro) = libproc_macro {
|
if let Some(proc_macro) = libproc_macro {
|
||||||
if crate_graph
|
if let Err(_) = crate_graph.add_dep(
|
||||||
.add_dep(
|
crate_id,
|
||||||
crate_id,
|
CrateName::new("proc_macro").unwrap(),
|
||||||
CrateName::new("proc_macro").unwrap(),
|
proc_macro,
|
||||||
proc_macro,
|
) {
|
||||||
)
|
|
||||||
.is_err()
|
|
||||||
{
|
|
||||||
log::error!(
|
log::error!(
|
||||||
"cyclic dependency on proc_macro for {}",
|
"cyclic dependency on proc_macro for {}",
|
||||||
&cargo[pkg].name
|
&cargo[pkg].name
|
||||||
|
@ -447,52 +407,22 @@ impl ProjectWorkspace {
|
||||||
// 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 in pkg_crates.get(&pkg).into_iter().flatten() {
|
for &from in pkg_crates.get(&pkg).into_iter().flatten() {
|
||||||
if let Some((to, name)) = lib_tgt.clone() {
|
if let Some((to, name)) = lib_tgt.clone() {
|
||||||
if to != from
|
// For root projects with dashes in their name,
|
||||||
&& crate_graph
|
// cargo metadata does not do any normalization,
|
||||||
.add_dep(
|
// so we do it ourselves currently
|
||||||
from,
|
let name = CrateName::normalize_dashes(&name);
|
||||||
// For root projects with dashes in their name,
|
if to != from && crate_graph.add_dep(from, name, to).is_err() {
|
||||||
// cargo metadata does not do any normalization,
|
log::error!(
|
||||||
// so we do it ourselves currently
|
"cyclic dependency between targets of {}",
|
||||||
CrateName::normalize_dashes(&name),
|
&cargo[pkg].name
|
||||||
to,
|
)
|
||||||
)
|
|
||||||
.is_err()
|
|
||||||
{
|
|
||||||
{
|
|
||||||
log::error!(
|
|
||||||
"cyclic dependency between targets of {}",
|
|
||||||
&cargo[pkg].name
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// core is added as a dependency before std in order to
|
for (name, krate) in public_deps.iter() {
|
||||||
// mimic rustcs dependency order
|
if let Err(_) = crate_graph.add_dep(from, name.clone(), *krate) {
|
||||||
if let Some(core) = libcore {
|
|
||||||
if crate_graph
|
|
||||||
.add_dep(from, CrateName::new("core").unwrap(), core)
|
|
||||||
.is_err()
|
|
||||||
{
|
|
||||||
log::error!("cyclic dependency on core for {}", &cargo[pkg].name)
|
log::error!("cyclic dependency on core for {}", &cargo[pkg].name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(alloc) = liballoc {
|
|
||||||
if crate_graph
|
|
||||||
.add_dep(from, CrateName::new("alloc").unwrap(), alloc)
|
|
||||||
.is_err()
|
|
||||||
{
|
|
||||||
log::error!("cyclic dependency on alloc for {}", &cargo[pkg].name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let Some(std) = libstd {
|
|
||||||
if crate_graph
|
|
||||||
.add_dep(from, CrateName::new("std").unwrap(), std)
|
|
||||||
.is_err()
|
|
||||||
{
|
|
||||||
log::error!("cyclic dependency on std for {}", &cargo[pkg].name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -500,12 +430,10 @@ impl ProjectWorkspace {
|
||||||
// target of downstream.
|
// target of downstream.
|
||||||
for pkg in cargo.packages() {
|
for pkg in cargo.packages() {
|
||||||
for dep in cargo[pkg].dependencies.iter() {
|
for dep in cargo[pkg].dependencies.iter() {
|
||||||
|
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 in pkg_crates.get(&pkg).into_iter().flatten() {
|
for &from in pkg_crates.get(&pkg).into_iter().flatten() {
|
||||||
if crate_graph
|
if let Err(_) = crate_graph.add_dep(from, name.clone(), to) {
|
||||||
.add_dep(from, CrateName::new(&dep.name).unwrap(), to)
|
|
||||||
.is_err()
|
|
||||||
{
|
|
||||||
log::error!(
|
log::error!(
|
||||||
"cyclic dependency {} -> {}",
|
"cyclic dependency {} -> {}",
|
||||||
&cargo[pkg].name,
|
&cargo[pkg].name,
|
||||||
|
@ -563,3 +491,49 @@ fn utf8_stdout(mut cmd: Command) -> Result<String> {
|
||||||
let stdout = String::from_utf8(output.stdout)?;
|
let stdout = String::from_utf8(output.stdout)?;
|
||||||
Ok(stdout.trim().to_string())
|
Ok(stdout.trim().to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn sysroot_to_crate_graph(
|
||||||
|
crate_graph: &mut CrateGraph,
|
||||||
|
sysroot: &Sysroot,
|
||||||
|
cfg_options: &CfgOptions,
|
||||||
|
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
||||||
|
) -> (Vec<(CrateName, CrateId)>, Option<CrateId>) {
|
||||||
|
let sysroot_crates: FxHashMap<_, _> = sysroot
|
||||||
|
.crates()
|
||||||
|
.filter_map(|krate| {
|
||||||
|
let file_id = load(&sysroot[krate].root)?;
|
||||||
|
|
||||||
|
let env = Env::default();
|
||||||
|
let proc_macro = vec![];
|
||||||
|
let name = sysroot[krate].name.clone();
|
||||||
|
let crate_id = crate_graph.add_crate_root(
|
||||||
|
file_id,
|
||||||
|
Edition::Edition2018,
|
||||||
|
Some(name),
|
||||||
|
cfg_options.clone(),
|
||||||
|
env,
|
||||||
|
proc_macro,
|
||||||
|
);
|
||||||
|
Some((krate, crate_id))
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
for from in sysroot.crates() {
|
||||||
|
for &to in sysroot[from].deps.iter() {
|
||||||
|
let name = CrateName::new(&sysroot[to].name).unwrap();
|
||||||
|
if let (Some(&from), Some(&to)) = (sysroot_crates.get(&from), sysroot_crates.get(&to)) {
|
||||||
|
if let Err(_) = crate_graph.add_dep(from, name, to) {
|
||||||
|
log::error!("cyclic dependency between sysroot crates")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let public_deps = sysroot
|
||||||
|
.public_deps()
|
||||||
|
.map(|(name, idx)| (CrateName::new(name).unwrap(), sysroot_crates[&idx]))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let libproc_macro = sysroot.proc_macro().and_then(|it| sysroot_crates.get(&it).copied());
|
||||||
|
(public_deps, libproc_macro)
|
||||||
|
}
|
||||||
|
|
|
@ -34,16 +34,10 @@ impl ops::Index<SysrootCrate> for Sysroot {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sysroot {
|
impl Sysroot {
|
||||||
pub fn core(&self) -> Option<SysrootCrate> {
|
pub fn public_deps(&self) -> impl Iterator<Item = (&'static str, SysrootCrate)> + '_ {
|
||||||
self.by_name("core")
|
// core is added as a dependency before std in order to
|
||||||
}
|
// mimic rustcs dependency order
|
||||||
|
vec!["core", "alloc", "std"].into_iter().filter_map(move |it| Some((it, self.by_name(it)?)))
|
||||||
pub fn alloc(&self) -> Option<SysrootCrate> {
|
|
||||||
self.by_name("alloc")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn std(&self) -> Option<SysrootCrate> {
|
|
||||||
self.by_name("std")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn proc_macro(&self) -> Option<SysrootCrate> {
|
pub fn proc_macro(&self) -> Option<SysrootCrate> {
|
||||||
|
@ -81,7 +75,7 @@ impl Sysroot {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(std) = sysroot.std() {
|
if let Some(std) = sysroot.by_name("std") {
|
||||||
for dep in STD_DEPS.trim().lines() {
|
for dep in STD_DEPS.trim().lines() {
|
||||||
if let Some(dep) = sysroot.by_name(dep) {
|
if let Some(dep) = sysroot.by_name(dep) {
|
||||||
sysroot.crates[std].deps.push(dep)
|
sysroot.crates[std].deps.push(dep)
|
||||||
|
@ -89,8 +83,8 @@ impl Sysroot {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(alloc) = sysroot.alloc() {
|
if let Some(alloc) = sysroot.by_name("alloc") {
|
||||||
if let Some(core) = sysroot.core() {
|
if let Some(core) = sysroot.by_name("core") {
|
||||||
sysroot.crates[alloc].deps.push(core);
|
sysroot.crates[alloc].deps.push(core);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue