From ff560d3c9a662786ab1126b32320cc7cb0169678 Mon Sep 17 00:00:00 2001 From: LorrensP-2158466 Date: Mon, 11 Aug 2025 22:33:12 +0200 Subject: [PATCH] resolve prelude import at `build_reduced_graph` phase --- .../rustc_resolve/src/build_reduced_graph.rs | 23 +++++++++++-------- compiler/rustc_resolve/src/imports.rs | 20 +++++----------- library/core/src/lib.rs | 8 +++---- library/std/src/lib.rs | 7 +++--- tests/ui/extern-flag/empty-extern-arg.rs | 1 + tests/ui/extern-flag/empty-extern-arg.stderr | 4 +++- .../derive-helper-legacy-spurious.rs | 2 +- .../derive-helper-legacy-spurious.stderr | 8 +------ tests/ui/resolve/inner-attr-prelude-macro.rs | 11 +++++++++ tests/ui/unpretty/exhaustive.expanded.stdout | 6 ++--- tests/ui/unpretty/exhaustive.hir.stdout | 6 ++--- tests/ui/unpretty/exhaustive.rs | 6 ++--- 12 files changed, 53 insertions(+), 49 deletions(-) create mode 100644 tests/ui/resolve/inner-attr-prelude-macro.rs diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 3fee2ab6afe1e..7bf366badb560 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -493,9 +493,6 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { }); } } - // We don't add prelude imports to the globs since they only affect lexical scopes, - // which are not relevant to import resolution. - ImportKind::Glob { is_prelude: true, .. } => {} ImportKind::Glob { .. } => current_module.globs.borrow_mut().push(import), _ => unreachable!(), } @@ -658,13 +655,19 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { self.add_import(module_path, kind, use_tree.span, item, root_span, item.id, vis); } ast::UseTreeKind::Glob => { - let kind = ImportKind::Glob { - is_prelude: ast::attr::contains_name(&item.attrs, sym::prelude_import), - max_vis: Cell::new(None), - id, - }; - - self.add_import(prefix, kind, use_tree.span, item, root_span, item.id, vis); + if !ast::attr::contains_name(&item.attrs, sym::prelude_import) { + let kind = ImportKind::Glob { max_vis: Cell::new(None), id }; + self.add_import(prefix, kind, use_tree.span, item, root_span, item.id, vis); + } else { + // Resolve the prelude import early. + let path_res = + self.r.cm().maybe_resolve_path(&prefix, None, &self.parent_scope, None); + if let PathResult::Module(ModuleOrUniformRoot::Module(module)) = path_res { + self.r.prelude = Some(module); + } else { + self.r.dcx().span_err(use_tree.span, "cannot resolve a prelude import"); + } + } } ast::UseTreeKind::Nested { ref items, .. } => { // Ensure there is at most one `self` in the list diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 403d440bee786..7c93fdb88ee44 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -87,7 +87,6 @@ pub(crate) enum ImportKind<'ra> { id: NodeId, }, Glob { - is_prelude: bool, // The visibility of the greatest re-export. // n.b. `max_vis` is only used in `finalize_import` to check for re-export errors. max_vis: Cell>, @@ -125,12 +124,9 @@ impl<'ra> std::fmt::Debug for ImportKind<'ra> { .field("nested", nested) .field("id", id) .finish(), - Glob { is_prelude, max_vis, id } => f - .debug_struct("Glob") - .field("is_prelude", is_prelude) - .field("max_vis", max_vis) - .field("id", id) - .finish(), + Glob { max_vis, id } => { + f.debug_struct("Glob").field("max_vis", max_vis).field("id", id).finish() + } ExternCrate { source, target, id } => f .debug_struct("ExternCrate") .field("source", source) @@ -1073,7 +1069,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ImportKind::Single { source, target, ref bindings, type_ns_only, id, .. } => { (source, target, bindings, type_ns_only, id) } - ImportKind::Glob { is_prelude, ref max_vis, id } => { + ImportKind::Glob { ref max_vis, id } => { if import.module_path.len() <= 1 { // HACK(eddyb) `lint_if_path_starts_with_module` needs at least // 2 segments, so the `resolve_path` above won't trigger it. @@ -1096,8 +1092,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { module: None, }); } - if !is_prelude - && let Some(max_vis) = max_vis.get() + if let Some(max_vis) = max_vis.get() && !max_vis.is_at_least(import.vis, self.tcx) { let def_id = self.local_def_id(id); @@ -1485,7 +1480,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { fn resolve_glob_import(&mut self, import: Import<'ra>) { // This function is only called for glob imports. - let ImportKind::Glob { id, is_prelude, .. } = import.kind else { unreachable!() }; + let ImportKind::Glob { id, .. } = import.kind else { unreachable!() }; let ModuleOrUniformRoot::Module(module) = import.imported_module.get().unwrap() else { self.dcx().emit_err(CannotGlobImportAllCrates { span: import.span }); @@ -1504,9 +1499,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if module == import.parent_scope.module { return; - } else if is_prelude { - self.prelude = Some(module); - return; } // Add to module's glob_importers diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index d5bce6ad233e9..f40bcf6a4bb81 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -210,6 +210,10 @@ #[allow(unused_extern_crates)] extern crate self as core; +/* The core prelude, not as all-encompassing as the std prelude */ +// The compiler expects the prelude definition to be defined before it's use statement. +pub mod prelude; + #[prelude_import] #[allow(unused)] use prelude::rust_2024::*; @@ -295,10 +299,6 @@ pub mod f64; #[macro_use] pub mod num; -/* The core prelude, not as all-encompassing as the std prelude */ - -pub mod prelude; - /* Core modules for ownership management */ pub mod hint; diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 07b38c658984d..40ad2d7146a66 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -428,6 +428,10 @@ // #![default_lib_allocator] +// The Rust prelude +// The compiler expects the prelude definition to be defined before it's use statement. +pub mod prelude; + // Explicitly import the prelude. The compiler uses this same unstable attribute // to import the prelude implicitly when building crates that depend on std. #[prelude_import] @@ -483,9 +487,6 @@ mod macros; #[macro_use] pub mod rt; -// The Rust prelude -pub mod prelude; - #[stable(feature = "rust1", since = "1.0.0")] pub use core::any; #[stable(feature = "core_array", since = "1.35.0")] diff --git a/tests/ui/extern-flag/empty-extern-arg.rs b/tests/ui/extern-flag/empty-extern-arg.rs index 2dee721ed03c0..10cc3be71135e 100644 --- a/tests/ui/extern-flag/empty-extern-arg.rs +++ b/tests/ui/extern-flag/empty-extern-arg.rs @@ -1,4 +1,5 @@ //~ ERROR extern location for std does not exist +//~^ ERROR cannot resolve a prelude import //@ compile-flags: --extern std= //@ needs-unwind since it affects the error output //@ ignore-emscripten missing eh_catch_typeinfo lang item diff --git a/tests/ui/extern-flag/empty-extern-arg.stderr b/tests/ui/extern-flag/empty-extern-arg.stderr index 79efcc5d8b041..3e0a0d6cd5f86 100644 --- a/tests/ui/extern-flag/empty-extern-arg.stderr +++ b/tests/ui/extern-flag/empty-extern-arg.stderr @@ -1,5 +1,7 @@ error: extern location for std does not exist: +error: cannot resolve a prelude import + error: `#[panic_handler]` function required, but not found error: unwinding panics are not supported without std @@ -7,5 +9,5 @@ error: unwinding panics are not supported without std = help: using nightly cargo, use -Zbuild-std with panic="abort" to avoid unwinding = note: since the core library is usually precompiled with panic="unwind", rebuilding your crate with panic="abort" may not be enough to fix the problem -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors diff --git a/tests/ui/proc-macro/derive-helper-legacy-spurious.rs b/tests/ui/proc-macro/derive-helper-legacy-spurious.rs index 8e902f3041932..0b55e775f38be 100644 --- a/tests/ui/proc-macro/derive-helper-legacy-spurious.rs +++ b/tests/ui/proc-macro/derive-helper-legacy-spurious.rs @@ -6,7 +6,7 @@ extern crate test_macros; #[derive(Empty)] -#[empty_helper] //~ ERROR cannot find attribute `empty_helper` in this scope +#[empty_helper] struct Foo {} fn main() {} diff --git a/tests/ui/proc-macro/derive-helper-legacy-spurious.stderr b/tests/ui/proc-macro/derive-helper-legacy-spurious.stderr index b34713b8ca68e..4cd89904ef3e1 100644 --- a/tests/ui/proc-macro/derive-helper-legacy-spurious.stderr +++ b/tests/ui/proc-macro/derive-helper-legacy-spurious.stderr @@ -4,11 +4,5 @@ error: cannot find attribute `dummy` in this scope LL | #![dummy] | ^^^^^ -error: cannot find attribute `empty_helper` in this scope - --> $DIR/derive-helper-legacy-spurious.rs:9:3 - | -LL | #[empty_helper] - | ^^^^^^^^^^^^ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error diff --git a/tests/ui/resolve/inner-attr-prelude-macro.rs b/tests/ui/resolve/inner-attr-prelude-macro.rs new file mode 100644 index 0000000000000..1047c908ad116 --- /dev/null +++ b/tests/ui/resolve/inner-attr-prelude-macro.rs @@ -0,0 +1,11 @@ +//@ check-pass +//! This test checks that macro names resolved from the libstd prelude +//! still work even if there's a crate-level custom inner attribute. + +#![feature(custom_inner_attributes)] + +#![rustfmt::skip] + +fn main() { + let _ = todo!(); +} diff --git a/tests/ui/unpretty/exhaustive.expanded.stdout b/tests/ui/unpretty/exhaustive.expanded.stdout index 6b08f3e1cd76d..0327ad5f92bb3 100644 --- a/tests/ui/unpretty/exhaustive.expanded.stdout +++ b/tests/ui/unpretty/exhaustive.expanded.stdout @@ -34,9 +34,6 @@ extern crate std; #[prelude_import] use std::prelude::rust_2024::*; -#[prelude_import] -use self::prelude::*; - mod prelude { pub use std::prelude::rust_2024::*; @@ -47,6 +44,9 @@ mod prelude { } } +#[prelude_import] +use self::prelude::*; + mod attributes { //! inner single-line doc comment /*! diff --git a/tests/ui/unpretty/exhaustive.hir.stdout b/tests/ui/unpretty/exhaustive.hir.stdout index e9823c9575bc9..68356a33c9e60 100644 --- a/tests/ui/unpretty/exhaustive.hir.stdout +++ b/tests/ui/unpretty/exhaustive.hir.stdout @@ -33,9 +33,6 @@ extern crate std; #[prelude_import] use std::prelude::rust_2024::*; -#[prelude_import] -use self::prelude::*; - mod prelude { use std::prelude::rust_2024::*; @@ -48,6 +45,9 @@ mod prelude { } } +#[prelude_import] +use self::prelude::*; + /// inner single-line doc comment /** * inner multi-line doc comment diff --git a/tests/ui/unpretty/exhaustive.rs b/tests/ui/unpretty/exhaustive.rs index 5292ddad4f6b2..b19d4f9fe2c0c 100644 --- a/tests/ui/unpretty/exhaustive.rs +++ b/tests/ui/unpretty/exhaustive.rs @@ -29,9 +29,6 @@ #![feature(yeet_expr)] #![allow(incomplete_features)] -#[prelude_import] -use self::prelude::*; - mod prelude { pub use std::prelude::rust_2024::*; @@ -42,6 +39,9 @@ mod prelude { } } +#[prelude_import] +use self::prelude::*; + mod attributes { //! inner single-line doc comment /*!