diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index f48fbe6324834..b408ac7bc5734 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -548,13 +548,9 @@ impl CombineAttributeParser for TargetFeatureParser { // `#[target_feature]` is incompatible with lang item functions, // except on WASM where calling target-feature functions is safe (see #84988). if !cx.sess().target.is_like_wasm && !cx.sess().opts.actually_rustdoc { - // `#[panic_handler]` is checked first so it takes priority in the diagnostic. - let lang_kind = cx - .all_attrs - .iter() - .find_map(|a| [sym::panic_handler, sym::lang].into_iter().find(|&s| a.word_is(s))); - if let Some(kind) = lang_kind { - cx.emit_err(TargetFeatureOnLangItem { attr_span, kind, item_span: cx.target_span }); + let is_lang_item = cx.all_attrs.iter().any(|a| a.word_is(sym::lang)); + if is_lang_item { + cx.emit_err(TargetFeatureOnLangItem { attr_span, item_span: cx.target_span }); } } } diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 24df9b100ce95..7becb957d2de6 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -589,9 +589,7 @@ impl SingleAttributeParser for LangParser { } // Check the target - let allowed_targets: &[_] = if lang_item == LangItem::PanicImpl { - &[Allow(Target::Fn), Allow(Target::ForeignFn)] - } else if lang_item.is_weak_only() { + let allowed_targets: &[_] = if lang_item.is_weak_only() { &[Allow(Target::ForeignFn)] } else { &[Allow(lang_item.target())] @@ -617,15 +615,6 @@ impl NoArgsAttributeParser for RustcHasIncoherentInherentImplsParser { const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcHasIncoherentInherentImpls; } -pub(crate) struct PanicHandlerParser; - -impl NoArgsAttributeParser for PanicHandlerParser { - const PATH: &[Symbol] = &[sym::panic_handler]; - const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn)]); - const STABILITY: AttributeStability = AttributeStability::Stable; - const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::Lang(LangItem::PanicImpl); -} - pub(crate) struct RustcNounwindParser; impl NoArgsAttributeParser for RustcNounwindParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 1595d2f80ddc7..9fae4c1ca3640 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -262,7 +262,6 @@ attribute_parsers!( Single>, Single>, Single>, - Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index 9e5d7bb2cf375..34ff10b973734 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -81,22 +81,11 @@ pub(crate) struct DocAttributeNotAttribute { } #[derive(Diagnostic)] -#[diag( - "`#[target_feature]` cannot be applied to a {$kind -> - [panic_handler] `#[panic_handler]` - *[other] lang item - } function" -)] +#[diag("`#[target_feature]` cannot be applied to a lang item function")] pub(crate) struct TargetFeatureOnLangItem { #[primary_span] pub attr_span: Span, - pub kind: Symbol, - #[label( - "{$kind -> - [panic_handler] `#[panic_handler]` - *[other] lang item - } function is not allowed to have `#[target_feature]`" - )] + #[label("lang item function is not allowed to have `#[target_feature]`")] pub item_span: Span, } diff --git a/compiler/rustc_builtin_macros/src/diagnostics.rs b/compiler/rustc_builtin_macros/src/diagnostics.rs index 6ae0f908a88a0..826bc711221d9 100644 --- a/compiler/rustc_builtin_macros/src/diagnostics.rs +++ b/compiler/rustc_builtin_macros/src/diagnostics.rs @@ -49,6 +49,13 @@ pub(crate) struct AllocErrorMustBeFn { pub(crate) span: Span, } +#[derive(Diagnostic)] +#[diag("panic_handler must be a function")] +pub(crate) struct PanicHandlerMustBeFn { + #[primary_span] + pub(crate) span: Span, +} + #[derive(Diagnostic)] #[diag("macro requires a boolean expression as an argument")] pub(crate) struct AssertRequiresBoolean { diff --git a/compiler/rustc_builtin_macros/src/eii.rs b/compiler/rustc_builtin_macros/src/eii.rs index 68d5278c85ef1..5d5eb0bbe0338 100644 --- a/compiler/rustc_builtin_macros/src/eii.rs +++ b/compiler/rustc_builtin_macros/src/eii.rs @@ -203,6 +203,9 @@ fn split_attrs( foreign_item_attributes.push(attr.clone()); macro_attributes.push(attr); } + Some(sym::rustc_diagnostic_item) => { + macro_attributes.push(attr.clone()); + } // Doc attributes should be forwarded to the macro and the foreign item, since those are // the two items you interact with as a user. // FIXME: idk yet how EIIs show up in docs, might want to customize diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index bd99b269ef5b6..8d67f9ddb8250 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -43,6 +43,7 @@ mod global_allocator; mod iter; mod log_syntax; mod offload; +mod panic_handler; mod pattern_type; mod source_util; mod test; @@ -120,6 +121,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { eii_shared_macro: eii::eii_shared_macro, global_allocator: global_allocator::expand, offload_kernel: offload::expand_kernel, + panic_handler: panic_handler::expand, test: test::expand_test, test_case: test::expand_test_case, unsafe_eii: eii::unsafe_eii, diff --git a/compiler/rustc_builtin_macros/src/panic_handler.rs b/compiler/rustc_builtin_macros/src/panic_handler.rs new file mode 100644 index 0000000000000..8eeb0a7e4bd2f --- /dev/null +++ b/compiler/rustc_builtin_macros/src/panic_handler.rs @@ -0,0 +1,43 @@ +use rustc_ast::{self as ast, AttrArgs, AttrItem, AttrItemKind, AttrStyle, Safety, StmtKind, attr}; +use rustc_expand::base::{Annotatable, ExtCtxt}; +use rustc_span::{Span, sym}; + +use crate::diagnostics; +use crate::util::check_builtin_macro_attribute; + +pub(crate) fn expand( + ecx: &mut ExtCtxt<'_>, + span: Span, + meta_item: &ast::MetaItem, + mut item: Annotatable, +) -> Vec { + check_builtin_macro_attribute(ecx, meta_item, sym::global_allocator); + + // Allow using `#[panic_handler]` on an item statement + // FIXME - if we get deref patterns, use them to reduce duplication here + let attrs = if let Annotatable::Item(item) = &mut item { + &mut item.attrs + } else if let Annotatable::Stmt(stmt) = &mut item + && let StmtKind::Item(item) = &mut stmt.kind + { + &mut item.attrs + } else { + ecx.dcx().emit_err(diagnostics::PanicHandlerMustBeFn { span: item.span() }); + return vec![item]; + }; + + attrs.push(attr::mk_attr_from_item( + &ecx.sess.psess.attr_id_generator, + AttrItem { + unsafety: Safety::Unsafe(span), + path: ecx.path_global(span, ecx.std_path(&[sym::panicking, sym::panic_handler])), + args: AttrItemKind::Unparsed(AttrArgs::Empty), + tokens: None, + }, + None, + AttrStyle::Outer, + span, + )); + + vec![item] +} diff --git a/compiler/rustc_codegen_cranelift/example/mini_core.rs b/compiler/rustc_codegen_cranelift/example/mini_core.rs index 08adec96a079b..288d266ef6821 100644 --- a/compiler/rustc_codegen_cranelift/example/mini_core.rs +++ b/compiler/rustc_codegen_cranelift/example/mini_core.rs @@ -835,6 +835,20 @@ struct PanicLocation { column: u32, } +#[track_caller] +#[lang = "panic_misaligned_pointer_dereference"] // needed by codegen for panic on misaligned pointer deref +#[rustc_nounwind] // `CheckAlignment` MIR pass requires this function to never unwind +fn panic_misaligned_pointer_dereference(_required: usize, _found: usize) -> ! { + loop {} +} + +#[track_caller] +#[lang = "panic_null_pointer_dereference"] // needed by codegen for panic on null pointer deref +#[rustc_nounwind] // `CheckNull` MIR pass requires this function to never unwind +fn panic_null_pointer_dereference() -> ! { + loop {} +} + #[unsafe(no_mangle)] #[cfg(not(all(windows, target_env = "gnu")))] pub fn get_tls() -> u8 { diff --git a/compiler/rustc_codegen_gcc/example/alloc_example.rs b/compiler/rustc_codegen_gcc/example/alloc_example.rs index 9a0b46d5b221a..caa278f0000ed 100644 --- a/compiler/rustc_codegen_gcc/example/alloc_example.rs +++ b/compiler/rustc_codegen_gcc/example/alloc_example.rs @@ -18,11 +18,6 @@ extern "C" { fn puts(s: *const u8) -> i32; } -#[panic_handler] -fn panic_handler(_: &core::panic::PanicInfo<'_>) -> ! { - core::intrinsics::abort(); -} - #[alloc_error_handler] fn alloc_error_handler(_: alloc::alloc::Layout) -> ! { core::intrinsics::abort(); diff --git a/compiler/rustc_codegen_gcc/example/mini_core.rs b/compiler/rustc_codegen_gcc/example/mini_core.rs index 2d5a29ceb8191..b1bb67e2871f1 100644 --- a/compiler/rustc_codegen_gcc/example/mini_core.rs +++ b/compiler/rustc_codegen_gcc/example/mini_core.rs @@ -6,6 +6,7 @@ extern_types, decl_macro, rustc_attrs, + rustc_private, transparent_unions, auto_traits, freeze_impls, @@ -572,6 +573,20 @@ fn panic_bounds_check(index: usize, len: usize) -> ! { } } +#[track_caller] +#[lang = "panic_misaligned_pointer_dereference"] // needed by codegen for panic on misaligned pointer deref +#[rustc_nounwind] // `CheckAlignment` MIR pass requires this function to never unwind +fn panic_misaligned_pointer_dereference(_required: usize, _found: usize) -> ! { + loop {} +} + +#[track_caller] +#[lang = "panic_null_pointer_dereference"] // needed by codegen for panic on null pointer deref +#[rustc_nounwind] // `CheckNull` MIR pass requires this function to never unwind +fn panic_null_pointer_dereference() -> ! { + loop {} +} + #[lang = "eh_personality"] fn eh_personality() -> ! { loop {} diff --git a/compiler/rustc_error_codes/src/error_codes/E0264.md b/compiler/rustc_error_codes/src/error_codes/E0264.md index b8d0f7d4d6af0..14358a5aba65c 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0264.md +++ b/compiler/rustc_error_codes/src/error_codes/E0264.md @@ -20,7 +20,7 @@ A list of available external lang items is available in #![allow(internal_features)] extern "C" { - #[lang = "panic_impl"] // ok! + #[lang = "eh_personality"] // ok! fn cake(); } ``` diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 6a9cfeff49339..a2e5ada92dbcd 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -145,7 +145,6 @@ pub static BUILTIN_ATTRIBUTES: &[Symbol] = &[ // Runtime sym::windows_subsystem, - sym::panic_handler, // RFC 2070 // Code generation: sym::inline, diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index f0b6d0fb8dcc9..08247dca602d3 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -284,9 +284,7 @@ language_item_table! { ConstPanicFmt, sym::const_panic_fmt, const_panic_fmt, Target::Fn, GenericRequirement::None; PanicBoundsCheck, sym::panic_bounds_check, panic_bounds_check_fn, Target::Fn, GenericRequirement::Exact(0); PanicMisalignedPointerDereference, sym::panic_misaligned_pointer_dereference, panic_misaligned_pointer_dereference_fn, Target::Fn, GenericRequirement::Exact(0); - PanicInfo, sym::panic_info, panic_info, Target::Struct, GenericRequirement::None; PanicLocation, sym::panic_location, panic_location, Target::Struct, GenericRequirement::None; - PanicImpl, sym::panic_impl, panic_impl, Target::Fn, GenericRequirement::None; PanicCannotUnwind, sym::panic_cannot_unwind, panic_cannot_unwind, Target::Fn, GenericRequirement::Exact(0); PanicInCleanup, sym::panic_in_cleanup, panic_in_cleanup, Target::Fn, GenericRequirement::Exact(0); /// Constant panic messages, used for codegen of MIR asserts. diff --git a/compiler/rustc_hir/src/weak_lang_items.rs b/compiler/rustc_hir/src/weak_lang_items.rs index f9d94bd505724..5f9b449c7df07 100644 --- a/compiler/rustc_hir/src/weak_lang_items.rs +++ b/compiler/rustc_hir/src/weak_lang_items.rs @@ -36,7 +36,6 @@ macro_rules! weak_only_lang_items { } weak_lang_items! { - PanicImpl, rust_begin_unwind; EhPersonality, rust_eh_personality; } diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index 1780430567a80..fd49141f10b0e 100644 --- a/compiler/rustc_hir_typeck/src/check.rs +++ b/compiler/rustc_hir_typeck/src/check.rs @@ -1,7 +1,6 @@ use std::cell::RefCell; use rustc_hir as hir; -use rustc_hir::def::DefKind; use rustc_hir::lang_items::LangItem; use rustc_hir_analysis::check::check_function_signature; use rustc_infer::infer::RegionVariableOrigin; @@ -149,11 +148,6 @@ pub(super) fn check_fn<'a, 'tcx>( // we have a recursive call site and do the sadly stabilized fallback to `()`. fcx.demand_suptype(span, ret_ty, actual_return_ty); - // Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !` - if tcx.is_lang_item(fn_def_id.to_def_id(), LangItem::PanicImpl) { - check_panic_info_fn(tcx, fn_def_id, fn_sig); - } - if tcx.is_lang_item(fn_def_id.to_def_id(), LangItem::Start) { check_lang_start_fn(tcx, fn_sig, fn_def_id); } @@ -161,63 +155,6 @@ pub(super) fn check_fn<'a, 'tcx>( fcx.coroutine_types } -fn check_panic_info_fn(tcx: TyCtxt<'_>, fn_id: LocalDefId, fn_sig: ty::FnSig<'_>) { - let span = tcx.def_span(fn_id); - - let DefKind::Fn = tcx.def_kind(fn_id) else { - tcx.dcx().span_err(span, "should be a function"); - return; - }; - - let generic_counts = tcx.generics_of(fn_id).own_counts(); - if generic_counts.types != 0 { - tcx.dcx().span_err(span, "should have no type parameters"); - } - if generic_counts.consts != 0 { - tcx.dcx().span_err(span, "should have no const parameters"); - } - - let panic_info_did = tcx.require_lang_item(hir::LangItem::PanicInfo, span); - - // build type `for<'a, 'b> fn(&'a PanicInfo<'b>) -> !` - let panic_info_ty = tcx - .type_of(panic_info_did) - .instantiate( - tcx, - &[ty::GenericArg::from(ty::Region::new_bound( - tcx, - ty::INNERMOST, - ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BoundRegionKind::Anon }, - ))], - ) - .skip_norm_wip(); - let panic_info_ref_ty = Ty::new_imm_ref( - tcx, - ty::Region::new_bound( - tcx, - ty::INNERMOST, - ty::BoundRegion { var: ty::BoundVar::ZERO, kind: ty::BoundRegionKind::Anon }, - ), - panic_info_ty, - ); - - let bounds = tcx.mk_bound_variable_kinds(&[ - ty::BoundVariableKind::Region(ty::BoundRegionKind::Anon), - ty::BoundVariableKind::Region(ty::BoundRegionKind::Anon), - ]); - let expected_sig = ty::Binder::bind_with_vars( - tcx.mk_fn_sig_rust_abi([panic_info_ref_ty], tcx.types.never, fn_sig.safety()), - bounds, - ); - - let _ = check_function_signature( - tcx, - ObligationCause::new(span, fn_id, ObligationCauseCode::LangFunctionType(sym::panic_impl)), - fn_id.into(), - expected_sig, - ); -} - fn check_lang_start_fn<'tcx>(tcx: TyCtxt<'tcx>, fn_sig: ty::FnSig<'tcx>, def_id: LocalDefId) { // build type `fn(main: fn() -> T, argc: isize, argv: *const *const u8, sigpipe: u8)` diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index bed2be51a3468..11ec035fe92e0 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -774,10 +774,9 @@ impl MetadataBlob { )?; writeln!( out, - "has_global_allocator {} has_alloc_error_handler {} has_panic_handler {} has_default_lib_allocator {}", + "has_global_allocator {} has_alloc_error_handler {} has_default_lib_allocator {}", root.has_global_allocator, root.has_alloc_error_handler, - root.has_panic_handler, root.has_default_lib_allocator )?; writeln!( diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index dff8a4078da16..339dd1000fa6b 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -332,8 +332,6 @@ provide! { tcx, def_id, other, cdata, has_global_allocator => { cdata.root.has_global_allocator } // FIXME: to be replaced with externally_implementable_items below has_alloc_error_handler => { cdata.root.has_alloc_error_handler } - // FIXME: to be replaced with externally_implementable_items below - has_panic_handler => { cdata.root.has_panic_handler } externally_implementable_items => { cdata.get_externally_implementable_items(tcx) diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 16a5a6c8877a5..4cffe02354473 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -737,7 +737,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { edition: tcx.sess.edition(), has_global_allocator: tcx.has_global_allocator(LOCAL_CRATE), has_alloc_error_handler: tcx.has_alloc_error_handler(LOCAL_CRATE), - has_panic_handler: tcx.has_panic_handler(LOCAL_CRATE), has_default_lib_allocator: find_attr!(attrs, DefaultLibAllocator), externally_implementable_items, proc_macro_data, diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 90721f0f1fc11..f823fdc0b9e87 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -257,7 +257,6 @@ pub(crate) struct CrateRoot { edition: Edition, has_global_allocator: bool, has_alloc_error_handler: bool, - has_panic_handler: bool, has_default_lib_allocator: bool, externally_implementable_items: LazyArray, diff --git a/compiler/rustc_middle/src/middle/lang_items.rs b/compiler/rustc_middle/src/middle/lang_items.rs index 07153d688d477..8d45f932cc109 100644 --- a/compiler/rustc_middle/src/middle/lang_items.rs +++ b/compiler/rustc_middle/src/middle/lang_items.rs @@ -113,8 +113,9 @@ pub fn required(tcx: TyCtxt<'_>, lang_item: LangItem) -> bool { // symbol. Other panic runtimes ensure that the relevant symbols are // available to link things together, but they're never exercised. match tcx.sess.panic_strategy() { - PanicStrategy::Abort => lang_item != LangItem::EhPersonality, + PanicStrategy::Abort | PanicStrategy::ImmediateAbort => { + lang_item != LangItem::EhPersonality + } PanicStrategy::Unwind => true, - PanicStrategy::ImmediateAbort => false, } } diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index f0557c3d3381a..0618b86afc6be 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -1816,10 +1816,6 @@ rustc_queries! { desc { "checking if the crate has_alloc_error_handler" } separate_provide_extern } - query has_panic_handler(_: CrateNum) -> bool { - desc { "checking if the crate has_panic_handler" } - separate_provide_extern - } query is_profiler_runtime(_: CrateNum) -> bool { desc { "checking if a crate is `#![profiler_runtime]`" } separate_provide_extern diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 8bbb5e9244c2e..b2b65b00d1a91 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2824,9 +2824,5 @@ impl<'tcx> TyCtxt<'tcx> { pub fn provide(providers: &mut Providers) { providers.is_panic_runtime = |tcx, LocalCrate| find_attr!(tcx, crate, PanicRuntime); providers.is_compiler_builtins = |tcx, LocalCrate| find_attr!(tcx, crate, CompilerBuiltins); - providers.has_panic_handler = |tcx, LocalCrate| { - // We want to check if the panic handler was defined in this crate - tcx.lang_items().panic_impl().is_some_and(|did| did.is_local()) - }; providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP); } diff --git a/compiler/rustc_mir_transform/src/check_enums.rs b/compiler/rustc_mir_transform/src/check_enums.rs index ea545317e980d..a494e06c86c7d 100644 --- a/compiler/rustc_mir_transform/src/check_enums.rs +++ b/compiler/rustc_mir_transform/src/check_enums.rs @@ -1,6 +1,5 @@ use rustc_abi::{Scalar, Size, TagEncoding, Variants, WrappingRange}; use rustc_data_structures::thin_vec::ThinVec; -use rustc_hir::LangItem; use rustc_index::IndexVec; use rustc_middle::bug; use rustc_middle::mir::visit::Visitor; @@ -21,12 +20,6 @@ impl<'tcx> crate::MirPass<'tcx> for CheckEnums { } fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - // This pass emits new panics. If for whatever reason we do not have a panic - // implementation, running this pass may cause otherwise-valid code to not compile. - if tcx.lang_items().get(LangItem::PanicImpl).is_none() { - return; - } - let typing_env = body.typing_env(tcx); let basic_blocks = body.basic_blocks.as_mut(); let local_decls = &mut body.local_decls; diff --git a/compiler/rustc_mir_transform/src/check_pointers.rs b/compiler/rustc_mir_transform/src/check_pointers.rs index 0a87e0ed5c78e..67fbe0ab6ad84 100644 --- a/compiler/rustc_mir_transform/src/check_pointers.rs +++ b/compiler/rustc_mir_transform/src/check_pointers.rs @@ -1,5 +1,4 @@ use rustc_data_structures::thin_vec::ThinVec; -use rustc_hir::lang_items::LangItem; use rustc_index::IndexVec; use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; @@ -58,12 +57,6 @@ pub(crate) fn check_pointers<'tcx, F>( /* source_info: */ SourceInfo, ) -> PointerCheck<'tcx>, { - // This pass emits new panics. If for whatever reason we do not have a panic - // implementation, running this pass may cause otherwise-valid code to not compile. - if tcx.lang_items().get(LangItem::PanicImpl).is_none() { - return; - } - let typing_env = body.typing_env(tcx); let basic_blocks = body.basic_blocks.as_mut(); let local_decls = &mut body.local_decls; diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index bf4a2bdd15107..e0c20be674031 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -887,9 +887,9 @@ fn mono_item_visibility<'tcx>( // // * First is weak lang items. These are basically mechanisms for // libcore to forward-reference symbols defined later in crates like - // the standard library or `#[panic_handler]` definitions. The - // definition of these weak lang items needs to be referenceable by - // libcore, so we're no longer a candidate for internalization. + // the standard library or `#[lang = "eh_personality"]` definitions. + // The definition of these weak lang items needs to be referenceable + // by libcore, so we're no longer a candidate for internalization. // Removal of these functions can't be done by LLVM but rather must be // done by the linker as it's a non-local decision. // diff --git a/compiler/rustc_passes/src/diagnostics.rs b/compiler/rustc_passes/src/diagnostics.rs index 92562cc462b87..aa7acea6c91a1 100644 --- a/compiler/rustc_passes/src/diagnostics.rs +++ b/compiler/rustc_passes/src/diagnostics.rs @@ -318,10 +318,6 @@ pub(crate) struct DeprecatedAnnotationHasNoEffect { pub span: Span, } -#[derive(Diagnostic)] -#[diag("`#[panic_handler]` function required, but not found")] -pub(crate) struct MissingPanicHandler; - #[derive(Diagnostic)] #[diag("unwinding panics are not supported without std")] #[help("using nightly cargo, use -Zbuild-std with panic=\"abort\" to avoid unwinding")] @@ -343,22 +339,12 @@ pub(crate) struct MissingLangItem { } #[derive(Diagnostic)] -#[diag( - "{$name -> - [panic_impl] `#[panic_handler]` - *[other] `{$name}` lang item -} function is not allowed to have `#[track_caller]`" -)] +#[diag("`{$name}` lang item function is not allowed to have `#[track_caller]`")] pub(crate) struct LangItemWithTrackCaller { #[primary_span] pub attr_span: Span, pub name: Symbol, - #[label( - "{$name -> - [panic_impl] `#[panic_handler]` - *[other] `{$name}` lang item - } function is not allowed to have `#[track_caller]`" - )] + #[label("`{$name}` lang item function is not allowed to have `#[track_caller]`")] pub sig_span: Span, } diff --git a/compiler/rustc_passes/src/lang_items.rs b/compiler/rustc_passes/src/lang_items.rs index a5a835d4a78c3..86c24bce41f8a 100644 --- a/compiler/rustc_passes/src/lang_items.rs +++ b/compiler/rustc_passes/src/lang_items.rs @@ -379,14 +379,12 @@ impl<'ast, 'tcx> visit::Visitor<'ast> for LanguageItemCollector<'ast, 'tcx> { } /// Extracts the first `lang = "$name"` out of a list of attributes. -/// The `#[panic_handler]` attribute is also extracted out when found. /// /// This function is used for `ast::Attribute`, for `hir::Attribute` use the `find_attr!` macro with `AttributeKind::Lang` pub(crate) fn extract_ast(attrs: &[rustc_ast::ast::Attribute]) -> Option<(Symbol, Span)> { attrs.iter().find_map(|attr| { Some(match attr { _ if attr.has_name(sym::lang) => (attr.value_str()?, attr.span()), - _ if attr.has_name(sym::panic_handler) => (sym::panic_impl, attr.span()), _ => return None, }) }) diff --git a/compiler/rustc_passes/src/weak_lang_items.rs b/compiler/rustc_passes/src/weak_lang_items.rs index 50730b852455c..86e6cc41f7694 100644 --- a/compiler/rustc_passes/src/weak_lang_items.rs +++ b/compiler/rustc_passes/src/weak_lang_items.rs @@ -9,7 +9,7 @@ use rustc_middle::middle::lang_items::required; use rustc_middle::ty::TyCtxt; use rustc_session::config::CrateType; -use crate::diagnostics::{MissingLangItem, MissingPanicHandler, PanicUnwindWithoutStd}; +use crate::diagnostics::{MissingLangItem, PanicUnwindWithoutStd}; use crate::lang_items::extract_ast; /// Checks the crate for usage of weak lang items, returning a vector of all the @@ -73,9 +73,7 @@ fn verify(tcx: TyCtxt<'_>, items: &lang_items::LanguageItems) { for &item in WEAK_LANG_ITEMS.iter() { if missing.contains(&item) && required(tcx, item) && items.get(item).is_none() { - if item == LangItem::PanicImpl { - tcx.dcx().emit_err(MissingPanicHandler); - } else if item == LangItem::EhPersonality { + if item == LangItem::EhPersonality { tcx.dcx().emit_err(PanicUnwindWithoutStd); } else { tcx.dcx().emit_err(MissingLangItem { name: item.name() }); diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index 4c5c591ad94e3..7af1d95e19e45 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -436,7 +436,6 @@ impl Resolver<'_, '_> { !tcx.is_compiler_builtins(cnum) && !tcx.is_panic_runtime(cnum) && !tcx.has_global_allocator(cnum) - && !tcx.has_panic_handler(cnum) && tcx .externally_implementable_items(cnum) .values() diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index db2804a3f83bf..0a4e6e9d0bdc4 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1527,7 +1527,6 @@ symbols! { panic_display, panic_fmt, panic_handler, - panic_impl, panic_implementation, panic_in_cleanup, panic_info, diff --git a/compiler/rustc_trait_selection/src/diagnostics.rs b/compiler/rustc_trait_selection/src/diagnostics.rs index ba89b0987659e..aee35c431c592 100644 --- a/compiler/rustc_trait_selection/src/diagnostics.rs +++ b/compiler/rustc_trait_selection/src/diagnostics.rs @@ -1804,12 +1804,7 @@ pub enum ObligationCauseFailureCode { #[primary_span] span: Span, }, - #[diag( - "{$lang_item_name -> - [panic_impl] `#[panic_handler]` - *[lang_item_name] lang item `{$lang_item_name}` - } function has wrong type" - , code = E0308)] + #[diag("lang item `{$lang_item_name}` function has wrong type", code = E0308)] FnLangCorrectType { #[primary_span] span: Span, diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 2d7dd41ebac2f..79f0a559a56e6 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -123,6 +123,7 @@ #![feature(diagnostic_on_unmatched_args)] #![feature(doc_cfg)] #![feature(doc_notable_trait)] +#![feature(extern_item_impls)] #![feature(extern_types)] #![feature(f16)] #![feature(f128)] diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 932a2fc0bad92..9a2cbdb1d8d2a 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -12,6 +12,16 @@ macro_rules! panic { }; } +#[macro_export] +#[rustc_builtin_macro(panic_handler)] +#[allow_internal_unstable(extern_item_impls)] +#[stable(feature = "panic_handler", since = "1.30.0")] +macro_rules! panic_handler { + ($($arg:tt)*) => { + /* compiler built-in */ + }; +} + /// Asserts that two expressions are equal to each other (using [`PartialEq`]). /// /// Assertions are always checked in both debug and release builds, and cannot diff --git a/library/core/src/panic/panic_info.rs b/library/core/src/panic/panic_info.rs index ee22521cb014c..e6fded4a7c561 100644 --- a/library/core/src/panic/panic_info.rs +++ b/library/core/src/panic/panic_info.rs @@ -8,7 +8,6 @@ use crate::panic::Location; /// For the type used by the panic hook mechanism in `std`, see [`std::panic::PanicHookInfo`]. /// /// [`std::panic::PanicHookInfo`]: ../../std/panic/struct.PanicHookInfo.html -#[lang = "panic_info"] #[stable(feature = "panic_hooks", since = "1.10.0")] #[derive(Debug)] pub struct PanicInfo<'a> { diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index 46790b620127b..15eda6f3ec844 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -13,7 +13,8 @@ //! interface for panicking is: //! //! ``` -//! fn panic_impl(pi: &core::panic::PanicInfo<'_>) -> ! +//! #[eii(panic_handler)] +//! fn panic_handler(pi: &core::panic::PanicInfo<'_>) -> ! //! # { loop {} } //! ``` //! @@ -40,6 +41,11 @@ compile_error!( In both cases, you still need to build core, e.g. with `-Zbuild-std`" ); +/// The user defined `#[panic_handler]` function. +#[eii(panic_handler)] +#[rustc_diagnostic_item = "panic_handler"] +fn panic_impl(pi: &PanicInfo<'_>) -> !; + // First we define the two main entry points that all panics go through. // In the end both are just convenience wrappers around `panic_impl`. @@ -62,13 +68,6 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! { super::intrinsics::abort() } - // NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call - // that gets resolved to the `#[panic_handler]` function. - unsafe extern "Rust" { - #[lang = "panic_impl"] - fn panic_impl(pi: &PanicInfo<'_>) -> !; - } - let pi = PanicInfo::new( &fmt, Location::caller(), @@ -76,8 +75,7 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! { /* force_no_backtrace */ false, ); - // SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call. - unsafe { panic_impl(&pi) } + panic_impl(&pi) } /// Like `panic_fmt`, but for non-unwinding panics. @@ -103,13 +101,6 @@ pub const fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>, force_no_backtrace: boo super::intrinsics::abort() } - // NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call - // that gets resolved to the `#[panic_handler]` function. - unsafe extern "Rust" { - #[lang = "panic_impl"] - fn panic_impl(pi: &PanicInfo<'_>) -> !; - } - // PanicInfo with the `can_unwind` flag set to false forces an abort. let pi = PanicInfo::new( &fmt, @@ -118,8 +109,7 @@ pub const fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>, force_no_backtrace: boo force_no_backtrace, ); - // SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call. - unsafe { panic_impl(&pi) } + panic_impl(&pi) } ) } diff --git a/library/core/src/prelude/v1.rs b/library/core/src/prelude/v1.rs index 6122ab12ec351..a86b76f14b91d 100644 --- a/library/core/src/prelude/v1.rs +++ b/library/core/src/prelude/v1.rs @@ -63,7 +63,8 @@ pub use crate::hash::macros::Hash; pub use crate::{ 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, + module_path, option_env, panic_handler, 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 diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index 7db6e93e8bd02..b3a52749dca8f 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -606,7 +606,7 @@ pub fn panicking() -> bool { !panic_count::count_is_zero() } -/// Entry point of panics from the core crate (`panic_impl` lang item). +/// Entry point of panics from the core crate (`panic_handler` EII). #[cfg(not(any(test, doctest)))] #[panic_handler] pub fn panic_handler(info: &core::panic::PanicInfo<'_>) -> ! { diff --git a/library/std/src/prelude/v1.rs b/library/std/src/prelude/v1.rs index aeefec8b9e084..8d7009837fd97 100644 --- a/library/std/src/prelude/v1.rs +++ b/library/std/src/prelude/v1.rs @@ -50,8 +50,8 @@ pub use crate::result::Result::{self, Err, Ok}; pub use core::prelude::v1::{ assert, assert_eq, assert_ne, cfg, column, compile_error, concat, debug_assert, debug_assert_eq, debug_assert_ne, env, file, format_args, include, include_bytes, include_str, line, matches, - module_path, option_env, stringify, todo, r#try, unimplemented, unreachable, write, - writeln, Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd, + module_path, option_env, panic_handler, stringify, todo, r#try, unimplemented, unreachable, + write, writeln, Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd, }; #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 0264c68776085..3a736db35e6c4 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -1069,8 +1069,11 @@ pub fn is_entrypoint_fn(cx: &LateContext<'_>, def_id: DefId) -> bool { /// Returns `true` if the expression is in the program's `#[panic_handler]`. pub fn is_in_panic_handler(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { - let parent = cx.tcx.hir_get_parent_item(e.hir_id); - Some(parent.to_def_id()) == cx.tcx.lang_items().panic_impl() + let parent = cx.tcx.hir_get_parent_item(e.hir_id).to_def_id(); + cx.tcx + .externally_implementable_items(parent.krate) + .get(&cx.tcx.get_diagnostic_item(sym::panic_handler).unwrap()) + .map_or(false, |(_, impls)| impls.keys().any(|&impl_| impl_ == parent)) } /// Gets the name of the item the expression is in, if available. diff --git a/tests/auxiliary/minicore.rs b/tests/auxiliary/minicore.rs index e50b9b785ad48..eafdc705cb9a7 100644 --- a/tests/auxiliary/minicore.rs +++ b/tests/auxiliary/minicore.rs @@ -112,6 +112,15 @@ impl Copy for [T; N] {} pub struct PhantomData; impl Copy for PhantomData {} +trait SizedTypeProperties: Sized { + #[lang = "mem_size_const"] + const SIZE: usize = mem::size_of::(); + + #[lang = "mem_align_const"] + const ALIGN: usize = mem::align_of::(); +} +impl SizedTypeProperties for T {} + pub enum Option { None, Some(T), @@ -428,3 +437,24 @@ pub enum SimdAlign { } impl ConstParamTy_ for SimdAlign {} + +#[lang = "panic_location"] +struct PanicLocation { + file: &'static str, + line: u32, + column: u32, +} + +#[track_caller] +#[lang = "panic_misaligned_pointer_dereference"] // needed by codegen for panic on misaligned pointer deref +#[rustc_nounwind] // `CheckAlignment` MIR pass requires this function to never unwind +fn panic_misaligned_pointer_dereference(_required: usize, _found: usize) -> ! { + loop {} +} + +#[track_caller] +#[lang = "panic_null_pointer_dereference"] // needed by codegen for panic on null pointer deref +#[rustc_nounwind] // `CheckNull` MIR pass requires this function to never unwind +fn panic_null_pointer_dereference() -> ! { + loop {} +} diff --git a/tests/ui/codegen/no-mangle-on-panic-handler.rs b/tests/ui/codegen/no-mangle-on-panic-handler.rs deleted file mode 100644 index 1dc0cce0a2ece..0000000000000 --- a/tests/ui/codegen/no-mangle-on-panic-handler.rs +++ /dev/null @@ -1,14 +0,0 @@ -// Issue an error when the user uses #[no_mangle] on the panic handler -//@ edition:2024 - -#![crate_type="lib"] -#![no_std] -#![no_main] - -use core::panic::PanicInfo; - -#[unsafe(no_mangle)] //~ ERROR `#[no_mangle]` cannot be used on internal language items -#[panic_handler] -pub unsafe fn panic_fmt(pi: &PanicInfo) -> ! { - loop {} -} diff --git a/tests/ui/codegen/no-mangle-on-panic-handler.stderr b/tests/ui/codegen/no-mangle-on-panic-handler.stderr deleted file mode 100644 index dc88b66d1b5d7..0000000000000 --- a/tests/ui/codegen/no-mangle-on-panic-handler.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error: `#[no_mangle]` cannot be used on internal language items - --> $DIR/no-mangle-on-panic-handler.rs:10:1 - | -LL | #[unsafe(no_mangle)] - | ^^^^^^^^^^^^^^^^^^^^ -LL | #[panic_handler] -LL | pub unsafe fn panic_fmt(pi: &PanicInfo) -> ! { - | -------------------------------------------- should be the internal language item - | - = note: Rustc requires this item to have a specific mangled name. - = note: If you are trying to prevent mangling to ease debugging, many - = note: debuggers support a command such as `rbreak rust_begin_unwind` to - = note: match `.*rust_begin_unwind.*` instead of `break rust_begin_unwind` on a specific name - -error: aborting due to 1 previous error - diff --git a/tests/ui/extern-flag/empty-extern-arg.stderr b/tests/ui/extern-flag/empty-extern-arg.stderr index 3e0a0d6cd5f86..c3d3c593c8c9a 100644 --- a/tests/ui/extern-flag/empty-extern-arg.stderr +++ b/tests/ui/extern-flag/empty-extern-arg.stderr @@ -2,12 +2,17 @@ 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: `#[panic_handler]` function required, but not found + --> $SRC_DIR/core/src/panicking.rs:LL:COL + | + = note: expected because `#[panic_handler]` was declared here in crate `core` + | + = help: expected at least one implementation in crate `empty_extern_arg` or any of its dependencies + error: aborting due to 4 previous errors diff --git a/tests/ui/limits/issue-17913.64bit.stderr b/tests/ui/limits/issue-17913.64bit.stderr index 5e92c70a764c4..b0481ee99378c 100644 --- a/tests/ui/limits/issue-17913.64bit.stderr +++ b/tests/ui/limits/issue-17913.64bit.stderr @@ -3,12 +3,17 @@ error[E0080]: values of the type `[&usize; usize::MAX]` are too big for the targ | = note: evaluation of `<[&usize; usize::MAX] as std::mem::SizedTypeProperties>::SIZE` failed here +error[E0080]: values of the type `[&usize; usize::MAX]` are too big for the target architecture + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL + | + = note: evaluation of `<[&usize; usize::MAX] as std::mem::SizedTypeProperties>::ALIGN` failed here + note: the above error was encountered while instantiating `fn Box::<[&usize; usize::MAX]>::new` --> $DIR/issue-17913.rs:9:21 | LL | let a: Box<_> = Box::new([&n; SIZE]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/limits/issue-17913.rs b/tests/ui/limits/issue-17913.rs index 9448358edba00..d804b64ab330e 100644 --- a/tests/ui/limits/issue-17913.rs +++ b/tests/ui/limits/issue-17913.rs @@ -18,3 +18,4 @@ fn main() { } //~? ERROR are too big for the target architecture +//~? ERROR are too big for the target architecture diff --git a/tests/ui/mir/checks_without_panic_impl.rs b/tests/ui/mir/checks_without_panic_impl.rs deleted file mode 100644 index f4624fedd0c85..0000000000000 --- a/tests/ui/mir/checks_without_panic_impl.rs +++ /dev/null @@ -1,18 +0,0 @@ -// Ensures that the alignment check we insert for raw pointer dereferences -// does not prevent crates without a panic_impl from compiling. -// See rust-lang/rust#109996 - -//@ add-minicore -//@ build-pass -//@ compile-flags: -Cdebug-assertions=yes - -#![crate_type = "lib"] - -#![feature(lang_items)] -#![feature(no_core)] -#![no_core] - -extern crate minicore; -use minicore::*; - -pub unsafe fn foo(x: *const i32) -> &'static i32 { unsafe { &*x } } diff --git a/tests/ui/panic-handler/panic-handler-bad-signature-1.rs b/tests/ui/panic-handler/panic-handler-bad-signature-1.rs index 71911afaa8430..aab04e1dfa3b5 100644 --- a/tests/ui/panic-handler/panic-handler-bad-signature-1.rs +++ b/tests/ui/panic-handler/panic-handler-bad-signature-1.rs @@ -7,4 +7,4 @@ use core::panic::PanicInfo; #[panic_handler] fn panic(info: PanicInfo) -> () {} -//~^ ERROR `#[panic_handler]` function has wrong type [E0308] +//~^ ERROR function `panic` has a type that is incompatible with the declaration of `#[panic_handler]` [E0806] diff --git a/tests/ui/panic-handler/panic-handler-bad-signature-1.stderr b/tests/ui/panic-handler/panic-handler-bad-signature-1.stderr index 4fea52fec6e11..1f5d636b91a39 100644 --- a/tests/ui/panic-handler/panic-handler-bad-signature-1.stderr +++ b/tests/ui/panic-handler/panic-handler-bad-signature-1.stderr @@ -1,12 +1,22 @@ -error[E0308]: `#[panic_handler]` function has wrong type +error[E0806]: function `panic` has a type that is incompatible with the declaration of `#[panic_handler]` --> $DIR/panic-handler-bad-signature-1.rs:9:16 | LL | fn panic(info: PanicInfo) -> () {} | ^^^^^^^^^ expected `&PanicInfo<'_>`, found `PanicInfo<'_>` | - = note: expected signature `for<'a, 'b> fn(&'a PanicInfo<'b>) -> !` - found signature `for<'a> fn(PanicInfo<'a>) -> ()` +note: expected this because of this attribute + --> $DIR/panic-handler-bad-signature-1.rs:8:1 + | +LL | #[panic_handler] + | ^^^^^^^^^^^^^^^^ + = note: expected signature `fn(&PanicInfo<'_>) -> !` + found signature `fn(PanicInfo<'_>) -> ()` +help: change the parameter type to match the declaration + | +LL - fn panic(info: PanicInfo) -> () {} +LL + fn panic(info: &PanicInfo<'_>) -> () {} + | error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0806`. diff --git a/tests/ui/panic-handler/panic-handler-bad-signature-2.rs b/tests/ui/panic-handler/panic-handler-bad-signature-2.rs index 9c0130eff21f7..f8d3ab305304f 100644 --- a/tests/ui/panic-handler/panic-handler-bad-signature-2.rs +++ b/tests/ui/panic-handler/panic-handler-bad-signature-2.rs @@ -7,7 +7,8 @@ use core::panic::PanicInfo; #[panic_handler] fn panic(info: &'static PanicInfo) -> ! -//~^ ERROR #[panic_handler]` function has wrong type [E0308] +//~^ ERROR mismatched types [E0308] +//~^^ ERROR cannot infer an appropriate lifetime for lifetime parameter '_ { loop {} } diff --git a/tests/ui/panic-handler/panic-handler-bad-signature-2.stderr b/tests/ui/panic-handler/panic-handler-bad-signature-2.stderr index 736a4c7094c5d..94d51297b8b78 100644 --- a/tests/ui/panic-handler/panic-handler-bad-signature-2.stderr +++ b/tests/ui/panic-handler/panic-handler-bad-signature-2.stderr @@ -1,12 +1,38 @@ -error[E0308]: `#[panic_handler]` function has wrong type +error[E0308]: mismatched types --> $DIR/panic-handler-bad-signature-2.rs:9:1 | LL | fn panic(info: &'static PanicInfo) -> ! - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch | - = note: expected signature `for<'a, 'b> fn(&'a PanicInfo<'b>) -> _` - found signature `for<'a> fn(&'static PanicInfo<'a>) -> _` + = note: expected signature `fn(&PanicInfo<'_>) -> _` + found signature `fn(&'static PanicInfo<'_>) -> _` +note: the anonymous lifetime as defined here... + --> $SRC_DIR/core/src/panicking.rs:LL:COL + = note: ...does not necessarily outlive the static lifetime -error: aborting due to 1 previous error +error[E0803]: cannot infer an appropriate lifetime for lifetime parameter '_ in generic type due to conflicting requirements + --> $DIR/panic-handler-bad-signature-2.rs:9:1 + | +LL | fn panic(info: &'static PanicInfo) -> ! + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: first, the lifetime cannot outlive the anonymous lifetime as defined here... + --> $SRC_DIR/core/src/panicking.rs:LL:COL +note: ...so that the types are compatible + --> $DIR/panic-handler-bad-signature-2.rs:9:1 + | +LL | fn panic(info: &'static PanicInfo) -> ! + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: expected `fn(&PanicInfo<'_>) -> _` + found `fn(&'static PanicInfo<'_>) -> _` + = note: but, the lifetime must be valid for the static lifetime... +note: ...so that the reference type `&'static PanicInfo<'_>` does not outlive the data it points at + --> $DIR/panic-handler-bad-signature-2.rs:9:1 + | +LL | fn panic(info: &'static PanicInfo) -> ! + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0308, E0803. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/panic-handler/panic-handler-bad-signature-3.rs b/tests/ui/panic-handler/panic-handler-bad-signature-3.rs index 14c8c7c63b70c..456092abbf61d 100644 --- a/tests/ui/panic-handler/panic-handler-bad-signature-3.rs +++ b/tests/ui/panic-handler/panic-handler-bad-signature-3.rs @@ -6,6 +6,7 @@ use core::panic::PanicInfo; #[panic_handler] -fn panic() -> ! { //~ ERROR #[panic_handler]` function has wrong type [E0308] +fn panic() -> ! { + //~^ ERROR `panic` has 0 parameters but #[panic_handler] requires it to have 1 [E0806] loop {} } diff --git a/tests/ui/panic-handler/panic-handler-bad-signature-3.stderr b/tests/ui/panic-handler/panic-handler-bad-signature-3.stderr index 6cd072c639625..086dffd218243 100644 --- a/tests/ui/panic-handler/panic-handler-bad-signature-3.stderr +++ b/tests/ui/panic-handler/panic-handler-bad-signature-3.stderr @@ -1,12 +1,15 @@ -error[E0308]: `#[panic_handler]` function has wrong type +error[E0806]: `panic` has 0 parameters but #[panic_handler] requires it to have 1 --> $DIR/panic-handler-bad-signature-3.rs:9:1 | +LL | #[panic_handler] + | ---------------- required because of this attribute LL | fn panic() -> ! { - | ^^^^^^^^^^^^^^^ incorrect number of function parameters + | ^^^^^^^^^^^^^^^ expected 1 parameter, found 0 | - = note: expected signature `for<'a, 'b> fn(&'a PanicInfo<'b>) -> _` - found signature `fn() -> _` + --> $SRC_DIR/core/src/panicking.rs:LL:COL + | + = note: requires 1 parameter error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0806`. diff --git a/tests/ui/panic-handler/panic-handler-bad-signature-4.rs b/tests/ui/panic-handler/panic-handler-bad-signature-4.rs index 8fc5b3240140f..385d16e8d7b7f 100644 --- a/tests/ui/panic-handler/panic-handler-bad-signature-4.rs +++ b/tests/ui/panic-handler/panic-handler-bad-signature-4.rs @@ -7,6 +7,6 @@ use core::panic::PanicInfo; #[panic_handler] fn panic(pi: &PanicInfo) -> ! { - //~^ ERROR should have no type parameters + //~^ ERROR `panic` cannot have generic parameters other than lifetimes loop {} } diff --git a/tests/ui/panic-handler/panic-handler-bad-signature-4.stderr b/tests/ui/panic-handler/panic-handler-bad-signature-4.stderr index 41a12e8dddf68..588bcd1d47bf2 100644 --- a/tests/ui/panic-handler/panic-handler-bad-signature-4.stderr +++ b/tests/ui/panic-handler/panic-handler-bad-signature-4.stderr @@ -1,8 +1,12 @@ -error: should have no type parameters +error: `panic` cannot have generic parameters other than lifetimes --> $DIR/panic-handler-bad-signature-4.rs:9:1 | +LL | #[panic_handler] + | ---------------- required by this attribute LL | fn panic(pi: &PanicInfo) -> ! { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[panic_handler]` marks the implementation of an "externally implementable item" error: aborting due to 1 previous error diff --git a/tests/ui/panic-handler/panic-handler-bad-signature-5.rs b/tests/ui/panic-handler/panic-handler-bad-signature-5.rs index a2a0e46ec6829..a0f2c7e3f1e44 100644 --- a/tests/ui/panic-handler/panic-handler-bad-signature-5.rs +++ b/tests/ui/panic-handler/panic-handler-bad-signature-5.rs @@ -7,7 +7,7 @@ use core::panic::PanicInfo; #[panic_handler] fn panic(info: &PanicInfo<'static>) -> ! -//~^ ERROR #[panic_handler]` function has wrong type [E0308] +//~^ ERROR mismatched types [E0308] { loop {} } diff --git a/tests/ui/panic-handler/panic-handler-bad-signature-5.stderr b/tests/ui/panic-handler/panic-handler-bad-signature-5.stderr index 3dcd253d3086e..8ed18df8ac856 100644 --- a/tests/ui/panic-handler/panic-handler-bad-signature-5.stderr +++ b/tests/ui/panic-handler/panic-handler-bad-signature-5.stderr @@ -1,11 +1,14 @@ -error[E0308]: `#[panic_handler]` function has wrong type +error[E0308]: mismatched types --> $DIR/panic-handler-bad-signature-5.rs:9:1 | LL | fn panic(info: &PanicInfo<'static>) -> ! - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch | - = note: expected signature `for<'a, 'b> fn(&'a PanicInfo<'b>) -> _` - found signature `for<'a> fn(&'a PanicInfo<'static>) -> _` + = note: expected signature `fn(&PanicInfo<'_>) -> _` + found signature `fn(&PanicInfo<'static>) -> _` +note: the anonymous lifetime as defined here... + --> $SRC_DIR/core/src/panicking.rs:LL:COL + = note: ...does not necessarily outlive the static lifetime error: aborting due to 1 previous error diff --git a/tests/ui/panic-handler/panic-handler-duplicate.rs b/tests/ui/panic-handler/panic-handler-duplicate.rs index 96a11157b5491..1fe97025a2a4c 100644 --- a/tests/ui/panic-handler/panic-handler-duplicate.rs +++ b/tests/ui/panic-handler/panic-handler-duplicate.rs @@ -8,10 +8,11 @@ use core::panic::PanicInfo; #[panic_handler] fn panic(info: &PanicInfo) -> ! { + //~^ ERROR multiple implementations of `#[panic_handler]` loop {} } #[panic_handler] -fn panic2(info: &PanicInfo) -> ! { //~ ERROR found duplicate lang item `panic_impl` +fn panic2(info: &PanicInfo) -> ! { loop {} } diff --git a/tests/ui/panic-handler/panic-handler-duplicate.stderr b/tests/ui/panic-handler/panic-handler-duplicate.stderr index 299847474cd58..fde13f7d8c75c 100644 --- a/tests/ui/panic-handler/panic-handler-duplicate.stderr +++ b/tests/ui/panic-handler/panic-handler-duplicate.stderr @@ -1,19 +1,13 @@ -error[E0152]: found duplicate lang item `panic_impl` - --> $DIR/panic-handler-duplicate.rs:15:1 - | -LL | / fn panic2(info: &PanicInfo) -> ! { -LL | | loop {} -LL | | } - | |_^ - | -note: the lang item is first defined here +error: multiple implementations of `#[panic_handler]` --> $DIR/panic-handler-duplicate.rs:10:1 | -LL | / fn panic(info: &PanicInfo) -> ! { -LL | | loop {} -LL | | } - | |_^ +LL | fn panic(info: &PanicInfo) -> ! { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ first implemented here in crate `panic_handler_duplicate` +... +LL | fn panic2(info: &PanicInfo) -> ! { + | -------------------------------- also implemented here in crate `panic_handler_duplicate` + | + = help: an "externally implementable item" can only have a single implementation in the final artifact. When multiple implementations are found, also in different crates, they conflict error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0152`. diff --git a/tests/ui/panic-handler/panic-handler-requires-panic-info.rs b/tests/ui/panic-handler/panic-handler-requires-panic-info.rs deleted file mode 100644 index 618ac7d88ddf2..0000000000000 --- a/tests/ui/panic-handler/panic-handler-requires-panic-info.rs +++ /dev/null @@ -1,21 +0,0 @@ -//@ compile-flags:-C panic=abort - -#![feature(lang_items)] -#![feature(no_core)] -#![no_core] -#![no_main] - -#[panic_handler] -fn panic() -> ! { - //~^ ERROR requires `panic_info` lang_item - loop {} -} - -#[lang = "pointee_sized"] -pub trait PointeeSized {} - -#[lang = "meta_sized"] -pub trait MetaSized: PointeeSized {} - -#[lang = "sized"] -trait Sized: MetaSized {} diff --git a/tests/ui/panic-handler/panic-handler-requires-panic-info.stderr b/tests/ui/panic-handler/panic-handler-requires-panic-info.stderr deleted file mode 100644 index 873f61a51632b..0000000000000 --- a/tests/ui/panic-handler/panic-handler-requires-panic-info.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: requires `panic_info` lang_item - --> $DIR/panic-handler-requires-panic-info.rs:9:1 - | -LL | fn panic() -> ! { - | ^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/panic-handler/panic-handler-std.rs b/tests/ui/panic-handler/panic-handler-std.rs index 4d4e20037aaa4..06b5257c352ab 100644 --- a/tests/ui/panic-handler/panic-handler-std.rs +++ b/tests/ui/panic-handler/panic-handler-std.rs @@ -1,11 +1,13 @@ //@ normalize-stderr: "loaded from .*libstd-.*.rmeta" -> "loaded from SYSROOT/libstd-*.rmeta" +//~? ERROR multiple implementations of `#[panic_handler]` + extern crate core; use core::panic::PanicInfo; #[panic_handler] -fn panic(info: PanicInfo) -> ! { //~ ERROR found duplicate lang item `panic_impl` +fn panic(info: &PanicInfo) -> ! { loop {} } diff --git a/tests/ui/panic-handler/panic-handler-std.stderr b/tests/ui/panic-handler/panic-handler-std.stderr index 3c44267822337..05c99260d9510 100644 --- a/tests/ui/panic-handler/panic-handler-std.stderr +++ b/tests/ui/panic-handler/panic-handler-std.stderr @@ -1,15 +1,14 @@ -error[E0152]: found duplicate lang item `panic_impl` - --> $DIR/panic-handler-std.rs:8:1 +error: multiple implementations of `#[panic_handler]` + --> $SRC_DIR/std/src/panicking.rs:LL:COL | -LL | / fn panic(info: PanicInfo) -> ! { -LL | | loop {} -LL | | } - | |_^ + = note: first implemented here in crate `std` | - = note: the lang item is first defined in crate `std` (which `panic_handler_std` depends on) - = note: first definition in `std` loaded from SYSROOT/libstd-*.rmeta - = note: second definition in the local crate (`panic_handler_std`) + ::: $DIR/panic-handler-std.rs:10:1 + | +LL | fn panic(info: &PanicInfo) -> ! { + | ------------------------------- also implemented here in crate `panic_handler_std` + | + = help: an "externally implementable item" can only have a single implementation in the final artifact. When multiple implementations are found, also in different crates, they conflict error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0152`. diff --git a/tests/ui/panic-handler/panic-handler-twice.rs b/tests/ui/panic-handler/panic-handler-twice.rs index 2d95a5028bf6b..b06fcecd87478 100644 --- a/tests/ui/panic-handler/panic-handler-twice.rs +++ b/tests/ui/panic-handler/panic-handler-twice.rs @@ -1,6 +1,8 @@ //@ dont-check-compiler-stderr //@ aux-build:some-panic-impl.rs +//~? ERROR multiple implementations of `#[panic_handler]` + #![feature(lang_items)] #![no_std] #![no_main] @@ -11,7 +13,6 @@ use core::panic::PanicInfo; #[panic_handler] fn panic(info: &PanicInfo) -> ! { - //~^ ERROR found duplicate lang item `panic_impl` loop {} } diff --git a/tests/ui/panic-handler/panic-handler-with-target-feature.rs b/tests/ui/panic-handler/panic-handler-with-target-feature.rs index 6e81516a91628..799ba94ef20b1 100644 --- a/tests/ui/panic-handler/panic-handler-with-target-feature.rs +++ b/tests/ui/panic-handler/panic-handler-with-target-feature.rs @@ -8,7 +8,7 @@ use core::panic::PanicInfo; #[panic_handler] #[target_feature(enable = "avx2")] -//~^ ERROR `#[target_feature]` cannot be applied to a `#[panic_handler]` function fn panic(info: &PanicInfo) -> ! { + //~^ ERROR function `panic` has a type that is incompatible with the declaration of `#[panic_handler]` unimplemented!(); } diff --git a/tests/ui/panic-handler/panic-handler-with-target-feature.stderr b/tests/ui/panic-handler/panic-handler-with-target-feature.stderr index 93cf164618ed9..8175c750f9cf2 100644 --- a/tests/ui/panic-handler/panic-handler-with-target-feature.stderr +++ b/tests/ui/panic-handler/panic-handler-with-target-feature.stderr @@ -1,13 +1,19 @@ -error: `#[target_feature]` cannot be applied to a `#[panic_handler]` function - --> $DIR/panic-handler-with-target-feature.rs:10:1 +error[E0806]: function `panic` has a type that is incompatible with the declaration of `#[panic_handler]` + --> $DIR/panic-handler-with-target-feature.rs:11:1 | -LL | #[target_feature(enable = "avx2")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | / fn panic(info: &PanicInfo) -> ! { -LL | | unimplemented!(); -LL | | } - | |_- `#[panic_handler]` function is not allowed to have `#[target_feature]` +LL | fn panic(info: &PanicInfo) -> ! { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected safe fn, found unsafe fn + | +note: expected this because of this attribute + --> $DIR/panic-handler-with-target-feature.rs:9:1 + | +LL | #[panic_handler] + | ^^^^^^^^^^^^^^^^ +note: type in declaration + --> $SRC_DIR/core/src/panicking.rs:LL:COL + = note: expected signature `fn(&PanicInfo<'_>) -> _` + found signature `unsafe fn(&PanicInfo<'_>) -> _` error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0806`. diff --git a/tests/ui/panic-handler/panic-handler-with-track-caller.rs b/tests/ui/panic-handler/panic-handler-with-track-caller.rs index 09c94139e1697..c78f5eeb926fb 100644 --- a/tests/ui/panic-handler/panic-handler-with-track-caller.rs +++ b/tests/ui/panic-handler/panic-handler-with-track-caller.rs @@ -8,7 +8,7 @@ use core::panic::PanicInfo; #[panic_handler] #[track_caller] -//~^ ERROR `#[panic_handler]` function is not allowed to have `#[track_caller]` +//~^ ERROR `#[panic_handler]` is not allowed to have `#[track_caller]` fn panic(info: &PanicInfo) -> ! { unimplemented!(); } diff --git a/tests/ui/panic-handler/panic-handler-with-track-caller.stderr b/tests/ui/panic-handler/panic-handler-with-track-caller.stderr index 605567acdb58b..9fbed1118df96 100644 --- a/tests/ui/panic-handler/panic-handler-with-track-caller.stderr +++ b/tests/ui/panic-handler/panic-handler-with-track-caller.stderr @@ -1,11 +1,11 @@ -error: `#[panic_handler]` function is not allowed to have `#[track_caller]` +error: `#[panic_handler]` is not allowed to have `#[track_caller]` --> $DIR/panic-handler-with-track-caller.rs:10:1 | LL | #[track_caller] | ^^^^^^^^^^^^^^^ LL | LL | fn panic(info: &PanicInfo) -> ! { - | ------------------------------- `#[panic_handler]` function is not allowed to have `#[track_caller]` + | ------------------------------- `#[panic_handler]` is not allowed to have `#[track_caller]` error: aborting due to 1 previous error diff --git a/tests/ui/panic-handler/panic-handler-wrong-location.rs b/tests/ui/panic-handler/panic-handler-wrong-location.rs index 22f6b6e724890..bdd7621a78ac1 100644 --- a/tests/ui/panic-handler/panic-handler-wrong-location.rs +++ b/tests/ui/panic-handler/panic-handler-wrong-location.rs @@ -3,7 +3,5 @@ #![no_std] #![no_main] -#[panic_handler] //~ ERROR attribute cannot be used on statics +#[panic_handler] //~ ERROR `#[panic_handler]` must be used on a function static X: u32 = 42; - -//~? ERROR `#[panic_handler]` function required, but not found diff --git a/tests/ui/panic-handler/panic-handler-wrong-location.stderr b/tests/ui/panic-handler/panic-handler-wrong-location.stderr index 7af0a4326d9a0..2c2d5a8abaff9 100644 --- a/tests/ui/panic-handler/panic-handler-wrong-location.stderr +++ b/tests/ui/panic-handler/panic-handler-wrong-location.stderr @@ -1,12 +1,8 @@ -error: `#[panic_handler]` function required, but not found - -error: `#[panic_handler]` attribute cannot be used on statics +error: `#[panic_handler]` must be used on a function --> $DIR/panic-handler-wrong-location.rs:6:1 | LL | #[panic_handler] | ^^^^^^^^^^^^^^^^ - | - = help: `#[panic_handler]` can only be applied to functions -error: aborting due to 2 previous errors +error: aborting due to 1 previous error diff --git a/tests/ui/panic-handler/weak-lang-item.stderr b/tests/ui/panic-handler/weak-lang-item.stderr index 5acd3e3187051..c81e1389315d2 100644 --- a/tests/ui/panic-handler/weak-lang-item.stderr +++ b/tests/ui/panic-handler/weak-lang-item.stderr @@ -10,13 +10,18 @@ help: you can use `as` to change the binding name of the import LL | extern crate core as other_core; | +++++++++++++ -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: `#[panic_handler]` function required, but not found + --> $SRC_DIR/core/src/panicking.rs:LL:COL + | + = note: expected because `#[panic_handler]` was declared here in crate `core` + | + = help: expected at least one implementation in crate `weak_lang_item` or any of its dependencies + error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0259`. diff --git a/tests/ui/proc-macro/issue-59191-replace-root-with-fn.stderr b/tests/ui/proc-macro/issue-59191-replace-root-with-fn.stderr index 3cd98d9c72b82..a8721e805d207 100644 --- a/tests/ui/proc-macro/issue-59191-replace-root-with-fn.stderr +++ b/tests/ui/proc-macro/issue-59191-replace-root-with-fn.stderr @@ -1,9 +1,14 @@ -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: `#[panic_handler]` function required, but not found + --> $SRC_DIR/core/src/panicking.rs:LL:COL + | + = note: expected because `#[panic_handler]` was declared here in crate `core` + | + = help: expected at least one implementation in crate `issue_59191_replace_root_with_fn` or any of its dependencies + error: aborting due to 2 previous errors