Skip to content

Commit 1fb8364

Browse files
committed
Auto merge of #17172 - Veykril:prelude, r=Veykril
fix: Correctly handle `no_core`/`no_std` for preludes Fixes #17169, my previous change missed the fact that the sysroot itself depends on its own crates explicitly
2 parents cfce2bb + a268eaf commit 1fb8364

File tree

9 files changed

+120
-71
lines changed

9 files changed

+120
-71
lines changed

crates/base-db/src/input.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -324,21 +324,27 @@ pub struct Dependency {
324324
pub crate_id: CrateId,
325325
pub name: CrateName,
326326
prelude: bool,
327+
sysroot: bool,
327328
}
328329

329330
impl Dependency {
330331
pub fn new(name: CrateName, crate_id: CrateId) -> Self {
331-
Self { name, crate_id, prelude: true }
332+
Self { name, crate_id, prelude: true, sysroot: false }
332333
}
333334

334-
pub fn with_prelude(name: CrateName, crate_id: CrateId, prelude: bool) -> Self {
335-
Self { name, crate_id, prelude }
335+
pub fn with_prelude(name: CrateName, crate_id: CrateId, prelude: bool, sysroot: bool) -> Self {
336+
Self { name, crate_id, prelude, sysroot }
336337
}
337338

338339
/// Whether this dependency is to be added to the depending crate's extern prelude.
339340
pub fn is_prelude(&self) -> bool {
340341
self.prelude
341342
}
343+
344+
/// Whether this dependency is a sysroot injected one.
345+
pub fn is_sysroot(&self) -> bool {
346+
self.sysroot
347+
}
342348
}
343349

344350
impl CrateGraph {

crates/hir-def/src/nameres/collector.rs

Lines changed: 41 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -289,19 +289,14 @@ impl DefCollector<'_> {
289289
crate_data.proc_macro_loading_error = Some(e.clone());
290290
}
291291

292-
for (name, dep) in &self.deps {
293-
if dep.is_prelude() {
294-
crate_data
295-
.extern_prelude
296-
.insert(name.clone(), (CrateRootModuleId { krate: dep.crate_id }, None));
297-
}
298-
}
292+
let mut process = true;
299293

300294
// Process other crate-level attributes.
301295
for attr in &*attrs {
302296
if let Some(cfg) = attr.cfg() {
303297
if self.cfg_options.check(&cfg) == Some(false) {
304-
return;
298+
process = false;
299+
break;
305300
}
306301
}
307302
let Some(attr_name) = attr.path.as_ident() else { continue };
@@ -319,43 +314,8 @@ impl DefCollector<'_> {
319314
self.is_proc_macro = true;
320315
}
321316
}
322-
() if *attr_name == hir_expand::name![no_core] => {
323-
if let Some((core, _)) =
324-
crate_data.extern_prelude.iter().find(|(_, (root, _))| {
325-
matches!(
326-
crate_graph[root.krate].origin,
327-
CrateOrigin::Lang(LangCrateOrigin::Core)
328-
)
329-
})
330-
{
331-
crate_data.extern_prelude.remove(&core.clone());
332-
}
333-
334-
crate_data.no_core = true
335-
}
336-
() if *attr_name == hir_expand::name![no_std] => {
337-
if let Some((alloc, _)) =
338-
crate_data.extern_prelude.iter().find(|(_, (root, _))| {
339-
matches!(
340-
crate_graph[root.krate].origin,
341-
CrateOrigin::Lang(LangCrateOrigin::Alloc)
342-
)
343-
})
344-
{
345-
crate_data.extern_prelude.remove(&alloc.clone());
346-
}
347-
if let Some((std, _)) =
348-
crate_data.extern_prelude.iter().find(|(_, (root, _))| {
349-
matches!(
350-
crate_graph[root.krate].origin,
351-
CrateOrigin::Lang(LangCrateOrigin::Std)
352-
)
353-
})
354-
{
355-
crate_data.extern_prelude.remove(&std.clone());
356-
}
357-
crate_data.no_std = true
358-
}
317+
() if *attr_name == hir_expand::name![no_core] => crate_data.no_core = true,
318+
() if *attr_name == hir_expand::name![no_std] => crate_data.no_std = true,
359319
() if attr_name.as_text().as_deref() == Some("rustc_coherence_is_core") => {
360320
crate_data.rustc_coherence_is_core = true;
361321
}
@@ -386,9 +346,38 @@ impl DefCollector<'_> {
386346
}
387347
}
388348

