Skip to content

Commit 506762f

Browse files
committed
Explicitly export core and std macros
Currently all core and std macros are automatically added to the prelude via #[macro_use]. However a situation arose where we want to add a new macro `assert_matches` but don't want to pull it into the standard prelude for compatibility reasons. By explicitly exporting the macros found in the core and std crates we get to decide on a per macro basis and can later add them via the rust_20xx preludes.
1 parent 2f1bd3f commit 506762f

File tree

103 files changed

+770
-123
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

103 files changed

+770
-123
lines changed

compiler/rustc_builtin_macros/src/standard_library_imports.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ pub fn inject(
4343

4444
let item = cx.item(
4545
span,
46-
thin_vec![cx.attr_word(sym::macro_use, span)],
46+
ast::AttrVec::new(),
4747
ast::ItemKind::ExternCrate(None, Ident::new(name, ident_span)),
4848
);
4949

compiler/rustc_lint_defs/src/builtin.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ declare_lint_pass! {
1919
AMBIGUOUS_ASSOCIATED_ITEMS,
2020
AMBIGUOUS_GLOB_IMPORTS,
2121
AMBIGUOUS_GLOB_REEXPORTS,
22+
AMBIGUOUS_PANIC_IMPORTS,
2223
ARITHMETIC_OVERFLOW,
2324
ASM_SUB_REGISTER,
2425
BAD_ASM_STYLE,
@@ -4472,6 +4473,42 @@ declare_lint! {
44724473
};
44734474
}
44744475

4476+
declare_lint! {
4477+
/// The `ambiguous_panic_imports` lint detects ambiguous core and std panic imports, but
4478+
/// previously didn't do that due to `#[macro_use]` prelude macro import.
4479+
///
4480+
/// ### Example
4481+
///
4482+
/// ```rust,compile_fail
4483+
/// #![deny(ambiguous_panic_imports)]
4484+
/// #![no_std]
4485+
///
4486+
/// extern crate std;
4487+
/// use std::prelude::v1::*;
4488+
///
4489+
/// fn xx() {
4490+
/// panic!(); // resolves to core::panic
4491+
/// }
4492+
/// ```
4493+
///
4494+
/// {{produces}}
4495+
///
4496+
/// ### Explanation
4497+
///
4498+
/// Future versions of Rust will no longer accept the ambiguous resolution.
4499+
///
4500+
/// This is a [future-incompatible] lint to transition this to a hard error in the future.
4501+
///
4502+
/// [future-incompatible]: ../index.md#future-incompatible-lints
4503+
pub AMBIGUOUS_PANIC_IMPORTS,
4504+
Warn,
4505+
"detects ambiguous core and std panic imports",
4506+
@future_incompatible = FutureIncompatibleInfo {
4507+
reason: fcw!(FutureReleaseError #147319),
4508+
report_in_deps: false,
4509+
};
4510+
}
4511+
44754512
declare_lint! {
44764513
/// The `refining_impl_trait_reachable` lint detects `impl Trait` return
44774514
/// types in method signatures that are refined by a publically reachable

compiler/rustc_resolve/src/diagnostics.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use rustc_middle::ty::TyCtxt;
2424
use rustc_session::Session;
2525
use rustc_session::lint::BuiltinLintDiag;
2626
use rustc_session::lint::builtin::{
27-
ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, AMBIGUOUS_GLOB_IMPORTS,
27+
ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, AMBIGUOUS_GLOB_IMPORTS, AMBIGUOUS_PANIC_IMPORTS,
2828
MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS,
2929
};
3030
use rustc_session::utils::was_invoked_from_cargo;
@@ -44,10 +44,11 @@ use crate::errors::{
4444
use crate::imports::{Import, ImportKind};
4545
use crate::late::{DiagMetadata, PatternSource, Rib};
4646
use crate::{
47-
AmbiguityError, AmbiguityKind, BindingError, BindingKey, Decl, DeclKind, Finalize,
48-
ForwardGenericParamBanReason, HasGenericParams, LateDecl, MacroRulesScope, Module, ModuleKind,
49-
ModuleOrUniformRoot, ParentScope, PathResult, PrivacyError, ResolutionError, Resolver, Scope,
50-
ScopeSet, Segment, UseError, Used, VisResolutionError, errors as errs, path_names_to_string,
47+
AmbiguityError, AmbiguityKind, AmbiguityWarning, BindingError, BindingKey, Decl, DeclKind,
48+
Finalize, ForwardGenericParamBanReason, HasGenericParams, LateDecl, MacroRulesScope, Module,
49+
ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, PrivacyError, ResolutionError,
50+
Resolver, Scope, ScopeSet, Segment, UseError, Used, VisResolutionError, errors as errs,
51+
path_names_to_string,
5152
};
5253

5354
type Res = def::Res<ast::NodeId>;
@@ -146,17 +147,18 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
146147
for ambiguity_error in &self.ambiguity_errors {
147148
let diag = self.ambiguity_diagnostic(ambiguity_error);
148149

149-
if ambiguity_error.warning {
150+
if let Some(ambiguity_warning) = ambiguity_error.warning {
150151
let node_id = match ambiguity_error.b1.0.kind {
151152
DeclKind::Import { import, .. } => import.root_id,
152153
DeclKind::Def(_) => CRATE_NODE_ID,
153154
};
154-
self.lint_buffer.buffer_lint(
155-
AMBIGUOUS_GLOB_IMPORTS,
156-
node_id,
157-
diag.ident.span,
158-
diag,
159-
);
155+
156+
let lint = match ambiguity_warning {
157+
AmbiguityWarning::GlobImport => AMBIGUOUS_GLOB_IMPORTS,
158+
AmbiguityWarning::PanicImport => AMBIGUOUS_PANIC_IMPORTS,
159+
};
160+
161+
self.lint_buffer.buffer_lint(lint, node_id, diag.ident.span, diag);
160162
} else {
161163
self.dcx().emit_err(diag);
162164
}

compiler/rustc_resolve/src/ident.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use rustc_hir::def::{DefKind, MacroKinds, Namespace, NonMacroAttrKind, PartialRe
88
use rustc_middle::{bug, span_bug};
99
use rustc_session::lint::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK;
1010
use rustc_session::parse::feature_err;
11+
use rustc_span::edition::Edition;
1112
use rustc_span::hygiene::{ExpnId, ExpnKind, LocalExpnId, MacroKind, SyntaxContext};
1213
use rustc_span::{Ident, Macros20NormalizedIdent, Span, kw, sym};
1314
use smallvec::SmallVec;
@@ -20,9 +21,10 @@ use crate::late::{
2021
};
2122
use crate::macros::{MacroRulesScope, sub_namespace_match};
2223
use crate::{
23-
AmbiguityError, AmbiguityKind, BindingKey, CmResolver, Decl, DeclKind, Determinacy, Finalize,
24-
ImportKind, LateDecl, Module, ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult,
25-
PrivacyError, Res, ResolutionError, Resolver, Scope, ScopeSet, Segment, Stage, Used, errors,
24+
AmbiguityError, AmbiguityKind, AmbiguityWarning, BindingKey, CmResolver, Decl, DeclKind,
25+
Determinacy, Finalize, ImportKind, LateDecl, Module, ModuleKind, ModuleOrUniformRoot,
26+
ParentScope, PathResult, PrivacyError, Res, ResolutionError, Resolver, Scope, ScopeSet,
27+
Segment, Stage, Used, errors,
2628
};
2729

2830
#[derive(Copy, Clone)]
@@ -841,14 +843,27 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
841843
if issue_145575_hack || issue_149681_hack {
842844
self.issue_145575_hack_applied = true;
843845
} else {
846+
// Turn ambiguity errors for core vs std panic into warnings.
847+
// FIXME: Remove with lang team approval.
848+
let is_issue_147319_hack = orig_ident.span.edition() <= Edition::Edition2024
849+
&& matches!(orig_ident.name, sym::panic)
850+
&& matches!(scope, Scope::StdLibPrelude)
851+
&& matches!(innermost_scope, Scope::ModuleGlobs(_, _))
852+
&& ((self.is_specific_builtin_macro(res, sym::std_panic)
853+
&& self.is_specific_builtin_macro(innermost_res, sym::core_panic))
854+
|| (self.is_specific_builtin_macro(res, sym::core_panic)
855+
&& self.is_specific_builtin_macro(innermost_res, sym::std_panic)));
856+
857+
let warning = is_issue_147319_hack.then_some(AmbiguityWarning::PanicImport);
858+
844859
self.ambiguity_errors.push(AmbiguityError {
845860
kind,
846861
ident: orig_ident,
847862
b1: innermost_decl,
848863
b2: decl,
849864
scope1: innermost_scope,
850865
scope2: scope,
851-
warning: false,
866+
warning,
852867
});
853868
return true;
854869
}

compiler/rustc_resolve/src/imports.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -959,8 +959,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
959959
ImportKind::Single { decls, .. } => decls[TypeNS].get().decl(),
960960
_ => None,
961961
};
962-
let ambiguity_errors_len =
963-
|errors: &Vec<AmbiguityError<'_>>| errors.iter().filter(|error| !error.warning).count();
962+
let ambiguity_errors_len = |errors: &Vec<AmbiguityError<'_>>| {
963+
errors.iter().filter(|error| error.warning.is_none()).count()
964+
};
964965
let prev_ambiguity_errors_len = ambiguity_errors_len(&self.ambiguity_errors);
965966
let finalize = Finalize::with_root_span(import.root_id, import.span, import.root_span);
966967

@@ -1176,7 +1177,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
11761177
});
11771178
let res = binding.res();
11781179
let has_ambiguity_error =
1179-
this.ambiguity_errors.iter().any(|error| !error.warning);
1180+
this.ambiguity_errors.iter().any(|error| error.warning.is_none());
11801181
if res == Res::Err || has_ambiguity_error {
11811182
this.dcx()
11821183
.span_delayed_bug(import.span, "some error happened for an import");

compiler/rustc_resolve/src/lib.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -911,6 +911,12 @@ impl AmbiguityKind {
911911
}
912912
}
913913

914+
#[derive(Clone, Copy, PartialEq)]
915+
enum AmbiguityWarning {
916+
GlobImport,
917+
PanicImport,
918+
}
919+
914920
struct AmbiguityError<'ra> {
915921
kind: AmbiguityKind,
916922
ident: Ident,
@@ -919,7 +925,7 @@ struct AmbiguityError<'ra> {
919925
// `empty_module` in module scope serves as an unknown module here.
920926
scope1: Scope<'ra>,
921927
scope2: Scope<'ra>,
922-
warning: bool,
928+
warning: Option<AmbiguityWarning>,
923929
}
924930

925931
impl<'ra> DeclData<'ra> {
@@ -1871,6 +1877,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
18711877
self.get_macro(res).is_some_and(|macro_data| macro_data.ext.builtin_name.is_some())
18721878
}
18731879

1880+
fn is_specific_builtin_macro(&self, res: Res, symbol: Symbol) -> bool {
1881+
self.get_macro(res).is_some_and(|macro_data| macro_data.ext.builtin_name == Some(symbol))
1882+
}
1883+
18741884
fn macro_def(&self, mut ctxt: SyntaxContext) -> DefId {
18751885
loop {
18761886
match ctxt.outer_expn_data().macro_def_id {
@@ -2063,7 +2073,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
20632073
b2,
20642074
scope1: Scope::ModuleGlobs(self.empty_module, None),
20652075
scope2: Scope::ModuleGlobs(self.empty_module, None),
2066-
warning: warn_ambiguity,
2076+
warning: if warn_ambiguity { Some(AmbiguityWarning::GlobImport) } else { None },
20672077
};
20682078
if !self.matches_previous_ambiguity_error(&ambiguity_error) {
20692079
// avoid duplicated span information to be emit out

compiler/rustc_resolve/src/macros.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -835,10 +835,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
835835
res: Res| {
836836
if let Some(initial_res) = initial_res {
837837
if res != initial_res {
838-
// Make sure compilation does not succeed if preferred macro resolution
839-
// has changed after the macro had been expanded. In theory all such
840-
// situations should be reported as errors, so this is a bug.
841-
this.dcx().span_delayed_bug(span, "inconsistent resolution for a macro");
838+
if this.ambiguity_errors.is_empty() {
839+
// Make sure compilation does not succeed if preferred macro resolution
840+
// has changed after the macro had been expanded. In theory all such
841+
// situations should be reported as errors, so this is a bug.
842+
this.dcx().span_delayed_bug(span, "inconsistent resolution for a macro");
843+
}
842844
}
843845
} else if this.tcx.dcx().has_errors().is_none() && this.privacy_errors.is_empty() {
844846
// It's possible that the macro was unresolved (indeterminate) and silently

library/alloctests/lib.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
#![feature(negative_impls)]
6666
#![feature(never_type)]
6767
#![feature(optimize_attribute)]
68+
#![feature(prelude_import)]
6869
#![feature(rustc_allow_const_fn_unstable)]
6970
#![feature(rustc_attrs)]
7071
#![feature(staged_api)]
@@ -74,11 +75,17 @@
7475

7576
// Allow testing this library
7677
extern crate alloc as realalloc;
77-
#[macro_use]
78+
79+
// This is needed to provide macros to the directly imported alloc modules below.
7880
extern crate std;
81+
#[prelude_import]
82+
#[allow(unused_imports)]
83+
use std::prelude::rust_2024::*;
84+
7985
#[cfg(test)]
8086
extern crate test;
8187
mod testing;
88+
8289
use realalloc::*;
8390

8491
// We are directly including collections, raw_vec, and wtf8 here as they use non-public
@@ -102,8 +109,7 @@ pub(crate) mod test_helpers {
102109
let mut hasher = std::hash::RandomState::new().build_hasher();
103110
std::panic::Location::caller().hash(&mut hasher);
104111
let hc64 = hasher.finish();
105-
let seed_vec =
106-
hc64.to_le_bytes().into_iter().chain(0u8..8).collect::<crate::vec::Vec<u8>>();
112+
let seed_vec = hc64.to_le_bytes().into_iter().chain(0u8..8).collect::<std::vec::Vec<u8>>();
107113
let seed: [u8; 16] = seed_vec.as_slice().try_into().unwrap();
108114
rand::SeedableRng::from_seed(seed)
109115
}

library/core/src/prelude/v1.rs

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,31 @@ pub use crate::hash::macros::Hash;
5959

6060
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
6161
#[doc(no_inline)]
62+
#[expect(deprecated)]
6263
pub use crate::{
63-
assert, cfg, column, compile_error, concat, env, file, format_args,
64-
format_args_nl, include, include_bytes, include_str, line, log_syntax, module_path, option_env,
65-
stringify, trace_macros,
64+
assert, assert_eq, assert_ne, cfg, column, compile_error, concat, debug_assert, debug_assert_eq,
65+
debug_assert_ne, file, format_args, include, include_bytes, include_str, line, matches,
66+
module_path, option_env, stringify, todo, r#try, unimplemented, unreachable, write, writeln,
6667
};
6768

69+
// These macros need special handling, so that we don't export them *and* the modules of the same
70+
// name. We only want the macros in the prelude so we shadow the original modules with private
71+
// modules with the same names.
72+
mod ambiguous_macros_only {
73+
mod env {}
74+
#[expect(hidden_glob_reexports)]
75+
mod panic {}
76+
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
77+
pub use crate::*;
78+
}
79+
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
80+
#[doc(no_inline)]
81+
pub use self::ambiguous_macros_only::{env, panic};
82+
83+
#[unstable(feature = "cfg_select", issue = "115585")]
84+
#[doc(no_inline)]
85+
pub use crate::cfg_select;
86+
6887
#[unstable(
6988
feature = "concat_bytes",
7089
issue = "87555",
@@ -73,6 +92,30 @@ pub use crate::{
7392
#[doc(no_inline)]
7493
pub use crate::concat_bytes;
7594

95+
#[unstable(feature = "const_format_args", issue = "none")]
96+
#[doc(no_inline)]
97+
pub use crate::const_format_args;
98+
99+
#[unstable(
100+
feature = "log_syntax",
101+
issue = "29598",
102+
reason = "`log_syntax!` is not stable enough for use and is subject to change"
103+
)]
104+
#[doc(no_inline)]
105+
pub use crate::log_syntax;
106+
107+
#[unstable(feature = "pattern_type_macro", issue = "123646")]
108+
#[doc(no_inline)]
109+
pub use crate::pattern_type;
110+
111+
#[unstable(
112+
feature = "trace_macros",
113+
issue = "29598",
114+
reason = "`trace_macros` is not stable enough for use and is subject to change"
115+
)]
116+
#[doc(no_inline)]
117+
pub use crate::trace_macros;
118+
76119
// Do not `doc(no_inline)` so that they become doc items on their own
77120
// (no public module for them to be re-exported from).
78121
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]

library/std/src/prelude/mod.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@
5454
//! * <code>[std::convert]::{[AsRef], [AsMut], [Into], [From]}</code>, generic
5555
//! conversions, used by savvy API authors to create overloaded methods.
5656
//! * <code>[std::default]::[Default]</code>, types that have default values.
57-
//! * <code>[std::iter]::{[Iterator], [Extend], [IntoIterator], [DoubleEndedIterator], [ExactSizeIterator]}</code>,
58-
//! iterators of various
59-
//! kinds.
57+
//! * <code>[std::iter]::{[Iterator], [Extend], [IntoIterator], [DoubleEndedIterator],
58+
//! [ExactSizeIterator]}</code>, iterators of various kinds.
59+
//! * Most of the standard macros.
6060
//! * <code>[std::option]::[Option]::{[self][Option], [Some], [None]}</code>, a
6161
//! type which expresses the presence or absence of a value. This type is so
6262
//! commonly used, its variants are also exported.
@@ -145,6 +145,11 @@ pub mod rust_2021 {
145145
#[stable(feature = "prelude_2021", since = "1.55.0")]
146146
#[doc(no_inline)]
147147
pub use core::prelude::rust_2021::*;
148+
149+
// There are two different panic macros, one in `core` and one in `std`. They are slightly
150+
// different. For `std` we explicitly want the one defined in `std`.
151+
#[stable(feature = "prelude_2021", since = "1.55.0")]
152+
pub use super::v1::panic;
148153
}
149154

150155
/// The 2024 version of the prelude of The Rust Standard Library.
@@ -159,6 +164,11 @@ pub mod rust_2024 {
159164
#[stable(feature = "prelude_2024", since = "1.85.0")]
160165
#[doc(no_inline)]
161166
pub use core::prelude::rust_2024::*;
167+
168+
// There are two different panic macros, one in `core` and one in `std`. They are slightly
169+
// different. For `std` we explicitly want the one defined in `std`.
170+
#[stable(feature = "prelude_2024", since = "1.85.0")]
171+
pub use super::v1::panic;
162172
}
163173

164174
/// The Future version of the prelude of The Rust Standard Library.
@@ -174,4 +184,9 @@ pub mod rust_future {
174184
#[unstable(feature = "prelude_next", issue = "none")]
175185
#[doc(no_inline)]
176186
pub use core::prelude::rust_future::*;
187+
188+
// There are two different panic macros, one in `core` and one in `std`. They are slightly
189+
// different. For `std` we explicitly want the one defined in `std`.
190+
#[unstable(feature = "prelude_next", issue = "none")]
191+
pub use super::v1::panic;
177192
}

0 commit comments

Comments
 (0)