fix: Correctly handle no_core/no_std for preludes

This commit is contained in:
Lukas Wirth 2024-05-02 09:53:42 +02:00
parent 9ce7ab6fa9
commit f4b4a12b02
9 changed files with 120 additions and 71 deletions

View File

@ -324,21 +324,27 @@ pub struct Dependency {
pub crate_id: CrateId, pub crate_id: CrateId,
pub name: CrateName, pub name: CrateName,
prelude: bool, prelude: bool,
sysroot: bool,
} }
impl Dependency { impl Dependency {
pub fn new(name: CrateName, crate_id: CrateId) -> Self { pub fn new(name: CrateName, crate_id: CrateId) -> Self {
Self { name, crate_id, prelude: true } Self { name, crate_id, prelude: true, sysroot: false }
} }
pub fn with_prelude(name: CrateName, crate_id: CrateId, prelude: bool) -> Self { pub fn with_prelude(name: CrateName, crate_id: CrateId, prelude: bool, sysroot: bool) -> Self {
Self { name, crate_id, prelude } Self { name, crate_id, prelude, sysroot }
} }
/// Whether this dependency is to be added to the depending crate's extern prelude. /// Whether this dependency is to be added to the depending crate's extern prelude.
pub fn is_prelude(&self) -> bool { pub fn is_prelude(&self) -> bool {
self.prelude self.prelude
} }
/// Whether this dependency is a sysroot injected one.
pub fn is_sysroot(&self) -> bool {
self.sysroot
}
} }
impl CrateGraph { impl CrateGraph {

View File

@ -289,19 +289,14 @@ impl DefCollector<'_> {
crate_data.proc_macro_loading_error = Some(e.clone()); crate_data.proc_macro_loading_error = Some(e.clone());
} }
for (name, dep) in &self.deps { let mut process = true;
if dep.is_prelude() {
crate_data
.extern_prelude
.insert(name.clone(), (CrateRootModuleId { krate: dep.crate_id }, None));
}
}
// Process other crate-level attributes. // Process other crate-level attributes.
for attr in &*attrs { for attr in &*attrs {
if let Some(cfg) = attr.cfg() { if let Some(cfg) = attr.cfg() {
if self.cfg_options.check(&cfg) == Some(false) { if self.cfg_options.check(&cfg) == Some(false) {
return; process = false;
break;
} }
} }
let Some(attr_name) = attr.path.as_ident() else { continue }; let Some(attr_name) = attr.path.as_ident() else { continue };
@ -319,43 +314,8 @@ impl DefCollector<'_> {
self.is_proc_macro = true; self.is_proc_macro = true;
} }
} }
() if *attr_name == hir_expand::name![no_core] => { () if *attr_name == hir_expand::name![no_core] => crate_data.no_core = true,
if let Some((core, _)) = () if *attr_name == hir_expand::name![no_std] => crate_data.no_std = true,
crate_data.extern_prelude.iter().find(|(_, (root, _))| {
matches!(
crate_graph[root.krate].origin,
CrateOrigin::Lang(LangCrateOrigin::Core)
)
})
{
crate_data.extern_prelude.remove(&core.clone());
}
crate_data.no_core = true
}
() if *attr_name == hir_expand::name![no_std] => {
if let Some((alloc, _)) =
crate_data.extern_prelude.iter().find(|(_, (root, _))| {
matches!(
crate_graph[root.krate].origin,
CrateOrigin::Lang(LangCrateOrigin::Alloc)
)
})
{
crate_data.extern_prelude.remove(&alloc.clone());
}
if let Some((std, _)) =
crate_data.extern_prelude.iter().find(|(_, (root, _))| {
matches!(
crate_graph[root.krate].origin,
CrateOrigin::Lang(LangCrateOrigin::Std)
)
})
{
crate_data.extern_prelude.remove(&std.clone());
}
crate_data.no_std = true
}
() if attr_name.as_text().as_deref() == Some("rustc_coherence_is_core") => { () if attr_name.as_text().as_deref() == Some("rustc_coherence_is_core") => {
crate_data.rustc_coherence_is_core = true; crate_data.rustc_coherence_is_core = true;
} }
@ -386,9 +346,38 @@ impl DefCollector<'_> {
} }
} }
crate_data.shrink_to_fit(); for (name, dep) in &self.deps {
if dep.is_prelude() {
// This is a bit confusing but the gist is that `no_core` and `no_std` remove the
// sysroot dependence on `core` and `std` respectively. Our `CrateGraph` is eagerly
// constructed with them in place no matter what though, since at that point we
// don't do pre-configured attribute resolution yet.
// So here check if we are no_core / no_std and we are trying to add the
// corresponding dep from the sysroot
let skip = match crate_graph[dep.crate_id].origin {
CrateOrigin::Lang(LangCrateOrigin::Core) => {
crate_data.no_core && dep.is_sysroot()
}
CrateOrigin::Lang(LangCrateOrigin::Std) => {
crate_data.no_std && dep.is_sysroot()
}
_ => false,
};
if skip {
continue;
}
crate_data
.extern_prelude
.insert(name.clone(), (CrateRootModuleId { krate: dep.crate_id }, None));
}
}
self.inject_prelude(); self.inject_prelude();
if !process {
return;
}
ModCollector { ModCollector {
def_collector: self, def_collector: self,
macro_depth: 0, macro_depth: 0,
@ -398,6 +387,7 @@ impl DefCollector<'_> {
mod_dir: ModDir::root(), mod_dir: ModDir::root(),
} }
.collect_in_top_module(item_tree.top_level_items()); .collect_in_top_module(item_tree.top_level_items());
Arc::get_mut(&mut self.def_map.data).unwrap().shrink_to_fit();
} }
fn seed_with_inner(&mut self, tree_id: TreeId) { fn seed_with_inner(&mut self, tree_id: TreeId) {
@ -555,15 +545,12 @@ impl DefCollector<'_> {
let krate = if self.def_map.data.no_std { let krate = if self.def_map.data.no_std {
name![core] name![core]
} else if self.def_map.extern_prelude().any(|(name, _)| *name == name![std]) {
name![std]
} else { } else {
let std = name![std]; // If `std` does not exist for some reason, fall back to core. This mostly helps
if self.def_map.extern_prelude().any(|(name, _)| *name == std) { // keep r-a's own tests minimal.
std name![core]
} else {
// If `std` does not exist for some reason, fall back to core. This mostly helps
// keep r-a's own tests minimal.
name![core]
}
}; };
let edition = match self.def_map.data.edition { let edition = match self.def_map.data.edition {

View File

@ -4,7 +4,7 @@
//! but we can't process `.rlib` and need source code instead. The source code //! but we can't process `.rlib` and need source code instead. The source code
//! is typically installed with `rustup component add rust-src` command. //! is typically installed with `rustup component add rust-src` command.
use std::{env, fs, iter, ops, process::Command, sync::Arc}; use std::{env, fs, ops, process::Command, sync::Arc};
use anyhow::{format_err, Result}; use anyhow::{format_err, Result};
use base_db::CrateName; use base_db::CrateName;
@ -58,13 +58,11 @@ impl Stitched {
pub(crate) fn public_deps(&self) -> impl Iterator<Item = (CrateName, SysrootCrate, bool)> + '_ { pub(crate) fn public_deps(&self) -> impl Iterator<Item = (CrateName, SysrootCrate, bool)> + '_ {
// 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
["core", "alloc", "std"] [("core", true), ("alloc", false), ("std", true), ("test", false)].into_iter().filter_map(
.into_iter() move |(name, prelude)| {
.zip(iter::repeat(true))
.chain(iter::once(("test", false)))
.filter_map(move |(name, prelude)| {
Some((CrateName::new(name).unwrap(), self.by_name(name)?, prelude)) Some((CrateName::new(name).unwrap(), self.by_name(name)?, prelude))
}) },
)
} }
pub(crate) fn proc_macro(&self) -> Option<SysrootCrate> { pub(crate) fn proc_macro(&self) -> Option<SysrootCrate> {

View File

@ -1413,7 +1413,7 @@ impl SysrootPublicDeps {
/// Makes `from` depend on the public sysroot crates. /// Makes `from` depend on the public sysroot crates.
fn add_to_crate_graph(&self, crate_graph: &mut CrateGraph, from: CrateId) { fn add_to_crate_graph(&self, crate_graph: &mut CrateGraph, from: CrateId) {
for (name, krate, prelude) in &self.deps { for (name, krate, prelude) in &self.deps {
add_dep_with_prelude(crate_graph, from, name.clone(), *krate, *prelude); add_dep_with_prelude(crate_graph, from, name.clone(), *krate, *prelude, true);
} }
} }
} }
@ -1466,7 +1466,7 @@ fn sysroot_to_crate_graph(
| LangCrateOrigin::Std => pub_deps.push(( | LangCrateOrigin::Std => pub_deps.push((
CrateName::normalize_dashes(&lang_crate.to_string()), CrateName::normalize_dashes(&lang_crate.to_string()),
cid, cid,
!matches!(lang_crate, LangCrateOrigin::Test), !matches!(lang_crate, LangCrateOrigin::Test | LangCrateOrigin::Alloc),
)), )),
LangCrateOrigin::ProcMacro => libproc_macro = Some(cid), LangCrateOrigin::ProcMacro => libproc_macro = Some(cid),
LangCrateOrigin::Other => (), LangCrateOrigin::Other => (),
@ -1567,12 +1567,20 @@ fn add_dep_with_prelude(
name: CrateName, name: CrateName,
to: CrateId, to: CrateId,
prelude: bool, prelude: bool,
sysroot: bool,
) { ) {
add_dep_inner(graph, from, Dependency::with_prelude(name, to, prelude)) add_dep_inner(graph, from, Dependency::with_prelude(name, to, prelude, sysroot))
} }
fn add_proc_macro_dep(crate_graph: &mut CrateGraph, from: CrateId, to: CrateId, prelude: bool) { fn add_proc_macro_dep(crate_graph: &mut CrateGraph, from: CrateId, to: CrateId, prelude: bool) {
add_dep_with_prelude(crate_graph, from, CrateName::new("proc_macro").unwrap(), to, prelude); add_dep_with_prelude(
crate_graph,
from,
CrateName::new("proc_macro").unwrap(),
to,
prelude,
true,
);
} }
fn add_dep_inner(graph: &mut CrateGraph, from: CrateId, dep: Dependency) { fn add_dep_inner(graph: &mut CrateGraph, from: CrateId, dep: Dependency) {

View File

@ -50,6 +50,7 @@
"libc", "libc",
), ),
prelude: true, prelude: true,
sysroot: false,
}, },
], ],
origin: Local { origin: Local {
@ -111,6 +112,7 @@
"hello_world", "hello_world",
), ),
prelude: true, prelude: true,
sysroot: false,
}, },
Dependency { Dependency {
crate_id: Idx::<CrateData>(4), crate_id: Idx::<CrateData>(4),
@ -118,6 +120,7 @@
"libc", "libc",
), ),
prelude: true, prelude: true,
sysroot: false,
}, },
], ],
origin: Local { origin: Local {
@ -179,6 +182,7 @@
"hello_world", "hello_world",
), ),
prelude: true, prelude: true,
sysroot: false,
}, },
Dependency { Dependency {
crate_id: Idx::<CrateData>(4), crate_id: Idx::<CrateData>(4),
@ -186,6 +190,7 @@
"libc", "libc",
), ),
prelude: true, prelude: true,
sysroot: false,
}, },
], ],
origin: Local { origin: Local {
@ -247,6 +252,7 @@
"hello_world", "hello_world",
), ),
prelude: true, prelude: true,
sysroot: false,
}, },
Dependency { Dependency {
crate_id: Idx::<CrateData>(4), crate_id: Idx::<CrateData>(4),
@ -254,6 +260,7 @@
"libc", "libc",
), ),
prelude: true, prelude: true,
sysroot: false,
}, },
], ],
origin: Local { origin: Local {

View File

@ -50,6 +50,7 @@
"libc", "libc",
), ),
prelude: true, prelude: true,
sysroot: false,
}, },
], ],
origin: Local { origin: Local {
@ -111,6 +112,7 @@
"hello_world", "hello_world",
), ),
prelude: true, prelude: true,
sysroot: false,
}, },
Dependency { Dependency {
crate_id: Idx::<CrateData>(4), crate_id: Idx::<CrateData>(4),
@ -118,6 +120,7 @@
"libc", "libc",
), ),
prelude: true, prelude: true,
sysroot: false,
}, },
], ],
origin: Local { origin: Local {
@ -179,6 +182,7 @@
"hello_world", "hello_world",
), ),
prelude: true, prelude: true,
sysroot: false,
}, },
Dependency { Dependency {
crate_id: Idx::<CrateData>(4), crate_id: Idx::<CrateData>(4),
@ -186,6 +190,7 @@
"libc", "libc",
), ),
prelude: true, prelude: true,
sysroot: false,
}, },
], ],
origin: Local { origin: Local {
@ -247,6 +252,7 @@
"hello_world", "hello_world",
), ),
prelude: true, prelude: true,
sysroot: false,
}, },
Dependency { Dependency {
crate_id: Idx::<CrateData>(4), crate_id: Idx::<CrateData>(4),
@ -254,6 +260,7 @@
"libc", "libc",
), ),
prelude: true, prelude: true,
sysroot: false,
}, },
], ],
origin: Local { origin: Local {

View File

@ -49,6 +49,7 @@
"libc", "libc",
), ),
prelude: true, prelude: true,
sysroot: false,
}, },
], ],
origin: Local { origin: Local {
@ -109,6 +110,7 @@
"hello_world", "hello_world",
), ),
prelude: true, prelude: true,
sysroot: false,
}, },
Dependency { Dependency {
crate_id: Idx::<CrateData>(4), crate_id: Idx::<CrateData>(4),
@ -116,6 +118,7 @@
"libc", "libc",
), ),
prelude: true, prelude: true,
sysroot: false,
}, },
], ],
origin: Local { origin: Local {
@ -176,6 +179,7 @@
"hello_world", "hello_world",
), ),
prelude: true, prelude: true,
sysroot: false,
}, },
Dependency { Dependency {
crate_id: Idx::<CrateData>(4), crate_id: Idx::<CrateData>(4),
@ -183,6 +187,7 @@
"libc", "libc",
), ),
prelude: true, prelude: true,
sysroot: false,
}, },
], ],
origin: Local { origin: Local {
@ -243,6 +248,7 @@
"hello_world", "hello_world",
), ),
prelude: true, prelude: true,
sysroot: false,
}, },
Dependency { Dependency {
crate_id: Idx::<CrateData>(4), crate_id: Idx::<CrateData>(4),
@ -250,6 +256,7 @@
"libc", "libc",
), ),
prelude: true, prelude: true,
sysroot: false,
}, },
], ],
origin: Local { origin: Local {

View File

@ -30,6 +30,7 @@
"core", "core",
), ),
prelude: true, prelude: true,
sysroot: false,
}, },
], ],
origin: Lang( origin: Lang(
@ -158,6 +159,7 @@
"std", "std",
), ),
prelude: true, prelude: true,
sysroot: false,
}, },
Dependency { Dependency {
crate_id: Idx::<CrateData>(1), crate_id: Idx::<CrateData>(1),
@ -165,6 +167,7 @@
"core", "core",
), ),
prelude: true, prelude: true,
sysroot: false,
}, },
], ],
origin: Lang( origin: Lang(
@ -233,6 +236,7 @@
"alloc", "alloc",
), ),
prelude: true, prelude: true,
sysroot: false,
}, },
Dependency { Dependency {
crate_id: Idx::<CrateData>(3), crate_id: Idx::<CrateData>(3),
@ -240,6 +244,7 @@
"panic_unwind", "panic_unwind",
), ),
prelude: true, prelude: true,
sysroot: false,
}, },
Dependency { Dependency {
crate_id: Idx::<CrateData>(2), crate_id: Idx::<CrateData>(2),
@ -247,6 +252,7 @@
"panic_abort", "panic_abort",
), ),
prelude: true, prelude: true,
sysroot: false,
}, },
Dependency { Dependency {
crate_id: Idx::<CrateData>(1), crate_id: Idx::<CrateData>(1),
@ -254,6 +260,7 @@
"core", "core",
), ),
prelude: true, prelude: true,
sysroot: false,
}, },
Dependency { Dependency {
crate_id: Idx::<CrateData>(5), crate_id: Idx::<CrateData>(5),
@ -261,6 +268,7 @@
"profiler_builtins", "profiler_builtins",
), ),
prelude: true, prelude: true,
sysroot: false,
}, },
Dependency { Dependency {
crate_id: Idx::<CrateData>(9), crate_id: Idx::<CrateData>(9),
@ -268,6 +276,7 @@
"unwind", "unwind",
), ),
prelude: true, prelude: true,
sysroot: false,
}, },
Dependency { Dependency {
crate_id: Idx::<CrateData>(7), crate_id: Idx::<CrateData>(7),
@ -275,6 +284,7 @@
"std_detect", "std_detect",
), ),
prelude: true, prelude: true,
sysroot: false,
}, },
Dependency { Dependency {
crate_id: Idx::<CrateData>(8), crate_id: Idx::<CrateData>(8),
@ -282,6 +292,7 @@
"test", "test",
), ),
prelude: true, prelude: true,
sysroot: false,
}, },
], ],
origin: Lang( origin: Lang(
@ -409,13 +420,15 @@
"core", "core",
), ),
prelude: true, prelude: true,
sysroot: true,
}, },
Dependency { Dependency {
crate_id: Idx::<CrateData>(0), crate_id: Idx::<CrateData>(0),
name: CrateName( name: CrateName(
"alloc", "alloc",
), ),
prelude: true, prelude: false,
sysroot: true,
}, },
Dependency { Dependency {
crate_id: Idx::<CrateData>(6), crate_id: Idx::<CrateData>(6),
@ -423,6 +436,7 @@
"std", "std",
), ),
prelude: true, prelude: true,
sysroot: true,
}, },
Dependency { Dependency {
crate_id: Idx::<CrateData>(8), crate_id: Idx::<CrateData>(8),
@ -430,6 +444,7 @@
"test", "test",
), ),
prelude: false, prelude: false,
sysroot: true,
}, },
Dependency { Dependency {
crate_id: Idx::<CrateData>(4), crate_id: Idx::<CrateData>(4),
@ -437,6 +452,7 @@
"proc_macro", "proc_macro",
), ),
prelude: false, prelude: false,
sysroot: true,
}, },
], ],
origin: Local { origin: Local {

View File

@ -240,7 +240,12 @@ impl ChangeFixture {
crate_graph crate_graph
.add_dep( .add_dep(
from_id, from_id,
Dependency::with_prelude(CrateName::new(&to).unwrap(), to_id, prelude), Dependency::with_prelude(
CrateName::new(&to).unwrap(),
to_id,
prelude,
false,
),
) )
.unwrap(); .unwrap();
} }
@ -275,7 +280,15 @@ impl ChangeFixture {
for krate in all_crates { for krate in all_crates {
crate_graph crate_graph
.add_dep(krate, Dependency::new(CrateName::new("core").unwrap(), core_crate)) .add_dep(
krate,
Dependency::with_prelude(
CrateName::new("core").unwrap(),
core_crate,
true,
true,
),
)
.unwrap(); .unwrap();
} }
} }