389-
crate_data.shrink_to_fit();
349+
for (name, dep) in &self.deps {
350+
if dep.is_prelude() {
351+
// This is a bit confusing but the gist is that `no_core` and `no_std` remove the
352+
// sysroot dependence on `core` and `std` respectively. Our `CrateGraph` is eagerly
353+
// constructed with them in place no matter what though, since at that point we
354+
// don't do pre-configured attribute resolution yet.
355+
// So here check if we are no_core / no_std and we are trying to add the
356+
// corresponding dep from the sysroot
357+
let skip = match crate_graph[dep.crate_id].origin {
358+
CrateOrigin::Lang(LangCrateOrigin::Core) => {
359+
crate_data.no_core && dep.is_sysroot()
360+
}
361+
CrateOrigin::Lang(LangCrateOrigin::Std) => {
362+
crate_data.no_std && dep.is_sysroot()
363+
}
364+
_ => false,
365+
};
366+
if skip {
367+
continue;
368+
}
369+
crate_data
370+
.extern_prelude
371+
.insert(name.clone(), (CrateRootModuleId { krate: dep.crate_id }, None));
372+
}
373+
}
374+
390375
self.inject_prelude();
391376

377+
if !process {
378+
return;
379+
}
380+
392381
ModCollector {
393382
def_collector: self,
394383
macro_depth: 0,
@@ -398,6 +387,7 @@ impl DefCollector<'_> {
398387
mod_dir: ModDir::root(),
399388
}
400389
.collect_in_top_module(item_tree.top_level_items());
390+
Arc::get_mut(&mut self.def_map.data).unwrap().shrink_to_fit();
401391
}
402392

