From e73522932ebc756793280fa264f418b6fc0b47c6 Mon Sep 17 00:00:00 2001 From: Raushan kumar Date: Thu, 16 Jul 2026 06:42:55 +0000 Subject: [PATCH 1/3] Fix accurate targeting for imperfect derives diagnostic Filters out false positives for the 'imperfect derives' E0277 note by checking if ADT fields satisfy the trait independently of the failing generic parameter. --- .../src/error_reporting/traits/suggestions.rs | 92 ++++++++++++++++++- tests/ui/associated-types/issue-38821.stderr | 4 - .../unsizing-wfcheck-issue-126272.stderr | 4 - .../clone-copy/deriving-copyclone.stderr | 2 - tests/ui/derives/imperfect-derive-advanced.rs | 42 +++++++++ .../derives/imperfect-derive-advanced.stderr | 81 ++++++++++++++++ tests/ui/derives/imperfect-derive-copy.rs | 16 ++++ tests/ui/derives/imperfect-derive-copy.stderr | 30 ++++++ tests/ui/derives/imperfect-derive-phantom.rs | 16 ++++ .../derives/imperfect-derive-phantom.stderr | 30 ++++++ ...undant-derive-note-on-unimplemented.stderr | 2 - .../issue-104884-trait-impl-sugg-err.stderr | 2 - ...missing-bound-in-derive-copy-impl-2.stderr | 4 - .../missing-bound-in-derive-copy-impl.stderr | 4 - 14 files changed, 306 insertions(+), 23 deletions(-) create mode 100644 tests/ui/derives/imperfect-derive-advanced.rs create mode 100644 tests/ui/derives/imperfect-derive-advanced.stderr create mode 100644 tests/ui/derives/imperfect-derive-copy.rs create mode 100644 tests/ui/derives/imperfect-derive-copy.stderr create mode 100644 tests/ui/derives/imperfect-derive-phantom.rs create mode 100644 tests/ui/derives/imperfect-derive-phantom.stderr diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 0a4691447b3d6..7921250a85a9e 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -4520,7 +4520,13 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } } err.span_note(spans, msg); - if derived && trait_name != "Copy" { + if derived + && self.is_truly_imperfect_derive( + parent_trait_pred, + predicate, + param_env, + ) + { err.help(format!( "consider manually implementing `{trait_name}` to avoid undesired bounds caused by \"imperfect derives\"", )); @@ -6472,6 +6478,90 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { _ => {} } } + + /// Checks whether the field independently satisfies the trait bound, ignoring + /// the specific generic parameter that caused the original E0277 error. + fn is_truly_imperfect_derive( + &self, + parent_trait_pred: ty::PolyTraitClause<'tcx>, + predicate: ty::Predicate<'tcx>, + param_env: ty::ParamEnv<'tcx>, + ) -> bool { + let tcx = self.tcx; + let ty::Adt(adt_def, parent_args) = parent_trait_pred.skip_binder().self_ty().kind() else { + return false; + }; + let Some(trait_clause) = predicate.as_trait_clause() else { + return false; + }; + let failing_ty = trait_clause.skip_binder().self_ty(); + let trait_def_id = parent_trait_pred.def_id(); + + let failing_adt_param_indices: FxHashSet = parent_args + .iter() + .enumerate() + .filter_map(|(idx, arg)| { + if let Some(t) = arg.as_type() + && t == failing_ty + { + Some(idx as u32) + } else { + None + } + }) + .collect(); + + if failing_adt_param_indices.is_empty() { + return false; + } + + adt_def.all_fields().all(|field| { + let raw_field_ty = tcx.type_of(field.did).skip_binder(); + // If the field type is exactly one of the failing parameters, it is not an imperfect derive. + if let ty::Param(p) = raw_field_ty.kind() + && failing_adt_param_indices.contains(&p.index) + { + return false; + } + // If the field type doesn't mention the parameter at all, it's independent. + if !raw_field_ty.walk().any(|arg| { + matches!(arg.as_type().map(|t| t.kind()), Some(ty::Param(p)) if failing_adt_param_indices.contains(&p.index)) + }) { + return true; + } + + self.probe(|_| { + // We keep the generic parameters that didn't fail as-is from the parent args, + // but replace the ones that did fail with fresh inference variable placeholders. + let fresh_args = ty::GenericArgs::for_item(tcx, adt_def.did(), |param, _| { + if failing_adt_param_indices.contains(¶m.index) { + self.var_for_def(DUMMY_SP, param) + } else { + parent_args[param.index as usize] + } + }); + + let field_ty = field.ty(tcx, fresh_args).skip_norm_wip(); + // Substitute the field's type for the bound's `Self` type to check whether + // the field alone would satisfy the trait, independent of other generics. + let parent_trait_args = parent_trait_pred.skip_binder().trait_ref.args; + let trait_args = parent_trait_args.iter().map(|arg| { + if arg.as_type() == Some(parent_trait_pred.skip_binder().self_ty()) { + field_ty.into() + } else { + arg + } + }); + let obligation = Obligation::new( + tcx, + ObligationCause::dummy(), + param_env, + ty::TraitRef::new(tcx, trait_def_id, trait_args), + ); + self.predicate_may_hold(&obligation) + }) + }) + } } /// Add a hint to add a missing borrow or remove an unnecessary one. diff --git a/tests/ui/associated-types/issue-38821.stderr b/tests/ui/associated-types/issue-38821.stderr index d7fcec380a3de..050054ad704bc 100644 --- a/tests/ui/associated-types/issue-38821.stderr +++ b/tests/ui/associated-types/issue-38821.stderr @@ -108,8 +108,6 @@ LL | pub enum ColumnInsertValue where ... LL | Expr: Expression::Nullable>, | ------------------------------------------------ unsatisfied trait bound - = help: consider manually implementing `Debug` to avoid undesired bounds caused by "imperfect derives" - = note: to learn more, visit help: consider further restricting the associated type | LL | Expr: Expression::Nullable>, ::SqlType: NotNull, @@ -239,8 +237,6 @@ LL | pub enum ColumnInsertValue where ... LL | Expr: Expression::Nullable>, | ------------------------------------------------ unsatisfied trait bound - = help: consider manually implementing `Clone` to avoid undesired bounds caused by "imperfect derives" - = note: to learn more, visit help: consider further restricting the associated type | LL | Expr: Expression::Nullable>, ::SqlType: NotNull, diff --git a/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr b/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr index 029c41b46ff40..ffbd0acd0f1e9 100644 --- a/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr +++ b/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr @@ -67,8 +67,6 @@ LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] | ----- in this derive macro expansion LL | struct Bar(T); | ^^^ - unsatisfied trait bound - = help: consider manually implementing `Debug` to avoid undesired bounds caused by "imperfect derives" - = note: to learn more, visit = note: 2 redundant requirements hidden = note: required for `&&'static Bar<(dyn Debug + 'static)>` to implement `Debug` = note: required for the cast from `&&&'static Bar<(dyn Debug + 'static)>` to `&dyn Debug` @@ -103,8 +101,6 @@ LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] | -- in this derive macro expansion LL | struct Bar(T); | ^^^ - type parameter would need to implement `Eq` - = help: consider manually implementing `Eq` to avoid undesired bounds caused by "imperfect derives" - = note: to learn more, visit = note: 1 redundant requirement hidden = note: required for `&'static Bar` to implement `Eq` note: required by a bound in `std::cmp::AssertParamIsEq` diff --git a/tests/ui/derives/clone-copy/deriving-copyclone.stderr b/tests/ui/derives/clone-copy/deriving-copyclone.stderr index 356678ada17bb..285ff40f4a877 100644 --- a/tests/ui/derives/clone-copy/deriving-copyclone.stderr +++ b/tests/ui/derives/clone-copy/deriving-copyclone.stderr @@ -38,8 +38,6 @@ LL | #[derive(Copy, Clone)] | ----- in this derive macro expansion LL | struct B { | ^ - type parameter would need to implement `Clone` - = help: consider manually implementing `Clone` to avoid undesired bounds caused by "imperfect derives" - = note: to learn more, visit note: required by a bound in `is_clone` --> $DIR/deriving-copyclone.rs:19:16 | diff --git a/tests/ui/derives/imperfect-derive-advanced.rs b/tests/ui/derives/imperfect-derive-advanced.rs new file mode 100644 index 0000000000000..52dcb03b71caa --- /dev/null +++ b/tests/ui/derives/imperfect-derive-advanced.rs @@ -0,0 +1,42 @@ +// Test that the "imperfect derives" note is emitted for associated types, +// `Rc`, and coinductive types. + +use std::rc::Rc; + +trait Trait { + type Assoc: Clone; +} + +#[derive(Clone)] +struct AssocStruct { + field: T::Assoc, +} + +struct NonClone; +impl Trait for NonClone { + type Assoc = u32; +} + +#[derive(Clone)] +struct RcStruct { + field: Rc, +} + +#[derive(Clone)] +struct List { + value: Rc, + next: Option>>, +} + +fn require_clone() {} + +fn main() { + require_clone::>(); + //~^ ERROR the trait bound `NonClone: Clone` is not satisfied + + require_clone::>(); + //~^ ERROR the trait bound `NonClone: Clone` is not satisfied + + require_clone::>(); + //~^ ERROR the trait bound `NonClone: Clone` is not satisfied +} diff --git a/tests/ui/derives/imperfect-derive-advanced.stderr b/tests/ui/derives/imperfect-derive-advanced.stderr new file mode 100644 index 0000000000000..d97d96e6dd4f8 --- /dev/null +++ b/tests/ui/derives/imperfect-derive-advanced.stderr @@ -0,0 +1,81 @@ +error[E0277]: the trait bound `NonClone: Clone` is not satisfied + --> $DIR/imperfect-derive-advanced.rs:34:21 + | +LL | require_clone::>(); + | ^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `NonClone` + | +note: required for `AssocStruct` to implement `Clone` + --> $DIR/imperfect-derive-advanced.rs:11:8 + | +LL | #[derive(Clone)] + | ----- in this derive macro expansion +LL | struct AssocStruct { + | ^^^^^^^^^^^ - type parameter would need to implement `Clone` + = help: consider manually implementing `Clone` to avoid undesired bounds caused by "imperfect derives" + = note: to learn more, visit +note: required by a bound in `require_clone` + --> $DIR/imperfect-derive-advanced.rs:31:21 + | +LL | fn require_clone() {} + | ^^^^^ required by this bound in `require_clone` +help: consider annotating `NonClone` with `#[derive(Clone)]` + | +LL + #[derive(Clone)] +LL | struct NonClone; + | + +error[E0277]: the trait bound `NonClone: Clone` is not satisfied + --> $DIR/imperfect-derive-advanced.rs:37:21 + | +LL | require_clone::>(); + | ^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `NonClone` + | +note: required for `RcStruct` to implement `Clone` + --> $DIR/imperfect-derive-advanced.rs:21:8 + | +LL | #[derive(Clone)] + | ----- in this derive macro expansion +LL | struct RcStruct { + | ^^^^^^^^ - type parameter would need to implement `Clone` + = help: consider manually implementing `Clone` to avoid undesired bounds caused by "imperfect derives" + = note: to learn more, visit +note: required by a bound in `require_clone` + --> $DIR/imperfect-derive-advanced.rs:31:21 + | +LL | fn require_clone() {} + | ^^^^^ required by this bound in `require_clone` +help: consider annotating `NonClone` with `#[derive(Clone)]` + | +LL + #[derive(Clone)] +LL | struct NonClone; + | + +error[E0277]: the trait bound `NonClone: Clone` is not satisfied + --> $DIR/imperfect-derive-advanced.rs:40:21 + | +LL | require_clone::>(); + | ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `NonClone` + | +note: required for `List` to implement `Clone` + --> $DIR/imperfect-derive-advanced.rs:26:8 + | +LL | #[derive(Clone)] + | ----- in this derive macro expansion +LL | struct List { + | ^^^^ - type parameter would need to implement `Clone` + = help: consider manually implementing `Clone` to avoid undesired bounds caused by "imperfect derives" + = note: to learn more, visit +note: required by a bound in `require_clone` + --> $DIR/imperfect-derive-advanced.rs:31:21 + | +LL | fn require_clone() {} + | ^^^^^ required by this bound in `require_clone` +help: consider annotating `NonClone` with `#[derive(Clone)]` + | +LL + #[derive(Clone)] +LL | struct NonClone; + | + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/derives/imperfect-derive-copy.rs b/tests/ui/derives/imperfect-derive-copy.rs new file mode 100644 index 0000000000000..cb68cfdb0507a --- /dev/null +++ b/tests/ui/derives/imperfect-derive-copy.rs @@ -0,0 +1,16 @@ +// Test that the "imperfect derives" note is emitted for Copy when the derive +// bound is genuinely unnecessary (e.g., `PhantomData`). + +use std::marker::PhantomData; + +#[derive(Copy, Clone)] +struct X(PhantomData); + +struct Y; // does not implement Copy + +fn require_copy(_t: T) {} + +fn main() { + require_copy(X::(PhantomData)); + //~^ ERROR the trait bound `X: Copy` is not satisfied +} diff --git a/tests/ui/derives/imperfect-derive-copy.stderr b/tests/ui/derives/imperfect-derive-copy.stderr new file mode 100644 index 0000000000000..125852de9b417 --- /dev/null +++ b/tests/ui/derives/imperfect-derive-copy.stderr @@ -0,0 +1,30 @@ +error[E0277]: the trait bound `X: Copy` is not satisfied + --> $DIR/imperfect-derive-copy.rs:14:25 + | +LL | require_copy(X::(PhantomData)); + | ------------ ^^^^^^^^^^^ the trait `Copy` is not implemented for `X` + | | + | required by a bound introduced by this call + | +note: required for `X` to implement `Copy` + --> $DIR/imperfect-derive-copy.rs:7:8 + | +LL | #[derive(Copy, Clone)] + | ---- in this derive macro expansion +LL | struct X(PhantomData); + | ^ - type parameter would need to implement `Copy` + = help: consider manually implementing `Copy` to avoid undesired bounds caused by "imperfect derives" + = note: to learn more, visit +note: required by a bound in `require_copy` + --> $DIR/imperfect-derive-copy.rs:11:20 + | +LL | fn require_copy(_t: T) {} + | ^^^^ required by this bound in `require_copy` +help: consider borrowing here + | +LL | require_copy(X::(&PhantomData)); + | + + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/derives/imperfect-derive-phantom.rs b/tests/ui/derives/imperfect-derive-phantom.rs new file mode 100644 index 0000000000000..23cc05626fb08 --- /dev/null +++ b/tests/ui/derives/imperfect-derive-phantom.rs @@ -0,0 +1,16 @@ +// Test that the "imperfect derives" note is emitted when the derive bound +// is genuinely unnecessary (e.g., `PhantomData`). + +use std::marker::PhantomData; + +#[derive(Clone)] +struct S(PhantomData); + +struct X; + +fn require_clone(_t: T) {} + +fn main() { + require_clone(S::(PhantomData)); + //~^ ERROR the trait bound `S: Clone` is not satisfied +} diff --git a/tests/ui/derives/imperfect-derive-phantom.stderr b/tests/ui/derives/imperfect-derive-phantom.stderr new file mode 100644 index 0000000000000..ff0d7e09f286f --- /dev/null +++ b/tests/ui/derives/imperfect-derive-phantom.stderr @@ -0,0 +1,30 @@ +error[E0277]: the trait bound `S: Clone` is not satisfied + --> $DIR/imperfect-derive-phantom.rs:14:26 + | +LL | require_clone(S::(PhantomData)); + | ------------- ^^^^^^^^^^^ the trait `Clone` is not implemented for `S` + | | + | required by a bound introduced by this call + | +note: required for `S` to implement `Clone` + --> $DIR/imperfect-derive-phantom.rs:7:8 + | +LL | #[derive(Clone)] + | ----- in this derive macro expansion +LL | struct S(PhantomData); + | ^ - type parameter would need to implement `Clone` + = help: consider manually implementing `Clone` to avoid undesired bounds caused by "imperfect derives" + = note: to learn more, visit +note: required by a bound in `require_clone` + --> $DIR/imperfect-derive-phantom.rs:11:21 + | +LL | fn require_clone(_t: T) {} + | ^^^^^ required by this bound in `require_clone` +help: consider borrowing here + | +LL | require_clone(S::(&PhantomData)); + | + + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/derives/redundant-derive-note-on-unimplemented.stderr b/tests/ui/derives/redundant-derive-note-on-unimplemented.stderr index ef3c94b4f07f7..69e6e53a19d28 100644 --- a/tests/ui/derives/redundant-derive-note-on-unimplemented.stderr +++ b/tests/ui/derives/redundant-derive-note-on-unimplemented.stderr @@ -21,8 +21,6 @@ LL | #[derive(Debug)] | ----- in this derive macro expansion LL | struct S(T); | ^ - type parameter would need to implement `Debug` - = help: consider manually implementing `Debug` to avoid undesired bounds caused by "imperfect derives" - = note: to learn more, visit help: consider annotating `X` with `#[derive(Debug)]` | LL + #[derive(Debug)] diff --git a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr index 179f9fc51a4ba..0390295a66a42 100644 --- a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr +++ b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr @@ -44,8 +44,6 @@ LL | #[derive(PartialOrd, AddImpl)] ... LL | struct PriorityQueue(BinaryHeap>); | ^^^^^^^^^^^^^ - type parameter would need to implement `PartialOrd` - = help: consider manually implementing `PartialOrd` to avoid undesired bounds caused by "imperfect derives" - = note: to learn more, visit note: required by a bound in `Ord` --> $SRC_DIR/core/src/cmp.rs:LL:COL diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr index 779339232e692..ad359b538cef9 100644 --- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr +++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr @@ -30,8 +30,6 @@ LL | #[derive(Debug, Copy, Clone)] | ----- in this derive macro expansion LL | pub struct Vector2 { | ^^^^^^^ ---- unsatisfied trait bound - = help: consider manually implementing `Debug` to avoid undesired bounds caused by "imperfect derives" - = note: to learn more, visit = note: required for the cast from `&Vector2` to `&dyn Debug` help: consider further restricting type parameter `K` with trait `Copy` | @@ -73,8 +71,6 @@ LL | #[derive(Debug, Copy, Clone)] | ----- in this derive macro expansion LL | pub struct Vector2 { | ^^^^^^^ ---- unsatisfied trait bound - = help: consider manually implementing `Clone` to avoid undesired bounds caused by "imperfect derives" - = note: to learn more, visit help: consider further restricting type parameter `K` with trait `Copy` | LL | pub struct AABB { diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr index 225ab3cd5838d..92e4188e2039f 100644 --- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr +++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr @@ -66,8 +66,6 @@ LL | #[derive(Debug, Copy, Clone)] | ----- in this derive macro expansion LL | pub struct Vector2 { | ^^^^^^^ ---- unsatisfied trait bound - = help: consider manually implementing `Debug` to avoid undesired bounds caused by "imperfect derives" - = note: to learn more, visit = note: required for the cast from `&Vector2` to `&dyn Debug` help: consider restricting type parameter `K` with trait `Copy` | @@ -137,8 +135,6 @@ LL | #[derive(Debug, Copy, Clone)] | ----- in this derive macro expansion LL | pub struct Vector2 { | ^^^^^^^ ---- unsatisfied trait bound - = help: consider manually implementing `Clone` to avoid undesired bounds caused by "imperfect derives" - = note: to learn more, visit help: consider restricting type parameter `K` with trait `Copy` | LL | pub struct AABB { From d180f00098c64d59b57ef8ed2823db143dfcd3b2 Mon Sep 17 00:00:00 2001 From: zakrad <49591476+zakrad@users.noreply.github.com> Date: Sat, 29 Aug 2026 14:07:14 +0330 Subject: [PATCH 2/3] Add regression test for TAIT in extern fn ICE with the new solver --- ...tait-extern-fn-next-solver-issue-156345.rs | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 tests/ui/lint/improper-ctypes/tait-extern-fn-next-solver-issue-156345.rs diff --git a/tests/ui/lint/improper-ctypes/tait-extern-fn-next-solver-issue-156345.rs b/tests/ui/lint/improper-ctypes/tait-extern-fn-next-solver-issue-156345.rs new file mode 100644 index 0000000000000..fd8ba56b10be6 --- /dev/null +++ b/tests/ui/lint/improper-ctypes/tait-extern-fn-next-solver-issue-156345.rs @@ -0,0 +1,42 @@ +//@ compile-flags: -Znext-solver=globally +//@ edition: 2021 +//@ check-pass + +// Regression test for . +// An `extern "C" fn` taking a type alias impl trait argument used to ICE with +// the new solver, leaving an entry in the `OpaqueTypeStorage`. Only the new +// solver was affected. + +#![feature(type_alias_impl_trait)] +#![allow(improper_ctypes_definitions)] + +struct Foo { + field: String, +} + +type Tait = impl Sized; + +#[define_opaque(Tait)] +extern "C" fn ice_cold(beverage: Tait) { + let Foo { field } = beverage; + let _ = field; +} + +// A second reproducer from the same issue, with the opaque type in return +// position behind a higher-ranked closure bound. +struct Parser(H); + +impl Parser +where + H: for<'a> Fn(&'a str) -> T, +{ + fn new(handler: H) -> Parser { + Parser(handler) + } + + extern "C" fn many<'s>() -> Parser Fn(&'a str) + 's> { + Parser::new(|_| ()) + } +} + +fn main() {} From 1253a875d17e122dc181a6a7842182bf12875deb Mon Sep 17 00:00:00 2001 From: malezjaa Date: Sat, 29 Aug 2026 23:32:51 +0200 Subject: [PATCH 3/3] regression test for unexpected region ICE --- .../assoc-const-equality-unexpected-region.rs | 14 +++++++ ...oc-const-equality-unexpected-region.stderr | 40 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 tests/ui/associated-consts/assoc-const-equality-unexpected-region.rs create mode 100644 tests/ui/associated-consts/assoc-const-equality-unexpected-region.stderr diff --git a/tests/ui/associated-consts/assoc-const-equality-unexpected-region.rs b/tests/ui/associated-consts/assoc-const-equality-unexpected-region.rs new file mode 100644 index 0000000000000..e8a3dcf47eea3 --- /dev/null +++ b/tests/ui/associated-consts/assoc-const-equality-unexpected-region.rs @@ -0,0 +1,14 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/143896. + +trait TraitA<'a> { + const K: usize = 0; +} + +impl TraitA<'_> for () {} +//~^ ERROR the type parameter `T` is not constrained + +impl dyn TraitA<'_> where (): TraitA<'a, K = 0> {} +//~^ ERROR use of undeclared lifetime name `'a` +//~| ERROR associated const equality is incomplete + +pub fn main() {} diff --git a/tests/ui/associated-consts/assoc-const-equality-unexpected-region.stderr b/tests/ui/associated-consts/assoc-const-equality-unexpected-region.stderr new file mode 100644 index 0000000000000..6e38e3e41acbf --- /dev/null +++ b/tests/ui/associated-consts/assoc-const-equality-unexpected-region.stderr @@ -0,0 +1,40 @@ +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/assoc-const-equality-unexpected-region.rs:10:38 + | +LL | impl dyn TraitA<'_> where (): TraitA<'a, K = 0> {} + | ^^ undeclared lifetime + | + = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html +help: consider making the bound lifetime-generic with a new `'a` lifetime + | +LL | impl dyn TraitA<'_> where (): for<'a> TraitA<'a, K = 0> {} + | +++++++ +help: consider making the bound lifetime-generic with a new `'a` lifetime + | +LL | impl dyn TraitA<'_> where for<'a> (): TraitA<'a, K = 0> {} + | +++++++ +help: consider introducing lifetime `'a` here + | +LL | impl<'a> dyn TraitA<'_> where (): TraitA<'a, K = 0> {} + | ++++ + +error[E0658]: associated const equality is incomplete + --> $DIR/assoc-const-equality-unexpected-region.rs:10:42 + | +LL | impl dyn TraitA<'_> where (): TraitA<'a, K = 0> {} + | ^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates + --> $DIR/assoc-const-equality-unexpected-region.rs:7:6 + | +LL | impl TraitA<'_> for () {} + | ^ unconstrained type parameter + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0207, E0261, E0658. +For more information about an error, try `rustc --explain E0207`.