Skip to content

Commit bbb9cfb

Browse files
committed
Auto merge of rust-lang#102318 - Amanieu:default_alloc_error_handler, r=oli-obk
Stabilize default_alloc_error_handler Tracking issue: rust-lang#66741 This turns `feature(default_alloc_error_handler)` on by default, which causes the compiler to automatically generate a default OOM handler which panics if `#[alloc_error_handler]` is not provided. The FCP completed over 2 years ago but the stabilization was blocked due to an issue with unwinding. This was fixed by rust-lang#88098 so stabilization can be unblocked. Closes rust-lang#66741
2 parents 9c07efe + e66220f commit bbb9cfb

File tree

9 files changed

+39
-125
lines changed

9 files changed

+39
-125
lines changed

Diff for: compiler/rustc_error_messages/locales/en-US/metadata.ftl

-6
Original file line numberDiff line numberDiff line change
@@ -166,12 +166,6 @@ metadata_conflicting_alloc_error_handler =
166166
metadata_global_alloc_required =
167167
no global memory allocator found but one is required; link to std or add `#[global_allocator]` to a static item that implements the GlobalAlloc trait
168168
169-
metadata_alloc_func_required =
170-
`#[alloc_error_handler]` function required, but not found
171-
172-
metadata_missing_alloc_error_handler =
173-
use `#![feature(default_alloc_error_handler)]` for a default error handler
174-
175169
metadata_no_transitive_needs_dep =
176170
the crate `{$crate_name}` cannot depend on a crate that needs {$needs_crate_name}, but it depends on `{$deps_crate_name}`
177171

Diff for: compiler/rustc_feature/src/accepted.rs