403393
fn seed_with_inner(&mut self, tree_id: TreeId) {
@@ -555,15 +545,12 @@ impl DefCollector<'_> {
555545

556546
let krate = if self.def_map.data.no_std {
557547
name![core]
548+
} else if self.def_map.extern_prelude().any(|(name, _)| *name == name![std]) {
549+
name![std]
558550
} else {
559-
let std = name![std];
560-
if self.def_map.extern_prelude().any(|(name, _)| *name == std) {
561-
std
562-
} else {
563-
// If `std` does not exist for some reason, fall back to core. This mostly helps
564-
// keep r-a's own tests minimal.
565-
name![core]
566-
}
551+
// If `std` does not exist for some reason, fall back to core. This mostly helps
552+
// keep r-a's own tests minimal.
553+
name![core]
567554
};
568555

569556
let edition = match self.def_map.data.edition {

crates/project-model/src/sysroot.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//! but we can't process `.rlib` and need source code instead. The source code
55
//! is typically installed with `rustup component add rust-src` command.
66
7-
use std::{env, fs, iter, ops, process::Command, sync::Arc};
7+
use std::{env, fs, ops, process::Command, sync::Arc};
88

99
use anyhow::{format_err, Result};
1010
use base_db::CrateName;
@@ -58,13 +58,11 @@ impl Stitched {
5858
pub(crate) fn public_deps(&self) -> impl Iterator<Item = (CrateName, SysrootCrate, bool)> + '_ {
5959
// core is added as a dependency before std in order to
6060
// mimic rustcs dependency order
61-
["core", "alloc", "std"]
62-
.into_iter()
63-
.zip(iter::repeat(true))
64-
.chain(iter::once(("test", false)))
65-
.filter_map(move |(name, prelude)| {
61+
[("core", true), ("alloc", false), ("std", true), ("test", false)].into_iter().filter_map(
62+
move |(name, prelude)| {
6663
Some((CrateName::new(name).unwrap(), self.by_name(name)?, prelude))
67-
})
64+
},
65+
)
6866
}
6967

7068
pub(crate) fn proc_macro(&self) -> Option<SysrootCrate> {

crates/project-model/src/workspace.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1413,7 +1413,7 @@ impl SysrootPublicDeps {
14131413
/// Makes `from` depend on the public sysroot crates.
14141414
fn add_to_crate_graph(&self, crate_graph: &mut CrateGraph, from: CrateId) {
14151415
for (name, krate, prelude) in &self.deps {
1416-
add_dep_with_prelude(crate_graph, from, name.clone(), *krate, *prelude);
1416+
add_dep_with_prelude(crate_graph, from, name.clone(), *krate, *prelude, true);
14171417
}
14181418
}
14191419
}
@@ -1466,7 +1466,7 @@ fn sysroot_to_crate_graph(
14661466
| LangCrateOrigin::Std => pub_deps.push((
14671467
CrateName::normalize_dashes(&lang_crate.to_string()),
14681468
cid,
1469-
!matches!(lang_crate, LangCrateOrigin::Test),
1469+
!matches!(lang_crate, LangCrateOrigin::Test | LangCrateOrigin::Alloc),
14701470
)),
14711471
LangCrateOrigin::ProcMacro => libproc_macro = Some(cid),
14721472
LangCrateOrigin::Other => (),
@@ -1567,12 +1567,20 @@ fn add_dep_with_prelude(
15671567
name: CrateName,
15681568
to: CrateId,
15691569
prelude: bool,
1570+
sysroot: bool,
15701571
) {
1571-
add_dep_inner(graph, from, Dependency::with_prelude(name, to, prelude))
1572+
add_dep_inner(graph, from, Dependency::with_prelude(name, to, prelude, sysroot))
15721573
}
15731574

15741575
fn add_proc_macro_dep(crate_graph: &mut CrateGraph, from: CrateId, to: CrateId, prelude: bool) {
1575-
add_dep_with_prelude(crate_graph, from, CrateName::new("proc_macro").unwrap(), to, prelude);
1576+
add_dep_with_prelude(
1577+
crate_graph,
1578+
from,
1579+
CrateName::new("proc_macro").unwrap(),
1580+
to,
1581+
prelude,
1582+
true,
1583+
);
15761584
}
15771585

15781586
fn add_dep_inner(graph: &mut CrateGraph, from: CrateId, dep: Dependency) {

crates/project-model/test_data/output/cargo_hello_world_project_model.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
"libc",
5151
),
5252
prelude: true,
53+
sysroot: false,
5354
},
5455
],
5556
origin: Local {
@@ -111,13 +112,15 @@
111112
"hello_world",
112113
),
113114
prelude: true,
115+
sysroot: false,
114116
},
115117
Dependency {
116118
crate_id: Idx::<CrateData>(4),
117119
name: CrateName(
118120
"libc",
119121
),
120122
prelude: true,
123+
sysroot: false,
121124
},
122125
],
123126
origin: Local {
@@ -179,13 +182,15 @@
179182
"hello_world",
180183
),
181184
prelude: true,
185+
sysroot: false,
182186
},
183187
Dependency {
184188
crate_id: Idx::<CrateData>(4),
185189
name: CrateName(
186190
"libc",
187191
),
188192
prelude: true,
193+
sysroot: false,
189194
},
190195
],
191196
origin: Local {
@@ -247,13 +252,15 @@
247252
"hello_world",
248253
),
249254
prelude: true,
255+
sysroot: false,
250256
},
251257
Dependency {
252258
crate_id: Idx::<CrateData>(4),
253259
name: CrateName(
254260
"libc",
255261
),
256262
prelude: true,
263+
sysroot: false,
257264
},
258265
],
259266
origin: Local {

crates/project-model/test_data/output/cargo_hello_world_project_model_with_selective_overrides.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
"libc",
5151
),
5252
prelude: true,
53+
sysroot: false,
5354
},
5455
],
5556
origin: Local {
@@ -111,13 +112,15 @@
111112
"hello_world",
112113
),
113114
prelude: true,
115+
sysroot: false,
114116
},
115117
Dependency {
116118
crate_id: Idx::<CrateData>(4),
117119
name: CrateName(
118120
"libc",
119121
),
120122
prelude: true,
123+
sysroot: false,
121124
},
122125
],
123126
origin: Local {
@@ -179,13 +182,15 @@
179182
"hello_world",
180183
),
181184
prelude: true,
185+
sysroot: false,
182186
},
183187
Dependency {
184188
crate_id: Idx::<CrateData>(4),
185189
name: CrateName(
186190
"libc",
187191
),
188192
prelude: true,
193+
sysroot: false,
189194
},
190195
],
191196
origin: Local {
@@ -247,13 +252,15 @@
247252
"hello_world",
248253
),
249254
prelude: true,
255+
sysroot: false,
250256
},
251257
Dependency {
252258
crate_id: Idx::<CrateData>(4),
253259
name: CrateName(
254260
"libc",
255261
),
256262
prelude: true,
263+
sysroot: false,
257264
},
258265
],
259266
origin: Local {

0 commit comments

Comments
 (0)