Skip to content

Commit 2775c09

Browse files
committed
remove panic handler from compiler
1 parent e1c4858 commit 2775c09

File tree

11 files changed

+72
-100
lines changed

11 files changed

+72
-100
lines changed

compiler/rustc_feature/src/builtin_attrs.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,6 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
473473
template!(NameValueStr: "windows|console"), FutureWarnFollowing,
474474
EncodeCrossCrate::No
475475
),
476-
ungated!(panic_handler, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes), // RFC 2070
477476

478477
// Code generation:
479478
ungated!(inline, Normal, template!(Word, List: "always|never"), FutureWarnFollowing, EncodeCrossCrate::No),

compiler/rustc_hir/src/lang_items.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,12 +151,10 @@ impl<CTX> HashStable<CTX> for LangItem {
151151
}
152152

153153
/// Extracts the first `lang = "$name"` out of a list of attributes.
154-
/// The `#[panic_handler]` attribute is also extracted out when found.
155154
pub fn extract(attrs: &[impl AttributeExt]) -> Option<(Symbol, Span)> {
156155
attrs.iter().find_map(|attr| {
157156
Some(match attr {
158157
_ if attr.has_name(sym::lang) => (attr.value_str()?, attr.span()),
159-
_ if attr.has_name(sym::panic_handler) => (sym::panic_impl, attr.span()),
160158
_ => return None,
161159
})
162160
})

compiler/rustc_hir/src/weak_lang_items.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ macro_rules! weak_lang_items {
2424
}
2525

2626
weak_lang_items! {
27-
PanicImpl, rust_begin_unwind;
2827
EhPersonality, rust_eh_personality;
2928
EhCatchTypeinfo, rust_eh_catch_typeinfo;
3029
}

compiler/rustc_hir_typeck/src/check.rs

Lines changed: 0 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -149,72 +149,13 @@ pub(super) fn check_fn<'a, 'tcx>(
149149
// we have a recursive call site and do the sadly stabilized fallback to `()`.
150150
fcx.demand_suptype(span, ret_ty, actual_return_ty);
151151

152-
// Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !`
153-
if tcx.is_lang_item(fn_def_id.to_def_id(), LangItem::PanicImpl) {
154-
check_panic_info_fn(tcx, fn_def_id, fn_sig);
155-
}
156-
157152
if tcx.is_lang_item(fn_def_id.to_def_id(), LangItem::Start) {
158153
check_lang_start_fn(tcx, fn_sig, fn_def_id);
159154
}
160155

161156
fcx.coroutine_types
162157
}
163158

164-
fn check_panic_info_fn(tcx: TyCtxt<'_>, fn_id: LocalDefId, fn_sig: ty::FnSig<'_>) {
165-
let span = tcx.def_span(fn_id);
166-
167-
let DefKind::Fn = tcx.def_kind(fn_id) else {
168-
tcx.dcx().span_err(span, "should be a function");
169-
return;
170-
};
171-
172-
let generic_counts = tcx.generics_of(fn_id).own_counts();
173-
if generic_counts.types != 0 {
174-
tcx.dcx().span_err(span, "should have no type parameters");
175-
}
176-
if generic_counts.consts != 0 {
177-
tcx.dcx().span_err(span, "should have no const parameters");
178-
}
179-
180-
let panic_info_did = tcx.require_lang_item(hir::LangItem::PanicInfo, Some(span));
181-
182-
// build type `for<'a, 'b> fn(&'a PanicInfo<'b>) -> !`
183-
let panic_info_ty = tcx.type_of(panic_info_did).instantiate(
184-
tcx,
185-
&[ty::GenericArg::from(ty::Region::new_bound(
186-
tcx,
187-
ty::INNERMOST,
188-
ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BoundRegionKind::Anon },
189-
))],
190-
);
191-
let panic_info_ref_ty = Ty::new_imm_ref(
192-
tcx,
193-
ty::Region::new_bound(
194-
tcx,
195-
ty::INNERMOST,
196-
ty::BoundRegion { var: ty::BoundVar::ZERO, kind: ty::BoundRegionKind::Anon },
197-
),
198-
panic_info_ty,
199-
);
200-
201-
let bounds = tcx.mk_bound_variable_kinds(&[
202-
ty::BoundVariableKind::Region(ty::BoundRegionKind::Anon),
203-
ty::BoundVariableKind::Region(ty::BoundRegionKind::Anon),
204-
]);
205-
let expected_sig = ty::Binder::bind_with_vars(
206-
tcx.mk_fn_sig([panic_info_ref_ty], tcx.types.never, false, fn_sig.safety, ExternAbi::Rust),
207-
bounds,
208-
);
209-
210-
let _ = check_function_signature(
211-
tcx,
212-
ObligationCause::new(span, fn_id, ObligationCauseCode::LangFunctionType(sym::panic_impl)),
213-
fn_id.into(),
214-
expected_sig,
215-
);
216-
}
217-
218159
fn check_lang_start_fn<'tcx>(tcx: TyCtxt<'tcx>, fn_sig: ty::FnSig<'tcx>, def_id: LocalDefId) {
219160
// build type `fn(main: fn() -> T, argc: isize, argv: *const *const u8, sigpipe: u8)`
220161

