From 175afd76180d47b655377768a87a55f8581686f0 Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Mon, 21 Apr 2025 23:27:01 -0700 Subject: [PATCH 1/8] Stabilize `new_zeroed_alloc` --- compiler/rustc_index/src/bit_set.rs | 4 ++-- compiler/rustc_index/src/lib.rs | 2 +- library/alloc/src/boxed.rs | 16 ++-------------- library/alloc/src/rc.rs | 16 ++-------------- library/alloc/src/sync.rs | 14 ++------------ library/std/src/lib.rs | 1 - 6 files changed, 9 insertions(+), 44 deletions(-) diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs index 645d95b1dba99..0b3bc8963a3bd 100644 --- a/compiler/rustc_index/src/bit_set.rs +++ b/compiler/rustc_index/src/bit_set.rs @@ -638,7 +638,7 @@ impl ChunkedBitSet { }; #[cfg(not(feature = "nightly"))] let mut words = { - // FIXME: unconditionally use `Rc::new_zeroed` once it is stable (#63291). + // FIXME: unconditionally use `Rc::new_zeroed` once it is stable (#129396). let words = mem::MaybeUninit::<[Word; CHUNK_WORDS]>::zeroed(); // SAFETY: `words` can safely be all zeroes. let words = unsafe { words.assume_init() }; @@ -704,7 +704,7 @@ impl ChunkedBitSet { }; #[cfg(not(feature = "nightly"))] let mut words = { - // FIXME: unconditionally use `Rc::new_zeroed` once it is stable (#63291). + // FIXME: unconditionally use `Rc::new_zeroed` once it is stable (#129396). let words = mem::MaybeUninit::<[Word; CHUNK_WORDS]>::zeroed(); // SAFETY: `words` can safely be all zeroes. let words = unsafe { words.assume_init() }; diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs index cc680838e7e7b..9d647209c6f89 100644 --- a/compiler/rustc_index/src/lib.rs +++ b/compiler/rustc_index/src/lib.rs @@ -1,9 +1,9 @@ // tidy-alphabetical-start #![cfg_attr(all(feature = "nightly", test), feature(stmt_expr_attributes))] +#![cfg_attr(bootstrap, feature(new_zeroed_alloc))] #![cfg_attr(feature = "nightly", allow(internal_features))] #![cfg_attr(feature = "nightly", feature(extend_one, step_trait, test))] #![cfg_attr(feature = "nightly", feature(new_range_api))] -#![cfg_attr(feature = "nightly", feature(new_zeroed_alloc))] // tidy-alphabetical-end pub mod bit_set; diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 3db37f1d16f3d..173d0103c119b 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -290,8 +290,6 @@ impl Box { /// # Examples /// /// ``` - /// #![feature(new_zeroed_alloc)] - /// /// let zero = Box::::new_zeroed(); /// let zero = unsafe { zero.assume_init() }; /// @@ -301,7 +299,7 @@ impl Box { /// [zeroed]: mem::MaybeUninit::zeroed #[cfg(not(no_global_oom_handling))] #[inline] - #[unstable(feature = "new_zeroed_alloc", issue = "129396")] + #[stable(feature = "new_zeroed_alloc", since = "CURRENT_RUSTC_VERSION")] #[must_use] pub fn new_zeroed() -> Box> { Self::new_zeroed_in(Global) @@ -358,7 +356,6 @@ impl Box { /// # Ok::<(), std::alloc::AllocError>(()) /// ``` #[unstable(feature = "allocator_api", issue = "32838")] - // #[unstable(feature = "new_uninit", issue = "63291")] #[inline] pub fn try_new_uninit() -> Result>, AllocError> { Box::try_new_uninit_in(Global) @@ -384,7 +381,6 @@ impl Box { /// /// [zeroed]: mem::MaybeUninit::zeroed #[unstable(feature = "allocator_api", issue = "32838")] - // #[unstable(feature = "new_uninit", issue = "63291")] #[inline] pub fn try_new_zeroed() -> Result>, AllocError> { Box::try_new_zeroed_in(Global) @@ -463,7 +459,6 @@ impl Box { #[unstable(feature = "allocator_api", issue = "32838")] #[cfg(not(no_global_oom_handling))] #[must_use] - // #[unstable(feature = "new_uninit", issue = "63291")] pub fn new_uninit_in(alloc: A) -> Box, A> where A: Allocator, @@ -496,7 +491,6 @@ impl Box { /// # Ok::<(), std::alloc::AllocError>(()) /// ``` #[unstable(feature = "allocator_api", issue = "32838")] - // #[unstable(feature = "new_uninit", issue = "63291")] pub fn try_new_uninit_in(alloc: A) -> Result, A>, AllocError> where A: Allocator, @@ -532,7 +526,6 @@ impl Box { /// [zeroed]: mem::MaybeUninit::zeroed #[unstable(feature = "allocator_api", issue = "32838")] #[cfg(not(no_global_oom_handling))] - // #[unstable(feature = "new_uninit", issue = "63291")] #[must_use] pub fn new_zeroed_in(alloc: A) -> Box, A> where @@ -570,7 +563,6 @@ impl Box { /// /// [zeroed]: mem::MaybeUninit::zeroed #[unstable(feature = "allocator_api", issue = "32838")] - // #[unstable(feature = "new_uninit", issue = "63291")] pub fn try_new_zeroed_in(alloc: A) -> Result, A>, AllocError> where A: Allocator, @@ -660,8 +652,6 @@ impl Box<[T]> { /// # Examples /// /// ``` - /// #![feature(new_zeroed_alloc)] - /// /// let values = Box::<[u32]>::new_zeroed_slice(3); /// let values = unsafe { values.assume_init() }; /// @@ -670,7 +660,7 @@ impl Box<[T]> { /// /// [zeroed]: mem::MaybeUninit::zeroed #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "new_zeroed_alloc", issue = "129396")] + #[stable(feature = "new_zeroed_alloc", since = "CURRENT_RUSTC_VERSION")] #[must_use] pub fn new_zeroed_slice(len: usize) -> Box<[mem::MaybeUninit]> { unsafe { RawVec::with_capacity_zeroed(len).into_box(len) } @@ -785,7 +775,6 @@ impl Box<[T], A> { /// ``` #[cfg(not(no_global_oom_handling))] #[unstable(feature = "allocator_api", issue = "32838")] - // #[unstable(feature = "new_uninit", issue = "63291")] #[must_use] pub fn new_uninit_slice_in(len: usize, alloc: A) -> Box<[mem::MaybeUninit], A> { unsafe { RawVec::with_capacity_in(len, alloc).into_box(len) } @@ -813,7 +802,6 @@ impl Box<[T], A> { /// [zeroed]: mem::MaybeUninit::zeroed #[cfg(not(no_global_oom_handling))] #[unstable(feature = "allocator_api", issue = "32838")] - // #[unstable(feature = "new_uninit", issue = "63291")] #[must_use] pub fn new_zeroed_slice_in(len: usize, alloc: A) -> Box<[mem::MaybeUninit], A> { unsafe { RawVec::with_capacity_zeroed_in(len, alloc).into_box(len) } diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 5018ff4ad71f3..0b5c9240db0f1 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -515,8 +515,6 @@ impl Rc { /// # Examples /// /// ``` - /// #![feature(new_zeroed_alloc)] - /// /// use std::rc::Rc; /// /// let zero = Rc::::new_zeroed(); @@ -527,7 +525,7 @@ impl Rc { /// /// [zeroed]: mem::MaybeUninit::zeroed #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "new_zeroed_alloc", issue = "129396")] + #[stable(feature = "new_zeroed_alloc", since = "CURRENT_RUSTC_VERSION")] #[must_use] pub fn new_zeroed() -> Rc> { unsafe { @@ -589,7 +587,6 @@ impl Rc { /// # Ok::<(), std::alloc::AllocError>(()) /// ``` #[unstable(feature = "allocator_api", issue = "32838")] - // #[unstable(feature = "new_uninit", issue = "63291")] pub fn try_new_uninit() -> Result>, AllocError> { unsafe { Ok(Rc::from_ptr(Rc::try_allocate_for_layout( @@ -622,7 +619,6 @@ impl Rc { /// /// [zeroed]: mem::MaybeUninit::zeroed #[unstable(feature = "allocator_api", issue = "32838")] - //#[unstable(feature = "new_uninit", issue = "63291")] pub fn try_new_zeroed() -> Result>, AllocError> { unsafe { Ok(Rc::from_ptr(Rc::try_allocate_for_layout( @@ -690,7 +686,6 @@ impl Rc { /// ``` #[cfg(not(no_global_oom_handling))] #[unstable(feature = "allocator_api", issue = "32838")] - // #[unstable(feature = "new_uninit", issue = "63291")] #[inline] pub fn new_uninit_in(alloc: A) -> Rc, A> { unsafe { @@ -728,7 +723,6 @@ impl Rc { /// [zeroed]: mem::MaybeUninit::zeroed #[cfg(not(no_global_oom_handling))] #[unstable(feature = "allocator_api", issue = "32838")] - // #[unstable(feature = "new_uninit", issue = "63291")] #[inline] pub fn new_zeroed_in(alloc: A) -> Rc, A> { unsafe { @@ -873,7 +867,6 @@ impl Rc { /// # Ok::<(), std::alloc::AllocError>(()) /// ``` #[unstable(feature = "allocator_api", issue = "32838")] - // #[unstable(feature = "new_uninit", issue = "63291")] #[inline] pub fn try_new_uninit_in(alloc: A) -> Result, A>, AllocError> { unsafe { @@ -912,7 +905,6 @@ impl Rc { /// /// [zeroed]: mem::MaybeUninit::zeroed #[unstable(feature = "allocator_api", issue = "32838")] - //#[unstable(feature = "new_uninit", issue = "63291")] #[inline] pub fn try_new_zeroed_in(alloc: A) -> Result, A>, AllocError> { unsafe { @@ -1054,8 +1046,6 @@ impl Rc<[T]> { /// # Examples /// /// ``` - /// #![feature(new_zeroed_alloc)] - /// /// use std::rc::Rc; /// /// let values = Rc::<[u32]>::new_zeroed_slice(3); @@ -1066,7 +1056,7 @@ impl Rc<[T]> { /// /// [zeroed]: mem::MaybeUninit::zeroed #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "new_zeroed_alloc", issue = "129396")] + #[stable(feature = "new_zeroed_alloc", since = "CURRENT_RUSTC_VERSION")] #[must_use] pub fn new_zeroed_slice(len: usize) -> Rc<[mem::MaybeUninit]> { unsafe { @@ -1129,7 +1119,6 @@ impl Rc<[T], A> { /// ``` #[cfg(not(no_global_oom_handling))] #[unstable(feature = "allocator_api", issue = "32838")] - // #[unstable(feature = "new_uninit", issue = "63291")] #[inline] pub fn new_uninit_slice_in(len: usize, alloc: A) -> Rc<[mem::MaybeUninit], A> { unsafe { Rc::from_ptr_in(Rc::allocate_for_slice_in(len, &alloc), alloc) } @@ -1158,7 +1147,6 @@ impl Rc<[T], A> { /// [zeroed]: mem::MaybeUninit::zeroed #[cfg(not(no_global_oom_handling))] #[unstable(feature = "allocator_api", issue = "32838")] - // #[unstable(feature = "new_uninit", issue = "63291")] #[inline] pub fn new_zeroed_slice_in(len: usize, alloc: A) -> Rc<[mem::MaybeUninit], A> { unsafe { diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index b8925f4544f44..4090a04f21a9f 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -516,8 +516,6 @@ impl Arc { /// # Examples /// /// ``` - /// #![feature(new_zeroed_alloc)] - /// /// use std::sync::Arc; /// /// let zero = Arc::::new_zeroed(); @@ -529,7 +527,7 @@ impl Arc { /// [zeroed]: mem::MaybeUninit::zeroed #[cfg(not(no_global_oom_handling))] #[inline] - #[unstable(feature = "new_zeroed_alloc", issue = "129396")] + #[stable(feature = "new_zeroed_alloc", since = "CURRENT_RUSTC_VERSION")] #[must_use] pub fn new_zeroed() -> Arc> { unsafe { @@ -603,7 +601,6 @@ impl Arc { /// # Ok::<(), std::alloc::AllocError>(()) /// ``` #[unstable(feature = "allocator_api", issue = "32838")] - // #[unstable(feature = "new_uninit", issue = "63291")] pub fn try_new_uninit() -> Result>, AllocError> { unsafe { Ok(Arc::from_ptr(Arc::try_allocate_for_layout( @@ -636,7 +633,6 @@ impl Arc { /// /// [zeroed]: mem::MaybeUninit::zeroed #[unstable(feature = "allocator_api", issue = "32838")] - // #[unstable(feature = "new_uninit", issue = "63291")] pub fn try_new_zeroed() -> Result>, AllocError> { unsafe { Ok(Arc::from_ptr(Arc::try_allocate_for_layout( @@ -703,7 +699,6 @@ impl Arc { /// ``` #[cfg(not(no_global_oom_handling))] #[unstable(feature = "allocator_api", issue = "32838")] - // #[unstable(feature = "new_uninit", issue = "63291")] #[inline] pub fn new_uninit_in(alloc: A) -> Arc, A> { unsafe { @@ -741,7 +736,6 @@ impl Arc { /// [zeroed]: mem::MaybeUninit::zeroed #[cfg(not(no_global_oom_handling))] #[unstable(feature = "allocator_api", issue = "32838")] - // #[unstable(feature = "new_uninit", issue = "63291")] #[inline] pub fn new_zeroed_in(alloc: A) -> Arc, A> { unsafe { @@ -927,7 +921,6 @@ impl Arc { /// # Ok::<(), std::alloc::AllocError>(()) /// ``` #[unstable(feature = "allocator_api", issue = "32838")] - // #[unstable(feature = "new_uninit", issue = "63291")] #[inline] pub fn try_new_uninit_in(alloc: A) -> Result, A>, AllocError> { unsafe { @@ -966,7 +959,6 @@ impl Arc { /// /// [zeroed]: mem::MaybeUninit::zeroed #[unstable(feature = "allocator_api", issue = "32838")] - // #[unstable(feature = "new_uninit", issue = "63291")] #[inline] pub fn try_new_zeroed_in(alloc: A) -> Result, A>, AllocError> { unsafe { @@ -1197,8 +1189,6 @@ impl Arc<[T]> { /// # Examples /// /// ``` - /// #![feature(new_zeroed_alloc)] - /// /// use std::sync::Arc; /// /// let values = Arc::<[u32]>::new_zeroed_slice(3); @@ -1210,7 +1200,7 @@ impl Arc<[T]> { /// [zeroed]: mem::MaybeUninit::zeroed #[cfg(not(no_global_oom_handling))] #[inline] - #[unstable(feature = "new_zeroed_alloc", issue = "129396")] + #[stable(feature = "new_zeroed_alloc", since = "CURRENT_RUSTC_VERSION")] #[must_use] pub fn new_zeroed_slice(len: usize) -> Arc<[mem::MaybeUninit]> { unsafe { diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 311b2cb932392..2c0061dc40320 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -376,7 +376,6 @@ #![feature(allocator_api)] #![feature(get_mut_unchecked)] #![feature(map_try_insert)] -#![feature(new_zeroed_alloc)] #![feature(slice_concat_trait)] #![feature(thin_box)] #![feature(try_reserve_kind)] From 46727f4cb06c3496a541ee8517a24ef5cb77627c Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Wed, 20 Aug 2025 15:04:34 +0000 Subject: [PATCH 2/8] Stabilize file_as_c_str --- library/core/src/panic/location.rs | 3 ++- tests/ui/rfcs/rfc-2091-track-caller/file-is-nul-terminated.rs | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/panic/location.rs b/library/core/src/panic/location.rs index 7a68d393906cb..5935849344475 100644 --- a/library/core/src/panic/location.rs +++ b/library/core/src/panic/location.rs @@ -193,8 +193,9 @@ impl<'a> Location<'a> { /// This is useful for interop with APIs that expect C/C++ `__FILE__` or /// `std::source_location::file_name`, both of which return a nul-terminated `const char*`. #[must_use] - #[unstable(feature = "file_with_nul", issue = "141727")] #[inline] + #[stable(feature = "file_with_nul", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "file_with_nul", since = "CURRENT_RUSTC_VERSION")] pub const fn file_as_c_str(&self) -> &'a CStr { let filename = self.filename.as_ptr(); diff --git a/tests/ui/rfcs/rfc-2091-track-caller/file-is-nul-terminated.rs b/tests/ui/rfcs/rfc-2091-track-caller/file-is-nul-terminated.rs index 7902f40b09bdb..698492966adf3 100644 --- a/tests/ui/rfcs/rfc-2091-track-caller/file-is-nul-terminated.rs +++ b/tests/ui/rfcs/rfc-2091-track-caller/file-is-nul-terminated.rs @@ -1,5 +1,4 @@ //@ run-pass -#![feature(file_with_nul)] #[track_caller] const fn assert_file_has_trailing_zero() { From 8b752cb37d646118c46f7739ae965b8e9c9a9b03 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sun, 14 Sep 2025 21:14:37 +0200 Subject: [PATCH 3/8] fix issue with `cmse-nonsecure-entry` ABI being both async and c-variadic --- .../src/hir_ty_lowering/cmse.rs | 6 ++ tests/crashes/132142.rs | 3 - .../cmse-nonsecure-entry/c-variadic.rs | 69 +++++++++++++++++++ .../cmse-nonsecure-entry/c-variadic.stderr | 28 ++++++++ .../cmse-nonsecure-entry/generics.rs | 7 +- .../cmse-nonsecure-entry/generics.stderr | 18 +---- 6 files changed, 105 insertions(+), 26 deletions(-) delete mode 100644 tests/crashes/132142.rs create mode 100644 tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.rs create mode 100644 tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.stderr diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs index 5088c63702e60..7867c1c3b4857 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs @@ -85,6 +85,12 @@ pub(crate) fn validate_cmse_abi<'tcx>( return; }; + // An `extern "cmse-nonsecure-entry"` function cannot be c-variadic. We run + // into https://github.com/rust-lang/rust/issues/132142 if we don't explicitly bail. + if decl.c_variadic { + return; + } + match is_valid_cmse_inputs(tcx, fn_sig) { Ok(Ok(())) => {} Ok(Err(index)) => { diff --git a/tests/crashes/132142.rs b/tests/crashes/132142.rs deleted file mode 100644 index 813bf0bf0a8e5..0000000000000 --- a/tests/crashes/132142.rs +++ /dev/null @@ -1,3 +0,0 @@ -//@ known-bug: #132142 - -async extern "cmse-nonsecure-entry" fn fun(...) {} diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.rs new file mode 100644 index 0000000000000..9317ab5cd2756 --- /dev/null +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.rs @@ -0,0 +1,69 @@ +//@ add-core-stubs +//@ edition: 2018 +//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib +//@ needs-llvm-components: arm +#![feature(cmse_nonsecure_entry, c_variadic, no_core, lang_items)] +#![no_core] + +extern crate minicore; +use minicore::*; + +#[lang = "va_list"] +struct VaList(*mut u8); + +unsafe extern "cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) { + //~^ ERROR `...` is not supported for `extern "cmse-nonsecure-entry"` functions +} + +// A regression test for https://github.com/rust-lang/rust/issues/132142 +async unsafe extern "cmse-nonsecure-entry" fn async_and_c_variadic(_: ...) { + //~^ ERROR `...` is not supported for `extern "cmse-nonsecure-entry"` functions + //~| ERROR functions cannot be both `async` and C-variadic +} + +// Below are the lang items that are required for a program that defines an `async` function. +// Without them, the ICE that is tested for here is not reached for this target. For now they are in +// this file, but they may be moved into `minicore` if/when other `#[no_core]` tests want to use +// them. + +// NOTE: in `core` this type uses `NonNull`. +#[lang = "ResumeTy"] +pub struct ResumeTy(*mut Context<'static>); + +#[lang = "future_trait"] +pub trait Future { + /// The type of value produced on completion. + #[lang = "future_output"] + type Output; + + // NOTE: misses the `poll` method. +} + +#[lang = "async_drop"] +pub trait AsyncDrop { + // NOTE: misses the `drop` method. +} + +#[lang = "Poll"] +pub enum Poll { + #[lang = "Ready"] + Ready(T), + + #[lang = "Pending"] + Pending, +} + +#[lang = "Context"] +pub struct Context<'a> { + // NOTE: misses a bunch of fields. + _marker: PhantomData &'a ()>, +} + +#[lang = "get_context"] +pub unsafe fn get_context<'a, 'b>(cx: ResumeTy) -> &'a mut Context<'b> { + // NOTE: the actual implementation looks different. + mem::transmute(cx.0) +} + +#[lang = "pin"] +pub struct Pin(T); diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.stderr new file mode 100644 index 0000000000000..948f8f5747b0e --- /dev/null +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.stderr @@ -0,0 +1,28 @@ +error: `...` is not supported for `extern "cmse-nonsecure-entry"` functions + --> $DIR/c-variadic.rs:14:60 + | +LL | unsafe extern "cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) { + | ----------------------------- ^^^^^^ + | | + | `extern "cmse-nonsecure-entry"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: functions cannot be both `async` and C-variadic + --> $DIR/c-variadic.rs:19:1 + | +LL | async unsafe extern "cmse-nonsecure-entry" fn async_and_c_variadic(_: ...) { + | ^^^^^ `async` because of this ^^^^^^ C-variadic because of this + +error: `...` is not supported for `extern "cmse-nonsecure-entry"` functions + --> $DIR/c-variadic.rs:19:68 + | +LL | async unsafe extern "cmse-nonsecure-entry" fn async_and_c_variadic(_: ...) { + | ----------------------------- ^^^^^^ + | | + | `extern "cmse-nonsecure-entry"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: aborting due to 3 previous errors + diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs index eb6f4a323655b..aee01e25ddc4f 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs @@ -1,7 +1,7 @@ //@ add-core-stubs //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm -#![feature(cmse_nonsecure_entry, c_variadic, no_core, lang_items)] +#![feature(cmse_nonsecure_entry, no_core, lang_items)] #![no_core] extern crate minicore; @@ -65,8 +65,3 @@ extern "cmse-nonsecure-entry" fn wrapped_trait_object(x: WrapperTransparent) -> //~^ ERROR return value of `"cmse-nonsecure-entry"` function too large to pass via registers [E0798] x } - -unsafe extern "cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) { - //~^ ERROR `...` is not supported for `extern "cmse-nonsecure-entry"` functions - //~| ERROR requires `va_list` lang_item -} diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr index 8937def9428cf..df1a910704378 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr @@ -1,13 +1,3 @@ -error: `...` is not supported for `extern "cmse-nonsecure-entry"` functions - --> $DIR/generics.rs:69:60 - | -LL | unsafe extern "cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) { - | ----------------------------- ^^^^^^ - | | - | `extern "cmse-nonsecure-entry"` because of this - | - = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list - error[E0798]: functions with the `"cmse-nonsecure-entry"` ABI cannot contain generics in their type --> $DIR/generics.rs:30:1 | @@ -71,12 +61,6 @@ LL | extern "cmse-nonsecure-entry" fn wrapped_trait_object(x: WrapperTransparent = note: functions with the `"cmse-nonsecure-entry"` ABI must pass their result via the available return registers = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size -error: requires `va_list` lang_item - --> $DIR/generics.rs:69:60 - | -LL | unsafe extern "cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) { - | ^^^^^^ - -error: aborting due to 9 previous errors +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0798`. From 7ce81d145359aa230f8fc2d7de12650091508329 Mon Sep 17 00:00:00 2001 From: beepster4096 <19316085+beepster4096@users.noreply.github.com> Date: Tue, 26 Aug 2025 01:12:20 -0700 Subject: [PATCH 4/8] deref related cleanups in ref_prop --- compiler/rustc_mir_transform/src/ref_prop.rs | 33 ++++++++------------ 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_mir_transform/src/ref_prop.rs b/compiler/rustc_mir_transform/src/ref_prop.rs index 6f61215cee2d6..b9d6e74ecae89 100644 --- a/compiler/rustc_mir_transform/src/ref_prop.rs +++ b/compiler/rustc_mir_transform/src/ref_prop.rs @@ -195,10 +195,10 @@ fn compute_replacement<'tcx>( // including DEF. This violates the DEF dominates USE condition, and so is impossible. let is_constant_place = |place: Place<'_>| { // We only allow `Deref` as the first projection, to avoid surprises. - if place.projection.first() == Some(&PlaceElem::Deref) { + if let Some((&PlaceElem::Deref, rest)) = place.projection.split_first() { // `place == (*some_local).xxx`, it is constant only if `some_local` is constant. // We approximate constness using SSAness. - ssa.is_ssa(place.local) && place.projection[1..].iter().all(PlaceElem::is_stable_offset) + ssa.is_ssa(place.local) && rest.iter().all(PlaceElem::is_stable_offset) } else { storage_live.has_single_storage(place.local) && place.projection[..].iter().all(PlaceElem::is_stable_offset) @@ -206,7 +206,7 @@ fn compute_replacement<'tcx>( }; let mut can_perform_opt = |target: Place<'tcx>, loc: Location| { - if target.projection.first() == Some(&PlaceElem::Deref) { + if target.is_indirect_first_projection() { // We are creating a reborrow. As `place.local` is a reference, removing the storage // statements should not make it much harder for LLVM to optimize. storage_to_remove.insert(target.local); @@ -266,7 +266,7 @@ fn compute_replacement<'tcx>( Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) => { let mut place = *place; // Try to see through `place` in order to collapse reborrow chains. - if place.projection.first() == Some(&PlaceElem::Deref) + if let Some((&PlaceElem::Deref, rest)) = place.projection.split_first() && let Value::Pointer(target, inner_needs_unique) = targets[place.local] // Only see through immutable reference and pointers, as we do not know yet if // mutable references are fully replaced. @@ -274,7 +274,7 @@ fn compute_replacement<'tcx>( // Only collapse chain if the pointee is definitely live. && can_perform_opt(target, location) { - place = target.project_deeper(&place.projection[1..], tcx); + place = target.project_deeper(rest, tcx); } assert_ne!(place.local, local); if is_constant_place(place) { @@ -323,7 +323,7 @@ fn compute_replacement<'tcx>( return; } - if place.projection.first() != Some(&PlaceElem::Deref) { + if !place.is_indirect_first_projection() { // This is not a dereference, nothing to do. return; } @@ -392,20 +392,15 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> { } fn visit_var_debug_info(&mut self, debuginfo: &mut VarDebugInfo<'tcx>) { - // If the debuginfo is a pointer to another place: - // - if it's a reborrow, see through it; - // - if it's a direct borrow, increase `debuginfo.references`. + // If the debuginfo is a pointer to another place + // and it's a reborrow: see through it while let VarDebugInfoContents::Place(ref mut place) = debuginfo.value && place.projection.is_empty() && let Value::Pointer(target, _) = self.targets[place.local] - && target.projection.iter().all(|p| p.can_use_in_debuginfo()) + && let &[PlaceElem::Deref] = &target.projection[..] { - if let Some((&PlaceElem::Deref, rest)) = target.projection.split_last() { - *place = Place::from(target.local).project_deeper(rest, self.tcx); - self.any_replacement = true; - } else { - break; - } + *place = Place::from(target.local); + self.any_replacement = true; } // Simplify eventual projections left inside `debuginfo`. @@ -414,9 +409,7 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> { fn visit_place(&mut self, place: &mut Place<'tcx>, ctxt: PlaceContext, loc: Location) { loop { - if place.projection.first() != Some(&PlaceElem::Deref) { - return; - } + let Some((&PlaceElem::Deref, rest)) = place.projection.split_first() else { return }; let Value::Pointer(target, _) = self.targets[place.local] else { return }; @@ -432,7 +425,7 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> { return; } - *place = target.project_deeper(&place.projection[1..], self.tcx); + *place = target.project_deeper(rest, self.tcx); self.any_replacement = true; } } From b27942853efdb2fde2b6f73023c38ebfec3fcb8f Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Fri, 19 Sep 2025 21:53:06 +0200 Subject: [PATCH 5/8] naked_asm: emit a label starting with `func_end` The `cargo asm` tool pattern matches on such labels to figure out where functions end: normal functions generated by LLVM always do have such a label. We don't guarantee that naked functions emit such a label, but having `cargo asm` work is convenient --- compiler/rustc_codegen_ssa/src/mir/naked_asm.rs | 6 ++++++ tests/assembly-llvm/naked-functions/wasm32.rs | 1 + 2 files changed, 7 insertions(+) diff --git a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs index 31784cabf4af3..e7239ebfecf63 100644 --- a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs +++ b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs @@ -228,6 +228,9 @@ fn prefix_and_suffix<'tcx>( writeln!(begin, "{asm_name}:").unwrap(); writeln!(end).unwrap(); + // emit a label starting with `func_end` for `cargo asm` and other tooling that might + // pattern match on assembly generated by LLVM. + writeln!(end, ".Lfunc_end_{asm_name}:").unwrap(); writeln!(end, ".size {asm_name}, . - {asm_name}").unwrap(); writeln!(end, ".popsection").unwrap(); if !arch_suffix.is_empty() { @@ -246,6 +249,7 @@ fn prefix_and_suffix<'tcx>( writeln!(begin, "{asm_name}:").unwrap(); writeln!(end).unwrap(); + writeln!(end, ".Lfunc_end_{asm_name}:").unwrap(); writeln!(end, ".popsection").unwrap(); if !arch_suffix.is_empty() { writeln!(end, "{}", arch_suffix).unwrap(); @@ -263,6 +267,7 @@ fn prefix_and_suffix<'tcx>( writeln!(begin, "{asm_name}:").unwrap(); writeln!(end).unwrap(); + writeln!(end, ".Lfunc_end_{asm_name}:").unwrap(); writeln!(end, ".popsection").unwrap(); if !arch_suffix.is_empty() { writeln!(end, "{}", arch_suffix).unwrap(); @@ -287,6 +292,7 @@ fn prefix_and_suffix<'tcx>( writeln!(end).unwrap(); // .size is ignored for function symbols, so we can skip it writeln!(end, "end_function").unwrap(); + writeln!(end, ".Lfunc_end_{asm_name}:").unwrap(); } BinaryFormat::Xcoff => { // the LLVM XCOFFAsmParser is extremely incomplete and does not implement many of the diff --git a/tests/assembly-llvm/naked-functions/wasm32.rs b/tests/assembly-llvm/naked-functions/wasm32.rs index 77547e82041fe..4bf04dd392341 100644 --- a/tests/assembly-llvm/naked-functions/wasm32.rs +++ b/tests/assembly-llvm/naked-functions/wasm32.rs @@ -21,6 +21,7 @@ use minicore::*; // CHECK: .functype nop () -> () // CHECK-NOT: .size // CHECK: end_function +// CHECK-LABEL: .Lfunc_end_nop: #[no_mangle] #[unsafe(naked)] extern "C" fn nop() { From 42b38e3781ee3c34cf3df4dea4cd836a814cfb60 Mon Sep 17 00:00:00 2001 From: Sidney Cammeresi Date: Fri, 19 Sep 2025 21:17:21 -0700 Subject: [PATCH 6/8] Add unstable attribute to BTreeMap-related allocator generics Although these types aren't directly constructable externally, since they're pub, I think this omission was an oversight. --- library/alloc/src/collections/btree/map.rs | 6 +++++- library/alloc/src/collections/btree/map/entry.rs | 7 ++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 98f11e2ea57fd..cebd25c6039cc 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -546,7 +546,11 @@ impl fmt::Debug for ValuesMut<'_, K, V> { /// [`into_keys`]: BTreeMap::into_keys #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "map_into_keys_values", since = "1.54.0")] -pub struct IntoKeys { +pub struct IntoKeys< + K, + V, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + Clone = Global, +> { inner: IntoIter, } diff --git a/library/alloc/src/collections/btree/map/entry.rs b/library/alloc/src/collections/btree/map/entry.rs index 21486651b0b0f..df51be3de54b9 100644 --- a/library/alloc/src/collections/btree/map/entry.rs +++ b/library/alloc/src/collections/btree/map/entry.rs @@ -99,7 +99,12 @@ impl Debug for OccupiedEntry<'_, /// /// Contains the occupied entry, and the value that was not inserted. #[unstable(feature = "map_try_insert", issue = "82766")] -pub struct OccupiedError<'a, K: 'a, V: 'a, A: Allocator + Clone = Global> { +pub struct OccupiedError< + 'a, + K: 'a, + V: 'a, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + Clone = Global, +> { /// The entry in the map that was already occupied. pub entry: OccupiedEntry<'a, K, V, A>, /// The value which was not inserted, because the entry was already occupied. From ac3c480388d27ee9ebeb23d308bd37289d37bc41 Mon Sep 17 00:00:00 2001 From: tk <49250442+tkr-sh@users.noreply.github.com> Date: Wed, 14 May 2025 00:54:47 +0200 Subject: [PATCH 7/8] docs: improve doc of some methods w/ ranges --- library/alloc/src/collections/vec_deque/mod.rs | 12 ++++++------ library/alloc/src/string.rs | 12 ++++++------ library/alloc/src/vec/mod.rs | 8 ++++---- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 2fce5c3e737e4..d589860524b82 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -1486,8 +1486,8 @@ impl VecDeque { /// /// # Panics /// - /// Panics if the starting point is greater than the end point or if - /// the end point is greater than the length of the deque. + /// Panics if the range has `start_bound > end_bound`, or, if the range is + /// bounded on either end and past the length of the deque. /// /// # Examples /// @@ -1522,8 +1522,8 @@ impl VecDeque { /// /// # Panics /// - /// Panics if the starting point is greater than the end point or if - /// the end point is greater than the length of the deque. + /// Panics if the range has `start_bound > end_bound`, or, if the range is + /// bounded on either end and past the length of the deque. /// /// # Examples /// @@ -1568,8 +1568,8 @@ impl VecDeque { /// /// # Panics /// - /// Panics if the starting point is greater than the end point or if - /// the end point is greater than the length of the deque. + /// Panics if the range has `start_bound > end_bound`, or, if the range is + /// bounded on either end and past the length of the deque. /// /// # Leaking /// diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 1d0dd4be1b66a..e669c4708ad09 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -1117,8 +1117,8 @@ impl String { /// /// # Panics /// - /// Panics if the starting point or end point do not lie on a [`char`] - /// boundary, or if they're out of bounds. + /// Panics if the range has `start_bound > end_bound`, or, if the range is + /// bounded on either end and does not lie on a [`char`] boundary. /// /// # Examples /// @@ -1939,8 +1939,8 @@ impl String { /// /// # Panics /// - /// Panics if the starting point or end point do not lie on a [`char`] - /// boundary, or if they're out of bounds. + /// Panics if the range has `start_bound > end_bound`, or, if the range is + /// bounded on either end and does not lie on a [`char`] boundary. /// /// # Leaking /// @@ -2050,8 +2050,8 @@ impl String { /// /// # Panics /// - /// Panics if the starting point or end point do not lie on a [`char`] - /// boundary, or if they're out of bounds. + /// Panics if the range has `start_bound > end_bound`, or, if the range is + /// bounded on either end and does not lie on a [`char`] boundary. /// /// # Examples /// diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 1b80b43abc357..10c7ee4f6c89d 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2796,8 +2796,8 @@ impl Vec { /// /// # Panics /// - /// Panics if the starting point is greater than the end point or if - /// the end point is greater than the length of the vector. + /// Panics if the range has `start_bound > end_bound`, or, if the range is + /// bounded on either end and past the length of the vector. /// /// # Leaking /// @@ -3860,8 +3860,8 @@ impl Vec { /// /// # Panics /// - /// Panics if the starting point is greater than the end point or if - /// the end point is greater than the length of the vector. + /// Panics if the range has `start_bound > end_bound`, or, if the range is + /// bounded on either end and past the length of the vector. /// /// # Examples /// From 5c0cb3af59e03b4248ae58ca4e65f14307320195 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Sat, 20 Sep 2025 18:27:33 -0400 Subject: [PATCH 8/8] Fix old typo in lang_start_internal comment --- library/std/src/rt.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/rt.rs b/library/std/src/rt.rs index b3f3b301e3db6..8d95cc1fb5747 100644 --- a/library/std/src/rt.rs +++ b/library/std/src/rt.rs @@ -161,7 +161,7 @@ fn lang_start_internal( // mechanism itself. // // There are a couple of instances where unwinding can begin. First is inside of the - // `rt::init`, `rt::cleanup` and similar functions controlled by bstd. In those instances a + // `rt::init`, `rt::cleanup` and similar functions controlled by std. In those instances a // panic is a std implementation bug. A quite likely one too, as there isn't any way to // prevent std from accidentally introducing a panic to these functions. Another is from // user code from `main` or, more nefariously, as described in e.g. issue #86030.