Suppress self-referential associated type constraint suggestion

This commit is contained in:
arferreira
2026-03-15 12:39:39 -04:00
parent 620e36a8d1
commit 4ecc78d637
3 changed files with 59 additions and 1 deletions
@@ -263,8 +263,13 @@ fn foo(&self, x: T) -> T { x }
cause.code(),
);
}
// Don't suggest constraining a projection to something
// containing itself, e.g. `Item = &<I as Iterator>::Item`.
(_, ty::Alias(ty::Projection | ty::Inherent, proj_ty))
if !tcx.is_impl_trait_in_trait(proj_ty.def_id) =>
if !tcx.is_impl_trait_in_trait(proj_ty.def_id)
&& !tcx
.erase_and_anonymize_regions(values.expected)
.contains(tcx.erase_and_anonymize_regions(values.found)) =>
{
let msg = || {
format!(
@@ -0,0 +1,20 @@
// Regression test for #112104.
//
// Don't suggest `Item = &<I as Iterator>::Item` when
// the expected type wraps the found projection.
fn option_of_ref_assoc<I: Iterator>(iter: &mut I) {
let _: Option<&I::Item> = iter.next();
//~^ ERROR mismatched types
}
// Valid constraint suggestions should still fire.
trait Foo {
type Assoc;
}
fn assoc_to_concrete<T: Foo>(x: T::Assoc) -> u32 {
x //~ ERROR mismatched types
}
fn main() {}
@@ -0,0 +1,33 @@
error[E0308]: mismatched types
--> $DIR/dont-suggest-self-referential-constraint.rs:7:31
|
LL | let _: Option<&I::Item> = iter.next();
| ---------------- ^^^^^^^^^^^ expected `Option<&<I as Iterator>::Item>`, found `Option<<I as Iterator>::Item>`
| |
| expected due to this
|
= note: expected enum `Option<&_>`
found enum `Option<_>`
help: try using `.as_ref()` to convert `Option<<I as Iterator>::Item>` to `Option<&<I as Iterator>::Item>`
|
LL | let _: Option<&I::Item> = iter.next().as_ref();
| +++++++++
error[E0308]: mismatched types
--> $DIR/dont-suggest-self-referential-constraint.rs:17:5
|
LL | fn assoc_to_concrete<T: Foo>(x: T::Assoc) -> u32 {
| --- expected `u32` because of return type
LL | x
| ^ expected `u32`, found associated type
|
= note: expected type `u32`
found associated type `<T as Foo>::Assoc`
help: consider constraining the associated type `<T as Foo>::Assoc` to `u32`
|
LL | fn assoc_to_concrete<T: Foo<Assoc = u32>>(x: T::Assoc) -> u32 {
| +++++++++++++
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.