Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub fn inject(

let item = cx.item(
span,
thin_vec![cx.attr_word(sym::macro_use, span)],
ast::AttrVec::new(),
ast::ItemKind::ExternCrate(None, Ident::new(name, ident_span)),
);

Expand Down
37 changes: 37 additions & 0 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ declare_lint_pass! {
AMBIGUOUS_ASSOCIATED_ITEMS,
AMBIGUOUS_GLOB_IMPORTS,
AMBIGUOUS_GLOB_REEXPORTS,
AMBIGUOUS_PANIC_IMPORTS,
ARITHMETIC_OVERFLOW,
ASM_SUB_REGISTER,
BAD_ASM_STYLE,
Expand Down Expand Up @@ -4472,6 +4473,42 @@ declare_lint! {
};
}

declare_lint! {
/// The `ambiguous_panic_imports` lint detects ambiguous core and std panic imports, but
/// previously didn't do that due to `#[macro_use]` prelude macro import.
///
/// ### Example
///
/// ```rust,compile_fail
/// #![deny(ambiguous_panic_imports)]
/// #![no_std]
///
/// extern crate std;
/// use std::prelude::v1::*;
///
/// fn xx() {
/// panic!(); // resolves to core::panic
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// Future versions of Rust will no longer accept the ambiguous resolution.
///
/// This is a [future-incompatible] lint to transition this to a hard error in the future.
///
/// [future-incompatible]: ../index.md#future-incompatible-lints
pub AMBIGUOUS_PANIC_IMPORTS,
Warn,
"detects ambiguous core and std panic imports",
@future_incompatible = FutureIncompatibleInfo {
reason: fcw!(FutureReleaseError #147319),
report_in_deps: false,
};
}

declare_lint! {
/// The `refining_impl_trait_reachable` lint detects `impl Trait` return
/// types in method signatures that are refined by a publically reachable
Expand Down
26 changes: 14 additions & 12 deletions compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use rustc_middle::ty::TyCtxt;
use rustc_session::Session;
use rustc_session::lint::BuiltinLintDiag;
use rustc_session::lint::builtin::{
ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, AMBIGUOUS_GLOB_IMPORTS,
ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, AMBIGUOUS_GLOB_IMPORTS, AMBIGUOUS_PANIC_IMPORTS,
MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS,
};
use rustc_session::utils::was_invoked_from_cargo;
Expand All @@ -44,10 +44,11 @@ use crate::errors::{
use crate::imports::{Import, ImportKind};
use crate::late::{DiagMetadata, PatternSource, Rib};
use crate::{
AmbiguityError, AmbiguityKind, BindingError, BindingKey, Decl, DeclKind, Finalize,
ForwardGenericParamBanReason, HasGenericParams, LateDecl, MacroRulesScope, Module, ModuleKind,
ModuleOrUniformRoot, ParentScope, PathResult, PrivacyError, ResolutionError, Resolver, Scope,
ScopeSet, Segment, UseError, Used, VisResolutionError, errors as errs, path_names_to_string,
AmbiguityError, AmbiguityKind, AmbiguityWarning, BindingError, BindingKey, Decl, DeclKind,
Finalize, ForwardGenericParamBanReason, HasGenericParams, LateDecl, MacroRulesScope, Module,
ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, PrivacyError, ResolutionError,
Resolver, Scope, ScopeSet, Segment, UseError, Used, VisResolutionError, errors as errs,
path_names_to_string,
};

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

if ambiguity_error.warning {
if let Some(ambiguity_warning) = ambiguity_error.warning {
let node_id = match ambiguity_error.b1.0.kind {
DeclKind::Import { import, .. } => import.root_id,
DeclKind::Def(_) => CRATE_NODE_ID,
};
self.lint_buffer.buffer_lint(
AMBIGUOUS_GLOB_IMPORTS,
node_id,
diag.ident.span,
diag,
);

let lint = match ambiguity_warning {
AmbiguityWarning::GlobImport => AMBIGUOUS_GLOB_IMPORTS,
AmbiguityWarning::PanicImport => AMBIGUOUS_PANIC_IMPORTS,
};

self.lint_buffer.buffer_lint(lint, node_id, diag.ident.span, diag);
} else {
self.dcx().emit_err(diag);
}
Expand Down
21 changes: 17 additions & 4 deletions compiler/rustc_resolve/src/ident.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use rustc_hir::def::{DefKind, MacroKinds, Namespace, NonMacroAttrKind, PartialRe
use rustc_middle::{bug, span_bug};
use rustc_session::lint::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK;
use rustc_session::parse::feature_err;
use rustc_span::edition::Edition;
use rustc_span::hygiene::{ExpnId, ExpnKind, LocalExpnId, MacroKind, SyntaxContext};
use rustc_span::{Ident, Span, kw, sym};
use tracing::{debug, instrument};
Expand All @@ -19,9 +20,10 @@ use crate::late::{
};
use crate::macros::{MacroRulesScope, sub_namespace_match};
use crate::{
AmbiguityError, AmbiguityKind, BindingKey, CmResolver, Decl, DeclKind, Determinacy, Finalize,
ImportKind, LateDecl, Module, ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult,
PrivacyError, Res, ResolutionError, Resolver, Scope, ScopeSet, Segment, Stage, Used, errors,
AmbiguityError, AmbiguityKind, AmbiguityWarning, BindingKey, CmResolver, Decl, DeclKind,
Determinacy, Finalize, ImportKind, LateDecl, Module, ModuleKind, ModuleOrUniformRoot,
ParentScope, PathResult, PrivacyError, Res, ResolutionError, Resolver, Scope, ScopeSet,
Segment, Stage, Used, errors,
};

#[derive(Copy, Clone)]
Expand Down Expand Up @@ -841,14 +843,25 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
if issue_145575_hack || issue_149681_hack {
self.issue_145575_hack_applied = true;
} else {
// Turn ambiguity errors for core vs std panic into warnings.
// FIXME: Remove with lang team approval.
let is_issue_147319_hack = orig_ident.span.edition() <= Edition::Edition2024
&& matches!(orig_ident.name, sym::panic)
&& matches!(scope, Scope::StdLibPrelude)
&& matches!(innermost_scope, Scope::ModuleGlobs(_, _))
&& (self.is_specific_builtin_macro(res, sym::core_panic)
&& self.is_specific_builtin_macro(innermost_res, sym::std_panic));

let warning = is_issue_147319_hack.then_some(AmbiguityWarning::PanicImport);

self.ambiguity_errors.push(AmbiguityError {
kind,
ident: orig_ident,
b1: innermost_decl,
b2: decl,
scope1: innermost_scope,
scope2: scope,
warning: false,
warning,
});
return true;
}
Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_resolve/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -921,8 +921,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ImportKind::Single { decls, .. } => decls[TypeNS].get().decl(),
_ => None,
};
let ambiguity_errors_len =
|errors: &Vec<AmbiguityError<'_>>| errors.iter().filter(|error| !error.warning).count();
let ambiguity_errors_len = |errors: &Vec<AmbiguityError<'_>>| {
errors.iter().filter(|error| error.warning.is_none()).count()
};
let prev_ambiguity_errors_len = ambiguity_errors_len(&self.ambiguity_errors);
let finalize = Finalize::with_root_span(import.root_id, import.span, import.root_span);

Expand Down Expand Up @@ -1138,7 +1139,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
});
let res = binding.res();
let has_ambiguity_error =
this.ambiguity_errors.iter().any(|error| !error.warning);
this.ambiguity_errors.iter().any(|error| error.warning.is_none());
if res == Res::Err || has_ambiguity_error {
this.dcx()
.span_delayed_bug(import.span, "some error happened for an import");
Expand Down
14 changes: 12 additions & 2 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -911,6 +911,12 @@ impl AmbiguityKind {
}
}

#[derive(Clone, Copy, PartialEq)]
enum AmbiguityWarning {
GlobImport,
PanicImport,
}

struct AmbiguityError<'ra> {
kind: AmbiguityKind,
ident: Ident,
Expand All @@ -919,7 +925,7 @@ struct AmbiguityError<'ra> {
// `empty_module` in module scope serves as an unknown module here.
scope1: Scope<'ra>,
scope2: Scope<'ra>,
warning: bool,
warning: Option<AmbiguityWarning>,
}

impl<'ra> DeclData<'ra> {
Expand Down Expand Up @@ -1867,6 +1873,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
self.get_macro(res).is_some_and(|macro_data| macro_data.ext.builtin_name.is_some())
}

fn is_specific_builtin_macro(&self, res: Res, symbol: Symbol) -> bool {
self.get_macro(res).is_some_and(|macro_data| macro_data.ext.builtin_name == Some(symbol))
}

fn macro_def(&self, mut ctxt: SyntaxContext) -> DefId {
loop {
match ctxt.outer_expn_data().macro_def_id {
Expand Down Expand Up @@ -2059,7 +2069,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
b2,
scope1: Scope::ModuleGlobs(self.empty_module, None),
scope2: Scope::ModuleGlobs(self.empty_module, None),
warning: warn_ambiguity,
warning: if warn_ambiguity { Some(AmbiguityWarning::GlobImport) } else { None },
};
if !self.matches_previous_ambiguity_error(&ambiguity_error) {
// avoid duplicated span information to be emit out
Expand Down
14 changes: 10 additions & 4 deletions compiler/rustc_resolve/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -838,10 +838,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
res: Res| {
if let Some(initial_res) = initial_res {
if res != initial_res {
// Make sure compilation does not succeed if preferred macro resolution
// has changed after the macro had been expanded. In theory all such
// situations should be reported as errors, so this is a bug.
this.dcx().span_delayed_bug(span, "inconsistent resolution for a macro");
if !this
.ambiguity_errors
.iter()
.any(|ambiguity_error| ambiguity_error.warning.is_none())
{
// Make sure compilation does not succeed if preferred macro resolution
// has changed after the macro had been expanded. In theory all such
// situations should be reported as errors, so this is a bug.
this.dcx().span_delayed_bug(span, "inconsistent resolution for a macro");
}
}
} else if this.tcx.dcx().has_errors().is_none() && this.privacy_errors.is_empty() {
// It's possible that the macro was unresolved (indeterminate) and silently
Expand Down
12 changes: 9 additions & 3 deletions library/alloctests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
#![feature(negative_impls)]
#![feature(never_type)]
#![feature(optimize_attribute)]
#![feature(prelude_import)]
#![feature(rustc_allow_const_fn_unstable)]
#![feature(rustc_attrs)]
#![feature(staged_api)]
Expand All @@ -74,11 +75,17 @@

// Allow testing this library
extern crate alloc as realalloc;
#[macro_use]

// This is needed to provide macros to the directly imported alloc modules below.
extern crate std;
#[prelude_import]
#[allow(unused_imports)]
use std::prelude::rust_2024::*;

#[cfg(test)]
extern crate test;
mod testing;

use realalloc::*;

// We are directly including collections, raw_vec, and wtf8 here as they use non-public
Expand All @@ -102,8 +109,7 @@ pub(crate) mod test_helpers {
let mut hasher = std::hash::RandomState::new().build_hasher();
std::panic::Location::caller().hash(&mut hasher);
let hc64 = hasher.finish();
let seed_vec =
hc64.to_le_bytes().into_iter().chain(0u8..8).collect::<crate::vec::Vec<u8>>();
let seed_vec = hc64.to_le_bytes().into_iter().chain(0u8..8).collect::<std::vec::Vec<u8>>();
let seed: [u8; 16] = seed_vec.as_slice().try_into().unwrap();
rand::SeedableRng::from_seed(seed)
}
Expand Down
49 changes: 46 additions & 3 deletions library/core/src/prelude/v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,31 @@ pub use crate::hash::macros::Hash;

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

// These macros need special handling, so that we don't export them *and* the modules of the same
// name. We only want the macros in the prelude so we shadow the original modules with private
// modules with the same names.
mod ambiguous_macros_only {
mod env {}
#[expect(hidden_glob_reexports)]
mod panic {}
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
pub use crate::*;
}
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[doc(no_inline)]
pub use self::ambiguous_macros_only::{env, panic};

#[unstable(feature = "cfg_select", issue = "115585")]
#[doc(no_inline)]
pub use crate::cfg_select;

#[unstable(
feature = "concat_bytes",
issue = "87555",
Expand All @@ -73,6 +92,30 @@ pub use crate::{
#[doc(no_inline)]
pub use crate::concat_bytes;

#[unstable(feature = "const_format_args", issue = "none")]
#[doc(no_inline)]
pub use crate::const_format_args;

#[unstable(
feature = "log_syntax",
issue = "29598",
reason = "`log_syntax!` is not stable enough for use and is subject to change"
)]
#[doc(no_inline)]
pub use crate::log_syntax;

#[unstable(feature = "pattern_type_macro", issue = "123646")]
#[doc(no_inline)]
pub use crate::pattern_type;

#[unstable(
feature = "trace_macros",
issue = "29598",
reason = "`trace_macros` is not stable enough for use and is subject to change"
)]
#[doc(no_inline)]
pub use crate::trace_macros;

// Do not `doc(no_inline)` so that they become doc items on their own
// (no public module for them to be re-exported from).
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
Expand Down
21 changes: 18 additions & 3 deletions library/std/src/prelude/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@
//! * <code>[std::convert]::{[AsRef], [AsMut], [Into], [From]}</code>, generic
//! conversions, used by savvy API authors to create overloaded methods.
//! * <code>[std::default]::[Default]</code>, types that have default values.
//! * <code>[std::iter]::{[Iterator], [Extend], [IntoIterator], [DoubleEndedIterator], [ExactSizeIterator]}</code>,
//! iterators of various
//! kinds.
//! * <code>[std::iter]::{[Iterator], [Extend], [IntoIterator], [DoubleEndedIterator],
//! [ExactSizeIterator]}</code>, iterators of various kinds.
//! * Most of the standard macros.
//! * <code>[std::option]::[Option]::{[self][Option], [Some], [None]}</code>, a
//! type which expresses the presence or absence of a value. This type is so
//! commonly used, its variants are also exported.
Expand Down Expand Up @@ -145,6 +145,11 @@ pub mod rust_2021 {
#[stable(feature = "prelude_2021", since = "1.55.0")]
#[doc(no_inline)]
pub use core::prelude::rust_2021::*;

// There are two different panic macros, one in `core` and one in `std`. They are slightly
// different. For `std` we explicitly want the one defined in `std`.
#[stable(feature = "prelude_2021", since = "1.55.0")]
pub use super::v1::panic;
}

/// The 2024 version of the prelude of The Rust Standard Library.
Expand All @@ -159,6 +164,11 @@ pub mod rust_2024 {
#[stable(feature = "prelude_2024", since = "1.85.0")]
#[doc(no_inline)]
pub use core::prelude::rust_2024::*;

// There are two different panic macros, one in `core` and one in `std`. They are slightly
// different. For `std` we explicitly want the one defined in `std`.
#[stable(feature = "prelude_2024", since = "1.85.0")]
pub use super::v1::panic;
}

/// The Future version of the prelude of The Rust Standard Library.
Expand All @@ -174,4 +184,9 @@ pub mod rust_future {
#[unstable(feature = "prelude_next", issue = "none")]
#[doc(no_inline)]
pub use core::prelude::rust_future::*;

// There are two different panic macros, one in `core` and one in `std`. They are slightly
// different. For `std` we explicitly want the one defined in `std`.
#[unstable(feature = "prelude_next", issue = "none")]
pub use super::v1::panic;
}
Loading
Loading