From c5388d838cf866d8a629bde7eb0d9dfaf4ad195c Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 28 Jun 2026 15:37:58 +0200 Subject: [PATCH 01/16] Fix feature gate for `repr(simd)` --- Cargo.lock | 1 - compiler/rustc_ast_passes/Cargo.toml | 1 - compiler/rustc_ast_passes/src/feature_gate.rs | 16 ---------- .../rustc_attr_parsing/src/attributes/repr.rs | 18 +++++++---- tests/ui/attributes/attr-on-mac-call.rs | 4 +-- tests/ui/attributes/attr-on-mac-call.stderr | 32 ++++++++++++------- .../feature-gate-repr-simd.stderr | 30 ++++++++--------- .../ui/feature-gates/feature-gate-simd.stderr | 4 +-- .../repr/explicit-rust-repr-conflicts.stderr | 4 +-- tests/ui/repr/issue-83505-repr-simd.stderr | 4 +-- .../ui/span/gated-features-attr-spans.stderr | 4 +-- 11 files changed, 57 insertions(+), 61 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3fae7958e8157..8fafc7d47ccbc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3699,7 +3699,6 @@ dependencies = [ "rustc_session", "rustc_span", "rustc_target", - "thin-vec", ] [[package]] diff --git a/compiler/rustc_ast_passes/Cargo.toml b/compiler/rustc_ast_passes/Cargo.toml index da9b4633fdae9..91305ebab808d 100644 --- a/compiler/rustc_ast_passes/Cargo.toml +++ b/compiler/rustc_ast_passes/Cargo.toml @@ -18,5 +18,4 @@ rustc_macros = { path = "../rustc_macros" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } -thin-vec = "0.2.18" # tidy-alphabetical-end diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index d2e3c00bb0c07..cda68b3d88ecb 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -8,7 +8,6 @@ use rustc_hir::attrs::AttributeKind; use rustc_session::Session; use rustc_session::errors::{feature_err, feature_warn}; use rustc_span::{Span, Spanned, Symbol, sym}; -use thin_vec::ThinVec; use crate::diagnostics; @@ -188,21 +187,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { ast::ItemKind::ForeignMod(_foreign_module) => { // handled during lowering } - ast::ItemKind::Struct(..) | ast::ItemKind::Enum(..) | ast::ItemKind::Union(..) => { - for attr in attr::filter_by_name(&i.attrs, sym::repr) { - for item in attr.meta_item_list().unwrap_or_else(ThinVec::new) { - if item.has_name(sym::simd) { - gate!( - self, - repr_simd, - attr.span, - "SIMD types are experimental and possibly buggy" - ); - } - } - } - } - ast::ItemKind::Impl(ast::Impl { of_trait: Some(of_trait), .. }) => { if let ast::ImplPolarity::Negative(span) = of_trait.polarity { gate!( diff --git a/compiler/rustc_attr_parsing/src/attributes/repr.rs b/compiler/rustc_attr_parsing/src/attributes/repr.rs index bf03d87942651..630edafef8c98 100644 --- a/compiler/rustc_attr_parsing/src/attributes/repr.rs +++ b/compiler/rustc_attr_parsing/src/attributes/repr.rs @@ -3,6 +3,7 @@ use rustc_ast::{IntTy, LitIntType, LitKind, UintTy}; use rustc_feature::AttributeStability; use rustc_hir::attrs::IntType::{SignedInt, UnsignedInt}; use rustc_hir::attrs::ReprAttr; +use rustc_session::errors::feature_err; use super::prelude::*; use crate::session_diagnostics; @@ -141,13 +142,16 @@ fn parse_repr(cx: &mut AcceptContext<'_, '_>, param: &MetaItemParser) -> Option< Some(ReprC) } Some(sym::simd) => { - cx.check_target( - "(simd)", - &AllowedTargets::AllowList(&[ - Allow(Target::Struct), // Feature gated in `rustc_ast_passes` - Warn(Target::MacroCall), // FIXME: This is not feature gated (!!) - ]), - ); + if cx.features.is_some_and(|feats| !feats.repr_simd()) { + feature_err( + &cx.sess(), + sym::repr_simd, + param.span(), + "SIMD types are experimental and possibly buggy", + ) + .emit(); + } + cx.check_target("(simd)", &AllowedTargets::AllowList(&[Allow(Target::Struct)])); cx.expect_no_args(param.args())?; Some(ReprSimd) } diff --git a/tests/ui/attributes/attr-on-mac-call.rs b/tests/ui/attributes/attr-on-mac-call.rs index 1fdc2a6ed3562..7b30ec810ff81 100644 --- a/tests/ui/attributes/attr-on-mac-call.rs +++ b/tests/ui/attributes/attr-on-mac-call.rs @@ -104,8 +104,8 @@ fn main() { //~| WARN previously accepted unreachable!(); #[repr(simd)] - //~^ WARN attribute cannot be used on macro calls - //~| WARN previously accepted + //~^ ERROR attribute cannot be used on macro calls + //~| ERROR SIMD types are experimental and possibly buggy unreachable!(); #[register_tool(xyz)] //~^ ERROR crate-level attribute should be an inner attribute diff --git a/tests/ui/attributes/attr-on-mac-call.stderr b/tests/ui/attributes/attr-on-mac-call.stderr index fcbcd45e52eab..55d04165855d2 100644 --- a/tests/ui/attributes/attr-on-mac-call.stderr +++ b/tests/ui/attributes/attr-on-mac-call.stderr @@ -7,6 +7,25 @@ LL | #[sanitize(address = "off")] = help: `#[sanitize]` can be applied to crates, functions, impl blocks, modules, and statics = note: placing this attribute on a macro invocation does nothing even if the macro expands to what would be a valid target for the attribute +error[E0658]: SIMD types are experimental and possibly buggy + --> $DIR/attr-on-mac-call.rs:106:12 + | +LL | #[repr(simd)] + | ^^^^ + | + = note: see issue #27731 for more information + = help: add `#![feature(repr_simd)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: `#[repr(simd)]` attribute cannot be used on macro calls + --> $DIR/attr-on-mac-call.rs:106:5 + | +LL | #[repr(simd)] + | ^^^^^^^^^^^^^ + | + = help: `#[repr(simd)]` can only be applied to structs + = note: placing this attribute on a macro invocation does nothing even if the macro expands to what would be a valid target for the attribute + error: crate-level attribute should be an inner attribute: add an exclamation mark: `#![register_tool]` --> $DIR/attr-on-mac-call.rs:110:5 | @@ -322,15 +341,6 @@ LL | #[repr(Rust)] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: placing this attribute on a macro invocation does nothing even if the macro expands to what would be a valid target for the attribute -warning: `#[repr(simd)]` attribute cannot be used on macro calls - --> $DIR/attr-on-mac-call.rs:106:5 - | -LL | #[repr(simd)] - | ^^^^^^^^^^^^^ - | - = help: `#[repr(simd)]` can only be applied to structs - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: placing this attribute on a macro invocation does nothing even if the macro expands to what would be a valid target for the attribute - -error: aborting due to 2 previous errors; 31 warnings emitted +error: aborting due to 4 previous errors; 30 warnings emitted +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-repr-simd.stderr b/tests/ui/feature-gates/feature-gate-repr-simd.stderr index 1eab0a04988a5..82ded7e300122 100644 --- a/tests/ui/feature-gates/feature-gate-repr-simd.stderr +++ b/tests/ui/feature-gates/feature-gate-repr-simd.stderr @@ -1,50 +1,50 @@ error[E0658]: SIMD types are experimental and possibly buggy - --> $DIR/feature-gate-repr-simd.rs:1:1 + --> $DIR/feature-gate-repr-simd.rs:1:8 | LL | #[repr(simd)] - | ^^^^^^^^^^^^^ + | ^^^^ | = note: see issue #27731 for more information = help: add `#![feature(repr_simd)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: SIMD types are experimental and possibly buggy - --> $DIR/feature-gate-repr-simd.rs:6:1 + --> $DIR/feature-gate-repr-simd.rs:6:8 | LL | #[repr(simd)] - | ^^^^^^^^^^^^^ + | ^^^^ | = note: see issue #27731 for more information = help: add `#![feature(repr_simd)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: SIMD types are experimental and possibly buggy - --> $DIR/feature-gate-repr-simd.rs:9:1 + --> $DIR/feature-gate-repr-simd.rs:9:8 | LL | #[repr(simd)] - | ^^^^^^^^^^^^^ + | ^^^^ | = note: see issue #27731 for more information = help: add `#![feature(repr_simd)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: SIMD types are experimental and possibly buggy - --> $DIR/feature-gate-repr-simd.rs:13:1 +error: `#[repr(simd)]` attribute cannot be used on unions + --> $DIR/feature-gate-repr-simd.rs:9:1 | LL | #[repr(simd)] | ^^^^^^^^^^^^^ | - = note: see issue #27731 for more information - = help: add `#![feature(repr_simd)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = help: `#[repr(simd)]` can only be applied to structs -error: `#[repr(simd)]` attribute cannot be used on unions - --> $DIR/feature-gate-repr-simd.rs:9:1 +error[E0658]: SIMD types are experimental and possibly buggy + --> $DIR/feature-gate-repr-simd.rs:13:8 | LL | #[repr(simd)] - | ^^^^^^^^^^^^^ + | ^^^^ | - = help: `#[repr(simd)]` can only be applied to structs + = note: see issue #27731 for more information + = help: add `#![feature(repr_simd)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: `#[repr(simd)]` attribute cannot be used on enums --> $DIR/feature-gate-repr-simd.rs:13:1 diff --git a/tests/ui/feature-gates/feature-gate-simd.stderr b/tests/ui/feature-gates/feature-gate-simd.stderr index 834baa0a564ea..21c75752b48de 100644 --- a/tests/ui/feature-gates/feature-gate-simd.stderr +++ b/tests/ui/feature-gates/feature-gate-simd.stderr @@ -1,8 +1,8 @@ error[E0658]: SIMD types are experimental and possibly buggy - --> $DIR/feature-gate-simd.rs:1:1 + --> $DIR/feature-gate-simd.rs:1:8 | LL | #[repr(simd)] - | ^^^^^^^^^^^^^ + | ^^^^ | = note: see issue #27731 for more information = help: add `#![feature(repr_simd)]` to the crate attributes to enable diff --git a/tests/ui/repr/explicit-rust-repr-conflicts.stderr b/tests/ui/repr/explicit-rust-repr-conflicts.stderr index 30b667f5f2be3..d0bb3030ba22b 100644 --- a/tests/ui/repr/explicit-rust-repr-conflicts.stderr +++ b/tests/ui/repr/explicit-rust-repr-conflicts.stderr @@ -1,8 +1,8 @@ error[E0658]: SIMD types are experimental and possibly buggy - --> $DIR/explicit-rust-repr-conflicts.rs:18:1 + --> $DIR/explicit-rust-repr-conflicts.rs:18:14 | LL | #[repr(Rust, simd)] - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^ | = note: see issue #27731 for more information = help: add `#![feature(repr_simd)]` to the crate attributes to enable diff --git a/tests/ui/repr/issue-83505-repr-simd.stderr b/tests/ui/repr/issue-83505-repr-simd.stderr index 4694fa770b6c2..d0f895b4e34d2 100644 --- a/tests/ui/repr/issue-83505-repr-simd.stderr +++ b/tests/ui/repr/issue-83505-repr-simd.stderr @@ -7,10 +7,10 @@ LL | static CLs: Es; | help: provide a definition for the static: `= ;` error[E0658]: SIMD types are experimental and possibly buggy - --> $DIR/issue-83505-repr-simd.rs:5:1 + --> $DIR/issue-83505-repr-simd.rs:5:8 | LL | #[repr(simd)] - | ^^^^^^^^^^^^^ + | ^^^^ | = note: see issue #27731 for more information = help: add `#![feature(repr_simd)]` to the crate attributes to enable diff --git a/tests/ui/span/gated-features-attr-spans.stderr b/tests/ui/span/gated-features-attr-spans.stderr index f05c71774bd98..aa1e6baf08f6e 100644 --- a/tests/ui/span/gated-features-attr-spans.stderr +++ b/tests/ui/span/gated-features-attr-spans.stderr @@ -1,8 +1,8 @@ error[E0658]: SIMD types are experimental and possibly buggy - --> $DIR/gated-features-attr-spans.rs:1:1 + --> $DIR/gated-features-attr-spans.rs:1:8 | LL | #[repr(simd)] - | ^^^^^^^^^^^^^ + | ^^^^ | = note: see issue #27731 for more information = help: add `#![feature(repr_simd)]` to the crate attributes to enable From 88a3c51a21f34df4885c6d49f895565a2e15495e Mon Sep 17 00:00:00 2001 From: joboet Date: Sat, 20 Jun 2026 18:29:54 +0200 Subject: [PATCH 02/16] std: use `OnceLock` for SGX argument storage --- library/std/src/sys/args/sgx.rs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/library/std/src/sys/args/sgx.rs b/library/std/src/sys/args/sgx.rs index 8c1e07a787716..6750cf33d7686 100644 --- a/library/std/src/sys/args/sgx.rs +++ b/library/std/src/sys/args/sgx.rs @@ -1,9 +1,7 @@ -#![allow(implicit_provenance_casts)] // FIXME: this module systematically confuses pointers and integers - use crate::ffi::OsString; use crate::num::NonZero; use crate::ops::Try; -use crate::sync::atomic::{Atomic, AtomicUsize, Ordering}; +use crate::sync::OnceLock; use crate::sys::FromInner; use crate::sys::os_str::Buf; use crate::sys::pal::abi::usercalls::alloc; @@ -13,8 +11,7 @@ use crate::{fmt, slice}; // Specifying linkage/symbol name is solely to ensure a single instance between this crate and its unit tests #[cfg_attr(test, linkage = "available_externally")] #[unsafe(export_name = "_ZN16__rust_internals3std3sys3sgx4args4ARGSE")] -static ARGS: Atomic = AtomicUsize::new(0); -type ArgsStore = Vec; +static ARGS: OnceLock> = OnceLock::new(); #[cfg_attr(test, allow(dead_code))] pub unsafe fn init(argc: isize, argv: *const *const u8) { @@ -23,15 +20,16 @@ pub unsafe fn init(argc: isize, argv: *const *const u8) { let args = args .iter() .map(|a| OsString::from_inner(Buf { inner: a.copy_user_buffer() })) - .collect::(); - ARGS.store(Box::into_raw(Box::new(args)) as _, Ordering::Relaxed); + .collect::>(); + + if let Err(_) = ARGS.set(args) { + rtabort!("init called twice"); + } } } pub fn args() -> Args { - let args = unsafe { (ARGS.load(Ordering::Relaxed) as *const ArgsStore).as_ref() }; - let slice = args.map(|args| args.as_slice()).unwrap_or(&[]); - Args { iter: slice.iter() } + Args { iter: ARGS.get().map_or_default(|args| args.iter()) } } pub struct Args { From 16dc40890c8c463983bab78fe87f19abf0fac7ed Mon Sep 17 00:00:00 2001 From: SangHun Kim Date: Mon, 22 Jun 2026 18:06:28 +0900 Subject: [PATCH 03/16] Include AtomicU128/AtomicI128 in docs for any target --- library/core/src/sync/atomic.rs | 230 ++++++++++++++++++++------------ 1 file changed, 146 insertions(+), 84 deletions(-) diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 802d38e3994b3..02d1841bf4ae7 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -269,7 +269,7 @@ mod private { #[cfg(target_has_atomic_load_store = "64")] #[repr(C, align(8))] pub struct Align8(T); - #[cfg(target_has_atomic_load_store = "128")] + #[cfg(any(target_has_atomic_load_store = "128", doc))] #[repr(C, align(16))] pub struct Align16(T); } @@ -294,18 +294,42 @@ pub impl(self) unsafe trait AtomicPrimitive: Sized + Copy { type Storage: Sized; } -macro impl_atomic_primitive( - [$($T:ident)?] $Primitive:ty as $Storage:ident<$Operand:ty>, size($size:literal) -) { - #[unstable( - feature = "atomic_internals", - reason = "implementation detail which may disappear or be replaced at any time", - issue = "none" - )] - #[cfg(target_has_atomic_load_store = $size)] - unsafe impl $(<$T>)? AtomicPrimitive for $Primitive { - type Storage = private::$Storage<$Operand>; - } +macro impl_atomic_primitive { + ( + @impl [$($T:ident)?] $Primitive:ty as $Storage:ident<$Operand:ty>, + $cfg:meta + ) => { + #[unstable( + feature = "atomic_internals", + reason = "implementation detail which may disappear or be replaced at any time", + issue = "none" + )] + #[cfg($cfg)] + unsafe impl $(<$T>)? AtomicPrimitive for $Primitive { + type Storage = private::$Storage<$Operand>; + } + }, + + ( + [$($T:ident)?] $Primitive:ty as $Storage:ident<$Operand:ty>, + size($size:literal) + ) => { + impl_atomic_primitive!( + @impl [$($T)?] $Primitive as $Storage<$Operand>, + target_has_atomic_load_store = $size + ); + }, + + ( + [$($T:ident)?] $Primitive:ty as $Storage:ident<$Operand:ty>, + size($size:literal), + doc + ) => { + impl_atomic_primitive!( + @impl [$($T)?] $Primitive as $Storage<$Operand>, + any(target_has_atomic_load_store = $size, doc) + ); + }, } impl_atomic_primitive!([] bool as Align1, size("8")); @@ -317,8 +341,8 @@ impl_atomic_primitive!([] i32 as Align4, size("32")); impl_atomic_primitive!([] u32 as Align4, size("32")); impl_atomic_primitive!([] i64 as Align8, size("64")); impl_atomic_primitive!([] u64 as Align8, size("64")); -impl_atomic_primitive!([] i128 as Align16, size("128")); -impl_atomic_primitive!([] u128 as Align16, size("128")); +impl_atomic_primitive!([] i128 as Align16, size("128"), doc); +impl_atomic_primitive!([] u128 as Align16, size("128"), doc); #[cfg(target_pointer_width = "16")] impl_atomic_primitive!([] isize as Align2, size("ptr")); @@ -2529,7 +2553,8 @@ macro_rules! if_8_bit { #[cfg(target_has_atomic_load_store)] macro_rules! atomic_int { - ($cfg_cas:meta, + ($cfg_base:meta, + $cfg_cas:meta, $cfg_align:meta, $stable:meta, $stable_cxchg:meta, @@ -2605,7 +2630,8 @@ macro_rules! atomic_int { /// /// # Examples /// - /// ``` + #[cfg_attr($cfg_base, doc = "```")] + #[cfg_attr(not($cfg_base), doc = "```compile_fail")] #[doc = concat!($extra_feature, "use std::sync::atomic::", stringify!($atomic_type), ";")] /// #[doc = concat!("let atomic_forty_two = ", stringify!($atomic_type), "::new(42);")] @@ -2624,7 +2650,8 @@ macro_rules! atomic_int { /// /// # Examples /// - /// ``` + #[cfg_attr($cfg_base, doc = "```rust")] + #[cfg_attr(not($cfg_base), doc = "```rust,compile_fail")] #[doc = concat!($extra_feature, "use std::sync::atomic::{self, ", stringify!($atomic_type), "};")] /// /// // Get a pointer to an allocated value @@ -2686,7 +2713,8 @@ macro_rules! atomic_int { /// /// # Examples /// - /// ``` + #[cfg_attr($cfg_base, doc = "```")] + #[cfg_attr(not($cfg_base), doc = "```compile_fail")] #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")] /// #[doc = concat!("let mut some_var = ", stringify!($atomic_type), "::new(10);")] @@ -2714,7 +2742,8 @@ macro_rules! atomic_int { /// /// # Examples /// - /// ``` + #[cfg_attr($cfg_align, doc = "```rust")] + #[cfg_attr(not($cfg_align), doc = "```rust,compile_fail")] #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")] /// /// let mut some_int = 123; @@ -2724,7 +2753,7 @@ macro_rules! atomic_int { /// ``` /// #[inline] - #[$cfg_align] + #[cfg(any($cfg_align, doc))] #[stable(feature = "atomic_from_mut", since = "CURRENT_RUSTC_VERSION")] pub fn from_mut(v: &mut $int_type) -> &mut Self { let [] = [(); align_of::() - align_of::<$int_type>()]; @@ -2742,7 +2771,8 @@ macro_rules! atomic_int { /// /// # Examples /// - /// ```ignore-wasm + #[cfg_attr($cfg_base, doc = "```ignore-wasm")] + #[cfg_attr(not($cfg_base), doc = "```ignore-wasm,compile_fail")] #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")] /// #[doc = concat!("let mut some_ints = [const { ", stringify!($atomic_type), "::new(0) }; 10];")] @@ -2782,7 +2812,8 @@ macro_rules! atomic_int { /// /// # Examples /// - /// ```ignore-wasm + #[cfg_attr($cfg_align, doc = "```ignore-wasm")] + #[cfg_attr(not($cfg_align), doc = "```ignore-wasm,compile_fail")] #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")] /// /// let mut some_ints = [0; 10]; @@ -2797,7 +2828,7 @@ macro_rules! atomic_int { /// } /// ``` #[inline] - #[$cfg_align] + #[cfg(any($cfg_align, doc))] #[stable(feature = "atomic_from_mut", since = "CURRENT_RUSTC_VERSION")] pub fn from_mut_slice(v: &mut [$int_type]) -> &mut [Self] { let [] = [(); align_of::() - align_of::<$int_type>()]; @@ -2815,7 +2846,8 @@ macro_rules! atomic_int { /// /// # Examples /// - /// ``` + #[cfg_attr($cfg_base, doc = "```")] + #[cfg_attr(not($cfg_base), doc = "```compile_fail")] #[doc = concat!($extra_feature, "use std::sync::atomic::", stringify!($atomic_type), ";")] /// #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")] @@ -2841,7 +2873,8 @@ macro_rules! atomic_int { /// /// # Examples /// - /// ``` + #[cfg_attr($cfg_base, doc = "```")] + #[cfg_attr(not($cfg_base), doc = "```compile_fail")] #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")] /// #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")] @@ -2867,7 +2900,8 @@ macro_rules! atomic_int { /// /// # Examples /// - /// ``` + #[cfg_attr($cfg_base, doc = "```")] + #[cfg_attr(not($cfg_base), doc = "```compile_fail")] #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")] /// #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")] @@ -2896,7 +2930,8 @@ macro_rules! atomic_int { /// /// # Examples /// - /// ``` + #[cfg_attr($cfg_cas, doc = "```")] + #[cfg_attr(not($cfg_cas), doc = "```compile_fail")] #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")] /// #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")] @@ -2905,7 +2940,7 @@ macro_rules! atomic_int { /// ``` #[inline] #[$stable] - #[$cfg_cas] + #[cfg(any($cfg_cas, doc))] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[rustc_should_not_be_called_on_const_items] pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type { @@ -2953,7 +2988,8 @@ macro_rules! atomic_int { /// /// # Examples /// - /// ``` + #[cfg_attr($cfg_cas, doc = "```")] + #[cfg_attr(not($cfg_cas), doc = "```compile_fail")] #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")] /// #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")] @@ -2970,7 +3006,7 @@ macro_rules! atomic_int { since = "1.50.0", note = "Use `compare_exchange` or `compare_exchange_weak` instead") ] - #[$cfg_cas] + #[cfg(any($cfg_cas, doc))] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[rustc_should_not_be_called_on_const_items] pub fn compare_and_swap(&self, @@ -3006,7 +3042,8 @@ macro_rules! atomic_int { /// /// # Examples /// - /// ``` + #[cfg_attr($cfg_cas, doc = "```")] + #[cfg_attr(not($cfg_cas), doc = "```compile_fail")] #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")] /// #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")] @@ -3039,7 +3076,7 @@ macro_rules! atomic_int { /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap #[inline] #[$stable_cxchg] - #[$cfg_cas] + #[cfg(any($cfg_cas, doc))] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[rustc_should_not_be_called_on_const_items] pub fn compare_exchange(&self, @@ -3073,7 +3110,8 @@ macro_rules! atomic_int { /// /// # Examples /// - /// ``` + #[cfg_attr($cfg_cas, doc = "```")] + #[cfg_attr(not($cfg_cas), doc = "```compile_fail")] #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")] /// #[doc = concat!("let val = ", stringify!($atomic_type), "::new(4);")] @@ -3103,7 +3141,7 @@ macro_rules! atomic_int { /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap #[inline] #[$stable_cxchg] - #[$cfg_cas] + #[cfg(any($cfg_cas, doc))] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[rustc_should_not_be_called_on_const_items] pub fn compare_exchange_weak(&self, @@ -3131,7 +3169,8 @@ macro_rules! atomic_int { /// /// # Examples /// - /// ``` + #[cfg_attr($cfg_cas, doc = "```")] + #[cfg_attr(not($cfg_cas), doc = "```compile_fail")] #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")] /// #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(0);")] @@ -3140,7 +3179,7 @@ macro_rules! atomic_int { /// ``` #[inline] #[$stable] - #[$cfg_cas] + #[cfg(any($cfg_cas, doc))] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[rustc_should_not_be_called_on_const_items] pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type { @@ -3162,7 +3201,8 @@ macro_rules! atomic_int { /// /// # Examples /// - /// ``` + #[cfg_attr($cfg_cas, doc = "```")] + #[cfg_attr(not($cfg_cas), doc = "```compile_fail")] #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")] /// #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(20);")] @@ -3171,7 +3211,7 @@ macro_rules! atomic_int { /// ``` #[inline] #[$stable] - #[$cfg_cas] + #[cfg(any($cfg_cas, doc))] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[rustc_should_not_be_called_on_const_items] pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type { @@ -3196,7 +3236,8 @@ macro_rules! atomic_int { /// /// # Examples /// - /// ``` + #[cfg_attr($cfg_cas, doc = "```")] + #[cfg_attr(not($cfg_cas), doc = "```compile_fail")] #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")] /// #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(0b101101);")] @@ -3205,7 +3246,7 @@ macro_rules! atomic_int { /// ``` #[inline] #[$stable] - #[$cfg_cas] + #[cfg(any($cfg_cas, doc))] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[rustc_should_not_be_called_on_const_items] pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type { @@ -3230,7 +3271,8 @@ macro_rules! atomic_int { /// /// # Examples /// - /// ``` + #[cfg_attr($cfg_cas, doc = "```")] + #[cfg_attr(not($cfg_cas), doc = "```compile_fail")] #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")] /// #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(0x13);")] @@ -3239,7 +3281,7 @@ macro_rules! atomic_int { /// ``` #[inline] #[$stable_nand] - #[$cfg_cas] + #[cfg(any($cfg_cas, doc))] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[rustc_should_not_be_called_on_const_items] pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type { @@ -3264,7 +3306,8 @@ macro_rules! atomic_int { /// /// # Examples /// - /// ``` + #[cfg_attr($cfg_cas, doc = "```")] + #[cfg_attr(not($cfg_cas), doc = "```compile_fail")] #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")] /// #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(0b101101);")] @@ -3273,7 +3316,7 @@ macro_rules! atomic_int { /// ``` #[inline] #[$stable] - #[$cfg_cas] + #[cfg(any($cfg_cas, doc))] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[rustc_should_not_be_called_on_const_items] pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type { @@ -3298,7 +3341,8 @@ macro_rules! atomic_int { /// /// # Examples /// - /// ``` + #[cfg_attr($cfg_cas, doc = "```")] + #[cfg_attr(not($cfg_cas), doc = "```compile_fail")] #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")] /// #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(0b101101);")] @@ -3307,7 +3351,7 @@ macro_rules! atomic_int { /// ``` #[inline] #[$stable] - #[$cfg_cas] + #[cfg(any($cfg_cas, doc))] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[rustc_should_not_be_called_on_const_items] pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type { @@ -3320,7 +3364,7 @@ macro_rules! atomic_int { /// . #[inline] #[stable(feature = "no_more_cas", since = "1.45.0")] - #[$cfg_cas] + #[cfg(any($cfg_cas, doc))] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[rustc_should_not_be_called_on_const_items] #[deprecated( @@ -3374,7 +3418,8 @@ macro_rules! atomic_int { /// /// # Examples /// - /// ```rust + #[cfg_attr($cfg_cas, doc = "```rust")] + #[cfg_attr(not($cfg_cas), doc = "```rust,compile_fail")] #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")] /// #[doc = concat!("let x = ", stringify!($atomic_type), "::new(7);")] @@ -3385,7 +3430,7 @@ macro_rules! atomic_int { /// ``` #[inline] #[stable(feature = "atomic_try_update", since = "1.95.0")] - #[$cfg_cas] + #[cfg(any($cfg_cas, doc))] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[rustc_should_not_be_called_on_const_items] pub fn try_update( @@ -3441,7 +3486,8 @@ macro_rules! atomic_int { /// /// # Examples /// - /// ```rust + #[cfg_attr($cfg_cas, doc = "```rust")] + #[cfg_attr(not($cfg_cas), doc = "```rust,compile_fail")] #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")] /// #[doc = concat!("let x = ", stringify!($atomic_type), "::new(7);")] @@ -3451,7 +3497,7 @@ macro_rules! atomic_int { /// ``` #[inline] #[stable(feature = "atomic_try_update", since = "1.95.0")] - #[$cfg_cas] + #[cfg(any($cfg_cas, doc))] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[rustc_should_not_be_called_on_const_items] pub fn update( @@ -3486,7 +3532,8 @@ macro_rules! atomic_int { /// /// # Examples /// - /// ``` + #[cfg_attr($cfg_cas, doc = "```")] + #[cfg_attr(not($cfg_cas), doc = "```compile_fail")] #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")] /// #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(23);")] @@ -3496,7 +3543,8 @@ macro_rules! atomic_int { /// /// If you want to obtain the maximum value in one step, you can use the following: /// - /// ``` + #[cfg_attr($cfg_cas, doc = "```")] + #[cfg_attr(not($cfg_cas), doc = "```compile_fail")] #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")] /// #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(23);")] @@ -3506,7 +3554,7 @@ macro_rules! atomic_int { /// ``` #[inline] #[stable(feature = "atomic_min_max", since = "1.45.0")] - #[$cfg_cas] + #[cfg(any($cfg_cas, doc))] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[rustc_should_not_be_called_on_const_items] pub fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type { @@ -3531,7 +3579,8 @@ macro_rules! atomic_int { /// /// # Examples /// - /// ``` + #[cfg_attr($cfg_cas, doc = "```")] + #[cfg_attr(not($cfg_cas), doc = "```compile_fail")] #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")] /// #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(23);")] @@ -3543,7 +3592,8 @@ macro_rules! atomic_int { /// /// If you want to obtain the minimum value in one step, you can use the following: /// - /// ``` + #[cfg_attr($cfg_cas, doc = "```")] + #[cfg_attr(not($cfg_cas), doc = "```compile_fail")] #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")] /// #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(23);")] @@ -3553,7 +3603,7 @@ macro_rules! atomic_int { /// ``` #[inline] #[stable(feature = "atomic_min_max", since = "1.45.0")] - #[$cfg_cas] + #[cfg(any($cfg_cas, doc))] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[rustc_should_not_be_called_on_const_items] pub fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type { @@ -3606,8 +3656,9 @@ macro_rules! atomic_int { #[cfg(target_has_atomic_load_store = "8")] atomic_int! { - cfg(target_has_atomic = "8"), - cfg(target_has_atomic_primitive_alignment = "8"), + target_has_atomic_load_store = "8", + target_has_atomic = "8", + target_has_atomic_primitive_alignment = "8", stable(feature = "integer_atomics_stable", since = "1.34.0"), stable(feature = "integer_atomics_stable", since = "1.34.0"), stable(feature = "integer_atomics_stable", since = "1.34.0"), @@ -3624,8 +3675,9 @@ atomic_int! { } #[cfg(target_has_atomic_load_store = "8")] atomic_int! { - cfg(target_has_atomic = "8"), - cfg(target_has_atomic_primitive_alignment = "8"), + target_has_atomic_load_store = "8", + target_has_atomic = "8", + target_has_atomic_primitive_alignment = "8", stable(feature = "integer_atomics_stable", since = "1.34.0"), stable(feature = "integer_atomics_stable", since = "1.34.0"), stable(feature = "integer_atomics_stable", since = "1.34.0"), @@ -3642,8 +3694,9 @@ atomic_int! { } #[cfg(target_has_atomic_load_store = "16")] atomic_int! { - cfg(target_has_atomic = "16"), - cfg(target_has_atomic_primitive_alignment = "16"), + target_has_atomic_load_store = "16", + target_has_atomic = "16", + target_has_atomic_primitive_alignment = "16", stable(feature = "integer_atomics_stable", since = "1.34.0"), stable(feature = "integer_atomics_stable", since = "1.34.0"), stable(feature = "integer_atomics_stable", since = "1.34.0"), @@ -3660,8 +3713,9 @@ atomic_int! { } #[cfg(target_has_atomic_load_store = "16")] atomic_int! { - cfg(target_has_atomic = "16"), - cfg(target_has_atomic_primitive_alignment = "16"), + target_has_atomic_load_store = "16", + target_has_atomic = "16", + target_has_atomic_primitive_alignment = "16", stable(feature = "integer_atomics_stable", since = "1.34.0"), stable(feature = "integer_atomics_stable", since = "1.34.0"), stable(feature = "integer_atomics_stable", since = "1.34.0"), @@ -3678,8 +3732,9 @@ atomic_int! { } #[cfg(target_has_atomic_load_store = "32")] atomic_int! { - cfg(target_has_atomic = "32"), - cfg(target_has_atomic_primitive_alignment = "32"), + target_has_atomic_load_store = "32", + target_has_atomic = "32", + target_has_atomic_primitive_alignment = "32", stable(feature = "integer_atomics_stable", since = "1.34.0"), stable(feature = "integer_atomics_stable", since = "1.34.0"), stable(feature = "integer_atomics_stable", since = "1.34.0"), @@ -3696,8 +3751,9 @@ atomic_int! { } #[cfg(target_has_atomic_load_store = "32")] atomic_int! { - cfg(target_has_atomic = "32"), - cfg(target_has_atomic_primitive_alignment = "32"), + target_has_atomic_load_store = "32", + target_has_atomic = "32", + target_has_atomic_primitive_alignment = "32", stable(feature = "integer_atomics_stable", since = "1.34.0"), stable(feature = "integer_atomics_stable", since = "1.34.0"), stable(feature = "integer_atomics_stable", since = "1.34.0"), @@ -3714,8 +3770,9 @@ atomic_int! { } #[cfg(target_has_atomic_load_store = "64")] atomic_int! { - cfg(target_has_atomic = "64"), - cfg(target_has_atomic_primitive_alignment = "64"), + target_has_atomic_load_store = "64", + target_has_atomic = "64", + target_has_atomic_primitive_alignment = "64", stable(feature = "integer_atomics_stable", since = "1.34.0"), stable(feature = "integer_atomics_stable", since = "1.34.0"), stable(feature = "integer_atomics_stable", since = "1.34.0"), @@ -3732,8 +3789,9 @@ atomic_int! { } #[cfg(target_has_atomic_load_store = "64")] atomic_int! { - cfg(target_has_atomic = "64"), - cfg(target_has_atomic_primitive_alignment = "64"), + target_has_atomic_load_store = "64", + target_has_atomic = "64", + target_has_atomic_primitive_alignment = "64", stable(feature = "integer_atomics_stable", since = "1.34.0"), stable(feature = "integer_atomics_stable", since = "1.34.0"), stable(feature = "integer_atomics_stable", since = "1.34.0"), @@ -3748,10 +3806,11 @@ atomic_int! { 8, u64 AtomicU64 } -#[cfg(target_has_atomic_load_store = "128")] +#[cfg(any(target_has_atomic_load_store = "128", doc))] atomic_int! { - cfg(target_has_atomic = "128"), - cfg(target_has_atomic_primitive_alignment = "128"), + target_has_atomic_load_store = "128", + target_has_atomic = "128", + target_has_atomic_primitive_alignment = "128", unstable(feature = "integer_atomics", issue = "99069"), unstable(feature = "integer_atomics", issue = "99069"), unstable(feature = "integer_atomics", issue = "99069"), @@ -3766,10 +3825,11 @@ atomic_int! { 16, i128 AtomicI128 } -#[cfg(target_has_atomic_load_store = "128")] +#[cfg(any(target_has_atomic_load_store = "128", doc))] atomic_int! { - cfg(target_has_atomic = "128"), - cfg(target_has_atomic_primitive_alignment = "128"), + target_has_atomic_load_store = "128", + target_has_atomic = "128", + target_has_atomic_primitive_alignment = "128", unstable(feature = "integer_atomics", issue = "99069"), unstable(feature = "integer_atomics", issue = "99069"), unstable(feature = "integer_atomics", issue = "99069"), @@ -3790,8 +3850,9 @@ macro_rules! atomic_int_ptr_sized { ( $($target_pointer_width:literal $align:literal)* ) => { $( #[cfg(target_pointer_width = $target_pointer_width)] atomic_int! { - cfg(target_has_atomic = "ptr"), - cfg(target_has_atomic_primitive_alignment = "ptr"), + target_has_atomic_load_store = "ptr", + target_has_atomic = "ptr", + target_has_atomic_primitive_alignment = "ptr", stable(feature = "rust1", since = "1.0.0"), stable(feature = "extended_compare_and_swap", since = "1.10.0"), stable(feature = "atomic_debug", since = "1.3.0"), @@ -3808,8 +3869,9 @@ macro_rules! atomic_int_ptr_sized { } #[cfg(target_pointer_width = $target_pointer_width)] atomic_int! { - cfg(target_has_atomic = "ptr"), - cfg(target_has_atomic_primitive_alignment = "ptr"), + target_has_atomic_load_store = "ptr", + target_has_atomic = "ptr", + target_has_atomic_primitive_alignment = "ptr", stable(feature = "rust1", since = "1.0.0"), stable(feature = "extended_compare_and_swap", since = "1.10.0"), stable(feature = "atomic_debug", since = "1.3.0"), From 0f52e5225c35401aae028ffcf304fcc3ba874310 Mon Sep 17 00:00:00 2001 From: Max Dexheimer Date: Mon, 6 Jul 2026 19:38:40 +0200 Subject: [PATCH 04/16] Fix various issues in Arc::make_mut and Rc::make_mut --- library/alloc/src/rc.rs | 10 ++++-- library/alloc/src/sync.rs | 32 +++++++++++++---- library/alloctests/tests/arc.rs | 62 +++++++++++++++++++++++++++++++++ library/alloctests/tests/rc.rs | 17 +++++++++ 4 files changed, 113 insertions(+), 8 deletions(-) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 785c1c8026a1c..f2dd2444e2392 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -2090,8 +2090,6 @@ impl Rc { } else if Rc::weak_count(this) != 0 { // Can just steal the data, all that's left is Weaks - // We don't need panic-protection like the above branch does, but we might as well - // use the same mechanism. let mut in_progress: UniqueRcUninit = UniqueRcUninit::new(&**this, this.alloc.clone()); unsafe { @@ -2104,10 +2102,18 @@ impl Rc { size_of_val, ); + // This leaves us with 0 strong refs, so the data has + // effectively been moved to the new rc. this.inner().dec_strong(); + // Remove implicit strong-weak ref (no need to craft a fake // Weak here -- we know other Weaks can clean up for us) this.inner().dec_weak(); + + // Last chance to not accidentally forget the allocator. + // Only drop at the end of the scope to avoid panics. + let _alloc = ptr::read(&this.alloc); + // Replace `this` with newly constructed Rc that has the moved data. ptr::write(this, in_progress.into_rc()); } diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index d0f59c8873300..bb46f14fb9a36 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -2539,16 +2539,27 @@ impl Arc { // usize::MAX (i.e., locked), since the weak count can only be // locked by a thread with a strong reference. - // Materialize our own implicit weak pointer, so that it can clean - // up the ArcInner as needed. - let _weak = Weak { ptr: this.ptr, alloc: this.alloc.clone() }; + // Guard against panics while using the allocator. + // If we unwind before the Arc is overwritten, we expose a strong + // count of 0, resulting in a UAF (#155746, #157203). + // Until the new Arc is written, the old Arc must remain valid + struct Guard<'a, T: ?Sized> { + inner: &'a ArcInner, + } + impl<'a, T: ?Sized> Drop for Guard<'a, T> { + fn drop(&mut self) { + self.inner.strong.store(1, Release); + } + } + let guard = Guard { inner: this.inner() }; // Can just steal the data, all that's left is Weaks - // - // We don't need panic-protection like the above branch does, but we might as well - // use the same mechanism. + // Note that this can panic in two ways: + // - The allocation can fail + // - The allocator clone can fail let mut in_progress: UniqueArcUninit = UniqueArcUninit::new(&**this, this.alloc.clone()); + unsafe { // Initialize `in_progress` with move of **this. // We have to express this in terms of bytes because `T: ?Sized`; there is no @@ -2559,6 +2570,15 @@ impl Arc { size_of_val, ); + // We are now safe from panics. + mem::forget(guard); + + // Materialize our own implicit weak pointer, so that it can clean + // up the ArcInner as needed. + // Make sure the allocator is not leaked when the Arc is overwritten. + // Only drop at the end of the scope to avoid panics. + let _weak = Weak { ptr: this.ptr, alloc: ptr::read(&this.alloc) }; + ptr::write(this, in_progress.into_arc()); } } else { diff --git a/library/alloctests/tests/arc.rs b/library/alloctests/tests/arc.rs index 4b4d1787ace63..0a7f9e82a9c4b 100644 --- a/library/alloctests/tests/arc.rs +++ b/library/alloctests/tests/arc.rs @@ -328,3 +328,65 @@ mod pin_coerce_unsized { arg } } + +/// Test that `Arc::make_mut` does not forget an allocator when it steals the data. +#[test] +fn issue_158875_make_mut_dont_leak_allocator() { + use std::alloc::Global; + + let alloc = Rc::new(Global); + + { + let mut arc = Arc::new_in(123, alloc.clone()); + let weak = Arc::downgrade(&arc); // create a weak so make_mut steals the data + _ = Arc::make_mut(&mut arc); + assert_eq!(weak.upgrade(), None); + } + + assert_eq!(Rc::strong_count(&alloc), 1); // if this is >1, we have a memory leak! +} + +/// Test that `Arc::make_mut` does not cause a UAF if the allocator panics on +/// clone when it steals the data. +#[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] +fn issue_155746_make_mut_panic_safety() { + use std::alloc::{Allocator, System}; + use std::panic::AssertUnwindSafe; + + #[derive(Default)] + struct PanickingCloneAlloc { + do_panic: Rc>, + } + unsafe impl Allocator for PanickingCloneAlloc { + fn allocate( + &self, + layout: std::alloc::Layout, + ) -> Result, std::alloc::AllocError> { + System.allocate(layout) + } + + unsafe fn deallocate(&self, ptr: std::ptr::NonNull, layout: std::alloc::Layout) { + unsafe { System.deallocate(ptr, layout) } + } + } + impl Clone for PanickingCloneAlloc { + fn clone(&self) -> Self { + if self.do_panic.get() { panic!() } else { Self { do_panic: self.do_panic.clone() } } + } + } + + let alloc = PanickingCloneAlloc::default(); + let mut arc = Arc::new_in(vec![vec![1]], alloc.clone()); + + let _weak = Arc::downgrade(&arc); // create a weak so make_mut steals the data + + alloc.do_panic.set(true); + std::panic::catch_unwind(AssertUnwindSafe(|| { + Arc::make_mut(&mut arc); + })) + .unwrap_err(); + + assert_eq!(*arc, [[1]]); + assert_eq!(Arc::strong_count(&arc), 1); // if this is 0, we have a UAF! +} diff --git a/library/alloctests/tests/rc.rs b/library/alloctests/tests/rc.rs index 0417206d713ef..698585e94f8a6 100644 --- a/library/alloctests/tests/rc.rs +++ b/library/alloctests/tests/rc.rs @@ -950,3 +950,20 @@ fn test_unique_rc_unsizing_coercion() { let rc: Rc<[u8]> = UniqueRc::into_rc(rc); assert_eq!(*rc, [123, 0, 0]); } + +/// Test that `Rc::make_mut` does not forget an allocator when it steals the data. +#[test] +fn issue_158875_make_mut_dont_leak_allocator() { + use std::alloc::Global; + + let alloc = Rc::new(Global); + + { + let mut arc = Rc::new_in(123, alloc.clone()); + let weak = Rc::downgrade(&arc); // create a weak so make_mut steals the data + _ = Rc::make_mut(&mut arc); + assert_eq!(weak.upgrade(), None); + } + + assert_eq!(Rc::strong_count(&alloc), 1); // if this is >1, we have a memory leak! +} From 54bf52fcf87fbdac9a9d8900cfde9ff3b7519f8a Mon Sep 17 00:00:00 2001 From: David Carlier Date: Tue, 7 Jul 2026 22:40:45 +0100 Subject: [PATCH 05/16] std: fix Xous UDP send_to length mismatch and truncation Cap the payload length to the buffer capacity so the declared length, bytes copied, and returned count agree, matching TcpStream::write. --- library/std/src/sys/net/connection/xous/udp.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/library/std/src/sys/net/connection/xous/udp.rs b/library/std/src/sys/net/connection/xous/udp.rs index 4e66ea5d06e11..987b2598d9fb2 100644 --- a/library/std/src/sys/net/connection/xous/udp.rs +++ b/library/std/src/sys/net/connection/xous/udp.rs @@ -241,13 +241,12 @@ impl UdpSocket { } } } - let len = buf.len() as u16; - let len_bytes = len.to_le_bytes(); + let header_len = 21; + let len = buf.len().min(tx_req.raw.len() - header_len); + let len_bytes = (len as u16).to_le_bytes(); tx_req.raw[19] = len_bytes[0]; tx_req.raw[20] = len_bytes[1]; - for (&s, d) in buf.iter().zip(tx_req.raw[21..].iter_mut()) { - *d = s; - } + tx_req.raw[header_len..header_len + len].copy_from_slice(&buf[..len]); // let buf = unsafe { // xous::MemoryRange::new( @@ -306,7 +305,7 @@ impl UdpSocket { } } else { // no error - return Ok(len as usize); + return Ok(len); } } Err(crate::os::xous::ffi::Error::ServerQueueFull) => { From 015e8af7ec5be1326efcb7a7c06d0af34b82582b Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 15 May 2026 11:54:45 -0700 Subject: [PATCH 06/16] rustdoc: test ignoring rustc lints in CLI --- tests/rustdoc-ui/lints/deny-cmd.deny.stderr | 10 ++++++++++ tests/rustdoc-ui/lints/deny-cmd.rs | 8 ++++++++ 2 files changed, 18 insertions(+) create mode 100644 tests/rustdoc-ui/lints/deny-cmd.deny.stderr create mode 100644 tests/rustdoc-ui/lints/deny-cmd.rs diff --git a/tests/rustdoc-ui/lints/deny-cmd.deny.stderr b/tests/rustdoc-ui/lints/deny-cmd.deny.stderr new file mode 100644 index 0000000000000..3bde64d97b93a --- /dev/null +++ b/tests/rustdoc-ui/lints/deny-cmd.deny.stderr @@ -0,0 +1,10 @@ +error: missing documentation for a struct + --> $DIR/deny-cmd.rs:7:1 + | +LL | pub struct Foo; + | ^^^^^^^^^^^^^^ + | + = note: requested on the command line with `-D missing-docs` + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/lints/deny-cmd.rs b/tests/rustdoc-ui/lints/deny-cmd.rs new file mode 100644 index 0000000000000..bbddb11953049 --- /dev/null +++ b/tests/rustdoc-ui/lints/deny-cmd.rs @@ -0,0 +1,8 @@ +//@ revisions: deny allow +//@[deny] compile-flags: -Dmissing_docs +//@[allow] compile-flags: -Amissing_docs +//@[allow] check-pass +//! docs for crate + +pub struct Foo; +//[deny]~^ ERROR missing_docs From 83f510188e4bce3b83e2ea250cda6cfe98afde8b Mon Sep 17 00:00:00 2001 From: George Tokmaji Date: Fri, 10 Jul 2026 10:49:12 +0200 Subject: [PATCH 07/16] Look for the cdb architecture that corresponds to the target triple instead of the build triple Debugging other architectures with the build target CDB is neither a common nor a good user experience - for example, when targeting i686 from a x86_64 build target, you get all the internal WOW64 events, which also break debuginfo tests. Use the cdb.exe that corresponds to the target's architecture instead. --- src/bootstrap/src/core/debuggers/cdb.rs | 28 +++++++++++++------------ 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/bootstrap/src/core/debuggers/cdb.rs b/src/bootstrap/src/core/debuggers/cdb.rs index 7f835f3618724..c3d3c5c3c7a8b 100644 --- a/src/bootstrap/src/core/debuggers/cdb.rs +++ b/src/bootstrap/src/core/debuggers/cdb.rs @@ -1,4 +1,3 @@ -use std::env; use std::path::PathBuf; use crate::core::config::TargetSelection; @@ -8,18 +7,19 @@ pub(crate) struct Cdb { } /// We consult the registry to find the installed cdb.exe and try "Program Files" if that fails. +#[cfg(windows)] pub(crate) fn discover_cdb(target: TargetSelection) -> Option { - if !cfg!(windows) || !target.ends_with("-pc-windows-msvc") { + if !target.ends_with("-pc-windows-msvc") { return None; } - let cdb_arch = if cfg!(target_arch = "x86") { + let cdb_arch = if target.starts_with("i686") { "x86" - } else if cfg!(target_arch = "x86_64") { + } else if target.starts_with("x86_64") { "x64" - } else if cfg!(target_arch = "aarch64") { + } else if target.starts_with("aarch64") || target.starts_with("arm64") { "arm64" - } else if cfg!(target_arch = "arm") { + } else if target.starts_with("arm") || target.starts_with("thumb") { "arm" } else { return None; // No compatible CDB.exe in the Windows 10 SDK @@ -29,6 +29,11 @@ pub(crate) fn discover_cdb(target: TargetSelection) -> Option { Some(Cdb { cdb: path }) } +#[cfg(not(windows))] +pub(crate) fn discover_cdb(_target: TargetSelection) -> Option { + None +} + #[cfg(windows)] fn discover_cdb_registry(cdb_arch: &'static str) -> Option { use windows_registry::LOCAL_MACHINE; @@ -39,14 +44,11 @@ fn discover_cdb_registry(cdb_arch: &'static str) -> Option { path.exists().then_some(path) } -#[cfg(not(windows))] -fn discover_cdb_registry(_cdb_arch: &'static str) -> Option { - None -} - +#[cfg(windows)] fn discover_cdb_program_files(cdb_arch: &'static str) -> Option { - let mut path = - PathBuf::from(env::var_os("ProgramFiles(x86)").or_else(|| env::var_os("ProgramFiles"))?); + let mut path = PathBuf::from( + std::env::var_os("ProgramFiles(x86)").or_else(|| std::env::var_os("ProgramFiles"))?, + ); path.extend([r"Windows Kits\10\Debuggers", cdb_arch, r"cdb.exe"]); path.exists().then_some(path) } From f5c700e81a616fc3071075fe2e249096f08f71c8 Mon Sep 17 00:00:00 2001 From: Augie Fackler Date: Fri, 10 Jul 2026 10:33:00 -0400 Subject: [PATCH 08/16] riscv: update c-variadic test for LLVM changes LLVM 23 is now handling register allocation slightly differently and only uses CostPerUse=1 in -O{s,z} instead of unconditionally. This causes the -O3 behavior in this test to be a little smarter and skip some moves. I have attempted to make the test pass on both LLVM 22 and 23 without overly weakening it. Hopefully this is good enough! --- tests/assembly-llvm/c-variadic/riscv.rs | 47 +++++++++++-------------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/tests/assembly-llvm/c-variadic/riscv.rs b/tests/assembly-llvm/c-variadic/riscv.rs index 893d2a65eb37d..a71c1787f1642 100644 --- a/tests/assembly-llvm/c-variadic/riscv.rs +++ b/tests/assembly-llvm/c-variadic/riscv.rs @@ -64,18 +64,16 @@ unsafe extern "C" fn read_i32(ap: &mut VaList<'_>) -> i32 { // CHECK-LABEL: read_i32 // // RISCV32: lw a2, 0(a0) - // RISCV32-NEXT: lw a1, 0(a2) + // RISCV32-NEXT: lw [[VAL:a[0-1]]], 0(a2) // RISCV32-NEXT: addi a2, a2, 4 - // RISCV32-NEXT: sw a2, 0(a0) - // RISCV32-NEXT: mv a0, a1 - // RISCV32-NEXT: ret + // RISCV32-NEXT: sw a2, 0([[PTR:a[0-1]]]) + // RISCV32: ret // // RISCV64: ld a2, 0(a0) - // RISCV64-NEXT: lw a1, 0(a2) + // RISCV64-NEXT: lw [[VAL:a[0-1]]], 0(a2) // RISCV64-NEXT: addi a2, a2, 8 - // RISCV64-NEXT: sd a2, 0(a0) - // RISCV64-NEXT: mv a0, a1 - // RISCV64-NEXT: ret + // RISCV64-NEXT: sd a2, 0([[PTR:a[0-1]]]) + // RISCV64: ret va_arg(ap) } @@ -83,22 +81,20 @@ unsafe extern "C" fn read_i32(ap: &mut VaList<'_>) -> i32 { unsafe extern "C" fn read_i64(ap: &mut VaList<'_>) -> i64 { // CHECK-LABEL: read_i64 // - // RISCV32: lw a1, 0(a0) - // RISCV32-NEXT: addi a1, a1, 7 - // RISCV32-NEXT: andi a3, a1, -8 - // RISCV32-NEXT: lw a2, 0(a3) + // RISCV32: lw [[PTR:a[0-1]]], 0(a0) + // RISCV32-NEXT: addi [[PTR]], [[PTR]], 7 + // RISCV32-NEXT: andi a3, [[PTR]], -8 + // RISCV32-NEXT: lw [[LOW:a[02]]], 0(a3) // RISCV32-NEXT: lw a1, 4(a3) // RISCV32-NEXT: addi a3, a3, 8 - // RISCV32-NEXT: sw a3, 0(a0) - // RISCV32-NEXT: mv a0, a2 - // RISCV32-NEXT: ret + // RISCV32-NEXT: sw a3, 0([[LIST:a[02]]]) + // RISCV32: ret // // RISCV64: ld a2, 0(a0) - // RISCV64-NEXT: ld a1, 0(a2) + // RISCV64-NEXT: ld [[VAL:a[0-1]]], 0(a2) // RISCV64-NEXT: addi a2, a2, 8 - // RISCV64-NEXT: sd a2, 0(a0) - // RISCV64-NEXT: mv a0, a1 - // RISCV64-NEXT: ret + // RISCV64-NEXT: sd a2, 0([[PTR:a[0-1]]]) + // RISCV64: ret va_arg(ap) } @@ -107,15 +103,14 @@ unsafe extern "C" fn read_i64(ap: &mut VaList<'_>) -> i64 { unsafe extern "C" fn read_i128(ap: &mut VaList<'_>) -> i128 { // RISCV64-LABEL: read_i128 // - // RISCV64: ld a1, 0(a0) - // RISCV64-NEXT: addi a1, a1, 15 - // RISCV64-NEXT: andi a3, a1, -16 - // RISCV64-NEXT: ld a2, 0(a3) + // RISCV64: ld [[PTR:a[0-1]]], 0(a0) + // RISCV64-NEXT: addi [[PTR]], [[PTR]], 15 + // RISCV64-NEXT: andi a3, [[PTR]], -16 + // RISCV64-NEXT: ld [[LOW:a[02]]], 0(a3) // RISCV64-NEXT: ld a1, 8(a3) // RISCV64-NEXT: addi a3, a3, 16 - // RISCV64-NEXT: sd a3, 0(a0) - // RISCV64-NEXT: mv a0, a2 - // RISCV64-NEXT: ret + // RISCV64-NEXT: sd a3, 0([[LIST:a[02]]]) + // RISCV64: ret va_arg(ap) } From 64e2dd511e87a040adedb68c40693907bd3e9af5 Mon Sep 17 00:00:00 2001 From: Jakob Jungreuthmayer <116195279+jakobjung10@users.noreply.github.com> Date: Fri, 10 Jul 2026 16:31:21 +0200 Subject: [PATCH 09/16] pretty-print: use inline asm's actual macro name `ExprKind::InlineAsm` was always printed as `asm!`, so `naked_asm!` was printed as `asm!` too. Use `asm_macro.macro_name()` in the AST and HIR pretty-printers to print the correct name. --- compiler/rustc_ast_pretty/src/pprust/state/expr.rs | 2 +- compiler/rustc_hir_pretty/src/lib.rs | 2 +- tests/ui/unpretty/exhaustive-asm.expanded.stdout | 4 ++++ tests/ui/unpretty/exhaustive-asm.hir.stdout | 4 ++++ tests/ui/unpretty/exhaustive-asm.rs | 6 ++++++ 5 files changed, 16 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index 4f3281641359d..c3a197eaf3ae8 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -778,7 +778,7 @@ impl<'a> State<'a> { } ast::ExprKind::InlineAsm(a) => { // FIXME: Print `builtin # asm` once macro `asm` uses `builtin_syntax`. - self.word("asm!"); + self.word(format!("{}!", a.asm_macro.macro_name())); self.print_inline_asm(a); } ast::ExprKind::FormatArgs(fmt) => { diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 447ad2447b3b9..14ec11daa22fb 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1740,7 +1740,7 @@ impl<'a> State<'a> { self.print_expr_cond_paren(result, self.precedence(result) < ExprPrecedence::Jump); } hir::ExprKind::InlineAsm(asm) => { - self.word("asm!"); + self.word(format!("{}!", asm.asm_macro.macro_name())); self.print_inline_asm(asm); } hir::ExprKind::OffsetOf(container, fields) => { diff --git a/tests/ui/unpretty/exhaustive-asm.expanded.stdout b/tests/ui/unpretty/exhaustive-asm.expanded.stdout index 9b3c60b03ba77..8d2c1a5bc48bd 100644 --- a/tests/ui/unpretty/exhaustive-asm.expanded.stdout +++ b/tests/ui/unpretty/exhaustive-asm.expanded.stdout @@ -22,6 +22,10 @@ mod expressions { out(reg) _); } + + /// ExprKind::InlineAsm, with the `naked_asm!` macro + #[unsafe(naked)] + extern "C" fn expr_naked_asm() { naked_asm!("ret"); } } mod items { diff --git a/tests/ui/unpretty/exhaustive-asm.hir.stdout b/tests/ui/unpretty/exhaustive-asm.hir.stdout index c44db08653967..e3375ddcc0604 100644 --- a/tests/ui/unpretty/exhaustive-asm.hir.stdout +++ b/tests/ui/unpretty/exhaustive-asm.hir.stdout @@ -21,6 +21,10 @@ mod expressions { out(reg) _); } + + /// ExprKind::InlineAsm, with the `naked_asm!` macro + #[attr = Naked] + extern "C" fn expr_naked_asm() { naked_asm!("ret"); } } mod items { diff --git a/tests/ui/unpretty/exhaustive-asm.rs b/tests/ui/unpretty/exhaustive-asm.rs index 74a45447a20f1..dc4b3eee5e2ba 100644 --- a/tests/ui/unpretty/exhaustive-asm.rs +++ b/tests/ui/unpretty/exhaustive-asm.rs @@ -21,6 +21,12 @@ mod expressions { tmp = out(reg) _, ); } + + /// ExprKind::InlineAsm, with the `naked_asm!` macro + #[unsafe(naked)] + extern "C" fn expr_naked_asm() { + core::arch::naked_asm!("ret"); + } } mod items { From 920f3f1de86496764ee01940c49d3217a5fcac60 Mon Sep 17 00:00:00 2001 From: Dnreikronos Date: Tue, 26 May 2026 09:32:06 -0300 Subject: [PATCH 10/16] Suggest `generic_const_args` + `type const` in const operation diagnostics Point users at `#![feature(generic_const_args)]` and `type const` items when they hit the "generic parameters may not be used in const operations" error, not just `generic_const_exprs`. --- .../src/hir_ty_lowering/mod.rs | 15 +++++---- compiler/rustc_resolve/src/diagnostics.rs | 4 +++ compiler/rustc_resolve/src/error_helper.rs | 4 ++- .../rustc_resolve/src/late/diagnostics.rs | 5 ++- ...ociated-const-type-parameter-arrays.stderr | 1 + tests/ui/associated-consts/issue-47814.stderr | 2 ++ .../associated-item-duplicate-bounds.stderr | 1 + .../index-oob-ice-83993.stderr | 2 ++ .../const-arg-in-const-arg.min.stderr | 23 +++++++++++++ .../const-argument-if-length.min.stderr | 1 + ...st-argument-non-static-lifetime.min.stderr | 1 + .../complex-generic-default-expr.min.stderr | 2 ++ ...const_arg_trivial_macro_expansion-4.stderr | 3 ++ .../early/macro_rules-braces.stderr | 4 +++ ...ial-const-arg-macro-nested-braces-2.stderr | 1 + ...ivial-const-arg-macro-nested-braces.stderr | 1 + .../trivial-const-arg-nested-braces.stderr | 1 + .../suggest-const-item-for-generic-expr.rs | 26 +++++++++++++++ ...suggest-const-item-for-generic-expr.stderr | 32 +++++++++++++++++++ ...ay-size-in-generic-struct-param.min.stderr | 2 ++ .../generic_const_exprs/bad-multiply.stderr | 1 + .../dependence_lint.full.stderr | 2 ++ ...bute-missing-in-dependent-crate-ice.stderr | 2 ++ .../feature-gate-generic_const_exprs.stderr | 1 + .../issue-72787.min.stderr | 4 +++ ...sue-72819-generic-in-const-eval.min.stderr | 1 + .../generic_const_exprs/issue-74713.stderr | 1 + .../trivial-anon-const-use-cases.min.stderr | 1 + tests/ui/const-generics/ice-68875.stderr | 3 ++ ...ics-type_name-as-const-argument.min.stderr | 1 + tests/ui/const-generics/issue-46511.stderr | 1 + .../issues/issue-56445-2.stderr | 2 ++ .../issues/issue-56445-3.stderr | 3 ++ .../issues/issue-67375.min.stderr | 1 + .../issues/issue-67945-1.min.stderr | 2 ++ .../issues/issue-67945-2.min.stderr | 3 ++ .../issues/issue-67945-3.min.stderr | 1 + .../issues/issue-67945-4.min.stderr | 1 + .../issues/issue-68366.min.stderr | 1 + .../issue-76701-ty-param-in-const.stderr | 2 ++ .../const-generics/issues/issue-80062.stderr | 1 + .../const-generics/issues/issue-80375.stderr | 1 + .../legacy-const-generics-bad.stderr | 1 + .../mgca/adt_expr_arg_simple.stderr | 2 +- .../mgca/early-bound-param-lt-bad.stderr | 2 +- .../mgca/explicit_anon_consts.stderr | 14 ++++---- .../mgca/selftyalias-containing-param.stderr | 2 +- .../ui/const-generics/mgca/selftyparam.stderr | 2 +- .../size-of-generic-ptr-in-array-len.stderr | 2 +- .../mgca/tuple_ctor_complex_args.stderr | 2 +- .../mgca/tuple_expr_arg_complex.stderr | 2 +- .../mgca/type_const-on-generic-expr.stderr | 4 +-- .../mgca/type_const-on-generic_expr-2.stderr | 6 ++-- .../complex-expression.stderr | 7 ++++ .../forbid-non-static-lifetimes.stderr | 2 ++ .../forbid-self-no-normalize.stderr | 2 ++ .../self-ty-in-const-1.stderr | 3 ++ .../self-ty-in-const-2.stderr | 2 ++ ...r-lifetime-in-const-generic-default.stderr | 1 + ...ams-in-ct-in-ty-param-lazy-norm.min.stderr | 1 + ...peat_expr_hack_gives_right_generics.stderr | 2 ++ .../type-relative-path-144547.min.stderr | 3 ++ tests/ui/consts/const-eval/size-of-t.stderr | 1 + .../feature-gate-generic-const-args.stderr | 2 +- ...feature-gate-min-generic-const-args.stderr | 1 + .../param-in-ct-in-ty-param-default.stderr | 1 + .../issue-64173-unused-lifetimes.stderr | 4 +++ tests/ui/resolve/issue-39559.stderr | 1 + .../pattern_types/assoc_const.default.stderr | 4 +++ 69 files changed, 215 insertions(+), 28 deletions(-) create mode 100644 tests/ui/const-generics/gca/suggest-const-item-for-generic-expr.rs create mode 100644 tests/ui/const-generics/gca/suggest-const-item-for-generic-expr.stderr diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 79197c846071d..3401b699f2f5b 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -431,13 +431,16 @@ impl<'tcx> ForbidParamUsesFolder<'tcx> { diag.span_note(impl_.self_ty.span, "not a concrete type"); } } - if matches!(self.context, ForbidParamContext::ConstArgument) - && self.tcx.features().min_generic_const_args() - { - if !self.tcx.features().generic_const_args() { - diag.help("add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items"); - } else { + if matches!(self.context, ForbidParamContext::ConstArgument) { + if self.tcx.features().generic_const_args() { diag.help("consider factoring the expression into a `type const` item and use it as the const argument instead"); + } else if self.tcx.features().min_generic_const_args() { + diag.help("add `#![feature(generic_const_args)]` and extract the expression into a `type const` item"); + } else if self.tcx.sess.is_nightly_build() { + diag.help( + "add `#![feature(generic_const_exprs)]` to allow generic const expressions", + ); + diag.help("alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item"); } } diag.emit() diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 22cc6a581f19a..915a3abd6632e 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -407,6 +407,10 @@ pub(crate) struct ParamInNonTrivialAnonConst { "consider factoring the expression into a `type const` item and use it as the const argument instead" )] pub(crate) help_gca: bool, + #[help( + "alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item" + )] + pub(crate) help_suggest_gca: bool, } #[derive(Debug)] diff --git a/compiler/rustc_resolve/src/error_helper.rs b/compiler/rustc_resolve/src/error_helper.rs index 8ab193afe0eee..2388c5df23a90 100644 --- a/compiler/rustc_resolve/src/error_helper.rs +++ b/compiler/rustc_resolve/src/error_helper.rs @@ -1288,9 +1288,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { span, name, param_kind: is_type, - help: self.tcx.sess.is_nightly_build(), + help: self.tcx.sess.is_nightly_build() + && !self.tcx.features().min_generic_const_args(), is_gca, help_gca: is_gca, + help_suggest_gca: self.tcx.sess.is_nightly_build() && !is_gca, }) } ResolutionError::ParamInEnumDiscriminant { name, param_kind: is_type } => { diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 668278f13d9cf..4618110583bcd 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -3983,9 +3983,12 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { span: lifetime_ref.ident.span, name: lifetime_ref.ident.name, param_kind: diagnostics::ParamKindInNonTrivialAnonConst::Lifetime, - help: self.r.tcx.sess.is_nightly_build(), + help: self.r.tcx.sess.is_nightly_build() + && !self.r.features.min_generic_const_args(), is_gca: self.r.features.generic_const_args(), help_gca: self.r.features.generic_const_args(), + help_suggest_gca: self.r.tcx.sess.is_nightly_build() + && !self.r.features.generic_const_args(), }) .emit() } diff --git a/tests/ui/associated-consts/associated-const-type-parameter-arrays.stderr b/tests/ui/associated-consts/associated-const-type-parameter-arrays.stderr index 7f9324035e408..2170857fd7994 100644 --- a/tests/ui/associated-consts/associated-const-type-parameter-arrays.stderr +++ b/tests/ui/associated-consts/associated-const-type-parameter-arrays.stderr @@ -6,6 +6,7 @@ LL | let _array: [u32; ::Y]; | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 1 previous error diff --git a/tests/ui/associated-consts/issue-47814.stderr b/tests/ui/associated-consts/issue-47814.stderr index 7382426b0ffaa..b59603861d2e8 100644 --- a/tests/ui/associated-consts/issue-47814.stderr +++ b/tests/ui/associated-consts/issue-47814.stderr @@ -9,6 +9,8 @@ note: not a concrete type | LL | impl<'a> ArpIPv4<'a> { | ^^^^^^^^^^^ + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 1 previous error diff --git a/tests/ui/associated-item/associated-item-duplicate-bounds.stderr b/tests/ui/associated-item/associated-item-duplicate-bounds.stderr index 9f8faf951940f..28bf0e8fb3327 100644 --- a/tests/ui/associated-item/associated-item-duplicate-bounds.stderr +++ b/tests/ui/associated-item/associated-item-duplicate-bounds.stderr @@ -6,6 +6,7 @@ LL | links: [u32; A::LINKS], // Shouldn't suggest bounds already there. | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/adt_const_params/index-oob-ice-83993.stderr b/tests/ui/const-generics/adt_const_params/index-oob-ice-83993.stderr index b7e459511f15c..d42a098be25cd 100644 --- a/tests/ui/const-generics/adt_const_params/index-oob-ice-83993.stderr +++ b/tests/ui/const-generics/adt_const_params/index-oob-ice-83993.stderr @@ -6,6 +6,7 @@ LL | let x: &'b (); | = note: lifetime parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/index-oob-ice-83993.rs:18:17 @@ -15,6 +16,7 @@ LL | let _: &'b (); | = note: lifetime parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/const-arg-in-const-arg.min.stderr b/tests/ui/const-generics/const-arg-in-const-arg.min.stderr index ebb3e821e07b7..9ab0a3f137d74 100644 --- a/tests/ui/const-generics/const-arg-in-const-arg.min.stderr +++ b/tests/ui/const-generics/const-arg-in-const-arg.min.stderr @@ -6,6 +6,7 @@ LL | let _: [u8; foo::()]; | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:16:23 @@ -15,6 +16,7 @@ LL | let _: [u8; bar::()]; | = help: const parameters may only be used as standalone arguments here, i.e. `N` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:18:23 @@ -24,6 +26,7 @@ LL | let _: [u8; faz::<'a>(&())]; | = note: lifetime parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:20:23 @@ -33,6 +36,7 @@ LL | let _: [u8; baz::<'a>(&())]; | = note: lifetime parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:21:23 @@ -42,6 +46,7 @@ LL | let _: [u8; faz::<'b>(&())]; | = note: lifetime parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:23:23 @@ -51,6 +56,7 @@ LL | let _: [u8; baz::<'b>(&())]; | = note: lifetime parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:27:23 @@ -60,6 +66,7 @@ LL | let _ = [0; bar::()]; | = help: const parameters may only be used as standalone arguments here, i.e. `N` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:29:23 @@ -69,6 +76,7 @@ LL | let _ = [0; faz::<'a>(&())]; | = note: lifetime parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:31:23 @@ -78,6 +86,7 @@ LL | let _ = [0; baz::<'a>(&())]; | = note: lifetime parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:32:23 @@ -87,6 +96,7 @@ LL | let _ = [0; faz::<'b>(&())]; | = note: lifetime parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:34:23 @@ -96,6 +106,7 @@ LL | let _ = [0; baz::<'b>(&())]; | = note: lifetime parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:35:24 @@ -105,6 +116,7 @@ LL | let _: Foo<{ foo::() }>; | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:36:24 @@ -114,6 +126,7 @@ LL | let _: Foo<{ bar::() }>; | = help: const parameters may only be used as standalone arguments here, i.e. `N` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:38:24 @@ -123,6 +136,7 @@ LL | let _: Foo<{ faz::<'a>(&()) }>; | = note: lifetime parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:40:24 @@ -132,6 +146,7 @@ LL | let _: Foo<{ baz::<'a>(&()) }>; | = note: lifetime parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:41:24 @@ -141,6 +156,7 @@ LL | let _: Foo<{ faz::<'b>(&()) }>; | = note: lifetime parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:43:24 @@ -150,6 +166,7 @@ LL | let _: Foo<{ baz::<'b>(&()) }>; | = note: lifetime parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:44:27 @@ -159,6 +176,7 @@ LL | let _ = Foo::<{ foo::() }>; | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:45:27 @@ -168,6 +186,7 @@ LL | let _ = Foo::<{ bar::() }>; | = help: const parameters may only be used as standalone arguments here, i.e. `N` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:47:27 @@ -177,6 +196,7 @@ LL | let _ = Foo::<{ faz::<'a>(&()) }>; | = note: lifetime parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:49:27 @@ -186,6 +206,7 @@ LL | let _ = Foo::<{ baz::<'a>(&()) }>; | = note: lifetime parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:50:27 @@ -195,6 +216,7 @@ LL | let _ = Foo::<{ faz::<'b>(&()) }>; | = note: lifetime parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:52:27 @@ -204,6 +226,7 @@ LL | let _ = Foo::<{ baz::<'b>(&()) }>; | = note: lifetime parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error[E0747]: unresolved item provided when a constant was expected --> $DIR/const-arg-in-const-arg.rs:16:23 diff --git a/tests/ui/const-generics/const-argument-if-length.min.stderr b/tests/ui/const-generics/const-argument-if-length.min.stderr index fdc3f58447631..f6046db879ee0 100644 --- a/tests/ui/const-generics/const-argument-if-length.min.stderr +++ b/tests/ui/const-generics/const-argument-if-length.min.stderr @@ -6,6 +6,7 @@ LL | pad: [u8; is_zst::()], | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error[E0277]: the size for values of type `T` cannot be known at compilation time --> $DIR/const-argument-if-length.rs:16:12 diff --git a/tests/ui/const-generics/const-argument-non-static-lifetime.min.stderr b/tests/ui/const-generics/const-argument-non-static-lifetime.min.stderr index a1254672c9dc9..4adcdf836c891 100644 --- a/tests/ui/const-generics/const-argument-non-static-lifetime.min.stderr +++ b/tests/ui/const-generics/const-argument-non-static-lifetime.min.stderr @@ -6,6 +6,7 @@ LL | let _: &'a (); | = note: lifetime parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/defaults/complex-generic-default-expr.min.stderr b/tests/ui/const-generics/defaults/complex-generic-default-expr.min.stderr index e41e488371a8a..71ca2b2888644 100644 --- a/tests/ui/const-generics/defaults/complex-generic-default-expr.min.stderr +++ b/tests/ui/const-generics/defaults/complex-generic-default-expr.min.stderr @@ -6,6 +6,7 @@ LL | struct Foo; | = help: const parameters may only be used as standalone arguments here, i.e. `N` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/complex-generic-default-expr.rs:9:62 @@ -15,6 +16,7 @@ LL | struct Bar() }>(T); | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-4.stderr b/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-4.stderr index a1aee041b1fc5..994f9158d5d80 100644 --- a/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-4.stderr +++ b/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-4.stderr @@ -9,6 +9,7 @@ LL | fn foo() -> Foo<{ arg!{} arg!{} }> { loop {} } | = help: const parameters may only be used as standalone arguments here, i.e. `N` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item = note: this error originates in the macro `arg` (in Nightly builds, run with -Z macro-backtrace for more info) error: generic parameters may not be used in const operations @@ -22,6 +23,7 @@ LL | fn foo() -> Foo<{ arg!{} arg!{} }> { loop {} } | = help: const parameters may only be used as standalone arguments here, i.e. `N` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item = note: this error originates in the macro `arg` (in Nightly builds, run with -Z macro-backtrace for more info) error: generic parameters may not be used in const operations @@ -32,6 +34,7 @@ LL | fn bar() -> [(); { empty!{}; N }] { loop {} } | = help: const parameters may only be used as standalone arguments here, i.e. `N` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 3 previous errors diff --git a/tests/ui/const-generics/early/macro_rules-braces.stderr b/tests/ui/const-generics/early/macro_rules-braces.stderr index 30efa18982be6..3d2bd39163e62 100644 --- a/tests/ui/const-generics/early/macro_rules-braces.stderr +++ b/tests/ui/const-generics/early/macro_rules-braces.stderr @@ -28,6 +28,7 @@ LL | let _: foo!({{ N }}); | = help: const parameters may only be used as standalone arguments here, i.e. `N` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/macro_rules-braces.rs:36:19 @@ -37,6 +38,7 @@ LL | let _: bar!({ N }); | = help: const parameters may only be used as standalone arguments here, i.e. `N` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/macro_rules-braces.rs:41:20 @@ -46,6 +48,7 @@ LL | let _: baz!({{ N }}); | = help: const parameters may only be used as standalone arguments here, i.e. `N` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/macro_rules-braces.rs:46:19 @@ -55,6 +58,7 @@ LL | let _: biz!({ N }); | = help: const parameters may only be used as standalone arguments here, i.e. `N` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 6 previous errors diff --git a/tests/ui/const-generics/early/trivial-const-arg-macro-nested-braces-2.stderr b/tests/ui/const-generics/early/trivial-const-arg-macro-nested-braces-2.stderr index d68715b4d8b70..a1db1f26077df 100644 --- a/tests/ui/const-generics/early/trivial-const-arg-macro-nested-braces-2.stderr +++ b/tests/ui/const-generics/early/trivial-const-arg-macro-nested-braces-2.stderr @@ -9,6 +9,7 @@ LL | fn foo() -> A<{{ y!() }}> { | = help: const parameters may only be used as standalone arguments here, i.e. `N` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item = note: this error originates in the macro `y` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/early/trivial-const-arg-macro-nested-braces.stderr b/tests/ui/const-generics/early/trivial-const-arg-macro-nested-braces.stderr index 1171b359f1703..2a826f657d68d 100644 --- a/tests/ui/const-generics/early/trivial-const-arg-macro-nested-braces.stderr +++ b/tests/ui/const-generics/early/trivial-const-arg-macro-nested-braces.stderr @@ -9,6 +9,7 @@ LL | fn foo() -> A<{ y!() }> { | = help: const parameters may only be used as standalone arguments here, i.e. `N` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item = note: this error originates in the macro `y` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/early/trivial-const-arg-nested-braces.stderr b/tests/ui/const-generics/early/trivial-const-arg-nested-braces.stderr index b812e3333d9ca..7c831d4353643 100644 --- a/tests/ui/const-generics/early/trivial-const-arg-nested-braces.stderr +++ b/tests/ui/const-generics/early/trivial-const-arg-nested-braces.stderr @@ -6,6 +6,7 @@ LL | fn foo() -> A<{ { N } }> { | = help: const parameters may only be used as standalone arguments here, i.e. `N` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/gca/suggest-const-item-for-generic-expr.rs b/tests/ui/const-generics/gca/suggest-const-item-for-generic-expr.rs new file mode 100644 index 0000000000000..63f1050861f54 --- /dev/null +++ b/tests/ui/const-generics/gca/suggest-const-item-for-generic-expr.rs @@ -0,0 +1,26 @@ +// Regression test for https://github.com/rust-lang/rust/issues/156729 +// +// When a generic parameter is used in a const operation, the diagnostic should +// suggest creating a `type const` item as an alternative to `generic_const_exprs`. + +use std::mem::size_of; + +// Exact case from the issue: `Self` in a trait method. +pub unsafe trait TrivialType: Copy { + fn as_bytes(&self) -> &[u8; size_of::()] { + //~^ ERROR generic parameters may not be used in const operations + todo!() + } +} + +fn foo() -> [u8; size_of::()] { + //~^ ERROR generic parameters may not be used in const operations + todo!() +} + +fn bar() -> [u8; N + 1] { + //~^ ERROR generic parameters may not be used in const operations + todo!() +} + +fn main() {} diff --git a/tests/ui/const-generics/gca/suggest-const-item-for-generic-expr.stderr b/tests/ui/const-generics/gca/suggest-const-item-for-generic-expr.stderr new file mode 100644 index 0000000000000..3727cc4551e6e --- /dev/null +++ b/tests/ui/const-generics/gca/suggest-const-item-for-generic-expr.stderr @@ -0,0 +1,32 @@ +error: generic parameters may not be used in const operations + --> $DIR/suggest-const-item-for-generic-expr.rs:10:43 + | +LL | fn as_bytes(&self) -> &[u8; size_of::()] { + | ^^^^ cannot perform const operation using `Self` + | + = note: type parameters may not be used in const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item + +error: generic parameters may not be used in const operations + --> $DIR/suggest-const-item-for-generic-expr.rs:16:31 + | +LL | fn foo() -> [u8; size_of::()] { + | ^ cannot perform const operation using `T` + | + = note: type parameters may not be used in const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item + +error: generic parameters may not be used in const operations + --> $DIR/suggest-const-item-for-generic-expr.rs:21:34 + | +LL | fn bar() -> [u8; N + 1] { + | ^ cannot perform const operation using `N` + | + = help: const parameters may only be used as standalone arguments here, i.e. `N` + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item + +error: aborting due to 3 previous errors + diff --git a/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr b/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr index 3b65a1b82fdf4..a507159a778f0 100644 --- a/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr +++ b/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr @@ -6,6 +6,7 @@ LL | struct ArithArrayLen([u32; 0 + N]); | = help: const parameters may only be used as standalone arguments here, i.e. `N` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/array-size-in-generic-struct-param.rs:23:15 @@ -15,6 +16,7 @@ LL | arr: [u8; CFG.arr_size], | = help: const parameters may only be used as standalone arguments here, i.e. `CFG` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: `Config` is forbidden as the type of a const generic parameter --> $DIR/array-size-in-generic-struct-param.rs:21:21 diff --git a/tests/ui/const-generics/generic_const_exprs/bad-multiply.stderr b/tests/ui/const-generics/generic_const_exprs/bad-multiply.stderr index 7719831e20cdb..5f9ecc8fc701f 100644 --- a/tests/ui/const-generics/generic_const_exprs/bad-multiply.stderr +++ b/tests/ui/const-generics/generic_const_exprs/bad-multiply.stderr @@ -6,6 +6,7 @@ LL | SmallVec<{ D * 2 }>:, | = help: const parameters may only be used as standalone arguments here, i.e. `D` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error[E0747]: constant provided when a type was expected --> $DIR/bad-multiply.rs:7:14 diff --git a/tests/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr b/tests/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr index 23e126d870205..6bfe4d60a54b3 100644 --- a/tests/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr +++ b/tests/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr @@ -6,6 +6,7 @@ LL | let _: [u8; size_of::<*mut T>()]; // error on stable, error with gce | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/dependence_lint.rs:22:37 @@ -15,6 +16,7 @@ LL | let _: [u8; if true { size_of::() } else { 3 }]; // error on stable, | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item warning: cannot use constants which depend on generic parameters in types --> $DIR/dependence_lint.rs:10:9 diff --git a/tests/ui/const-generics/generic_const_exprs/feature-attribute-missing-in-dependent-crate-ice.stderr b/tests/ui/const-generics/generic_const_exprs/feature-attribute-missing-in-dependent-crate-ice.stderr index 5c3306651426b..d322775a5d974 100644 --- a/tests/ui/const-generics/generic_const_exprs/feature-attribute-missing-in-dependent-crate-ice.stderr +++ b/tests/ui/const-generics/generic_const_exprs/feature-attribute-missing-in-dependent-crate-ice.stderr @@ -9,6 +9,8 @@ note: not a concrete type | LL | impl aux::FromSlice for Wrapper { | ^^^^^^^^^^ + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/generic_const_exprs/feature-gate-generic_const_exprs.stderr b/tests/ui/const-generics/generic_const_exprs/feature-gate-generic_const_exprs.stderr index 3208bbbd86b88..4d8118d0ad530 100644 --- a/tests/ui/const-generics/generic_const_exprs/feature-gate-generic_const_exprs.stderr +++ b/tests/ui/const-generics/generic_const_exprs/feature-gate-generic_const_exprs.stderr @@ -6,6 +6,7 @@ LL | type Arr = [u8; N - 1]; | = help: const parameters may only be used as standalone arguments here, i.e. `N` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/generic_const_exprs/issue-72787.min.stderr b/tests/ui/const-generics/generic_const_exprs/issue-72787.min.stderr index cccf6dc6ae01c..392a7c5ec3914 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-72787.min.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-72787.min.stderr @@ -6,6 +6,7 @@ LL | Condition<{ LHS <= RHS }>: True | = help: const parameters may only be used as standalone arguments here, i.e. `LHS` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/issue-72787.rs:11:24 @@ -15,6 +16,7 @@ LL | Condition<{ LHS <= RHS }>: True | = help: const parameters may only be used as standalone arguments here, i.e. `RHS` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/issue-72787.rs:23:25 @@ -24,6 +26,7 @@ LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True, | = help: const parameters may only be used as standalone arguments here, i.e. `I` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/issue-72787.rs:23:36 @@ -33,6 +36,7 @@ LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True, | = help: const parameters may only be used as standalone arguments here, i.e. `J` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 4 previous errors diff --git a/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.min.stderr b/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.min.stderr index f91a2a302869e..345a7b381645f 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.min.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.min.stderr @@ -6,6 +6,7 @@ LL | where Assert::<{N < usize::MAX / 2}>: IsTrue, | = help: const parameters may only be used as standalone arguments here, i.e. `N` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/generic_const_exprs/issue-74713.stderr b/tests/ui/const-generics/generic_const_exprs/issue-74713.stderr index 78717028f6565..5cc02160d1878 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-74713.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-74713.stderr @@ -6,6 +6,7 @@ LL | let _: &'a (); | = note: lifetime parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error[E0308]: mismatched types --> $DIR/issue-74713.rs:3:10 diff --git a/tests/ui/const-generics/generic_const_exprs/trivial-anon-const-use-cases.min.stderr b/tests/ui/const-generics/generic_const_exprs/trivial-anon-const-use-cases.min.stderr index 6a868e95c8955..1d62f1da03ea7 100644 --- a/tests/ui/const-generics/generic_const_exprs/trivial-anon-const-use-cases.min.stderr +++ b/tests/ui/const-generics/generic_const_exprs/trivial-anon-const-use-cases.min.stderr @@ -6,6 +6,7 @@ LL | stuff: [u8; { S + 1 }], // `S + 1` is NOT a valid const expression in t | = help: const parameters may only be used as standalone arguments here, i.e. `S` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/ice-68875.stderr b/tests/ui/const-generics/ice-68875.stderr index 5a39a57242110..6cca0090cdaeb 100644 --- a/tests/ui/const-generics/ice-68875.stderr +++ b/tests/ui/const-generics/ice-68875.stderr @@ -3,6 +3,9 @@ error: generic `Self` types are currently not permitted in anonymous constants | LL | data: &'a [u8; Self::SIZE], | ^^^^ + | + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr b/tests/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr index 324738e44629e..f24817668e411 100644 --- a/tests/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr +++ b/tests/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr @@ -6,6 +6,7 @@ LL | T: Trait<{ std::intrinsics::type_name::() }>, | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: `&'static str` is forbidden as the type of a const generic parameter --> $DIR/intrinsics-type_name-as-const-argument.rs:9:22 diff --git a/tests/ui/const-generics/issue-46511.stderr b/tests/ui/const-generics/issue-46511.stderr index 75d59ee40b3b7..766c0a7ff596f 100644 --- a/tests/ui/const-generics/issue-46511.stderr +++ b/tests/ui/const-generics/issue-46511.stderr @@ -6,6 +6,7 @@ LL | _a: [u8; std::mem::size_of::<&'a mut u8>()] | = note: lifetime parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error[E0392]: lifetime parameter `'a` is never used --> $DIR/issue-46511.rs:3:12 diff --git a/tests/ui/const-generics/issues/issue-56445-2.stderr b/tests/ui/const-generics/issues/issue-56445-2.stderr index 351dcb1a15579..f13f4fd0a36db 100644 --- a/tests/ui/const-generics/issues/issue-56445-2.stderr +++ b/tests/ui/const-generics/issues/issue-56445-2.stderr @@ -9,6 +9,8 @@ note: not a concrete type | LL | impl<'a> OnDiskDirEntry<'a> { | ^^^^^^^^^^^^^^^^^^ + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/issues/issue-56445-3.stderr b/tests/ui/const-generics/issues/issue-56445-3.stderr index 96b68ca22f4fc..4e1300969487b 100644 --- a/tests/ui/const-generics/issues/issue-56445-3.stderr +++ b/tests/ui/const-generics/issues/issue-56445-3.stderr @@ -3,6 +3,9 @@ error: generic `Self` types are currently not permitted in anonymous constants | LL | ram: [u8; Self::SIZE], | ^^^^ + | + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/issues/issue-67375.min.stderr b/tests/ui/const-generics/issues/issue-67375.min.stderr index e871203ed9b89..cee31a88b181c 100644 --- a/tests/ui/const-generics/issues/issue-67375.min.stderr +++ b/tests/ui/const-generics/issues/issue-67375.min.stderr @@ -6,6 +6,7 @@ LL | inner: [(); { [|_: &T| {}; 0].len() }], | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error[E0392]: type parameter `T` is never used --> $DIR/issue-67375.rs:5:12 diff --git a/tests/ui/const-generics/issues/issue-67945-1.min.stderr b/tests/ui/const-generics/issues/issue-67945-1.min.stderr index 1de607644f570..932ab653f2ca9 100644 --- a/tests/ui/const-generics/issues/issue-67945-1.min.stderr +++ b/tests/ui/const-generics/issues/issue-67945-1.min.stderr @@ -6,6 +6,7 @@ LL | let x: S = MaybeUninit::uninit(); | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/issue-67945-1.rs:13:45 @@ -15,6 +16,7 @@ LL | let b = &*(&x as *const _ as *const S); | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error[E0392]: type parameter `S` is never used --> $DIR/issue-67945-1.rs:7:12 diff --git a/tests/ui/const-generics/issues/issue-67945-2.min.stderr b/tests/ui/const-generics/issues/issue-67945-2.min.stderr index 62fbed71aef54..c73ddd35369b1 100644 --- a/tests/ui/const-generics/issues/issue-67945-2.min.stderr +++ b/tests/ui/const-generics/issues/issue-67945-2.min.stderr @@ -3,6 +3,9 @@ error: generic `Self` types are currently not permitted in anonymous constants | LL | let x: Option> = None; | ^^^^ + | + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/issues/issue-67945-3.min.stderr b/tests/ui/const-generics/issues/issue-67945-3.min.stderr index 0ccba18e953cf..9f726ed8e5e14 100644 --- a/tests/ui/const-generics/issues/issue-67945-3.min.stderr +++ b/tests/ui/const-generics/issues/issue-67945-3.min.stderr @@ -6,6 +6,7 @@ LL | let x: Option = None; | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error[E0392]: type parameter `S` is never used --> $DIR/issue-67945-3.rs:9:12 diff --git a/tests/ui/const-generics/issues/issue-67945-4.min.stderr b/tests/ui/const-generics/issues/issue-67945-4.min.stderr index 83ae68e2dbf0e..94873bc45c440 100644 --- a/tests/ui/const-generics/issues/issue-67945-4.min.stderr +++ b/tests/ui/const-generics/issues/issue-67945-4.min.stderr @@ -6,6 +6,7 @@ LL | let x: Option> = None; | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error[E0392]: type parameter `S` is never used --> $DIR/issue-67945-4.rs:8:12 diff --git a/tests/ui/const-generics/issues/issue-68366.min.stderr b/tests/ui/const-generics/issues/issue-68366.min.stderr index 40bf7dc6deeab..89bd073e4011b 100644 --- a/tests/ui/const-generics/issues/issue-68366.min.stderr +++ b/tests/ui/const-generics/issues/issue-68366.min.stderr @@ -6,6 +6,7 @@ LL | impl Collatz<{Some(N)}> {} | = help: const parameters may only be used as standalone arguments here, i.e. `N` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: `Option` is forbidden as the type of a const generic parameter --> $DIR/issue-68366.rs:9:25 diff --git a/tests/ui/const-generics/issues/issue-76701-ty-param-in-const.stderr b/tests/ui/const-generics/issues/issue-76701-ty-param-in-const.stderr index e58c894a27034..289e9f59b697e 100644 --- a/tests/ui/const-generics/issues/issue-76701-ty-param-in-const.stderr +++ b/tests/ui/const-generics/issues/issue-76701-ty-param-in-const.stderr @@ -6,6 +6,7 @@ LL | fn ty_param() -> [u8; std::mem::size_of::()] { | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/issue-76701-ty-param-in-const.rs:6:42 @@ -15,6 +16,7 @@ LL | fn const_param() -> [u8; N + 1] { | = help: const parameters may only be used as standalone arguments here, i.e. `N` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/issues/issue-80062.stderr b/tests/ui/const-generics/issues/issue-80062.stderr index 5da8e45fac805..bff3886d6328b 100644 --- a/tests/ui/const-generics/issues/issue-80062.stderr +++ b/tests/ui/const-generics/issues/issue-80062.stderr @@ -6,6 +6,7 @@ LL | let _: [u8; sof::()]; | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/issues/issue-80375.stderr b/tests/ui/const-generics/issues/issue-80375.stderr index 9a15e0380a193..552bdc6618785 100644 --- a/tests/ui/const-generics/issues/issue-80375.stderr +++ b/tests/ui/const-generics/issues/issue-80375.stderr @@ -6,6 +6,7 @@ LL | struct MyArray([u8; COUNT + 1]); | = help: const parameters may only be used as standalone arguments here, i.e. `COUNT` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/legacy-const-generics-bad.stderr b/tests/ui/const-generics/legacy-const-generics-bad.stderr index a8681d6205309..df686f6484c75 100644 --- a/tests/ui/const-generics/legacy-const-generics-bad.stderr +++ b/tests/ui/const-generics/legacy-const-generics-bad.stderr @@ -18,6 +18,7 @@ LL | legacy_const_generics::foo(0, N + 1, 2); | = help: const parameters may only be used as standalone arguments here, i.e. `N` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/mgca/adt_expr_arg_simple.stderr b/tests/ui/const-generics/mgca/adt_expr_arg_simple.stderr index 8f02ce0f82315..2ce1e55e4f832 100644 --- a/tests/ui/const-generics/mgca/adt_expr_arg_simple.stderr +++ b/tests/ui/const-generics/mgca/adt_expr_arg_simple.stderr @@ -10,7 +10,7 @@ error: generic parameters may not be used in const operations LL | foo::<{ Some:: { 0: const { N + 1 } } }>(); | ^ | - = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/mgca/early-bound-param-lt-bad.stderr b/tests/ui/const-generics/mgca/early-bound-param-lt-bad.stderr index b25199bca2e28..511c888ee24f0 100644 --- a/tests/ui/const-generics/mgca/early-bound-param-lt-bad.stderr +++ b/tests/ui/const-generics/mgca/early-bound-param-lt-bad.stderr @@ -4,7 +4,7 @@ error: generic parameters may not be used in const operations LL | T: Trait | ^^ | - = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts.stderr b/tests/ui/const-generics/mgca/explicit_anon_consts.stderr index 9ab6af010bf21..e9b32b6860c13 100644 --- a/tests/ui/const-generics/mgca/explicit_anon_consts.stderr +++ b/tests/ui/const-generics/mgca/explicit_anon_consts.stderr @@ -40,7 +40,7 @@ error: generic parameters may not be used in const operations LL | type const ITEM3: usize = const { N }; | ^ | - = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/explicit_anon_consts.rs:60:31 @@ -48,7 +48,7 @@ error: generic parameters may not be used in const operations LL | T3: Trait, | ^ | - = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/explicit_anon_consts.rs:69:58 @@ -56,7 +56,7 @@ error: generic parameters may not be used in const operations LL | struct Default3; | ^ | - = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/explicit_anon_consts.rs:28:27 @@ -64,7 +64,7 @@ error: generic parameters may not be used in const operations LL | let _3 = [(); const { N }]; | ^ | - = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/explicit_anon_consts.rs:33:26 @@ -72,7 +72,7 @@ error: generic parameters may not be used in const operations LL | let _6: [(); const { N }] = todo!(); | ^ | - = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/explicit_anon_consts.rs:11:41 @@ -80,7 +80,7 @@ error: generic parameters may not be used in const operations LL | type Adt3 = Foo; | ^ | - = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/explicit_anon_consts.rs:19:42 @@ -88,7 +88,7 @@ error: generic parameters may not be used in const operations LL | type Arr3 = [(); const { N }]; | ^ | - = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 13 previous errors diff --git a/tests/ui/const-generics/mgca/selftyalias-containing-param.stderr b/tests/ui/const-generics/mgca/selftyalias-containing-param.stderr index cf5974fd83df9..26e7b495b4406 100644 --- a/tests/ui/const-generics/mgca/selftyalias-containing-param.stderr +++ b/tests/ui/const-generics/mgca/selftyalias-containing-param.stderr @@ -9,7 +9,7 @@ note: not a concrete type | LL | impl S { | ^^^^ - = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/mgca/selftyparam.stderr b/tests/ui/const-generics/mgca/selftyparam.stderr index 74d8f083ee09e..11e23efb4a127 100644 --- a/tests/ui/const-generics/mgca/selftyparam.stderr +++ b/tests/ui/const-generics/mgca/selftyparam.stderr @@ -4,7 +4,7 @@ error: generic parameters may not be used in const operations LL | fn foo() -> [(); const { let _: Self; 1 }]; | ^^^^ | - = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.stderr b/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.stderr index 694d4c8ebabd4..2752484046341 100644 --- a/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.stderr +++ b/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.stderr @@ -10,7 +10,7 @@ error: generic parameters may not be used in const operations LL | [0; const { size_of::<*mut T>() }]; | ^ | - = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/mgca/tuple_ctor_complex_args.stderr b/tests/ui/const-generics/mgca/tuple_ctor_complex_args.stderr index a4e7cb94c57c3..9b7c40d91515b 100644 --- a/tests/ui/const-generics/mgca/tuple_ctor_complex_args.stderr +++ b/tests/ui/const-generics/mgca/tuple_ctor_complex_args.stderr @@ -10,7 +10,7 @@ error: generic parameters may not be used in const operations LL | with_point::<{ Point(const { N + 1 }, N) }>(); | ^ | - = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/mgca/tuple_expr_arg_complex.stderr b/tests/ui/const-generics/mgca/tuple_expr_arg_complex.stderr index 4bed120284c08..e4dad6f03e511 100644 --- a/tests/ui/const-generics/mgca/tuple_expr_arg_complex.stderr +++ b/tests/ui/const-generics/mgca/tuple_expr_arg_complex.stderr @@ -22,7 +22,7 @@ error: generic parameters may not be used in const operations LL | takes_nested_tuple::<{ core::direct_const_arg!((N, (N, const { N + 1 }))) }>(); | ^ | - = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 4 previous errors diff --git a/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr b/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr index 0c88fbfb8578c..b6737d31ef012 100644 --- a/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr +++ b/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr @@ -4,7 +4,7 @@ error: generic parameters may not be used in const operations LL | type const FREE1: usize = const { std::mem::size_of::() }; | ^ | - = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/type_const-on-generic-expr.rs:8:51 @@ -12,7 +12,7 @@ error: generic parameters may not be used in const operations LL | type const FREE2: usize = const { I + 1 }; | ^ | - = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.stderr b/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.stderr index 78e38d800524e..56d94d5d928b9 100644 --- a/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.stderr +++ b/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.stderr @@ -4,7 +4,7 @@ error: generic parameters may not be used in const operations LL | type const N1: usize = const { std::mem::size_of::() }; | ^ | - = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/type_const-on-generic_expr-2.rs:15:52 @@ -12,7 +12,7 @@ error: generic parameters may not be used in const operations LL | type const N2: usize = const { I + 1 }; | ^ | - = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/type_const-on-generic_expr-2.rs:17:40 @@ -20,7 +20,7 @@ error: generic parameters may not be used in const operations LL | type const N3: usize = const { 2 & X }; | ^ | - = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 3 previous errors diff --git a/tests/ui/const-generics/min_const_generics/complex-expression.stderr b/tests/ui/const-generics/min_const_generics/complex-expression.stderr index ed3fa840cdfed..96d67fb642a66 100644 --- a/tests/ui/const-generics/min_const_generics/complex-expression.stderr +++ b/tests/ui/const-generics/min_const_generics/complex-expression.stderr @@ -6,6 +6,7 @@ LL | struct Break0([u8; { N + 1 }]); | = help: const parameters may only be used as standalone arguments here, i.e. `N` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/complex-expression.rs:13:40 @@ -15,6 +16,7 @@ LL | struct Break1([u8; { { N } }]); | = help: const parameters may only be used as standalone arguments here, i.e. `N` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/complex-expression.rs:17:17 @@ -24,6 +26,7 @@ LL | let _: [u8; N + 1]; | = help: const parameters may only be used as standalone arguments here, i.e. `N` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/complex-expression.rs:22:17 @@ -33,6 +36,7 @@ LL | let _ = [0; N + 1]; | = help: const parameters may only be used as standalone arguments here, i.e. `N` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/complex-expression.rs:26:45 @@ -42,6 +46,7 @@ LL | struct BreakTy0(T, [u8; { size_of::<*mut T>() }]); | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/complex-expression.rs:29:47 @@ -51,6 +56,7 @@ LL | struct BreakTy1(T, [u8; { { size_of::<*mut T>() } }]); | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/complex-expression.rs:33:32 @@ -60,6 +66,7 @@ LL | let _: [u8; size_of::<*mut T>() + 1]; | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item warning: cannot use constants which depend on generic parameters in types --> $DIR/complex-expression.rs:38:17 diff --git a/tests/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.stderr b/tests/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.stderr index 909b0476999f3..c8def64d8f2a4 100644 --- a/tests/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.stderr +++ b/tests/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.stderr @@ -6,6 +6,7 @@ LL | test::<{ let _: &'a (); 3 },>(); | = note: lifetime parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/forbid-non-static-lifetimes.rs:21:16 @@ -15,6 +16,7 @@ LL | [(); (|_: &'a u8| (), 0).1]; | = note: lifetime parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/min_const_generics/forbid-self-no-normalize.stderr b/tests/ui/const-generics/min_const_generics/forbid-self-no-normalize.stderr index 03c76150010fb..d8dd17f0c8ffe 100644 --- a/tests/ui/const-generics/min_const_generics/forbid-self-no-normalize.stderr +++ b/tests/ui/const-generics/min_const_generics/forbid-self-no-normalize.stderr @@ -9,6 +9,8 @@ note: not a concrete type | LL | impl BindsParam for ::Assoc { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr b/tests/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr index e9216fc12a22a..2350453634541 100644 --- a/tests/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr +++ b/tests/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr @@ -6,6 +6,7 @@ LL | fn t1() -> [u8; std::mem::size_of::()]; | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic `Self` types are currently not permitted in anonymous constants --> $DIR/self-ty-in-const-1.rs:12:41 @@ -18,6 +19,8 @@ note: not a concrete type | LL | impl Bar { | ^^^^^^ + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/min_const_generics/self-ty-in-const-2.stderr b/tests/ui/const-generics/min_const_generics/self-ty-in-const-2.stderr index 4943f0d70bd03..a8aa970929d5e 100644 --- a/tests/ui/const-generics/min_const_generics/self-ty-in-const-2.stderr +++ b/tests/ui/const-generics/min_const_generics/self-ty-in-const-2.stderr @@ -9,6 +9,8 @@ note: not a concrete type | LL | impl Baz for Bar { | ^^^^^^ + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/outer-lifetime-in-const-generic-default.stderr b/tests/ui/const-generics/outer-lifetime-in-const-generic-default.stderr index 38b25445f611a..11212a1b2e4ad 100644 --- a/tests/ui/const-generics/outer-lifetime-in-const-generic-default.stderr +++ b/tests/ui/const-generics/outer-lifetime-in-const-generic-default.stderr @@ -6,6 +6,7 @@ LL | let x: &'a (); | = note: lifetime parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr b/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr index 3f0e5e96fc814..534e30b7fdab5 100644 --- a/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr +++ b/tests/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr @@ -12,6 +12,7 @@ LL | struct Foo()]>(T, U); | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error[E0128]: generic parameter defaults cannot reference parameters before they are declared --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:8:21 diff --git a/tests/ui/const-generics/repeat_expr_hack_gives_right_generics.stderr b/tests/ui/const-generics/repeat_expr_hack_gives_right_generics.stderr index fe32fbcc87d57..627ffb15c56a6 100644 --- a/tests/ui/const-generics/repeat_expr_hack_gives_right_generics.stderr +++ b/tests/ui/const-generics/repeat_expr_hack_gives_right_generics.stderr @@ -6,6 +6,7 @@ LL | bar::<{ [1; N] }>(); | = help: const parameters may only be used as standalone arguments here, i.e. `N` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/repeat_expr_hack_gives_right_generics.rs:22:19 @@ -15,6 +16,7 @@ LL | bar::<{ [1; { N + 1 }] }>(); | = help: const parameters may only be used as standalone arguments here, i.e. `N` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/type-relative-path-144547.min.stderr b/tests/ui/const-generics/type-relative-path-144547.min.stderr index 1192a7434ec8e..76f48afe60f42 100644 --- a/tests/ui/const-generics/type-relative-path-144547.min.stderr +++ b/tests/ui/const-generics/type-relative-path-144547.min.stderr @@ -3,6 +3,9 @@ error: generic parameters may not be used in const operations | LL | type SupportedArray = [T; ::SUPPORTED_SLOTS]; | ^^^^^^^^^^^^^^ + | + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 1 previous error diff --git a/tests/ui/consts/const-eval/size-of-t.stderr b/tests/ui/consts/const-eval/size-of-t.stderr index 418ac6f612ca5..c2183dc99a7db 100644 --- a/tests/ui/consts/const-eval/size-of-t.stderr +++ b/tests/ui/consts/const-eval/size-of-t.stderr @@ -6,6 +6,7 @@ LL | let _arr: [u8; size_of::()]; | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 1 previous error diff --git a/tests/ui/feature-gates/feature-gate-generic-const-args.stderr b/tests/ui/feature-gates/feature-gate-generic-const-args.stderr index 27794b43966cd..1e4628a8c4f0a 100644 --- a/tests/ui/feature-gates/feature-gate-generic-const-args.stderr +++ b/tests/ui/feature-gates/feature-gate-generic-const-args.stderr @@ -4,7 +4,7 @@ error: generic parameters may not be used in const operations LL | type const INC: usize = const { N + 1 }; | ^ | - = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 1 previous error diff --git a/tests/ui/feature-gates/feature-gate-min-generic-const-args.stderr b/tests/ui/feature-gates/feature-gate-min-generic-const-args.stderr index 05166b4857fb0..c0e79c6694b0a 100644 --- a/tests/ui/feature-gates/feature-gate-min-generic-const-args.stderr +++ b/tests/ui/feature-gates/feature-gate-min-generic-const-args.stderr @@ -6,6 +6,7 @@ LL | fn foo() -> [u8; ::ASSOC] { | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error[E0658]: `type const` syntax is experimental --> $DIR/feature-gate-min-generic-const-args.rs:2:5 diff --git a/tests/ui/generics/param-in-ct-in-ty-param-default.stderr b/tests/ui/generics/param-in-ct-in-ty-param-default.stderr index 03dbb3eb9fc5b..71db114cb8738 100644 --- a/tests/ui/generics/param-in-ct-in-ty-param-default.stderr +++ b/tests/ui/generics/param-in-ct-in-ty-param-default.stderr @@ -6,6 +6,7 @@ LL | struct Foo()]>(T, U); | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 1 previous error diff --git a/tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr b/tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr index 4bfbe0eeff774..2aef26cf44151 100644 --- a/tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr +++ b/tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr @@ -6,6 +6,7 @@ LL | beta: [(); foo::<&'a ()>()], | = note: lifetime parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error[E0392]: lifetime parameter `'s` is never used --> $DIR/issue-64173-unused-lifetimes.rs:3:12 @@ -20,6 +21,9 @@ error: generic `Self` types are currently not permitted in anonymous constants | LL | array: [(); size_of::<&Self>()], | ^^^^ + | + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error[E0392]: lifetime parameter `'a` is never used --> $DIR/issue-64173-unused-lifetimes.rs:15:12 diff --git a/tests/ui/resolve/issue-39559.stderr b/tests/ui/resolve/issue-39559.stderr index 14c7a6a9f6abf..71e763820a279 100644 --- a/tests/ui/resolve/issue-39559.stderr +++ b/tests/ui/resolve/issue-39559.stderr @@ -6,6 +6,7 @@ LL | entries: [T; D::dim()], | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 1 previous error diff --git a/tests/ui/type/pattern_types/assoc_const.default.stderr b/tests/ui/type/pattern_types/assoc_const.default.stderr index 00d5ac6af26b4..678a154659481 100644 --- a/tests/ui/type/pattern_types/assoc_const.default.stderr +++ b/tests/ui/type/pattern_types/assoc_const.default.stderr @@ -6,6 +6,7 @@ LL | fn foo(_: pattern_type!(u32 is ::START..=::END) | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/assoc_const.rs:17:61 @@ -15,6 +16,7 @@ LL | fn foo(_: pattern_type!(u32 is ::START..=::END) | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/assoc_const.rs:20:40 @@ -24,6 +26,7 @@ LL | fn bar(_: pattern_type!(u32 is T::START..=T::END)) {} | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: generic parameters may not be used in const operations --> $DIR/assoc_const.rs:20:51 @@ -33,6 +36,7 @@ LL | fn bar(_: pattern_type!(u32 is T::START..=T::END)) {} | = note: type parameters may not be used in const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 4 previous errors From 9211a895b8e85abed71871e6b014a2c9910f58cf Mon Sep 17 00:00:00 2001 From: Dnreikronos Date: Tue, 7 Jul 2026 12:32:50 -0300 Subject: [PATCH 11/16] Update const generic diagnostic fixture --- .../ui/const-generics/mgca/direct-const-arg-feature-gate.stderr | 1 + tests/ui/const-generics/mgca/double-inline-const.stderr | 2 +- .../mgca/double-wrapped-path-not-accidentally-stabilized.stderr | 1 + .../mgca/mixed-direct-anon-expression-diagnostics.stderr | 2 +- 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/ui/const-generics/mgca/direct-const-arg-feature-gate.stderr b/tests/ui/const-generics/mgca/direct-const-arg-feature-gate.stderr index f5dc211c2f71a..a2927d0625b55 100644 --- a/tests/ui/const-generics/mgca/direct-const-arg-feature-gate.stderr +++ b/tests/ui/const-generics/mgca/direct-const-arg-feature-gate.stderr @@ -16,6 +16,7 @@ LL | fn foo(_: [(); core::direct_const_arg!(N)]) {} | = help: const parameters may only be used as standalone arguments here, i.e. `N` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: expected expression, found `direct_const_arg!()` constant --> $DIR/direct-const-arg-feature-gate.rs:1:32 diff --git a/tests/ui/const-generics/mgca/double-inline-const.stderr b/tests/ui/const-generics/mgca/double-inline-const.stderr index bc73e3d93575e..c0ae0392562a2 100644 --- a/tests/ui/const-generics/mgca/double-inline-const.stderr +++ b/tests/ui/const-generics/mgca/double-inline-const.stderr @@ -9,7 +9,7 @@ note: not a concrete type | LL | impl S { | ^^^^ - = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/mgca/double-wrapped-path-not-accidentally-stabilized.stderr b/tests/ui/const-generics/mgca/double-wrapped-path-not-accidentally-stabilized.stderr index 6168ec242a38c..aecb2b6681b43 100644 --- a/tests/ui/const-generics/mgca/double-wrapped-path-not-accidentally-stabilized.stderr +++ b/tests/ui/const-generics/mgca/double-wrapped-path-not-accidentally-stabilized.stderr @@ -6,6 +6,7 @@ LL | f::<{ { N } }>(); | = help: const parameters may only be used as standalone arguments here, i.e. `N` = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/mgca/mixed-direct-anon-expression-diagnostics.stderr b/tests/ui/const-generics/mgca/mixed-direct-anon-expression-diagnostics.stderr index ae297de108493..50f849b6389ee 100644 --- a/tests/ui/const-generics/mgca/mixed-direct-anon-expression-diagnostics.stderr +++ b/tests/ui/const-generics/mgca/mixed-direct-anon-expression-diagnostics.stderr @@ -10,7 +10,7 @@ error: generic parameters may not be used in const operations LL | f::<{ (N, 1 + 1) }>(); | ^ | - = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items + = help: add `#![feature(generic_const_args)]` and extract the expression into a `type const` item error: aborting due to 2 previous errors From d905d0a45ed039144a277adc772dfcb992c311a0 Mon Sep 17 00:00:00 2001 From: asuto15 Date: Sat, 11 Jul 2026 10:37:30 +0900 Subject: [PATCH 12/16] Add regression test for dollar-prefixed fragments in a repetition --- tests/ui/macros/macro-missing-fragment.rs | 4 ++++ tests/ui/macros/macro-missing-fragment.stderr | 16 +++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/tests/ui/macros/macro-missing-fragment.rs b/tests/ui/macros/macro-missing-fragment.rs index 827c7fc319272..e9cfc07e3363c 100644 --- a/tests/ui/macros/macro-missing-fragment.rs +++ b/tests/ui/macros/macro-missing-fragment.rs @@ -17,6 +17,10 @@ macro_rules! accidental_dollar_prefix { ( $test:$tt ) => {}; //~ ERROR missing fragment } +macro_rules! accidental_dollar_prefix_in_repetition { + ( $($test:$tt),* ) => {}; //~ ERROR missing fragment +} + fn main() { used_arm!(); used_macro_unused_arm!(); diff --git a/tests/ui/macros/macro-missing-fragment.stderr b/tests/ui/macros/macro-missing-fragment.stderr index b1b9bf3d8aa97..b705544df1665 100644 --- a/tests/ui/macros/macro-missing-fragment.stderr +++ b/tests/ui/macros/macro-missing-fragment.stderr @@ -51,5 +51,19 @@ LL - ( $test:$tt ) => {}; LL + ( $test:tt ) => {}; | -error: aborting due to 4 previous errors +error: missing fragment specifier + --> $DIR/macro-missing-fragment.rs:21:15 + | +LL | ( $($test:$tt),* ) => {}; + | ^ + | + = note: fragment specifiers must be provided + = help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis`, along with `expr_2021` and `pat_param` for edition compatibility +help: fragment specifiers should not be prefixed with `$` + | +LL - ( $($test:$tt),* ) => {}; +LL + ( $($test:tt),* ) => {}; + | + +error: aborting due to 5 previous errors From 2200ed1c97f2d58772bd532e3fb4ffc8f95b27f3 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 10 Jul 2026 18:04:30 -0700 Subject: [PATCH 13/16] Add requested description comment --- tests/rustdoc-ui/lints/deny-cmd.deny.stderr | 2 +- tests/rustdoc-ui/lints/deny-cmd.rs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/rustdoc-ui/lints/deny-cmd.deny.stderr b/tests/rustdoc-ui/lints/deny-cmd.deny.stderr index 3bde64d97b93a..1c6abb55d6721 100644 --- a/tests/rustdoc-ui/lints/deny-cmd.deny.stderr +++ b/tests/rustdoc-ui/lints/deny-cmd.deny.stderr @@ -1,5 +1,5 @@ error: missing documentation for a struct - --> $DIR/deny-cmd.rs:7:1 + --> $DIR/deny-cmd.rs:8:1 | LL | pub struct Foo; | ^^^^^^^^^^^^^^ diff --git a/tests/rustdoc-ui/lints/deny-cmd.rs b/tests/rustdoc-ui/lints/deny-cmd.rs index bbddb11953049..b4255c8f69405 100644 --- a/tests/rustdoc-ui/lints/deny-cmd.rs +++ b/tests/rustdoc-ui/lints/deny-cmd.rs @@ -2,7 +2,8 @@ //@[deny] compile-flags: -Dmissing_docs //@[allow] compile-flags: -Amissing_docs //@[allow] check-pass -//! docs for crate + +//! Verify that the `-D` flag, passed to rustdoc, works as expected pub struct Foo; //[deny]~^ ERROR missing_docs From 05a2bf7f34485462384ccbff616948d925e4fe4c Mon Sep 17 00:00:00 2001 From: Xuyang Zhang Date: Sat, 11 Jul 2026 13:51:06 +0800 Subject: [PATCH 14/16] doc: use ptr::addr in offset_from docs --- library/core/src/ptr/const_ptr.rs | 5 ++--- library/core/src/ptr/mut_ptr.rs | 5 ++--- library/core/src/ptr/non_null.rs | 5 ++--- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 56f6a561f4bb9..1dc6a9f9f105e 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -567,9 +567,8 @@ impl *const T { /// needed for `const`-compatibility: the distance between pointers into *different* allocated /// objects is not known at compile-time. However, the requirement also exists at /// runtime and may be exploited by optimizations. If you wish to compute the difference between - /// pointers that are not guaranteed to be from the same allocation, use `(self as isize - - /// origin as isize) / size_of::()`. - // FIXME: recommend `addr()` instead of `as usize` once that is stable. + /// pointers that are not guaranteed to be from the same allocation, use + /// `(self.addr() as isize - origin.addr() as isize) / size_of::()`. /// /// [`add`]: #method.add /// [allocation]: crate::ptr#allocation diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index b333f8217b2c0..c7585fde42180 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -748,9 +748,8 @@ impl *mut T { /// needed for `const`-compatibility: the distance between pointers into *different* allocated /// objects is not known at compile-time. However, the requirement also exists at /// runtime and may be exploited by optimizations. If you wish to compute the difference between - /// pointers that are not guaranteed to be from the same allocation, use `(self as isize - - /// origin as isize) / size_of::()`. - // FIXME: recommend `addr()` instead of `as usize` once that is stable. + /// pointers that are not guaranteed to be from the same allocation, use + /// `(self.addr() as isize - origin.addr() as isize) / size_of::()`. /// /// [`add`]: #method.add /// [allocation]: crate::ptr#allocation diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 6ec34206a4248..d2c2a88bbd08b 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -736,9 +736,8 @@ impl NonNull { /// needed for `const`-compatibility: the distance between pointers into *different* allocated /// objects is not known at compile-time. However, the requirement also exists at /// runtime and may be exploited by optimizations. If you wish to compute the difference between - /// pointers that are not guaranteed to be from the same allocation, use `(self as isize - - /// origin as isize) / size_of::()`. - // FIXME: recommend `addr()` instead of `as usize` once that is stable. + /// pointers that are not guaranteed to be from the same allocation, use + /// `(self.addr() as isize - origin.addr() as isize) / size_of::()`. /// /// [`add`]: #method.add /// [allocation]: crate::ptr#allocation From 74dc8e7b14325b8e3da1d5b9b58705bb9f490b3b Mon Sep 17 00:00:00 2001 From: panstromek Date: Thu, 9 Jul 2026 14:44:28 +0200 Subject: [PATCH 15/16] shrink mir::Statement to 40 bytes We do this by using old-style ThinVec for storing debuginfos collection, which is almost always empty. --- compiler/rustc_middle/src/mir/mod.rs | 4 +- compiler/rustc_middle/src/mir/statement.rs | 86 ++++++++++++++++------ 2 files changed, 66 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index ce30b3fae47ae..1f9c5a8eecad0 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1730,10 +1730,10 @@ mod size_asserts { use super::*; // tidy-alphabetical-start - static_assert_size!(BasicBlockData<'_>, 160); + static_assert_size!(BasicBlockData<'_>, 144); static_assert_size!(LocalDecl<'_>, 40); static_assert_size!(SourceScopeData<'_>, 64); - static_assert_size!(Statement<'_>, 56); + static_assert_size!(Statement<'_>, 40); static_assert_size!(Terminator<'_>, 104); static_assert_size!(VarDebugInfo<'_>, 88); // tidy-alphabetical-end diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index f25eaf3c6d32e..8e1479d284fd8 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -2,6 +2,7 @@ use std::ops; +use rustc_data_structures::outline; use tracing::{debug, instrument}; use super::interpret::GlobalAlloc; @@ -1034,66 +1035,107 @@ impl RawPtrKind { } } +// FIXME(panstromek) +// I'd like to use real ThinVec here, but it fails to borrow check, +// probably because ThinVec doesn't have #[may_dangle] on Drop impl? +type ThinVec = Option>>; + +// This collection is almost always empty, so we +// use thin representation and optimize all methods +// for that by inlining the empty check +// and outlining the rest. #[derive(Default, Debug, Clone, TyEncodable, TyDecodable, StableHash, TypeFoldable, TypeVisitable)] -pub struct StmtDebugInfos<'tcx>(Vec>); +pub struct StmtDebugInfos<'tcx>(ThinVec>); impl<'tcx> StmtDebugInfos<'tcx> { pub fn push(&mut self, debuginfo: StmtDebugInfo<'tcx>) { - self.0.push(debuginfo); + self.0.get_or_insert_default().push(debuginfo); } - + #[inline] pub fn drop_debuginfo(&mut self) { - self.0.clear(); + match &mut self.0 { + None => (), + Some(v) => outline(move || v.clear()), + } } + #[inline] pub fn is_empty(&self) -> bool { - self.0.is_empty() + match &self.0 { + None => true, + Some(v) => outline(move || v.is_empty()), + } } - + #[inline] pub fn prepend(&mut self, debuginfos: &mut Self) { if debuginfos.is_empty() { return; }; - debuginfos.0.append(self); - std::mem::swap(debuginfos, self); + outline(move || { + debuginfos.append(self); + std::mem::swap(debuginfos, self); + }) } - + #[inline] pub fn append(&mut self, debuginfos: &mut Self) { if debuginfos.is_empty() { return; }; - self.0.append(debuginfos); + outline(move || { + self.0.get_or_insert_default().append(debuginfos.0.as_mut().unwrap().as_mut()) + }); } - + #[inline] pub fn extend(&mut self, debuginfos: &Self) { if debuginfos.is_empty() { return; }; - self.0.extend_from_slice(debuginfos); + outline(move || self.0.get_or_insert_default().extend_from_slice(debuginfos.as_slice())) } + #[inline] + pub fn as_slice(&self) -> &[StmtDebugInfo<'tcx>] { + match &self.0 { + None => &[], + Some(items) => outline(move || items.as_slice()), + } + } + + #[inline] + pub fn as_mut_slice(&mut self) -> &mut [StmtDebugInfo<'tcx>] { + match &mut self.0 { + None => &mut [], + Some(items) => outline(move || items.as_mut_slice()), + } + } + #[inline] pub fn retain_locals(&mut self, locals: &DenseBitSet) { - self.retain(|debuginfo| match debuginfo { - StmtDebugInfo::AssignRef(local, _) | StmtDebugInfo::InvalidAssign(local) => { - locals.contains(*local) - } - }); + match &mut self.0 { + None => (), + Some(items) => outline(move || { + items.retain(|debuginfo| match debuginfo { + StmtDebugInfo::AssignRef(local, _) | StmtDebugInfo::InvalidAssign(local) => { + locals.contains(*local) + } + }) + }), + } } } impl<'tcx> ops::Deref for StmtDebugInfos<'tcx> { - type Target = Vec>; + type Target = [StmtDebugInfo<'tcx>]; #[inline] - fn deref(&self) -> &Vec> { - &self.0 + fn deref(&self) -> &Self::Target { + self.as_slice() } } impl<'tcx> ops::DerefMut for StmtDebugInfos<'tcx> { #[inline] - fn deref_mut(&mut self) -> &mut Vec> { - &mut self.0 + fn deref_mut(&mut self) -> &mut Self::Target { + self.as_mut_slice() } } From fbef898d457857968d30ac24365e86308d0d0b3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 11 Jul 2026 10:24:56 +0200 Subject: [PATCH 16/16] Fix PR number in bootstrap's change tracker --- src/bootstrap/src/utils/change_tracker.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index 94a7acf30d4e9..0a87925018538 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -637,7 +637,7 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ summary: "New option `rust.compress-debuginfo` allows configuring whether Rust and C/C++ debuginfo should be compressed.", }, ChangeInfo { - change_id: 999999, + change_id: 158912, severity: ChangeSeverity::Info, summary: "New config section `pgo` was introduced, to configure PGO profiling options. The `--rust-profile-use`/`--rust-profile-generate`/`--llvm-profile-use`/`--llvm-profile-generate` flags and the `rust.profile-use`/`rust.profile-generate` config options have been deprecated.", },