+2
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ declare_features! (
126126
(accepted, copy_closures, "1.26.0", Some(44490), None),
127127
/// Allows `crate` in paths.
128128
(accepted, crate_in_paths, "1.30.0", Some(45477), None),
129+
/// Allows rustc to inject a default alloc_error_handler
130+
(accepted, default_alloc_error_handler, "CURRENT_RUSTC_VERSION", Some(66741), None),
129131
/// Allows using assigning a default type to type parameters in algebraic data type definitions.
130132
(accepted, default_type_params, "1.0.0", None, None),
131133
/// Allows `#[deprecated]` attribute.

Diff for: compiler/rustc_feature/src/active.rs

-2
Original file line numberDiff line numberDiff line change
@@ -368,8 +368,6 @@ declare_features! (
368368
(active, debugger_visualizer, "1.62.0", Some(95939), None),
369369
/// Allows declarative macros 2.0 (`macro`).
370370
(active, decl_macro, "1.17.0", Some(39412), None),
371-
/// Allows rustc to inject a default alloc_error_handler
372-
(active, default_alloc_error_handler, "1.48.0", Some(66741), None),
373371
/// Allows default type parameters to influence type inference.
374372
(active, default_type_parameter_fallback, "1.3.0", Some(27336), None),
375373
/// Allows using `#[deprecated_safe]` to deprecate the safeness of a function or trait

Diff for: compiler/rustc_metadata/src/creader.rs

+3-8
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
//! Validates all used crates and extern libraries and loads their metadata
22
33
use crate::errors::{
4-
AllocFuncRequired, ConflictingAllocErrorHandler, ConflictingGlobalAlloc, CrateNotPanicRuntime,
5-
GlobalAllocRequired, MissingAllocErrorHandler, NoMultipleAllocErrorHandler,
6-
NoMultipleGlobalAlloc, NoPanicStrategy, NoTransitiveNeedsDep, NotProfilerRuntime,
7-
ProfilerBuiltinsNeedsCore,
4+
ConflictingAllocErrorHandler, ConflictingGlobalAlloc, CrateNotPanicRuntime,
5+
GlobalAllocRequired, NoMultipleAllocErrorHandler, NoMultipleGlobalAlloc, NoPanicStrategy,
6+
NoTransitiveNeedsDep, NotProfilerRuntime, ProfilerBuiltinsNeedsCore,
87
};
98
use crate::locator::{CrateError, CrateLocator, CratePaths};
109
use crate::rmeta::{CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob};
@@ -895,10 +894,6 @@ impl<'a> CrateLoader<'a> {
895894
} else {
896895
// The alloc crate provides a default allocation error handler if
897896
// one isn't specified.
898-
if !self.sess.features_untracked().default_alloc_error_handler {
899-
self.sess.emit_err(AllocFuncRequired);
900-
self.sess.emit_note(MissingAllocErrorHandler);
901-
}
902897
self.cstore.alloc_error_handler_kind = Some(AllocatorKind::Default);
903898
}
904899
}

Diff for: compiler/rustc_metadata/src/errors.rs

-8
Original file line numberDiff line numberDiff line change
@@ -371,14 +371,6 @@ pub struct ConflictingAllocErrorHandler {
371371
#[diag(metadata_global_alloc_required)]
372372
pub struct GlobalAllocRequired;
373373

374-
#[derive(Diagnostic)]
375-
#[diag(metadata_alloc_func_required)]
376-
pub struct AllocFuncRequired;
377-
378-
#[derive(Diagnostic)]
379-
#[diag(metadata_missing_alloc_error_handler)]
380-
pub struct MissingAllocErrorHandler;
381-
382374
#[derive(Diagnostic)]
383375
#[diag(metadata_no_transitive_needs_dep)]
384376
pub struct NoTransitiveNeedsDep<'a> {

Diff for: src/test/ui/allocator/no_std-alloc-error-handler-custom.rs

+19-38
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77
// compile-flags:-C panic=abort
88
// aux-build:helper.rs
99

10-
#![feature(start, rustc_private, new_uninit, panic_info_message, lang_items)]
10+
#![feature(rustc_private, lang_items)]
1111
#![feature(alloc_error_handler)]
1212
#![no_std]
13+
#![no_main]
1314

1415
extern crate alloc;
1516
extern crate libc;
@@ -21,35 +22,30 @@ pub fn __aeabi_unwind_cpp_pr0() {}
2122
#[no_mangle]
2223
pub fn __aeabi_unwind_cpp_pr1() {}
2324

24-
use core::ptr::null_mut;
25-
use core::alloc::{GlobalAlloc, Layout};
2625
use alloc::boxed::Box;
26+
use alloc::string::ToString;
27+
use core::alloc::{GlobalAlloc, Layout};
28+
use core::ptr::null_mut;
2729

2830
extern crate helper;
2931

3032
struct MyAllocator;
3133

3234
#[alloc_error_handler]
33-
fn my_oom(layout: Layout) -> !
34-
{
35+
fn my_oom(layout: Layout) -> ! {
3536
use alloc::fmt::write;
3637
unsafe {
3738
let size = layout.size();
3839
let mut s = alloc::string::String::new();
3940
write(&mut s, format_args!("My OOM: failed to allocate {} bytes!\n", size)).unwrap();
40-
let s = s.as_str();
41-
libc::write(libc::STDERR_FILENO, s as *const _ as _, s.len());
41+
libc::write(libc::STDERR_FILENO, s.as_ptr() as *const _, s.len());
4242
libc::exit(0)
4343
}
4444
}
4545

4646
unsafe impl GlobalAlloc for MyAllocator {
4747
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
48-
if layout.size() < 4096 {
49-
libc::malloc(layout.size()) as _
50-
} else {
51-
null_mut()
52-
}
48+
if layout.size() < 4096 { libc::malloc(layout.size()) as _ } else { null_mut() }
5349
}
5450
unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
5551
}
@@ -60,26 +56,12 @@ static A: MyAllocator = MyAllocator;
6056
#[panic_handler]
6157
fn panic(panic_info: &core::panic::PanicInfo) -> ! {
6258
unsafe {
63-
if let Some(s) = panic_info.payload().downcast_ref::<&str>() {
64-
const PSTR: &str = "panic occurred: ";
65-
const CR: &str = "\n";
66-
libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len());
67-
libc::write(libc::STDERR_FILENO, s as *const _ as _, s.len());
68-
libc::write(libc::STDERR_FILENO, CR as *const _ as _, CR.len());
69-
}
70-
if let Some(args) = panic_info.message() {
71-
let mut s = alloc::string::String::new();
72-
alloc::fmt::write(&mut s, *args).unwrap();
73-
let s = s.as_str();
74-
const PSTR: &str = "panic occurred: ";
75-
const CR: &str = "\n";
76-
libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len());
77-
libc::write(libc::STDERR_FILENO, s as *const _ as _, s.len());
78-
libc::write(libc::STDERR_FILENO, CR as *const _ as _, CR.len());
79-
} else {
80-
const PSTR: &str = "panic occurred\n";
81-
libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len());
82-
}
59+
let s = panic_info.to_string();
60+
const PSTR: &str = "panic occurred: ";
61+
const CR: &str = "\n";
62+
libc::write(libc::STDERR_FILENO, PSTR.as_ptr() as *const _, PSTR.len());
63+
libc::write(libc::STDERR_FILENO, s.as_ptr() as *const _, s.len());
64+
libc::write(libc::STDERR_FILENO, CR.as_ptr() as *const _, CR.len());
8365
libc::exit(1)
8466
}
8567
}
@@ -89,15 +71,14 @@ fn panic(panic_info: &core::panic::PanicInfo) -> ! {
8971
// in these libraries will refer to `rust_eh_personality` if LLVM can not *prove* the contents won't
9072
// unwind. So, for this test case we will define the symbol.
9173
#[lang = "eh_personality"]
92-
extern fn rust_eh_personality() {}
74+
extern "C" fn rust_eh_personality() {}
9375

94-
#[derive(Debug)]
76+
#[derive(Default, Debug)]
9577
struct Page(#[allow(unused_tuple_struct_fields)] [[u64; 32]; 16]);
9678

97-
#[start]
98-
pub fn main(_argc: isize, _argv: *const *const u8) -> isize {
99-
let zero = Box::<Page>::new_zeroed();
100-
let zero = unsafe { zero.assume_init() };
79+
#[no_mangle]
80+
fn main(_argc: i32, _argv: *const *const u8) -> isize {
81+
let zero = Box::<Page>::new(Default::default());
10182
helper::work_with(&zero);
10283
1
10384
}

Diff for: src/test/ui/allocator/no_std-alloc-error-handler-default.rs

+15-34
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@
66
// only-linux
77
// compile-flags:-C panic=abort
88
// aux-build:helper.rs
9-
// gate-test-default_alloc_error_handler
109

11-
#![feature(start, rustc_private, new_uninit, panic_info_message, lang_items)]
12-
#![feature(default_alloc_error_handler)]
10+
#![feature(rustc_private, lang_items)]
1311
#![no_std]
12+
#![no_main]
1413

1514
extern crate alloc;
1615
extern crate libc;
@@ -23,6 +22,7 @@ pub fn __aeabi_unwind_cpp_pr0() {}
2322
pub fn __aeabi_unwind_cpp_pr1() {}
2423

2524
use alloc::boxed::Box;
25+
use alloc::string::ToString;
2626
use core::alloc::{GlobalAlloc, Layout};
2727
use core::ptr::null_mut;
2828

@@ -32,11 +32,7 @@ struct MyAllocator;
3232

3333
unsafe impl GlobalAlloc for MyAllocator {
3434
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
35-
if layout.size() < 4096 {
36-
libc::malloc(layout.size()) as _
37-
} else {
38-
null_mut()
39-
}
35+
if layout.size() < 4096 { libc::malloc(layout.size()) as _ } else { null_mut() }
4036
}
4137
unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
4238
}
@@ -47,26 +43,12 @@ static A: MyAllocator = MyAllocator;
4743
#[panic_handler]
4844
fn panic(panic_info: &core::panic::PanicInfo) -> ! {
4945
unsafe {
50-
if let Some(s) = panic_info.payload().downcast_ref::<&str>() {
51-
const PSTR: &str = "panic occurred: ";
52-
const CR: &str = "\n";
53-
libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len());
54-
libc::write(libc::STDERR_FILENO, s as *const _ as _, s.len());
55-
libc::write(libc::STDERR_FILENO, CR as *const _ as _, CR.len());
56-
}
57-
if let Some(args) = panic_info.message() {
58-
let mut s = alloc::string::String::new();
59-
alloc::fmt::write(&mut s, *args).unwrap();
60-
let s = s.as_str();
61-
const PSTR: &str = "panic occurred: ";
62-
const CR: &str = "\n";
63-
libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len());
64-
libc::write(libc::STDERR_FILENO, s as *const _ as _, s.len());
65-
libc::write(libc::STDERR_FILENO, CR as *const _ as _, CR.len());
66-
} else {
67-
const PSTR: &str = "panic occurred\n";
68-
libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len());
69-
}
46+
let s = panic_info.to_string();
47+
const PSTR: &str = "panic occurred: ";
48+
const CR: &str = "\n";
49+
libc::write(libc::STDERR_FILENO, PSTR.as_ptr() as *const _, PSTR.len());
50+
libc::write(libc::STDERR_FILENO, s.as_ptr() as *const _, s.len());
51+
libc::write(libc::STDERR_FILENO, CR.as_ptr() as *const _, CR.len());
7052
libc::exit(0)
7153
}
7254
}
@@ -76,15 +58,14 @@ fn panic(panic_info: &core::panic::PanicInfo) -> ! {
7658
// in these libraries will refer to `rust_eh_personality` if LLVM can not *prove* the contents won't
7759
// unwind. So, for this test case we will define the symbol.
7860
#[lang = "eh_personality"]
79-
extern fn rust_eh_personality() {}
61+
extern "C" fn rust_eh_personality() {}
8062

81-
#[derive(Debug)]
63+
#[derive(Default, Debug)]
8264
struct Page(#[allow(unused_tuple_struct_fields)] [[u64; 32]; 16]);
8365

84-
#[start]
85-
pub fn main(_argc: isize, _argv: *const *const u8) -> isize {
86-
let zero = Box::<Page>::new_zeroed();
87-
let zero = unsafe { zero.assume_init() };
66+
#[no_mangle]
67+
fn main(_argc: i32, _argv: *const *const u8) -> isize {
68+
let zero = Box::<Page>::new(Default::default());
8869
helper::work_with(&zero);
8970
1
9071
}

Diff for: src/test/ui/missing/missing-alloc_error_handler.rs

-23
This file was deleted.

Diff for: src/test/ui/missing/missing-alloc_error_handler.stderr

-6
This file was deleted.

0 commit comments

Comments
 (0)