Skip to content

Resolve the prelude import in build_reduced_graph #145322

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 13 additions & 10 deletions compiler/rustc_resolve/src/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!(),
}
Expand Down Expand Up @@ -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
Expand Down
20 changes: 6 additions & 14 deletions compiler/rustc_resolve/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Option<Visibility>>,
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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.
Expand All @@ -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);
Expand Down Expand Up @@ -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 });
Expand All @@ -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
Expand Down
8 changes: 4 additions & 4 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand Down Expand Up @@ -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;
Expand Down
7 changes: 4 additions & 3 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -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")]
Expand Down
1 change: 1 addition & 0 deletions tests/ui/extern-flag/empty-extern-arg.rs
Original file line number Diff line number Diff line change
@@ -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
Expand Down
4 changes: 3 additions & 1 deletion tests/ui/extern-flag/empty-extern-arg.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
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
|
= 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

2 changes: 1 addition & 1 deletion tests/ui/proc-macro/derive-helper-legacy-spurious.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
8 changes: 1 addition & 7 deletions tests/ui/proc-macro/derive-helper-legacy-spurious.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

11 changes: 11 additions & 0 deletions tests/ui/resolve/inner-attr-prelude-macro.rs
Original file line number Diff line number Diff line change
@@ -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!();
}
6 changes: 3 additions & 3 deletions tests/ui/unpretty/exhaustive.expanded.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;

Expand All @@ -47,6 +44,9 @@ mod prelude {
}
}

#[prelude_import]
use self::prelude::*;

mod attributes {
//! inner single-line doc comment
/*!
Expand Down
6 changes: 3 additions & 3 deletions tests/ui/unpretty/exhaustive.hir.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;

Expand All @@ -48,6 +45,9 @@ mod prelude {
}
}

#[prelude_import]
use self::prelude::*;

/// inner single-line doc comment
/**
* inner multi-line doc comment
Expand Down
6 changes: 3 additions & 3 deletions tests/ui/unpretty/exhaustive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@
#![feature(yeet_expr)]
#![allow(incomplete_features)]

#[prelude_import]
use self::prelude::*;

mod prelude {
pub use std::prelude::rust_2024::*;

Expand All @@ -42,6 +39,9 @@ mod prelude {
}
}

#[prelude_import]
use self::prelude::*;

mod attributes {
//! inner single-line doc comment
/*!
Expand Down
Loading