compiler/rustc_passes/src/check_attr.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
295295
| sym::deprecated_safe // FIXME(deprecated_safe)
296296
// internal
297297
| sym::prelude_import
298-
| sym::panic_handler
299298
| sym::allow_internal_unsafe
300299
| sym::fundamental
301300
| sym::lang

compiler/rustc_passes/src/dead.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -691,8 +691,6 @@ fn has_allow_dead_code_or_lang_attr(
691691
) -> Option<ComesFromAllowExpect> {
692692
fn has_lang_attr(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
693693
tcx.has_attr(def_id, sym::lang)
694-
// Stable attribute for #[lang = "panic_impl"]
695-
|| tcx.has_attr(def_id, sym::panic_handler)
696694
}
697695

698696
fn has_allow_expect_dead_code(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {

compiler/rustc_resolve/src/check_unused.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,7 @@ impl Resolver<'_, '_> {
402402
!tcx.is_compiler_builtins(cnum)
403403
&& !tcx.is_panic_runtime(cnum)
404404
&& !tcx.has_global_allocator(cnum)
405+
// TODO: test for EII in the crate
405406
}) {
406407
maybe_unused_extern_crates.insert(id, import.span);
407408
}

compiler/rustc_trait_selection/messages.ftl

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -248,10 +248,7 @@ trait_selection_oc_cant_coerce_force_inline =
248248
trait_selection_oc_cant_coerce_intrinsic = cannot coerce intrinsics to function pointers
249249
trait_selection_oc_closure_selfref = closure/coroutine type that references itself
250250
trait_selection_oc_const_compat = const not compatible with trait
251-
trait_selection_oc_fn_lang_correct_type = {$lang_item_name ->
252-
[panic_impl] `#[panic_handler]`
253-
*[lang_item_name] lang item `{$lang_item_name}`
254-
} function has wrong type
251+
trait_selection_oc_fn_lang_correct_type = lang item `{$lang_item_name}` function has wrong type
255252
trait_selection_oc_fn_main_correct_type = `main` function has wrong type
256253
trait_selection_oc_generic = mismatched types
257254

library/core/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595
//
9696
// Library features:
9797
// tidy-alphabetical-start
98+
#![cfg_attr(not(bootstrap), feature(eii))]
9899
#![feature(array_ptr_get)]
99100
#![feature(asm_experimental_arch)]
100101
#![feature(bigint_helper_methods)]
@@ -238,6 +239,9 @@ pub mod contracts;
238239

239240
#[unstable(feature = "cfg_match", issue = "115585")]
240241
pub use crate::macros::cfg_match;
242+
#[cfg(not(bootstrap))]
243+
#[stable(feature = "panic_hooks", since = "1.10.0")]
244+
pub use crate::panic::panic_handler;
241245

242246
#[macro_use]
243247
mod internal_macros;

library/core/src/panic.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ pub use self::panic_info::PanicMessage;
1616
pub use self::unwind_safe::{AssertUnwindSafe, RefUnwindSafe, UnwindSafe};
1717
use crate::any::Any;
1818

19+
/// Core expects some crate to provide a function annotated with `#[panic_handler]` with this
20+
/// signature. This annotated function will be called when a panic occurs.
21+
#[stable(feature = "panic_hooks", since = "1.10.0")]
22+
#[cfg(not(bootstrap))]
23+
#[eii(panic_handler)]
24+
pub(crate) fn panic_impl(info: &PanicInfo<'_>) -> !;
25+
1926
#[doc(hidden)]
2027
#[unstable(feature = "edition_panic", issue = "none", reason = "use panic!() instead")]
2128
#[allow_internal_unstable(panic_internals, const_format_args)]

library/core/src/panicking.rs

Lines changed: 59 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -56,23 +56,36 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
5656
if cfg!(feature = "panic_immediate_abort") {
5757
super::intrinsics::abort()
5858
}
59+
#[cfg(bootstrap)]
60+
{
61+
// NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call
62+
// that gets resolved to the `#[panic_handler]` function.
63+
unsafe extern "Rust" {
64+
#[lang = "panic_impl"]
65+
fn panic_impl(pi: &PanicInfo<'_>) -> !;
66+
}
5967

60-
// NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call
61-
// that gets resolved to the `#[panic_handler]` function.
62-
unsafe extern "Rust" {
63-
#[lang = "panic_impl"]
64-
fn panic_impl(pi: &PanicInfo<'_>) -> !;
65-
}
66-
67-
let pi = PanicInfo::new(
68-
&fmt,
69-
Location::caller(),
70-
/* can_unwind */ true,
71-
/* force_no_backtrace */ false,
72-
);
68+
let pi = PanicInfo::new(
69+
&fmt,
70+
Location::caller(),
71+
/* can_unwind */ true,
72+
/* force_no_backtrace */ false,
73+
);
7374

74-
// SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call.
75-
unsafe { panic_impl(&pi) }
75+
// SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call.
76+
unsafe { panic_impl(&pi) }
77+
}
78+
#[cfg(not(bootstrap))]
79+
{
80+
let pi = PanicInfo::new(
81+
&fmt,
82+
Location::caller(),
83+
/* can_unwind */ true,
84+
/* force_no_backtrace */ false,
85+
);
86+
87+
crate::panic::panic_impl(&pi)
88+
}
7689
}
7790

7891
/// Like `panic_fmt`, but for non-unwinding panics.
@@ -98,23 +111,39 @@ pub const fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>, force_no_backtrace: boo
98111
super::intrinsics::abort()
99112
}
100113

101-
// NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call
102-
// that gets resolved to the `#[panic_handler]` function.
103-
unsafe extern "Rust" {
104-
#[lang = "panic_impl"]
105-
fn panic_impl(pi: &PanicInfo<'_>) -> !;
106-
}
114+
#[cfg(bootstrap)]
115+
{
116+
// NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call
117+
// that gets resolved to the `#[panic_handler]` function.
118+
unsafe extern "Rust" {
119+
#[lang = "panic_impl"]
120+
fn panic_impl(pi: &PanicInfo<'_>) -> !;
121+
}
107122

108-
// PanicInfo with the `can_unwind` flag set to false forces an abort.
109-
let pi = PanicInfo::new(
110-
&fmt,
111-
Location::caller(),
112-
/* can_unwind */ false,
113-
force_no_backtrace,
114-
);
123+
// PanicInfo with the `can_unwind` flag set to false forces an abort.
124+
let pi = PanicInfo::new(
125+
&fmt,
126+
Location::caller(),
127+
/* can_unwind */ false,
128+
force_no_backtrace,
129+
);
115130

116-
// SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call.
117-
unsafe { panic_impl(&pi) }
131+
// SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call.
132+
unsafe { panic_impl(&pi) }
133+
}
134+
135+
#[cfg(not(bootstrap))]
136+
{
137+
// PanicInfo with the `can_unwind` flag set to false forces an abort.
138+
let pi = PanicInfo::new(
139+
&fmt,
140+
Location::caller(),
141+
/* can_unwind */ false,
142+
force_no_backtrace,
143+
);
144+
145+
crate::panic::panic_impl(&pi)
146+
}
118147
}
119148
)
120149
}

0 commit comments

Comments
 (0)