From 5ac90c6def09b0c5b15fe8cc846d5be4b37685fc Mon Sep 17 00:00:00 2001 From: Arthur Carcano Date: Fri, 3 Apr 2026 19:01:40 +0200 Subject: [PATCH 1/9] Clarify ascii whitespace exclusion of vertical tab in the doc This especially means that for c: char, c.is_ascii() && c.is_whitespace() does **not** imply c.is_ascii_whitespace(). --- library/core/src/char/methods.rs | 3 +++ library/core/src/num/mod.rs | 3 +++ library/core/src/slice/ascii.rs | 12 +++++++++--- library/core/src/str/mod.rs | 15 ++++++++++++--- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index e9c3b040dc50b..f1a1ffe98b5fc 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -1930,6 +1930,9 @@ impl char { /// U+0020 SPACE, U+0009 HORIZONTAL TAB, U+000A LINE FEED, /// U+000C FORM FEED, or U+000D CARRIAGE RETURN. /// + /// **Warning:** Because the list above excludes U+000B VERTICAL TAB, + /// `c.is_ascii_whitespace()` is **not** equivalent to `c.is_ascii() && c.is_whitespace()`. + /// /// Rust uses the WhatWG Infra Standard's [definition of ASCII /// whitespace][infra-aw]. There are several other definitions in /// wide use. For instance, [the POSIX locale][pct] includes diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 333e44649d8f6..fd2aa06a28985 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -1064,6 +1064,9 @@ impl u8 { /// U+0020 SPACE, U+0009 HORIZONTAL TAB, U+000A LINE FEED, /// U+000C FORM FEED, or U+000D CARRIAGE RETURN. /// + /// **Warning:** Because the list above excludes U+000B VERTICAL TAB, + /// `b.is_ascii_whitespace()` is **not** equivalent to `char::from(b).is_whitespace()`. + /// /// Rust uses the WhatWG Infra Standard's [definition of ASCII /// whitespace][infra-aw]. There are several other definitions in /// wide use. For instance, [the POSIX locale][pct] includes diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index edf058c96a522..33ecc05c56955 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -222,7 +222,9 @@ impl [u8] { /// Returns a byte slice with leading ASCII whitespace bytes removed. /// /// 'Whitespace' refers to the definition used by - /// [`u8::is_ascii_whitespace`]. + /// [`u8::is_ascii_whitespace`]. Importantly, this definition excludes + /// the `\0x0B` byte even though it has the unicode WhiteSpace property + /// and is removed by [`str::trim_start`]. /// /// # Examples /// @@ -251,7 +253,9 @@ impl [u8] { /// Returns a byte slice with trailing ASCII whitespace bytes removed. /// /// 'Whitespace' refers to the definition used by - /// [`u8::is_ascii_whitespace`]. + /// [`u8::is_ascii_whitespace`]. Importantly, this definition excludes + /// the `\0x0B` byte even though it has the unicode WhiteSpace property + /// and is removed by [`str::trim_end`]. /// /// # Examples /// @@ -281,7 +285,9 @@ impl [u8] { /// removed. /// /// 'Whitespace' refers to the definition used by - /// [`u8::is_ascii_whitespace`]. + /// [`u8::is_ascii_whitespace`]. Importantly, this definition excludes + /// the `\0x0B` byte even though it has the unicode WhiteSpace property + /// and is removed by [`str::trim`]. /// /// # Examples /// diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 0d52bfb8c9aa4..c9ac34e091f97 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -1202,6 +1202,9 @@ impl str { /// /// This uses the same definition as [`char::is_ascii_whitespace`]. /// To split by Unicode `Whitespace` instead, use [`split_whitespace`]. + /// Note that because of this difference in definition, even if `s.is_ascii()` + /// is `true`, `s.split_ascii_whitespace()` behavior will differ from `s.split_whitespace()` + /// if `s` contains U+000B VERTICAL TAB. /// /// [`split_whitespace`]: str::split_whitespace /// @@ -2896,7 +2899,9 @@ impl str { /// Returns a string slice with leading ASCII whitespace removed. /// /// 'Whitespace' refers to the definition used by - /// [`u8::is_ascii_whitespace`]. + /// [`u8::is_ascii_whitespace`]. Importantly, this definition excludes + /// the U+000B code point even though it has the unicode WhiteSpace property + /// and is removed by [`str::trim_start`]. /// /// [`u8::is_ascii_whitespace`]: u8::is_ascii_whitespace /// @@ -2921,7 +2926,9 @@ impl str { /// Returns a string slice with trailing ASCII whitespace removed. /// /// 'Whitespace' refers to the definition used by - /// [`u8::is_ascii_whitespace`]. + /// [`u8::is_ascii_whitespace`]. Importantly, this definition excludes + /// the U+000B code point even though it has the unicode WhiteSpace property + /// and is removed by [`str::trim_end`]. /// /// [`u8::is_ascii_whitespace`]: u8::is_ascii_whitespace /// @@ -2947,7 +2954,9 @@ impl str { /// removed. /// /// 'Whitespace' refers to the definition used by - /// [`u8::is_ascii_whitespace`]. + /// [`u8::is_ascii_whitespace`]. Importantly, this definition excludes + /// the U+000B code point even though it has the unicode WhiteSpace property + /// and is removed by [`str::trim`]. /// /// [`u8::is_ascii_whitespace`]: u8::is_ascii_whitespace /// From 335585b1d415136d261c98d49edc14fd54f920d6 Mon Sep 17 00:00:00 2001 From: zedddie Date: Sat, 7 Mar 2026 10:18:35 +0100 Subject: [PATCH 2/9] add `const_param_ty_unchecked` gate --- compiler/rustc_feature/src/unstable.rs | 2 + .../rustc_hir_analysis/src/check/wfcheck.rs | 21 ++++--- .../src/coherence/builtin.rs | 4 ++ compiler/rustc_span/src/symbol.rs | 1 + .../rustc_trait_selection/src/traits/wf.rs | 5 ++ .../const_param_ty_unchecked-unsupported.rs | 19 +++++++ ...onst_param_ty_unchecked-unsupported.stderr | 34 +++++++++++ .../const_param_ty_unchecked.rs | 28 ++++++++++ .../const_param_ty_unchecked_fail.rs | 31 ++++++++++ .../const_param_ty_unchecked_fail.stderr | 56 +++++++++++++++++++ 10 files changed, 194 insertions(+), 7 deletions(-) create mode 100644 tests/ui/const-generics/adt_const_params/const_param_ty_unchecked-unsupported.rs create mode 100644 tests/ui/const-generics/adt_const_params/const_param_ty_unchecked-unsupported.stderr create mode 100644 tests/ui/const-generics/adt_const_params/const_param_ty_unchecked.rs create mode 100644 tests/ui/const-generics/adt_const_params/const_param_ty_unchecked_fail.rs create mode 100644 tests/ui/const-generics/adt_const_params/const_param_ty_unchecked_fail.stderr diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 859a1ad391cb9..309f26415aadf 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -229,6 +229,8 @@ declare_features! ( (internal, cfg_target_has_reliable_f16_f128, "1.88.0", None), /// Allows identifying the `compiler_builtins` crate. (internal, compiler_builtins, "1.13.0", None), + /// Allows skipping `ConstParamTy_` trait implementation checks + (internal, const_param_ty_unchecked, "CURRENT_RUSTC_VERSION", None), /// Allows writing custom MIR (internal, custom_mir, "1.65.0", None), /// Implementation details of externally implementable items diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 52cb061177c1f..928745095997c 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -842,7 +842,12 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &ty::GenericParamDef) -> Result<(), Er let span = tcx.def_span(param.def_id); let def_id = param.def_id.expect_local(); - if tcx.features().adt_const_params() || tcx.features().min_adt_const_params() { + if tcx.features().const_param_ty_unchecked() { + enter_wf_checking_ctxt(tcx, tcx.local_parent(def_id), |wfcx| { + wfcx.register_wf_obligation(span, None, ty.into()); + Ok(()) + }) + } else if tcx.features().adt_const_params() || tcx.features().min_adt_const_params() { enter_wf_checking_ctxt(tcx, tcx.local_parent(def_id), |wfcx| { wfcx.register_bound( ObligationCause::new(span, def_id, ObligationCauseCode::ConstParam(ty)), @@ -1313,12 +1318,14 @@ pub(super) fn check_type_const<'tcx>( let tcx = wfcx.tcx(); let span = tcx.def_span(def_id); - wfcx.register_bound( - ObligationCause::new(span, def_id, ObligationCauseCode::ConstParam(item_ty)), - wfcx.param_env, - item_ty, - tcx.require_lang_item(LangItem::ConstParamTy, span), - ); + if !tcx.features().const_param_ty_unchecked() { + wfcx.register_bound( + ObligationCause::new(span, def_id, ObligationCauseCode::ConstParam(item_ty)), + wfcx.param_env, + item_ty, + tcx.require_lang_item(LangItem::ConstParamTy, span), + ); + } if has_value { let raw_ct = tcx.const_of_item(def_id).instantiate_identity(); diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 61453e5328d5f..9100d0e952696 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -184,6 +184,10 @@ fn visit_implementation_of_const_param_ty(checker: &Checker<'_>) -> Result<(), E return Ok(()); } + if tcx.features().const_param_ty_unchecked() { + return Ok(()); + } + if !tcx.features().adt_const_params() { match *self_type.kind() { ty::Adt(adt, _) if adt.is_struct() => { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 71d67f9608bfa..528487edf7873 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -676,6 +676,7 @@ symbols! { const_panic, const_panic_fmt, const_param_ty, + const_param_ty_unchecked, const_precise_live_drops, const_ptr_cast, const_raw_ptr_deref, diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index b8f5336115e12..17991fcd20ae0 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -575,6 +575,11 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { if self.tcx().is_lang_item(def_id, LangItem::Sized) { return Default::default(); } + if self.tcx().is_lang_item(def_id, LangItem::ConstParamTy) + && self.tcx().features().const_param_ty_unchecked() + { + return Default::default(); + } let predicates = self.tcx().predicates_of(def_id); let mut origins = vec![def_id; predicates.predicates.len()]; diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked-unsupported.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked-unsupported.rs new file mode 100644 index 0000000000000..3d4d7d20615a8 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked-unsupported.rs @@ -0,0 +1,19 @@ +//! Ensure we don't allow Vec<[u8]> as const parameter even with +//! `const_param_ty_unchecked` feature. +#![allow(incomplete_features)] +#![feature(adt_const_params, const_param_ty_unchecked, const_param_ty_trait)] +use std::marker::ConstParamTy_; + +struct VectorOfBytes { + a: Vec<[u8]> + //~^ ERROR: the size for values of type `[u8]` cannot be known at compilation time [E0277] +} +impl ConstParamTy_ for VectorOfBytes {} + +fn bar() {} +fn foo>() {} + //~^ ERROR: the size for values of type `[u8]` cannot be known at compilation time [E0277] + //~| ERROR: the size for values of type `[u8]` cannot be known at compilation time [E0277] + + +fn main() {} diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked-unsupported.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked-unsupported.stderr new file mode 100644 index 0000000000000..c24f676161441 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked-unsupported.stderr @@ -0,0 +1,34 @@ +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/const_param_ty_unchecked-unsupported.rs:8:8 + | +LL | a: Vec<[u8]> + | ^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: required by an implicit `Sized` bound in `Vec` + --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/const_param_ty_unchecked-unsupported.rs:14:8 + | +LL | fn foo>() {} + | ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: required by an implicit `Sized` bound in `Vec` + --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/const_param_ty_unchecked-unsupported.rs:14:8 + | +LL | fn foo>() {} + | ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: required by an implicit `Sized` bound in `Vec` + --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked.rs new file mode 100644 index 0000000000000..11da20102fe8e --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked.rs @@ -0,0 +1,28 @@ +//@run-pass +//! Ensure that const_param_ty_unchecked gate allow +//! bypassing `ConstParamTy_` implementation check + +#![allow(dead_code, incomplete_features)] +#![feature(const_param_ty_unchecked, const_param_ty_trait)] + +use std::marker::ConstParamTy_; + +struct Miow; + +struct Meoww(Miow); + +struct Float { + float: f32, +} + +impl ConstParamTy_ for Meoww {} +impl ConstParamTy_ for Float {} + +fn something2() {} +fn something(a: f64) -> f64 { + N + a +} + +fn main() { + assert_eq!(2.0, something::<{1.0}>(1.0)); +} diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked_fail.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked_fail.rs new file mode 100644 index 0000000000000..3f09a308cbe07 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked_fail.rs @@ -0,0 +1,31 @@ +// gate-test-const_param_ty_unchecked +//! Ensure this fails when const_param_ty_unchecked isn't used +#![allow(incomplete_features)] +#![feature(const_param_ty_trait)] + +use std::marker::ConstParamTy_; + +struct Miow; + +struct Meoww(Miow); + +struct Float { + float: f32, +} + +impl ConstParamTy_ for Meoww {} + //~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type [E0204] +impl ConstParamTy_ for Float {} + //~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type [E0204] + +fn something2() {} + //~^ ERROR: using raw pointers as const generic parameters is forbidden +fn something(a: f64) -> f64 { + //~^ ERROR: `f64` is forbidden as the type of a const generic parameter + N + a +} +fn foo>() {} + //~^ ERROR: the size for values of type `[u8]` cannot be known at compilation time [E0277] + //~^^ ERROR: `Vec<[u8]>` is forbidden as the type of a const generic parameter + +fn main() {} diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked_fail.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked_fail.stderr new file mode 100644 index 0000000000000..ae1ae61260f1a --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_unchecked_fail.stderr @@ -0,0 +1,56 @@ +error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type + --> $DIR/const_param_ty_unchecked_fail.rs:16:24 + | +LL | struct Meoww(Miow); + | ---- this field does not implement `ConstParamTy_` +... +LL | impl ConstParamTy_ for Meoww {} + | ^^^^^ + +error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type + --> $DIR/const_param_ty_unchecked_fail.rs:18:24 + | +LL | float: f32, + | ---------- this field does not implement `ConstParamTy_` +... +LL | impl ConstParamTy_ for Float {} + | ^^^^^ + +error: using raw pointers as const generic parameters is forbidden + --> $DIR/const_param_ty_unchecked_fail.rs:21:24 + | +LL | fn something2() {} + | ^^^^^^^ + | + = note: the only supported types are integers, `bool`, and `char` + +error: `f64` is forbidden as the type of a const generic parameter + --> $DIR/const_param_ty_unchecked_fail.rs:23:23 + | +LL | fn something(a: f64) -> f64 { + | ^^^ + | + = note: the only supported types are integers, `bool`, and `char` + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/const_param_ty_unchecked_fail.rs:27:8 + | +LL | fn foo>() {} + | ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: required by an implicit `Sized` bound in `Vec` + --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + +error: `Vec<[u8]>` is forbidden as the type of a const generic parameter + --> $DIR/const_param_ty_unchecked_fail.rs:27:17 + | +LL | fn foo>() {} + | ^^^^^^^^^ + | + = note: the only supported types are integers, `bool`, and `char` + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0204, E0277. +For more information about an error, try `rustc --explain E0204`. From baf246f27e8d242fd0ecaaeaaf50ca825cb0f2f1 Mon Sep 17 00:00:00 2001 From: zedddie Date: Mon, 6 Apr 2026 13:52:38 +0200 Subject: [PATCH 3/9] gate tuple const params behind adt_const_params --- library/core/src/tuple.rs | 3 +-- .../tuple-wihtout-unsized_const_params-gate.rs | 8 ++++++++ 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 tests/ui/const-generics/adt_const_params/tuple-wihtout-unsized_const_params-gate.rs diff --git a/library/core/src/tuple.rs b/library/core/src/tuple.rs index 58f81372aff75..3d2782fb5a858 100644 --- a/library/core/src/tuple.rs +++ b/library/core/src/tuple.rs @@ -47,8 +47,7 @@ macro_rules! tuple_impls { maybe_tuple_doc! { $($T)+ @ - #[unstable(feature = "adt_const_params", issue = "95174")] - #[unstable_feature_bound(unsized_const_params)] + #[unstable(feature = "min_adt_const_params", issue = "154042", implied_by = "adt_const_params")] impl<$($T: ConstParamTy_),+> ConstParamTy_ for ($($T,)+) {} } diff --git a/tests/ui/const-generics/adt_const_params/tuple-wihtout-unsized_const_params-gate.rs b/tests/ui/const-generics/adt_const_params/tuple-wihtout-unsized_const_params-gate.rs new file mode 100644 index 0000000000000..70abca75c139a --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/tuple-wihtout-unsized_const_params-gate.rs @@ -0,0 +1,8 @@ +//! Ensure we allow tuples behind `adt_const_params` +//@check-pass +#![feature(min_adt_const_params)] + +#[allow(dead_code)] +fn foo() {} + +fn main() {} From a4c494472be7ccf13830fced409c27a1d4000d54 Mon Sep 17 00:00:00 2001 From: jackh726 Date: Sat, 11 Apr 2026 22:14:13 +0000 Subject: [PATCH 4/9] A couple small comment cleanups, and update tests. --- compiler/rustc_hir_typeck/src/method/probe.rs | 7 +++-- .../auxiliary/shadowed_stability.rs | 22 ++++++++++++++ .../trivially-false-subtrait.rs | 12 +++++--- .../trivially-false-subtrait.run.stdout | 1 + .../unstable.off_normal.run.stdout | 1 + .../unstable.off_normal.stderr | 17 +++++++++++ .../unstable.off_shadowing.run.stdout | 1 + .../unstable.off_shadowing.stderr | 17 +++++++++++ .../unstable.on_normal.stderr | 22 ++++++++++++++ .../unstable.on_shadowing.run.stdout | 1 + .../methods/supertrait-shadowing/unstable.rs | 29 +++++++++++++++++++ 11 files changed, 123 insertions(+), 7 deletions(-) create mode 100644 tests/ui/methods/supertrait-shadowing/auxiliary/shadowed_stability.rs create mode 100644 tests/ui/methods/supertrait-shadowing/trivially-false-subtrait.run.stdout create mode 100644 tests/ui/methods/supertrait-shadowing/unstable.off_normal.run.stdout create mode 100644 tests/ui/methods/supertrait-shadowing/unstable.off_normal.stderr create mode 100644 tests/ui/methods/supertrait-shadowing/unstable.off_shadowing.run.stdout create mode 100644 tests/ui/methods/supertrait-shadowing/unstable.off_shadowing.stderr create mode 100644 tests/ui/methods/supertrait-shadowing/unstable.on_normal.stderr create mode 100644 tests/ui/methods/supertrait-shadowing/unstable.on_shadowing.run.stdout create mode 100644 tests/ui/methods/supertrait-shadowing/unstable.rs diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index c7442373353eb..75270dc945035 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -2377,8 +2377,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { continue; } - // This pick is not a supertrait of the `child_pick`. - // Check if it's a subtrait of the `child_pick`, instead. + // This candidate is not a supertrait of the `child_trait`. + // Check if it's a subtrait of the `child_trait`, instead. // If it is, then it must have been a subtrait of every // other pick we've eliminated at this point. It will // take over at this point. @@ -2392,7 +2392,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { continue; } - // `child_pick` is not a supertrait of this pick. + // Neither `child_trait` or the current candidate are + // supertraits of each other. // Don't bail here, since we may be comparing two supertraits // of a common subtrait. These two supertraits won't be related // at all, but we will pick them up next round when we find their diff --git a/tests/ui/methods/supertrait-shadowing/auxiliary/shadowed_stability.rs b/tests/ui/methods/supertrait-shadowing/auxiliary/shadowed_stability.rs new file mode 100644 index 0000000000000..7b97c63ef1b00 --- /dev/null +++ b/tests/ui/methods/supertrait-shadowing/auxiliary/shadowed_stability.rs @@ -0,0 +1,22 @@ +#![feature(staged_api)] +#![stable(feature = "main", since = "1.0.0")] + +#[stable(feature = "main", since = "1.0.0")] +pub trait A { + #[stable(feature = "main", since = "1.0.0")] + fn hello(&self) { + println!("A"); + } +} +#[stable(feature = "main", since = "1.0.0")] +impl A for T {} + +#[stable(feature = "main", since = "1.0.0")] +pub trait B: A { + #[unstable(feature = "downstream", issue = "none")] + fn hello(&self) { + println!("B"); + } +} +#[stable(feature = "main", since = "1.0.0")] +impl B for T {} diff --git a/tests/ui/methods/supertrait-shadowing/trivially-false-subtrait.rs b/tests/ui/methods/supertrait-shadowing/trivially-false-subtrait.rs index e44c7c18083d0..799ba53a0f0e6 100644 --- a/tests/ui/methods/supertrait-shadowing/trivially-false-subtrait.rs +++ b/tests/ui/methods/supertrait-shadowing/trivially-false-subtrait.rs @@ -1,20 +1,24 @@ -//@ check-pass +//@ run-pass +//@ check-run-results // Make sure we don't prefer a subtrait that we would've otherwise eliminated // in `consider_probe` during method probing. -#![feature(supertrait_item_shadowing)] #![allow(dead_code)] struct W(T); trait Upstream { - fn hello(&self) {} + fn hello(&self) { + println!("upstream"); + } } impl Upstream for T {} trait Downstream: Upstream { - fn hello(&self) {} + fn hello(&self) { + println!("downstream"); + } } impl Downstream for W where T: Foo {} diff --git a/tests/ui/methods/supertrait-shadowing/trivially-false-subtrait.run.stdout b/tests/ui/methods/supertrait-shadowing/trivially-false-subtrait.run.stdout new file mode 100644 index 0000000000000..045951300cf48 --- /dev/null +++ b/tests/ui/methods/supertrait-shadowing/trivially-false-subtrait.run.stdout @@ -0,0 +1 @@ +upstream diff --git a/tests/ui/methods/supertrait-shadowing/unstable.off_normal.run.stdout b/tests/ui/methods/supertrait-shadowing/unstable.off_normal.run.stdout new file mode 100644 index 0000000000000..f70f10e4db190 --- /dev/null +++ b/tests/ui/methods/supertrait-shadowing/unstable.off_normal.run.stdout @@ -0,0 +1 @@ +A diff --git a/tests/ui/methods/supertrait-shadowing/unstable.off_normal.stderr b/tests/ui/methods/supertrait-shadowing/unstable.off_normal.stderr new file mode 100644 index 0000000000000..fc55ac7dde0cc --- /dev/null +++ b/tests/ui/methods/supertrait-shadowing/unstable.off_normal.stderr @@ -0,0 +1,17 @@ +warning: a method with this name may be added to the standard library in the future + --> $DIR/unstable.rs:25:8 + | +LL | ().hello(); + | ^^^^^ + | + = help: call with fully qualified syntax `shadowed_stability::A::hello(...)` to keep using the current method + = warning: once this associated item is added to the standard library, the ambiguity may cause an error or change in behavior! + = note: for more information, see issue #48919 + = note: `#[warn(unstable_name_collisions)]` (part of `#[warn(future_incompatible)]`) on by default +help: add `#![feature(downstream)]` to the crate attributes to enable `shadowed_stability::B::hello` + | +LL + #![feature(downstream)] + | + +warning: 1 warning emitted + diff --git a/tests/ui/methods/supertrait-shadowing/unstable.off_shadowing.run.stdout b/tests/ui/methods/supertrait-shadowing/unstable.off_shadowing.run.stdout new file mode 100644 index 0000000000000..f70f10e4db190 --- /dev/null +++ b/tests/ui/methods/supertrait-shadowing/unstable.off_shadowing.run.stdout @@ -0,0 +1 @@ +A diff --git a/tests/ui/methods/supertrait-shadowing/unstable.off_shadowing.stderr b/tests/ui/methods/supertrait-shadowing/unstable.off_shadowing.stderr new file mode 100644 index 0000000000000..fc55ac7dde0cc --- /dev/null +++ b/tests/ui/methods/supertrait-shadowing/unstable.off_shadowing.stderr @@ -0,0 +1,17 @@ +warning: a method with this name may be added to the standard library in the future + --> $DIR/unstable.rs:25:8 + | +LL | ().hello(); + | ^^^^^ + | + = help: call with fully qualified syntax `shadowed_stability::A::hello(...)` to keep using the current method + = warning: once this associated item is added to the standard library, the ambiguity may cause an error or change in behavior! + = note: for more information, see issue #48919 + = note: `#[warn(unstable_name_collisions)]` (part of `#[warn(future_incompatible)]`) on by default +help: add `#![feature(downstream)]` to the crate attributes to enable `shadowed_stability::B::hello` + | +LL + #![feature(downstream)] + | + +warning: 1 warning emitted + diff --git a/tests/ui/methods/supertrait-shadowing/unstable.on_normal.stderr b/tests/ui/methods/supertrait-shadowing/unstable.on_normal.stderr new file mode 100644 index 0000000000000..e664f10880951 --- /dev/null +++ b/tests/ui/methods/supertrait-shadowing/unstable.on_normal.stderr @@ -0,0 +1,22 @@ +error[E0034]: multiple applicable items in scope + --> $DIR/unstable.rs:25:8 + | +LL | ().hello(); + | ^^^^^ multiple `hello` found + | + = note: candidate #1 is defined in an impl of the trait `shadowed_stability::A` for the type `T` + = note: candidate #2 is defined in an impl of the trait `shadowed_stability::B` for the type `T` +help: disambiguate the method for candidate #1 + | +LL - ().hello(); +LL + shadowed_stability::A::hello(&()); + | +help: disambiguate the method for candidate #2 + | +LL - ().hello(); +LL + shadowed_stability::B::hello(&()); + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0034`. diff --git a/tests/ui/methods/supertrait-shadowing/unstable.on_shadowing.run.stdout b/tests/ui/methods/supertrait-shadowing/unstable.on_shadowing.run.stdout new file mode 100644 index 0000000000000..223b7836fb19f --- /dev/null +++ b/tests/ui/methods/supertrait-shadowing/unstable.on_shadowing.run.stdout @@ -0,0 +1 @@ +B diff --git a/tests/ui/methods/supertrait-shadowing/unstable.rs b/tests/ui/methods/supertrait-shadowing/unstable.rs new file mode 100644 index 0000000000000..e9c336bb8d4d0 --- /dev/null +++ b/tests/ui/methods/supertrait-shadowing/unstable.rs @@ -0,0 +1,29 @@ +// This tests the interaction of feature staging and supertrait item shadowing. +// When a feature is *off*, then we should not consider unstable methods for probing. +// When a feature is *on*, then we follow the normal supertrait item shadowing rules: +// - When supertrait item shadowing is disabled, this is a clash. +// - When supertrait item shadowing is enabled, we pick subtraits. + +//@ aux-build: shadowed_stability.rs +//@ revisions: off_normal on_normal off_shadowing on_shadowing +//@[off_normal] run-pass +//@[on_normal] check-fail +//@[off_shadowing] run-pass +//@[on_shadowing] run-pass +//@ check-run-results + +#![allow(dead_code, unused_features, unused_imports)] +#![cfg_attr(on_shadowing, feature(downstream))] +#![cfg_attr(on_normal, feature(downstream))] +#![cfg_attr(off_shadowing, feature(supertrait_item_shadowing))] +#![cfg_attr(on_shadowing, feature(supertrait_item_shadowing))] + +extern crate shadowed_stability; +use shadowed_stability::*; + +fn main() { + ().hello(); + //[off_normal,off_shadowing]~^ WARN a method with this name may be added + //[off_normal,off_shadowing]~| WARN once this associated item is added + //[on_normal]~^^^ ERROR multiple applicable items in scope +} From b52a38dbf368a4db698c07808e5a6306bee48ac5 Mon Sep 17 00:00:00 2001 From: Arthur Carcano Date: Mon, 13 Apr 2026 11:47:54 +0200 Subject: [PATCH 5/9] Add link to Unicode White_Space property --- library/core/src/slice/ascii.rs | 12 +++++++++--- library/core/src/str/mod.rs | 9 ++++++--- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index 33ecc05c56955..9db07d8abbbef 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -223,9 +223,11 @@ impl [u8] { /// /// 'Whitespace' refers to the definition used by /// [`u8::is_ascii_whitespace`]. Importantly, this definition excludes - /// the `\0x0B` byte even though it has the unicode WhiteSpace property + /// the `\0x0B` byte even though it has the Unicode [`White_Space`] property /// and is removed by [`str::trim_start`]. /// + /// [`White_Space`]: https://www.unicode.org/reports/tr44/#White_Space + /// /// # Examples /// /// ``` @@ -254,9 +256,11 @@ impl [u8] { /// /// 'Whitespace' refers to the definition used by /// [`u8::is_ascii_whitespace`]. Importantly, this definition excludes - /// the `\0x0B` byte even though it has the unicode WhiteSpace property + /// the `\0x0B` byte even though it has the Unicode [`White_Space`] property /// and is removed by [`str::trim_end`]. /// + /// [`White_Space`]: https://www.unicode.org/reports/tr44/#White_Space + /// /// # Examples /// /// ``` @@ -286,9 +290,11 @@ impl [u8] { /// /// 'Whitespace' refers to the definition used by /// [`u8::is_ascii_whitespace`]. Importantly, this definition excludes - /// the `\0x0B` byte even though it has the unicode WhiteSpace property + /// the `\0x0B` byte even though it has the Unicode [`White_Space`] property /// and is removed by [`str::trim`]. /// + /// [`White_Space`]: https://www.unicode.org/reports/tr44/#White_Space + /// /// # Examples /// /// ``` diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index c9ac34e091f97..d4b77b90c1d16 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -2900,10 +2900,11 @@ impl str { /// /// 'Whitespace' refers to the definition used by /// [`u8::is_ascii_whitespace`]. Importantly, this definition excludes - /// the U+000B code point even though it has the unicode WhiteSpace property + /// the U+000B code point even though it has the Unicode [`White_Space`] property /// and is removed by [`str::trim_start`]. /// /// [`u8::is_ascii_whitespace`]: u8::is_ascii_whitespace + /// [`White_Space`]: https://www.unicode.org/reports/tr44/#White_Space /// /// # Examples /// @@ -2927,10 +2928,11 @@ impl str { /// /// 'Whitespace' refers to the definition used by /// [`u8::is_ascii_whitespace`]. Importantly, this definition excludes - /// the U+000B code point even though it has the unicode WhiteSpace property + /// the U+000B code point even though it has the Unicode [`White_Space`] property /// and is removed by [`str::trim_end`]. /// /// [`u8::is_ascii_whitespace`]: u8::is_ascii_whitespace + /// [`White_Space`]: https://www.unicode.org/reports/tr44/#White_Space /// /// # Examples /// @@ -2955,10 +2957,11 @@ impl str { /// /// 'Whitespace' refers to the definition used by /// [`u8::is_ascii_whitespace`]. Importantly, this definition excludes - /// the U+000B code point even though it has the unicode WhiteSpace property + /// the U+000B code point even though it has the Unicode [`White_Space`] property /// and is removed by [`str::trim`]. /// /// [`u8::is_ascii_whitespace`]: u8::is_ascii_whitespace + /// [`White_Space`]: https://www.unicode.org/reports/tr44/#White_Space /// /// # Examples /// From c681ae69310a0645c867e02264d40793b828fcdf Mon Sep 17 00:00:00 2001 From: jackh726 Date: Mon, 13 Apr 2026 17:19:30 +0000 Subject: [PATCH 6/9] For supertrait-shadowing tests, assert str rather than println --- .../supertrait-shadowing/assoc-const.rs | 3 +- .../assoc-const.run.stdout | 1 - .../auxiliary/shadowed_stability.rs | 8 +-- .../supertrait-shadowing/common-ancestor-2.rs | 15 ++--- .../common-ancestor-2.run.stdout | 1 - .../common-ancestor-2.stderr | 42 ++++++------ .../supertrait-shadowing/common-ancestor-3.rs | 19 +++--- .../common-ancestor-3.run.stdout | 1 - .../common-ancestor-3.stderr | 66 +++++++++---------- .../supertrait-shadowing/common-ancestor.rs | 11 ++-- .../common-ancestor.run.stdout | 1 - .../common-ancestor.stderr | 34 +++++----- .../no-common-ancestor-2.rs | 16 ++--- .../no-common-ancestor-2.stderr | 16 ++--- .../no-common-ancestor.rs | 8 +-- .../no-common-ancestor.stderr | 8 +-- .../supertrait-shadowing/out-of-scope.rs | 11 ++-- .../out-of-scope.run.stdout | 1 - .../trivially-false-subtrait.rs | 11 ++-- .../trivially-false-subtrait.run.stdout | 1 - .../supertrait-shadowing/type-dependent.rs | 15 ++--- .../type-dependent.run.stdout | 1 - .../unstable.off_normal.run.stdout | 1 - .../unstable.off_normal.stderr | 6 +- .../unstable.off_shadowing.run.stdout | 1 - .../unstable.off_shadowing.stderr | 6 +- .../unstable.on_normal.stderr | 14 ++-- .../unstable.on_shadowing.run.stdout | 1 - .../methods/supertrait-shadowing/unstable.rs | 7 +- 29 files changed, 156 insertions(+), 170 deletions(-) delete mode 100644 tests/ui/methods/supertrait-shadowing/assoc-const.run.stdout delete mode 100644 tests/ui/methods/supertrait-shadowing/common-ancestor-2.run.stdout delete mode 100644 tests/ui/methods/supertrait-shadowing/common-ancestor-3.run.stdout delete mode 100644 tests/ui/methods/supertrait-shadowing/common-ancestor.run.stdout delete mode 100644 tests/ui/methods/supertrait-shadowing/out-of-scope.run.stdout delete mode 100644 tests/ui/methods/supertrait-shadowing/trivially-false-subtrait.run.stdout delete mode 100644 tests/ui/methods/supertrait-shadowing/type-dependent.run.stdout delete mode 100644 tests/ui/methods/supertrait-shadowing/unstable.off_normal.run.stdout delete mode 100644 tests/ui/methods/supertrait-shadowing/unstable.off_shadowing.run.stdout delete mode 100644 tests/ui/methods/supertrait-shadowing/unstable.on_shadowing.run.stdout diff --git a/tests/ui/methods/supertrait-shadowing/assoc-const.rs b/tests/ui/methods/supertrait-shadowing/assoc-const.rs index a542ce7d326d1..01d045b9fb74f 100644 --- a/tests/ui/methods/supertrait-shadowing/assoc-const.rs +++ b/tests/ui/methods/supertrait-shadowing/assoc-const.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ check-run-results #![feature(supertrait_item_shadowing)] #![allow(dead_code)] @@ -19,5 +18,5 @@ impl B for T { } fn main() { - println!("{}", i32::CONST); + assert_eq!(i32::CONST, 2) } diff --git a/tests/ui/methods/supertrait-shadowing/assoc-const.run.stdout b/tests/ui/methods/supertrait-shadowing/assoc-const.run.stdout deleted file mode 100644 index 0cfbf08886fca..0000000000000 --- a/tests/ui/methods/supertrait-shadowing/assoc-const.run.stdout +++ /dev/null @@ -1 +0,0 @@ -2 diff --git a/tests/ui/methods/supertrait-shadowing/auxiliary/shadowed_stability.rs b/tests/ui/methods/supertrait-shadowing/auxiliary/shadowed_stability.rs index 7b97c63ef1b00..6371b3225a881 100644 --- a/tests/ui/methods/supertrait-shadowing/auxiliary/shadowed_stability.rs +++ b/tests/ui/methods/supertrait-shadowing/auxiliary/shadowed_stability.rs @@ -4,8 +4,8 @@ #[stable(feature = "main", since = "1.0.0")] pub trait A { #[stable(feature = "main", since = "1.0.0")] - fn hello(&self) { - println!("A"); + fn hello(&self) -> &'static str { + "A" } } #[stable(feature = "main", since = "1.0.0")] @@ -14,8 +14,8 @@ impl A for T {} #[stable(feature = "main", since = "1.0.0")] pub trait B: A { #[unstable(feature = "downstream", issue = "none")] - fn hello(&self) { - println!("B"); + fn hello(&self) -> &'static str { + "B" } } #[stable(feature = "main", since = "1.0.0")] diff --git a/tests/ui/methods/supertrait-shadowing/common-ancestor-2.rs b/tests/ui/methods/supertrait-shadowing/common-ancestor-2.rs index 525844983f510..ce56c25df19ea 100644 --- a/tests/ui/methods/supertrait-shadowing/common-ancestor-2.rs +++ b/tests/ui/methods/supertrait-shadowing/common-ancestor-2.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ check-run-results #![feature(supertrait_item_shadowing)] #![warn(resolving_to_items_shadowing_supertrait_items)] @@ -7,28 +6,28 @@ #![allow(dead_code)] trait A { - fn hello(&self) { - println!("A"); + fn hello(&self) -> &'static str { + "A" } } impl A for T {} trait B { - fn hello(&self) { - println!("B"); + fn hello(&self) -> &'static str { + "B" } } impl B for T {} trait C: A + B { - fn hello(&self) { + fn hello(&self) -> &'static str { //~^ WARN trait item `hello` from `C` shadows identically named item - println!("C"); + "C" } } impl C for T {} fn main() { - ().hello(); + assert_eq!(().hello(), "C"); //~^ WARN trait item `hello` from `C` shadows identically named item from supertrait } diff --git a/tests/ui/methods/supertrait-shadowing/common-ancestor-2.run.stdout b/tests/ui/methods/supertrait-shadowing/common-ancestor-2.run.stdout deleted file mode 100644 index 3cc58df837521..0000000000000 --- a/tests/ui/methods/supertrait-shadowing/common-ancestor-2.run.stdout +++ /dev/null @@ -1 +0,0 @@ -C diff --git a/tests/ui/methods/supertrait-shadowing/common-ancestor-2.stderr b/tests/ui/methods/supertrait-shadowing/common-ancestor-2.stderr index 392489c6734a1..b0f61b46b6911 100644 --- a/tests/ui/methods/supertrait-shadowing/common-ancestor-2.stderr +++ b/tests/ui/methods/supertrait-shadowing/common-ancestor-2.stderr @@ -1,44 +1,44 @@ warning: trait item `hello` from `C` shadows identically named item from supertrait - --> $DIR/common-ancestor-2.rs:24:5 + --> $DIR/common-ancestor-2.rs:23:5 | -LL | fn hello(&self) { - | ^^^^^^^^^^^^^^^ +LL | fn hello(&self) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: items from several supertraits are shadowed: `B` and `A` - --> $DIR/common-ancestor-2.rs:10:5 + --> $DIR/common-ancestor-2.rs:9:5 | -LL | fn hello(&self) { - | ^^^^^^^^^^^^^^^ +LL | fn hello(&self) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... -LL | fn hello(&self) { - | ^^^^^^^^^^^^^^^ +LL | fn hello(&self) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: the lint level is defined here - --> $DIR/common-ancestor-2.rs:6:9 + --> $DIR/common-ancestor-2.rs:5:9 | LL | #![warn(shadowing_supertrait_items)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: trait item `hello` from `C` shadows identically named item from supertrait - --> $DIR/common-ancestor-2.rs:32:8 + --> $DIR/common-ancestor-2.rs:31:19 | -LL | ().hello(); - | ^^^^^ +LL | assert_eq!(().hello(), "C"); + | ^^^^^ | note: item from `C` shadows a supertrait item - --> $DIR/common-ancestor-2.rs:24:5 + --> $DIR/common-ancestor-2.rs:23:5 | -LL | fn hello(&self) { - | ^^^^^^^^^^^^^^^ +LL | fn hello(&self) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: items from several supertraits are shadowed: `A` and `B` - --> $DIR/common-ancestor-2.rs:10:5 + --> $DIR/common-ancestor-2.rs:9:5 | -LL | fn hello(&self) { - | ^^^^^^^^^^^^^^^ +LL | fn hello(&self) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... -LL | fn hello(&self) { - | ^^^^^^^^^^^^^^^ +LL | fn hello(&self) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: the lint level is defined here - --> $DIR/common-ancestor-2.rs:5:9 + --> $DIR/common-ancestor-2.rs:4:9 | LL | #![warn(resolving_to_items_shadowing_supertrait_items)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/methods/supertrait-shadowing/common-ancestor-3.rs b/tests/ui/methods/supertrait-shadowing/common-ancestor-3.rs index d647c07d966d3..b29f3c8d014ec 100644 --- a/tests/ui/methods/supertrait-shadowing/common-ancestor-3.rs +++ b/tests/ui/methods/supertrait-shadowing/common-ancestor-3.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ check-run-results #![feature(supertrait_item_shadowing)] #![warn(resolving_to_items_shadowing_supertrait_items)] @@ -7,23 +6,23 @@ #![allow(dead_code)] trait A { - fn hello(&self) { - println!("A"); + fn hello(&self) -> &'static str { + "A" } } impl A for T {} trait B { - fn hello(&self) { - println!("B"); + fn hello(&self) -> &'static str { + "B" } } impl B for T {} trait C: A + B { - fn hello(&self) { + fn hello(&self) -> &'static str { //~^ WARN trait item `hello` from `C` shadows identically named item - println!("C"); + "C" } } impl C for T {} @@ -31,14 +30,14 @@ impl C for T {} // `D` extends `C` which extends `B` and `A` trait D: C { - fn hello(&self) { + fn hello(&self) -> &'static str { //~^ WARN trait item `hello` from `D` shadows identically named item - println!("D"); + "D" } } impl D for T {} fn main() { - ().hello(); + assert_eq!(().hello(), "D"); //~^ WARN trait item `hello` from `D` shadows identically named item from supertrait } diff --git a/tests/ui/methods/supertrait-shadowing/common-ancestor-3.run.stdout b/tests/ui/methods/supertrait-shadowing/common-ancestor-3.run.stdout deleted file mode 100644 index 178481050188c..0000000000000 --- a/tests/ui/methods/supertrait-shadowing/common-ancestor-3.run.stdout +++ /dev/null @@ -1 +0,0 @@ -D diff --git a/tests/ui/methods/supertrait-shadowing/common-ancestor-3.stderr b/tests/ui/methods/supertrait-shadowing/common-ancestor-3.stderr index fc0a22a9cf330..28fe7f72f94c3 100644 --- a/tests/ui/methods/supertrait-shadowing/common-ancestor-3.stderr +++ b/tests/ui/methods/supertrait-shadowing/common-ancestor-3.stderr @@ -1,65 +1,65 @@ warning: trait item `hello` from `C` shadows identically named item from supertrait - --> $DIR/common-ancestor-3.rs:24:5 + --> $DIR/common-ancestor-3.rs:23:5 | -LL | fn hello(&self) { - | ^^^^^^^^^^^^^^^ +LL | fn hello(&self) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: items from several supertraits are shadowed: `B` and `A` - --> $DIR/common-ancestor-3.rs:10:5 + --> $DIR/common-ancestor-3.rs:9:5 | -LL | fn hello(&self) { - | ^^^^^^^^^^^^^^^ +LL | fn hello(&self) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... -LL | fn hello(&self) { - | ^^^^^^^^^^^^^^^ +LL | fn hello(&self) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: the lint level is defined here - --> $DIR/common-ancestor-3.rs:6:9 + --> $DIR/common-ancestor-3.rs:5:9 | LL | #![warn(shadowing_supertrait_items)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: trait item `hello` from `D` shadows identically named item from supertrait - --> $DIR/common-ancestor-3.rs:34:5 + --> $DIR/common-ancestor-3.rs:33:5 | -LL | fn hello(&self) { - | ^^^^^^^^^^^^^^^ +LL | fn hello(&self) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: items from several supertraits are shadowed: `C`, `B`, and `A` - --> $DIR/common-ancestor-3.rs:10:5 + --> $DIR/common-ancestor-3.rs:9:5 | -LL | fn hello(&self) { - | ^^^^^^^^^^^^^^^ +LL | fn hello(&self) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... -LL | fn hello(&self) { - | ^^^^^^^^^^^^^^^ +LL | fn hello(&self) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... -LL | fn hello(&self) { - | ^^^^^^^^^^^^^^^ +LL | fn hello(&self) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: trait item `hello` from `D` shadows identically named item from supertrait - --> $DIR/common-ancestor-3.rs:42:8 + --> $DIR/common-ancestor-3.rs:41:19 | -LL | ().hello(); - | ^^^^^ +LL | assert_eq!(().hello(), "D"); + | ^^^^^ | note: item from `D` shadows a supertrait item - --> $DIR/common-ancestor-3.rs:34:5 + --> $DIR/common-ancestor-3.rs:33:5 | -LL | fn hello(&self) { - | ^^^^^^^^^^^^^^^ +LL | fn hello(&self) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: items from several supertraits are shadowed: `A`, `B`, and `C` - --> $DIR/common-ancestor-3.rs:10:5 + --> $DIR/common-ancestor-3.rs:9:5 | -LL | fn hello(&self) { - | ^^^^^^^^^^^^^^^ +LL | fn hello(&self) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... -LL | fn hello(&self) { - | ^^^^^^^^^^^^^^^ +LL | fn hello(&self) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... -LL | fn hello(&self) { - | ^^^^^^^^^^^^^^^ +LL | fn hello(&self) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: the lint level is defined here - --> $DIR/common-ancestor-3.rs:5:9 + --> $DIR/common-ancestor-3.rs:4:9 | LL | #![warn(resolving_to_items_shadowing_supertrait_items)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/methods/supertrait-shadowing/common-ancestor.rs b/tests/ui/methods/supertrait-shadowing/common-ancestor.rs index eeda26c4bd7e0..b288d6e22b8c3 100644 --- a/tests/ui/methods/supertrait-shadowing/common-ancestor.rs +++ b/tests/ui/methods/supertrait-shadowing/common-ancestor.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ check-run-results #![feature(supertrait_item_shadowing)] #![warn(resolving_to_items_shadowing_supertrait_items)] @@ -7,21 +6,21 @@ #![allow(dead_code)] trait A { - fn hello(&self) { - println!("A"); + fn hello(&self) -> &'static str { + "A" } } impl A for T {} trait B: A { - fn hello(&self) { + fn hello(&self) -> &'static str { //~^ WARN trait item `hello` from `B` shadows identically named item - println!("B"); + "B" } } impl B for T {} fn main() { - ().hello(); + assert_eq!(().hello(), "B"); //~^ WARN trait item `hello` from `B` shadows identically named item from supertrait } diff --git a/tests/ui/methods/supertrait-shadowing/common-ancestor.run.stdout b/tests/ui/methods/supertrait-shadowing/common-ancestor.run.stdout deleted file mode 100644 index 223b7836fb19f..0000000000000 --- a/tests/ui/methods/supertrait-shadowing/common-ancestor.run.stdout +++ /dev/null @@ -1 +0,0 @@ -B diff --git a/tests/ui/methods/supertrait-shadowing/common-ancestor.stderr b/tests/ui/methods/supertrait-shadowing/common-ancestor.stderr index be67fdf456b88..9afedeab5e2c2 100644 --- a/tests/ui/methods/supertrait-shadowing/common-ancestor.stderr +++ b/tests/ui/methods/supertrait-shadowing/common-ancestor.stderr @@ -1,38 +1,38 @@ warning: trait item `hello` from `B` shadows identically named item from supertrait - --> $DIR/common-ancestor.rs:17:5 + --> $DIR/common-ancestor.rs:16:5 | -LL | fn hello(&self) { - | ^^^^^^^^^^^^^^^ +LL | fn hello(&self) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: item from `A` is shadowed by a subtrait item - --> $DIR/common-ancestor.rs:10:5 + --> $DIR/common-ancestor.rs:9:5 | -LL | fn hello(&self) { - | ^^^^^^^^^^^^^^^ +LL | fn hello(&self) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: the lint level is defined here - --> $DIR/common-ancestor.rs:6:9 + --> $DIR/common-ancestor.rs:5:9 | LL | #![warn(shadowing_supertrait_items)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: trait item `hello` from `B` shadows identically named item from supertrait - --> $DIR/common-ancestor.rs:25:8 + --> $DIR/common-ancestor.rs:24:19 | -LL | ().hello(); - | ^^^^^ +LL | assert_eq!(().hello(), "B"); + | ^^^^^ | note: item from `B` shadows a supertrait item - --> $DIR/common-ancestor.rs:17:5 + --> $DIR/common-ancestor.rs:16:5 | -LL | fn hello(&self) { - | ^^^^^^^^^^^^^^^ +LL | fn hello(&self) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: item from `A` is shadowed by a subtrait item - --> $DIR/common-ancestor.rs:10:5 + --> $DIR/common-ancestor.rs:9:5 | -LL | fn hello(&self) { - | ^^^^^^^^^^^^^^^ +LL | fn hello(&self) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: the lint level is defined here - --> $DIR/common-ancestor.rs:5:9 + --> $DIR/common-ancestor.rs:4:9 | LL | #![warn(resolving_to_items_shadowing_supertrait_items)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/methods/supertrait-shadowing/no-common-ancestor-2.rs b/tests/ui/methods/supertrait-shadowing/no-common-ancestor-2.rs index 2834ca31b7140..b49476c7a4f68 100644 --- a/tests/ui/methods/supertrait-shadowing/no-common-ancestor-2.rs +++ b/tests/ui/methods/supertrait-shadowing/no-common-ancestor-2.rs @@ -1,22 +1,22 @@ #![feature(supertrait_item_shadowing)] trait A { - fn hello(&self) { - println!("A"); + fn hello(&self) -> &'static str { + "A" } } impl A for T {} trait B { - fn hello(&self) { - println!("B"); + fn hello(&self) -> &'static str { + "B" } } impl B for T {} trait C: A + B { - fn hello(&self) { - println!("C"); + fn hello(&self) -> &'static str { + "C" } } impl C for T {} @@ -25,8 +25,8 @@ impl C for T {} // we have no obvious lower bound. trait D: B { - fn hello(&self) { - println!("D"); + fn hello(&self) -> &'static str { + "D" } } impl D for T {} diff --git a/tests/ui/methods/supertrait-shadowing/no-common-ancestor-2.stderr b/tests/ui/methods/supertrait-shadowing/no-common-ancestor-2.stderr index 231cb9b1cb2bc..745f61d00d660 100644 --- a/tests/ui/methods/supertrait-shadowing/no-common-ancestor-2.stderr +++ b/tests/ui/methods/supertrait-shadowing/no-common-ancestor-2.stderr @@ -7,23 +7,23 @@ LL | ().hello(); note: candidate #1 is defined in an impl of the trait `A` for the type `T` --> $DIR/no-common-ancestor-2.rs:4:5 | -LL | fn hello(&self) { - | ^^^^^^^^^^^^^^^ +LL | fn hello(&self) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: candidate #2 is defined in an impl of the trait `B` for the type `T` --> $DIR/no-common-ancestor-2.rs:11:5 | -LL | fn hello(&self) { - | ^^^^^^^^^^^^^^^ +LL | fn hello(&self) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: candidate #3 is defined in an impl of the trait `C` for the type `T` --> $DIR/no-common-ancestor-2.rs:18:5 | -LL | fn hello(&self) { - | ^^^^^^^^^^^^^^^ +LL | fn hello(&self) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: candidate #4 is defined in an impl of the trait `D` for the type `T` --> $DIR/no-common-ancestor-2.rs:28:5 | -LL | fn hello(&self) { - | ^^^^^^^^^^^^^^^ +LL | fn hello(&self) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the method for candidate #1 | LL - ().hello(); diff --git a/tests/ui/methods/supertrait-shadowing/no-common-ancestor.rs b/tests/ui/methods/supertrait-shadowing/no-common-ancestor.rs index 7323439d5884f..03c822eb7375e 100644 --- a/tests/ui/methods/supertrait-shadowing/no-common-ancestor.rs +++ b/tests/ui/methods/supertrait-shadowing/no-common-ancestor.rs @@ -1,15 +1,15 @@ #![feature(supertrait_item_shadowing)] trait A { - fn hello(&self) { - println!("A"); + fn hello(&self) -> &'static str { + "A" } } impl A for T {} trait B { - fn hello(&self) { - println!("B"); + fn hello(&self) -> &'static str { + "B" } } impl B for T {} diff --git a/tests/ui/methods/supertrait-shadowing/no-common-ancestor.stderr b/tests/ui/methods/supertrait-shadowing/no-common-ancestor.stderr index 4e83f60c76514..29cf7ff1dbb11 100644 --- a/tests/ui/methods/supertrait-shadowing/no-common-ancestor.stderr +++ b/tests/ui/methods/supertrait-shadowing/no-common-ancestor.stderr @@ -7,13 +7,13 @@ LL | ().hello(); note: candidate #1 is defined in an impl of the trait `A` for the type `T` --> $DIR/no-common-ancestor.rs:4:5 | -LL | fn hello(&self) { - | ^^^^^^^^^^^^^^^ +LL | fn hello(&self) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: candidate #2 is defined in an impl of the trait `B` for the type `T` --> $DIR/no-common-ancestor.rs:11:5 | -LL | fn hello(&self) { - | ^^^^^^^^^^^^^^^ +LL | fn hello(&self) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the method for candidate #1 | LL - ().hello(); diff --git a/tests/ui/methods/supertrait-shadowing/out-of-scope.rs b/tests/ui/methods/supertrait-shadowing/out-of-scope.rs index 8e0f5ba978e3a..4112634399b78 100644 --- a/tests/ui/methods/supertrait-shadowing/out-of-scope.rs +++ b/tests/ui/methods/supertrait-shadowing/out-of-scope.rs @@ -1,24 +1,23 @@ //@ run-pass -//@ check-run-results #![allow(dead_code)] mod out_of_scope { pub trait Subtrait: super::Supertrait { - fn hello(&self) { - println!("subtrait"); + fn hello(&self) -> &'static str { + "subtrait" } } impl Subtrait for T {} } trait Supertrait { - fn hello(&self) { - println!("supertrait"); + fn hello(&self) -> &'static str { + "supertrait" } } impl Supertrait for T {} fn main() { - ().hello(); + assert_eq!(().hello(), "supertrait"); } diff --git a/tests/ui/methods/supertrait-shadowing/out-of-scope.run.stdout b/tests/ui/methods/supertrait-shadowing/out-of-scope.run.stdout deleted file mode 100644 index 1019e5f354346..0000000000000 --- a/tests/ui/methods/supertrait-shadowing/out-of-scope.run.stdout +++ /dev/null @@ -1 +0,0 @@ -supertrait diff --git a/tests/ui/methods/supertrait-shadowing/trivially-false-subtrait.rs b/tests/ui/methods/supertrait-shadowing/trivially-false-subtrait.rs index 799ba53a0f0e6..b0cb8b2ac7b32 100644 --- a/tests/ui/methods/supertrait-shadowing/trivially-false-subtrait.rs +++ b/tests/ui/methods/supertrait-shadowing/trivially-false-subtrait.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ check-run-results // Make sure we don't prefer a subtrait that we would've otherwise eliminated // in `consider_probe` during method probing. @@ -9,15 +8,15 @@ struct W(T); trait Upstream { - fn hello(&self) { - println!("upstream"); + fn hello(&self) -> &'static str { + "upstream" } } impl Upstream for T {} trait Downstream: Upstream { - fn hello(&self) { - println!("downstream"); + fn hello(&self) -> &'static str { + "downstream" } } impl Downstream for W where T: Foo {} @@ -26,5 +25,5 @@ trait Foo {} fn main() { let x = W(1i32); - x.hello(); + assert_eq!(x.hello(), "upstream"); } diff --git a/tests/ui/methods/supertrait-shadowing/trivially-false-subtrait.run.stdout b/tests/ui/methods/supertrait-shadowing/trivially-false-subtrait.run.stdout deleted file mode 100644 index 045951300cf48..0000000000000 --- a/tests/ui/methods/supertrait-shadowing/trivially-false-subtrait.run.stdout +++ /dev/null @@ -1 +0,0 @@ -upstream diff --git a/tests/ui/methods/supertrait-shadowing/type-dependent.rs b/tests/ui/methods/supertrait-shadowing/type-dependent.rs index 3af884fd52dcd..4a5af1d598812 100644 --- a/tests/ui/methods/supertrait-shadowing/type-dependent.rs +++ b/tests/ui/methods/supertrait-shadowing/type-dependent.rs @@ -1,5 +1,4 @@ //@ run-pass -//@ check-run-results // Makes sure we can shadow with type-dependent method syntax. @@ -7,23 +6,23 @@ #![allow(dead_code)] trait A { - fn hello() { - println!("A"); + fn hello() -> &'static str { + "A" } } impl A for T {} trait B: A { - fn hello() { - println!("B"); + fn hello() -> &'static str { + "B" } } impl B for T {} -fn foo() { - T::hello(); +fn foo() -> &'static str { + T::hello() } fn main() { - foo::<()>(); + assert_eq!(foo::<()>(), "B"); } diff --git a/tests/ui/methods/supertrait-shadowing/type-dependent.run.stdout b/tests/ui/methods/supertrait-shadowing/type-dependent.run.stdout deleted file mode 100644 index 223b7836fb19f..0000000000000 --- a/tests/ui/methods/supertrait-shadowing/type-dependent.run.stdout +++ /dev/null @@ -1 +0,0 @@ -B diff --git a/tests/ui/methods/supertrait-shadowing/unstable.off_normal.run.stdout b/tests/ui/methods/supertrait-shadowing/unstable.off_normal.run.stdout deleted file mode 100644 index f70f10e4db190..0000000000000 --- a/tests/ui/methods/supertrait-shadowing/unstable.off_normal.run.stdout +++ /dev/null @@ -1 +0,0 @@ -A diff --git a/tests/ui/methods/supertrait-shadowing/unstable.off_normal.stderr b/tests/ui/methods/supertrait-shadowing/unstable.off_normal.stderr index fc55ac7dde0cc..b8725ebdb4c1c 100644 --- a/tests/ui/methods/supertrait-shadowing/unstable.off_normal.stderr +++ b/tests/ui/methods/supertrait-shadowing/unstable.off_normal.stderr @@ -1,8 +1,8 @@ warning: a method with this name may be added to the standard library in the future - --> $DIR/unstable.rs:25:8 + --> $DIR/unstable.rs:26:19 | -LL | ().hello(); - | ^^^^^ +LL | assert_eq!(().hello(), "A"); + | ^^^^^ | = help: call with fully qualified syntax `shadowed_stability::A::hello(...)` to keep using the current method = warning: once this associated item is added to the standard library, the ambiguity may cause an error or change in behavior! diff --git a/tests/ui/methods/supertrait-shadowing/unstable.off_shadowing.run.stdout b/tests/ui/methods/supertrait-shadowing/unstable.off_shadowing.run.stdout deleted file mode 100644 index f70f10e4db190..0000000000000 --- a/tests/ui/methods/supertrait-shadowing/unstable.off_shadowing.run.stdout +++ /dev/null @@ -1 +0,0 @@ -A diff --git a/tests/ui/methods/supertrait-shadowing/unstable.off_shadowing.stderr b/tests/ui/methods/supertrait-shadowing/unstable.off_shadowing.stderr index fc55ac7dde0cc..b8725ebdb4c1c 100644 --- a/tests/ui/methods/supertrait-shadowing/unstable.off_shadowing.stderr +++ b/tests/ui/methods/supertrait-shadowing/unstable.off_shadowing.stderr @@ -1,8 +1,8 @@ warning: a method with this name may be added to the standard library in the future - --> $DIR/unstable.rs:25:8 + --> $DIR/unstable.rs:26:19 | -LL | ().hello(); - | ^^^^^ +LL | assert_eq!(().hello(), "A"); + | ^^^^^ | = help: call with fully qualified syntax `shadowed_stability::A::hello(...)` to keep using the current method = warning: once this associated item is added to the standard library, the ambiguity may cause an error or change in behavior! diff --git a/tests/ui/methods/supertrait-shadowing/unstable.on_normal.stderr b/tests/ui/methods/supertrait-shadowing/unstable.on_normal.stderr index e664f10880951..a0d8ff08d7c0a 100644 --- a/tests/ui/methods/supertrait-shadowing/unstable.on_normal.stderr +++ b/tests/ui/methods/supertrait-shadowing/unstable.on_normal.stderr @@ -1,20 +1,20 @@ error[E0034]: multiple applicable items in scope - --> $DIR/unstable.rs:25:8 + --> $DIR/unstable.rs:30:19 | -LL | ().hello(); - | ^^^^^ multiple `hello` found +LL | assert_eq!(().hello(), "B"); + | ^^^^^ multiple `hello` found | = note: candidate #1 is defined in an impl of the trait `shadowed_stability::A` for the type `T` = note: candidate #2 is defined in an impl of the trait `shadowed_stability::B` for the type `T` help: disambiguate the method for candidate #1 | -LL - ().hello(); -LL + shadowed_stability::A::hello(&()); +LL - assert_eq!(().hello(), "B"); +LL + assert_eq!(shadowed_stability::A::hello(&()), "B"); | help: disambiguate the method for candidate #2 | -LL - ().hello(); -LL + shadowed_stability::B::hello(&()); +LL - assert_eq!(().hello(), "B"); +LL + assert_eq!(shadowed_stability::B::hello(&()), "B"); | error: aborting due to 1 previous error diff --git a/tests/ui/methods/supertrait-shadowing/unstable.on_shadowing.run.stdout b/tests/ui/methods/supertrait-shadowing/unstable.on_shadowing.run.stdout deleted file mode 100644 index 223b7836fb19f..0000000000000 --- a/tests/ui/methods/supertrait-shadowing/unstable.on_shadowing.run.stdout +++ /dev/null @@ -1 +0,0 @@ -B diff --git a/tests/ui/methods/supertrait-shadowing/unstable.rs b/tests/ui/methods/supertrait-shadowing/unstable.rs index e9c336bb8d4d0..dbf0d0c89bd25 100644 --- a/tests/ui/methods/supertrait-shadowing/unstable.rs +++ b/tests/ui/methods/supertrait-shadowing/unstable.rs @@ -22,8 +22,11 @@ extern crate shadowed_stability; use shadowed_stability::*; fn main() { - ().hello(); + #[cfg(any(off_normal, off_shadowing))] + assert_eq!(().hello(), "A"); //[off_normal,off_shadowing]~^ WARN a method with this name may be added //[off_normal,off_shadowing]~| WARN once this associated item is added - //[on_normal]~^^^ ERROR multiple applicable items in scope + #[cfg(any(on_normal, on_shadowing))] + assert_eq!(().hello(), "B"); + //[on_normal]~^ ERROR multiple applicable items in scope } From 9a9f5b51413ac84ac49cd22972b65cfb47ef7ae3 Mon Sep 17 00:00:00 2001 From: zedddie Date: Sat, 11 Apr 2026 23:47:52 +0200 Subject: [PATCH 7/9] gate primitives behind `min_adt_const_params`; change suggestion to `min_adt_const_params` --- .../rustc_hir_analysis/src/check/wfcheck.rs | 8 ++++--- library/core/src/marker.rs | 6 ++++- library/core/src/tuple.rs | 2 +- .../suggest_feature_only_when_possible.rs | 6 ++--- .../suggest_feature_only_when_possible.stderr | 12 +++++----- ...tuple-wihtout-unsized_const_params-gate.rs | 10 ++++++-- ...ram-type-depends-on-const-param.min.stderr | 8 +++---- ...ay-size-in-generic-struct-param.min.stderr | 4 ++-- .../generic_const_exprs/error_in_ty.stderr | 4 ++-- .../unevaluated-const-ice-119731.stderr | 4 ++-- ...ics-type_name-as-const-argument.min.stderr | 4 ++-- .../issues/issue-62878.min.stderr | 4 ++-- .../issues/issue-63322-forbid-dyn.min.stderr | 4 ++-- .../issues/issue-68366.full.stderr | 4 ++-- .../issues/issue-68366.min.stderr | 4 ++-- .../issues/issue-68615-adt.min.stderr | 4 ++-- .../issues/issue-68615-array.min.stderr | 4 ++-- .../issues/issue-71169.min.stderr | 4 ++-- .../issues/issue-73491.min.stderr | 4 ++-- ...tic-reference-array-const-param.min.stderr | 4 ++-- .../issues/issue-74101.min.stderr | 8 +++---- .../issues/issue-74255.min.stderr | 4 ++-- .../issues/issue-74950.min.stderr | 16 ++++++------- .../issues/issue-75047.min.stderr | 4 ++-- .../min_const_generics/complex-types.stderr | 24 +++++++++---------- .../ui/const-generics/nested-type.min.stderr | 4 ++-- .../slice-const-param-mismatch.min.stderr | 8 +++---- .../std/const-generics-range.min.stderr | 24 +++++++++---------- ...te-const-param-static-reference.min.stderr | 4 ++-- .../type-dependent/issue-71348.min.stderr | 8 +++---- .../feature-gate-adt_const_params.stderr | 4 ++-- ...eneric-const-parameter-types.normal.stderr | 4 ++-- .../feature-gate-unsized-const-params.rs | 2 +- .../feature-gate-unsized-const-params.stderr | 4 ++-- .../mismatched_generic_args.stderr | 12 +++++----- .../ice-unexpected-region-123863.stderr | 8 +++---- 36 files changed, 127 insertions(+), 115 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 52cb061177c1f..0a5f1f85bb97e 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -902,7 +902,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &ty::GenericParamDef) -> Result<(), Er ) => None, Err(ConstParamTyImplementationError::UnsizedConstParamsFeatureRequired) => { Some(vec![ - (adt_const_params_feature_string, sym::adt_const_params), + (adt_const_params_feature_string, sym::min_adt_const_params), ( " references to implement the `ConstParamTy` trait".into(), sym::unsized_const_params, @@ -929,11 +929,13 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &ty::GenericParamDef) -> Result<(), Er ty_is_local(ty).then_some(vec![( adt_const_params_feature_string, - sym::adt_const_params, + sym::min_adt_const_params, )]) } // Implements `ConstParamTy`, suggest adding the feature to enable. - Ok(..) => Some(vec![(adt_const_params_feature_string, sym::adt_const_params)]), + Ok(..) => { + Some(vec![(adt_const_params_feature_string, sym::min_adt_const_params)]) + } }; if let Some(features) = may_suggest_feature { tcx.disabled_nightly_features(&mut diag, features); diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index e0f8e10484732..bc7a053900e14 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -1093,9 +1093,13 @@ pub macro ConstParamTy($item:item) { /* compiler built-in */ } +// For `adt_const_params` to be recognized as a feature +#[unstable(feature = "adt_const_params", issue = "95174")] +const _: () = (); + // FIXME(adt_const_params): handle `ty::FnDef`/`ty::Closure` marker_impls! { - #[unstable(feature = "adt_const_params", issue = "95174")] + #[unstable(feature = "min_adt_const_params", issue = "154042")] ConstParamTy_ for usize, u8, u16, u32, u64, u128, isize, i8, i16, i32, i64, i128, diff --git a/library/core/src/tuple.rs b/library/core/src/tuple.rs index 3d2782fb5a858..187e201c3cea6 100644 --- a/library/core/src/tuple.rs +++ b/library/core/src/tuple.rs @@ -47,7 +47,7 @@ macro_rules! tuple_impls { maybe_tuple_doc! { $($T)+ @ - #[unstable(feature = "min_adt_const_params", issue = "154042", implied_by = "adt_const_params")] + #[unstable(feature = "min_adt_const_params", issue = "154042")] impl<$($T: ConstParamTy_),+> ConstParamTy_ for ($($T,)+) {} } diff --git a/tests/ui/const-generics/adt_const_params/suggest_feature_only_when_possible.rs b/tests/ui/const-generics/adt_const_params/suggest_feature_only_when_possible.rs index 33988bc067850..f9898e26a8bbb 100644 --- a/tests/ui/const-generics/adt_const_params/suggest_feature_only_when_possible.rs +++ b/tests/ui/const-generics/adt_const_params/suggest_feature_only_when_possible.rs @@ -5,9 +5,9 @@ // Can never be used as const generics. fn uwu_0() {} //~^ ERROR: forbidden as the type of a const generic -//~| HELP: add `#![feature(adt_const_params)]` -//~| HELP: add `#![feature(adt_const_params)]` -//~| HELP: add `#![feature(adt_const_params)]` +//~| HELP: add `#![feature(min_adt_const_params)]` +//~| HELP: add `#![feature(min_adt_const_params)]` +//~| HELP: add `#![feature(min_adt_const_params)]` //~| HELP: add `#![feature(unsized_const_params)]` //~| HELP: add `#![feature(unsized_const_params)]` diff --git a/tests/ui/const-generics/adt_const_params/suggest_feature_only_when_possible.stderr b/tests/ui/const-generics/adt_const_params/suggest_feature_only_when_possible.stderr index 8c54aef36cac0..2f9f2af38217c 100644 --- a/tests/ui/const-generics/adt_const_params/suggest_feature_only_when_possible.stderr +++ b/tests/ui/const-generics/adt_const_params/suggest_feature_only_when_possible.stderr @@ -13,9 +13,9 @@ LL | fn owo_0() {} | ^^^^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | help: add `#![feature(unsized_const_params)]` to the crate attributes to enable references to implement the `ConstParamTy` trait | @@ -29,9 +29,9 @@ LL | fn meow_0() {} | ^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error: `&'static Meow` is forbidden as the type of a const generic parameter @@ -41,9 +41,9 @@ LL | fn meow_1() {} | ^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | help: add `#![feature(unsized_const_params)]` to the crate attributes to enable references to implement the `ConstParamTy` trait | diff --git a/tests/ui/const-generics/adt_const_params/tuple-wihtout-unsized_const_params-gate.rs b/tests/ui/const-generics/adt_const_params/tuple-wihtout-unsized_const_params-gate.rs index 70abca75c139a..9fd584b109744 100644 --- a/tests/ui/const-generics/adt_const_params/tuple-wihtout-unsized_const_params-gate.rs +++ b/tests/ui/const-generics/adt_const_params/tuple-wihtout-unsized_const_params-gate.rs @@ -1,8 +1,14 @@ -//! Ensure we allow tuples behind `adt_const_params` +//! Ensure we allow tuples behind `min_adt_const_params` //@check-pass #![feature(min_adt_const_params)] +#![allow(dead_code)] + +use std::marker::ConstParamTy; -#[allow(dead_code)] fn foo() {} +fn foo2() {} + +#[derive(PartialEq, Eq, ConstParamTy)] +struct Something(i8, i16, i32); fn main() {} diff --git a/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr b/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr index 44fcf9a13b12d..3a5419588cae9 100644 --- a/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr +++ b/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr @@ -17,9 +17,9 @@ LL | pub struct Dependent([(); N]); | ^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error: `[u8; N]` is forbidden as the type of a const generic parameter @@ -29,9 +29,9 @@ LL | pub struct SelfDependent; | ^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error: aborting due to 4 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 1f93c4f89098d..3b65a1b82fdf4 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 @@ -23,9 +23,9 @@ LL | struct B { | ^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error: aborting due to 3 previous errors diff --git a/tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr b/tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr index e10ea5a44b263..6c017c8cc6ba9 100644 --- a/tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr +++ b/tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr @@ -19,9 +19,9 @@ LL | pub struct A {} | ^^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error[E0308]: mismatched types diff --git a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr index 4fab35591ef43..022074181cecd 100644 --- a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr +++ b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr @@ -82,9 +82,9 @@ LL | pub struct v17 { | ^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error[E0425]: cannot find function `v6` in this scope 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 506f7d05fa63a..324738e44629e 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 @@ -14,9 +14,9 @@ LL | trait Trait {} | ^^^^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | help: add `#![feature(unsized_const_params)]` to the crate attributes to enable references to implement the `ConstParamTy` trait | diff --git a/tests/ui/const-generics/issues/issue-62878.min.stderr b/tests/ui/const-generics/issues/issue-62878.min.stderr index d7ca0e1e2db59..754e76269bdb8 100644 --- a/tests/ui/const-generics/issues/issue-62878.min.stderr +++ b/tests/ui/const-generics/issues/issue-62878.min.stderr @@ -11,9 +11,9 @@ LL | fn foo() {} | ^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr b/tests/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr index f14485a4976e7..aee5bb9653317 100644 --- a/tests/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr +++ b/tests/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr @@ -5,9 +5,9 @@ LL | fn test() { | ^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | help: add `#![feature(unsized_const_params)]` to the crate attributes to enable references to implement the `ConstParamTy` trait | diff --git a/tests/ui/const-generics/issues/issue-68366.full.stderr b/tests/ui/const-generics/issues/issue-68366.full.stderr index caed3c1bf3f7d..02c34b8256d6d 100644 --- a/tests/ui/const-generics/issues/issue-68366.full.stderr +++ b/tests/ui/const-generics/issues/issue-68366.full.stderr @@ -5,9 +5,9 @@ LL | struct Collatz>; | ^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates diff --git a/tests/ui/const-generics/issues/issue-68366.min.stderr b/tests/ui/const-generics/issues/issue-68366.min.stderr index 4d721e958cbc7..4b544c49af8c1 100644 --- a/tests/ui/const-generics/issues/issue-68366.min.stderr +++ b/tests/ui/const-generics/issues/issue-68366.min.stderr @@ -14,9 +14,9 @@ LL | struct Collatz>; | ^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates diff --git a/tests/ui/const-generics/issues/issue-68615-adt.min.stderr b/tests/ui/const-generics/issues/issue-68615-adt.min.stderr index d25b34435ede8..ace0cf2411955 100644 --- a/tests/ui/const-generics/issues/issue-68615-adt.min.stderr +++ b/tests/ui/const-generics/issues/issue-68615-adt.min.stderr @@ -5,9 +5,9 @@ LL | struct Const {} | ^^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/issues/issue-68615-array.min.stderr b/tests/ui/const-generics/issues/issue-68615-array.min.stderr index 60cbc9b4eab14..a0139845eaa15 100644 --- a/tests/ui/const-generics/issues/issue-68615-array.min.stderr +++ b/tests/ui/const-generics/issues/issue-68615-array.min.stderr @@ -5,9 +5,9 @@ LL | struct Foo {} | ^^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/issues/issue-71169.min.stderr b/tests/ui/const-generics/issues/issue-71169.min.stderr index c04a710eee9c7..13adc4b627a0f 100644 --- a/tests/ui/const-generics/issues/issue-71169.min.stderr +++ b/tests/ui/const-generics/issues/issue-71169.min.stderr @@ -11,9 +11,9 @@ LL | fn foo() {} | ^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/issues/issue-73491.min.stderr b/tests/ui/const-generics/issues/issue-73491.min.stderr index 2cdbeea2fd6e5..292836a370a5e 100644 --- a/tests/ui/const-generics/issues/issue-73491.min.stderr +++ b/tests/ui/const-generics/issues/issue-73491.min.stderr @@ -5,9 +5,9 @@ LL | fn hoge() {} | ^^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/issues/issue-73727-static-reference-array-const-param.min.stderr b/tests/ui/const-generics/issues/issue-73727-static-reference-array-const-param.min.stderr index 256636c0628cd..21328eb16f2a2 100644 --- a/tests/ui/const-generics/issues/issue-73727-static-reference-array-const-param.min.stderr +++ b/tests/ui/const-generics/issues/issue-73727-static-reference-array-const-param.min.stderr @@ -5,9 +5,9 @@ LL | fn a() {} | ^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | help: add `#![feature(unsized_const_params)]` to the crate attributes to enable references to implement the `ConstParamTy` trait | diff --git a/tests/ui/const-generics/issues/issue-74101.min.stderr b/tests/ui/const-generics/issues/issue-74101.min.stderr index 65fb51d7df99f..f8195c2ba9523 100644 --- a/tests/ui/const-generics/issues/issue-74101.min.stderr +++ b/tests/ui/const-generics/issues/issue-74101.min.stderr @@ -5,9 +5,9 @@ LL | fn test() {} | ^^^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error: `[u8; 1 + 2]` is forbidden as the type of a const generic parameter @@ -17,9 +17,9 @@ LL | struct Foo; | ^^^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/issues/issue-74255.min.stderr b/tests/ui/const-generics/issues/issue-74255.min.stderr index 3b30227a9a673..945f34c47d01f 100644 --- a/tests/ui/const-generics/issues/issue-74255.min.stderr +++ b/tests/ui/const-generics/issues/issue-74255.min.stderr @@ -5,9 +5,9 @@ LL | fn ice_struct_fn() {} | ^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/issues/issue-74950.min.stderr b/tests/ui/const-generics/issues/issue-74950.min.stderr index 22537af786b14..b5a8db4936b3e 100644 --- a/tests/ui/const-generics/issues/issue-74950.min.stderr +++ b/tests/ui/const-generics/issues/issue-74950.min.stderr @@ -5,9 +5,9 @@ LL | struct Outer; | ^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error: `Inner` is forbidden as the type of a const generic parameter @@ -18,9 +18,9 @@ LL | struct Outer; | = note: the only supported types are integers, `bool`, and `char` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error: `Inner` is forbidden as the type of a const generic parameter @@ -31,9 +31,9 @@ LL | struct Outer; | = note: the only supported types are integers, `bool`, and `char` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error: `Inner` is forbidden as the type of a const generic parameter @@ -44,9 +44,9 @@ LL | struct Outer; | = note: the only supported types are integers, `bool`, and `char` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error: aborting due to 4 previous errors diff --git a/tests/ui/const-generics/issues/issue-75047.min.stderr b/tests/ui/const-generics/issues/issue-75047.min.stderr index d78ab6718201a..2b17dbf9003d3 100644 --- a/tests/ui/const-generics/issues/issue-75047.min.stderr +++ b/tests/ui/const-generics/issues/issue-75047.min.stderr @@ -5,9 +5,9 @@ LL | struct Foo::value()]>; | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/min_const_generics/complex-types.stderr b/tests/ui/const-generics/min_const_generics/complex-types.stderr index bca68982c399d..3233da6382381 100644 --- a/tests/ui/const-generics/min_const_generics/complex-types.stderr +++ b/tests/ui/const-generics/min_const_generics/complex-types.stderr @@ -5,9 +5,9 @@ LL | struct Foo; | ^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error: `()` is forbidden as the type of a const generic parameter @@ -17,9 +17,9 @@ LL | struct Bar; | ^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error: `No` is forbidden as the type of a const generic parameter @@ -29,9 +29,9 @@ LL | struct Fez; | ^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error: `&'static u8` is forbidden as the type of a const generic parameter @@ -41,9 +41,9 @@ LL | struct Faz; | ^^^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | help: add `#![feature(unsized_const_params)]` to the crate attributes to enable references to implement the `ConstParamTy` trait | @@ -65,9 +65,9 @@ LL | enum Goo { A, B } | ^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error: `()` is forbidden as the type of a const generic parameter @@ -77,9 +77,9 @@ LL | union Boo { a: () } | ^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error: aborting due to 7 previous errors diff --git a/tests/ui/const-generics/nested-type.min.stderr b/tests/ui/const-generics/nested-type.min.stderr index 8282acd4ea7b1..ff15612140902 100644 --- a/tests/ui/const-generics/nested-type.min.stderr +++ b/tests/ui/const-generics/nested-type.min.stderr @@ -29,9 +29,9 @@ LL | | }]>; | |__^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/slice-const-param-mismatch.min.stderr b/tests/ui/const-generics/slice-const-param-mismatch.min.stderr index 594f8b9b79a33..8e167d369756e 100644 --- a/tests/ui/const-generics/slice-const-param-mismatch.min.stderr +++ b/tests/ui/const-generics/slice-const-param-mismatch.min.stderr @@ -5,9 +5,9 @@ LL | struct ConstString; | ^^^^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | help: add `#![feature(unsized_const_params)]` to the crate attributes to enable references to implement the `ConstParamTy` trait | @@ -21,9 +21,9 @@ LL | struct ConstBytes; | ^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | help: add `#![feature(unsized_const_params)]` to the crate attributes to enable references to implement the `ConstParamTy` trait | diff --git a/tests/ui/const-generics/std/const-generics-range.min.stderr b/tests/ui/const-generics/std/const-generics-range.min.stderr index 43a57c880d5d8..f302085254c64 100644 --- a/tests/ui/const-generics/std/const-generics-range.min.stderr +++ b/tests/ui/const-generics/std/const-generics-range.min.stderr @@ -5,9 +5,9 @@ LL | struct _Range>; | ^^^^^^^^^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error: `std::ops::RangeFrom` is forbidden as the type of a const generic parameter @@ -17,9 +17,9 @@ LL | struct _RangeFrom>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error: `RangeFull` is forbidden as the type of a const generic parameter @@ -29,9 +29,9 @@ LL | struct _RangeFull; | ^^^^^^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error: `std::ops::RangeInclusive` is forbidden as the type of a const generic parameter @@ -41,9 +41,9 @@ LL | struct _RangeInclusive>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error: `RangeTo` is forbidden as the type of a const generic parameter @@ -53,9 +53,9 @@ LL | struct _RangeTo>; | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error: `std::ops::RangeToInclusive` is forbidden as the type of a const generic parameter @@ -65,9 +65,9 @@ LL | struct _RangeToInclusive>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error: aborting due to 6 previous errors diff --git a/tests/ui/const-generics/transmute-const-param-static-reference.min.stderr b/tests/ui/const-generics/transmute-const-param-static-reference.min.stderr index 911afa3391d16..b8876b33295c3 100644 --- a/tests/ui/const-generics/transmute-const-param-static-reference.min.stderr +++ b/tests/ui/const-generics/transmute-const-param-static-reference.min.stderr @@ -5,9 +5,9 @@ LL | struct Const; | ^^^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | help: add `#![feature(unsized_const_params)]` to the crate attributes to enable references to implement the `ConstParamTy` trait | diff --git a/tests/ui/const-generics/type-dependent/issue-71348.min.stderr b/tests/ui/const-generics/type-dependent/issue-71348.min.stderr index c491469bcbd2d..1555049b877f0 100644 --- a/tests/ui/const-generics/type-dependent/issue-71348.min.stderr +++ b/tests/ui/const-generics/type-dependent/issue-71348.min.stderr @@ -5,9 +5,9 @@ LL | trait Get<'a, const N: &'static str> { | ^^^^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | help: add `#![feature(unsized_const_params)]` to the crate attributes to enable references to implement the `ConstParamTy` trait | @@ -21,9 +21,9 @@ LL | fn ask<'a, const N: &'static str>(&'a self) -> &'a >::Ta | ^^^^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | help: add `#![feature(unsized_const_params)]` to the crate attributes to enable references to implement the `ConstParamTy` trait | diff --git a/tests/ui/feature-gates/feature-gate-adt_const_params.stderr b/tests/ui/feature-gates/feature-gate-adt_const_params.stderr index 7ea91a8f4c2bf..607e7869c7892 100644 --- a/tests/ui/feature-gates/feature-gate-adt_const_params.stderr +++ b/tests/ui/feature-gates/feature-gate-adt_const_params.stderr @@ -5,9 +5,9 @@ LL | struct Foo; | ^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error: aborting due to 1 previous error diff --git a/tests/ui/feature-gates/feature-gate-generic-const-parameter-types.normal.stderr b/tests/ui/feature-gates/feature-gate-generic-const-parameter-types.normal.stderr index 1377f845d1640..48b3c43c30a0e 100644 --- a/tests/ui/feature-gates/feature-gate-generic-const-parameter-types.normal.stderr +++ b/tests/ui/feature-gates/feature-gate-generic-const-parameter-types.normal.stderr @@ -11,9 +11,9 @@ LL | struct MyADT; | ^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error: aborting due to 2 previous errors diff --git a/tests/ui/feature-gates/feature-gate-unsized-const-params.rs b/tests/ui/feature-gates/feature-gate-unsized-const-params.rs index d088d382377cf..c38aa3ea4f75a 100644 --- a/tests/ui/feature-gates/feature-gate-unsized-const-params.rs +++ b/tests/ui/feature-gates/feature-gate-unsized-const-params.rs @@ -1,6 +1,6 @@ struct Foo; //~^ ERROR: `[u8]` is forbidden as the type of a const generic parameter -//~| HELP: add `#![feature(adt_const_params)]` to the crate +//~| HELP: add `#![feature(min_adt_const_params)]` to the crate //~| HELP: add `#![feature(unsized_const_params)]` to the crate fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-unsized-const-params.stderr b/tests/ui/feature-gates/feature-gate-unsized-const-params.stderr index 85ca2f59cb639..90906058dfe68 100644 --- a/tests/ui/feature-gates/feature-gate-unsized-const-params.stderr +++ b/tests/ui/feature-gates/feature-gate-unsized-const-params.stderr @@ -5,9 +5,9 @@ LL | struct Foo; | ^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | help: add `#![feature(unsized_const_params)]` to the crate attributes to enable references to implement the `ConstParamTy` trait | diff --git a/tests/ui/traits/const-traits/mismatched_generic_args.stderr b/tests/ui/traits/const-traits/mismatched_generic_args.stderr index 3094cb5013308..7dfbe75099470 100644 --- a/tests/ui/traits/const-traits/mismatched_generic_args.stderr +++ b/tests/ui/traits/const-traits/mismatched_generic_args.stderr @@ -20,9 +20,9 @@ LL | pub struct Quantity(S); | ^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error[E0107]: trait takes at most 1 generic argument but 2 generic arguments were supplied @@ -38,9 +38,9 @@ LL | impl Add for Quantity(x: Quantity) -> Quantity { | ^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | error: aborting due to 5 previous errors diff --git a/tests/ui/typeck/ice-unexpected-region-123863.stderr b/tests/ui/typeck/ice-unexpected-region-123863.stderr index e5050b4d3167a..c529fe750890d 100644 --- a/tests/ui/typeck/ice-unexpected-region-123863.stderr +++ b/tests/ui/typeck/ice-unexpected-region-123863.stderr @@ -5,9 +5,9 @@ LL | const fn concat_strs() -> &'static str { | ^^^^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | help: add `#![feature(unsized_const_params)]` to the crate attributes to enable references to implement the `ConstParamTy` trait | @@ -21,9 +21,9 @@ LL | struct Inner; | ^^^^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` -help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types +help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable more complex and user defined types | -LL + #![feature(adt_const_params)] +LL + #![feature(min_adt_const_params)] | help: add `#![feature(unsized_const_params)]` to the crate attributes to enable references to implement the `ConstParamTy` trait | From 7d4b12b6009f4b712de0b6e4c09ad72edef5b22f Mon Sep 17 00:00:00 2001 From: Sandijigs Date: Tue, 14 Apr 2026 11:49:28 +0100 Subject: [PATCH 8/9] Add lexer test for vertical tab as Pattern_White_Space whitespace --- tests/ui/lexer/unicode-pattern-white-space.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 tests/ui/lexer/unicode-pattern-white-space.rs diff --git a/tests/ui/lexer/unicode-pattern-white-space.rs b/tests/ui/lexer/unicode-pattern-white-space.rs new file mode 100644 index 0000000000000..7d72f604153bd --- /dev/null +++ b/tests/ui/lexer/unicode-pattern-white-space.rs @@ -0,0 +1,12 @@ +//@ run-pass +// Test that the Rust lexer accepts vertical tab (\x0B) as valid whitespace +// between tokens. Vertical tab is part of Unicode Pattern_White_Space, which +// the Rust language specification uses to define whitespace tokens. +// See: https://unicode.org/reports/tr31/#Pattern_White_Space +// +// The space between "let" and "_" below is a vertical tab character (\x0B), +// not a regular space. + +fn main() { + let _ = 1; +} From aacac7e2e372740307b61343fecdf23b6da77606 Mon Sep 17 00:00:00 2001 From: GokhanKabar Date: Tue, 14 Apr 2026 14:32:11 +0000 Subject: [PATCH 9/9] Fix ICE when Self is used in enum discriminant of a generic enum * Fix ICE when Self is used in enum discriminant of a generic enum Move the validation into the existing `check_param_uses_if_mcg` machinery in HIR ty lowering instead of adding a new check in wfcheck. After the `AnonConstKind` refactoring, `ForbidMCGParamUsesFolder` was only gated on `AnonConstKind::MCG`, causing discriminant anon consts (`NonTypeSystem`) to bypass it entirely. Add `anon_const_forbids_generic_params()` which returns the appropriate `ForbidParamContext` for both MCG and enum discriminant contexts. Wire it into `check_param_uses_if_mcg` so that `Self` aliasing a generic type is caught before reaching `const_eval_poly`. Convert the `TooGeneric` span_bug into a proper diagnostic as a fallback for anything slipping through type-dependent path resolution. * Address review comments - Rename `ForbidMCGParamUsesFolder` to `ForbidParamUsesFolder` - Rename `MinConstGenerics` variant to `ConstArgument` with updated doc - Simplify doc comment on `anon_const_forbids_generic_params` - Make match on `AnonConstKind` exhaustive - Move `anon_const_def_id` inside the `if let` in `check_param_uses_if_mcg` - Remove now-unreachable `TooGeneric` span_err in wfcheck * Revert TooGeneric arm back to span_bug! as requested by reviewer * Use generics_of to determine if NonTypeSystem anon consts allow generic params * Also check InlineConst and Closure defs nested in enum discriminants * Simplify logic for determining anonymous constant parent in generic contexts * add test --- .../src/hir_ty_lowering/mod.rs | 111 ++++++++++++++---- .../generic-self-in-discr-ice.rs | 12 ++ .../generic-self-in-discr-ice.stderr | 8 ++ .../generic-self-in-discr-inline-const.rs | 17 +++ .../generic-self-in-discr-inline-const.stderr | 14 +++ 5 files changed, 139 insertions(+), 23 deletions(-) create mode 100644 tests/ui/enum-discriminant/generic-self-in-discr-ice.rs create mode 100644 tests/ui/enum-discriminant/generic-self-in-discr-ice.stderr create mode 100644 tests/ui/enum-discriminant/generic-self-in-discr-inline-const.rs create mode 100644 tests/ui/enum-discriminant/generic-self-in-discr-inline-const.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 9ec5632a74982..15dff10d8310c 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -376,24 +376,44 @@ pub trait GenericArgsLowerer<'a, 'tcx> { ) -> ty::GenericArg<'tcx>; } -struct ForbidMCGParamUsesFolder<'tcx> { +/// Context in which `ForbidParamUsesFolder` is being used, to emit appropriate diagnostics. +enum ForbidParamContext { + /// Anon const in a const argument position. + ConstArgument, + /// Enum discriminant expression. + EnumDiscriminant, +} + +struct ForbidParamUsesFolder<'tcx> { tcx: TyCtxt<'tcx>, anon_const_def_id: LocalDefId, span: Span, is_self_alias: bool, + context: ForbidParamContext, } -impl<'tcx> ForbidMCGParamUsesFolder<'tcx> { +impl<'tcx> ForbidParamUsesFolder<'tcx> { fn error(&self) -> ErrorGuaranteed { - let msg = if self.is_self_alias { - "generic `Self` types are currently not permitted in anonymous constants" - } else if self.tcx.features().generic_const_args() { - "generic parameters in const blocks are only allowed as the direct value of a `type const`" - } else { - "generic parameters may not be used in const operations" + let msg = match self.context { + ForbidParamContext::EnumDiscriminant if self.is_self_alias => { + "generic `Self` types are not permitted in enum discriminant values" + } + ForbidParamContext::EnumDiscriminant => { + "generic parameters may not be used in enum discriminant values" + } + ForbidParamContext::ConstArgument if self.is_self_alias => { + "generic `Self` types are currently not permitted in anonymous constants" + } + ForbidParamContext::ConstArgument => { + if self.tcx.features().generic_const_args() { + "generic parameters in const blocks are only allowed as the direct value of a `type const`" + } else { + "generic parameters may not be used in const operations" + } + } }; let mut diag = self.tcx.dcx().struct_span_err(self.span, msg); - if self.is_self_alias { + if self.is_self_alias && matches!(self.context, ForbidParamContext::ConstArgument) { let anon_const_hir_id: HirId = HirId::make_owner(self.anon_const_def_id); let parent_impl = self.tcx.hir_parent_owner_iter(anon_const_hir_id).find_map( |(_, node)| match node { @@ -407,18 +427,20 @@ impl<'tcx> ForbidMCGParamUsesFolder<'tcx> { diag.span_note(impl_.self_ty.span, "not a concrete type"); } } - if self.tcx.features().min_generic_const_args() { + 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 { diag.help("consider factoring the expression into a `type const` item and use it as the const argument instead"); } - }; + } diag.emit() } } -impl<'tcx> ty::TypeFolder> for ForbidMCGParamUsesFolder<'tcx> { +impl<'tcx> ty::TypeFolder> for ForbidParamUsesFolder<'tcx> { fn cx(&self) -> TyCtxt<'tcx> { self.tcx } @@ -460,37 +482,80 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { && tcx.def_kind(parent_def_id) == DefKind::AnonConst && let ty::AnonConstKind::MCG = tcx.anon_const_kind(parent_def_id) { - let folder = ForbidMCGParamUsesFolder { + let folder = ForbidParamUsesFolder { tcx, anon_const_def_id: parent_def_id, span, is_self_alias: false, + context: ForbidParamContext::ConstArgument, }; return Err(folder.error()); } Ok(()) } + /// Returns the `ForbidParamContext` for the current anon const if it is a context that + /// forbids uses of generic parameters. `None` if the current item is not such a context. + /// + /// Name resolution handles most invalid generic parameter uses in these contexts, but it + /// cannot reject `Self` that aliases a generic type, nor generic parameters introduced by + /// type-dependent name resolution (e.g. `::Assoc` resolving to a type that + /// contains params). Those cases are handled by `check_param_uses_if_mcg`. + fn anon_const_forbids_generic_params(&self) -> Option { + let tcx = self.tcx(); + let parent_def_id = self.item_def_id(); + + // Inline consts and closures can be nested inside anon consts that forbid generic + // params (e.g. an enum discriminant). Walk up the def parent chain to find the + // nearest enclosing AnonConst and use that to determine the context. + let anon_const_def_id = match tcx.def_kind(parent_def_id) { + DefKind::AnonConst => parent_def_id, + DefKind::InlineConst | DefKind::Closure => { + let root = tcx.typeck_root_def_id(parent_def_id.into()); + match tcx.def_kind(root) { + DefKind::AnonConst => root.expect_local(), + _ => return None, + } + } + _ => return None, + }; + + match tcx.anon_const_kind(anon_const_def_id) { + ty::AnonConstKind::MCG => Some(ForbidParamContext::ConstArgument), + ty::AnonConstKind::NonTypeSystem => { + // NonTypeSystem anon consts only have accessible generic parameters in specific + // positions (ty patterns and field defaults — see `generics_of`). In all other + // positions (e.g. enum discriminants) generic parameters are not in scope. + if tcx.generics_of(anon_const_def_id).count() == 0 { + Some(ForbidParamContext::EnumDiscriminant) + } else { + None + } + } + ty::AnonConstKind::GCE + | ty::AnonConstKind::GCA + | ty::AnonConstKind::RepeatExprCount => None, + } + } + /// Check for uses of generic parameters that are not in scope due to this being - /// in a non-generic anon const context. + /// in a non-generic anon const context (e.g. MCG or an enum discriminant). + /// + /// Name resolution rejects most invalid uses, but cannot handle `Self` aliasing a + /// generic type or generic parameters introduced by type-dependent name resolution. #[must_use = "need to use transformed output"] fn check_param_uses_if_mcg(&self, term: T, span: Span, is_self_alias: bool) -> T where T: ty::TypeFoldable>, { let tcx = self.tcx(); - let parent_def_id = self.item_def_id(); - if tcx.def_kind(parent_def_id) == DefKind::AnonConst - && let ty::AnonConstKind::MCG = tcx.anon_const_kind(parent_def_id) + if let Some(context) = self.anon_const_forbids_generic_params() // Fast path if contains no params/escaping bound vars. && (term.has_param() || term.has_escaping_bound_vars()) { - let mut folder = ForbidMCGParamUsesFolder { - tcx, - anon_const_def_id: parent_def_id, - span, - is_self_alias, - }; + let anon_const_def_id = self.item_def_id(); + let mut folder = + ForbidParamUsesFolder { tcx, anon_const_def_id, span, is_self_alias, context }; term.fold_with(&mut folder) } else { term diff --git a/tests/ui/enum-discriminant/generic-self-in-discr-ice.rs b/tests/ui/enum-discriminant/generic-self-in-discr-ice.rs new file mode 100644 index 0000000000000..2d60380efffa0 --- /dev/null +++ b/tests/ui/enum-discriminant/generic-self-in-discr-ice.rs @@ -0,0 +1,12 @@ +#![feature(sized_hierarchy)] + +use std::marker::PointeeSized; + +#[repr(usize)] +enum What { + X = size_of::<*mut Self>(), + //~^ ERROR generic `Self` types are not permitted in enum discriminant values + Y(*mut T), +} + +fn main() {} diff --git a/tests/ui/enum-discriminant/generic-self-in-discr-ice.stderr b/tests/ui/enum-discriminant/generic-self-in-discr-ice.stderr new file mode 100644 index 0000000000000..d827897c8e3e7 --- /dev/null +++ b/tests/ui/enum-discriminant/generic-self-in-discr-ice.stderr @@ -0,0 +1,8 @@ +error: generic `Self` types are not permitted in enum discriminant values + --> $DIR/generic-self-in-discr-ice.rs:7:24 + | +LL | X = size_of::<*mut Self>(), + | ^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/enum-discriminant/generic-self-in-discr-inline-const.rs b/tests/ui/enum-discriminant/generic-self-in-discr-inline-const.rs new file mode 100644 index 0000000000000..de02bb95e5a0d --- /dev/null +++ b/tests/ui/enum-discriminant/generic-self-in-discr-inline-const.rs @@ -0,0 +1,17 @@ +//@ check-fail +// Test that `Self` is rejected even when nested inside an inline const +// or closure within an enum discriminant. Regression test for issue #154281. +#![feature(sized_hierarchy)] + +use std::marker::PointeeSized; + +#[repr(usize)] +enum What { + X = const { { let _: *mut Self; 1_usize } }, + //~^ ERROR generic `Self` types are not permitted in enum discriminant values + Y = { let _f = || { let _: *mut Self; }; 1_usize }, + //~^ ERROR generic `Self` types are not permitted in enum discriminant values + Z(*mut T), +} + +fn main() {} diff --git a/tests/ui/enum-discriminant/generic-self-in-discr-inline-const.stderr b/tests/ui/enum-discriminant/generic-self-in-discr-inline-const.stderr new file mode 100644 index 0000000000000..cc5db2eb266d1 --- /dev/null +++ b/tests/ui/enum-discriminant/generic-self-in-discr-inline-const.stderr @@ -0,0 +1,14 @@ +error: generic `Self` types are not permitted in enum discriminant values + --> $DIR/generic-self-in-discr-inline-const.rs:10:31 + | +LL | X = const { { let _: *mut Self; 1_usize } }, + | ^^^^ + +error: generic `Self` types are not permitted in enum discriminant values + --> $DIR/generic-self-in-discr-inline-const.rs:12:37 + | +LL | Y = { let _f = || { let _: *mut Self; }; 1_usize }, + | ^^^^ + +error: aborting due to 2 previous errors +