[implied_bounds_in_impls
]: avoid linting on overlapping associated types
This commit is contained in:
parent
fff46c1667
commit
92616c0aaa
@ -317,6 +317,15 @@ fn check(cx: &LateContext<'_>, decl: &FnDecl<'_>) {
|
||||
&& let implied_bindings = path.args.map_or([].as_slice(), |a| a.bindings)
|
||||
&& let Some(def_id) = poly_trait.trait_ref.path.res.opt_def_id()
|
||||
&& let Some(bound) = find_bound_in_supertraits(cx, def_id, implied_args, &supertraits)
|
||||
// If the implied bound has a type binding that also exists in the implied-by trait,
|
||||
// then we shouldn't lint. See #11880 for an example.
|
||||
&& let assocs = cx.tcx.associated_items(bound.trait_def_id)
|
||||
&& !implied_bindings.iter().any(|binding| {
|
||||
assocs
|
||||
.filter_by_name_unhygienic(binding.ident.name)
|
||||
.next()
|
||||
.is_some_and(|assoc| assoc.kind == ty::AssocKind::Type)
|
||||
})
|
||||
{
|
||||
emit_lint(cx, poly_trait, opaque_ty, index, implied_bindings, bound);
|
||||
}
|
||||
|
@ -121,4 +121,33 @@ mod issue11435 {
|
||||
fn f3() -> impl Trait4<i8, X = i32, Y = i128> {}
|
||||
}
|
||||
|
||||
fn issue11880() {
|
||||
trait X {
|
||||
type T;
|
||||
type U;
|
||||
}
|
||||
trait Y: X {
|
||||
type T;
|
||||
type V;
|
||||
}
|
||||
impl X for () {
|
||||
type T = i32;
|
||||
type U = String;
|
||||
}
|
||||
impl Y for () {
|
||||
type T = u32;
|
||||
type V = Vec<u8>;
|
||||
}
|
||||
|
||||
// Can't constrain `X::T` through `Y`
|
||||
fn f() -> impl X<T = i32> + Y {}
|
||||
fn f2() -> impl X<T = i32> + Y<T = u32> {}
|
||||
|
||||
// X::T is never constrained in the first place, so it can be omitted
|
||||
// and left unconstrained
|
||||
fn f3() -> impl Y {}
|
||||
fn f4() -> impl Y<T = u32> {}
|
||||
fn f5() -> impl Y<T = u32, U = String> {}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -121,4 +121,33 @@ impl Trait4<i8> for () {}
|
||||
fn f3() -> impl Trait3<i8, i16, i64, X = i32, Y = i128> + Trait4<i8, X = i32> {}
|
||||
}
|
||||
|
||||
fn issue11880() {
|
||||
trait X {
|
||||
type T;
|
||||
type U;
|
||||
}
|
||||
trait Y: X {
|
||||
type T;
|
||||
type V;
|
||||
}
|
||||
impl X for () {
|
||||
type T = i32;
|
||||
type U = String;
|
||||
}
|
||||
impl Y for () {
|
||||
type T = u32;
|
||||
type V = Vec<u8>;
|
||||
}
|
||||
|
||||
// Can't constrain `X::T` through `Y`
|
||||
fn f() -> impl X<T = i32> + Y {}
|
||||
fn f2() -> impl X<T = i32> + Y<T = u32> {}
|
||||
|
||||
// X::T is never constrained in the first place, so it can be omitted
|
||||
// and left unconstrained
|
||||
fn f3() -> impl X + Y {}
|
||||
fn f4() -> impl X + Y<T = u32> {}
|
||||
fn f5() -> impl X<U = String> + Y<T = u32> {}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -192,5 +192,41 @@ LL - fn f3() -> impl Trait3<i8, i16, i64, X = i32, Y = i128> + Trait4<i8, X
|
||||
LL + fn f3() -> impl Trait4<i8, X = i32, Y = i128> {}
|
||||
|
|
||||
|
||||
error: aborting due to 16 previous errors
|
||||
error: this bound is already specified as the supertrait of `Y`
|
||||
--> $DIR/implied_bounds_in_impls.rs:148:21
|
||||
|
|
||||
LL | fn f3() -> impl X + Y {}
|
||||
| ^
|
||||
|
|
||||
help: try removing this bound
|
||||
|
|
||||
LL - fn f3() -> impl X + Y {}
|
||||
LL + fn f3() -> impl Y {}
|
||||
|
|
||||
|
||||
error: this bound is already specified as the supertrait of `Y<T = u32>`
|
||||
--> $DIR/implied_bounds_in_impls.rs:149:21
|
||||
|
|
||||
LL | fn f4() -> impl X + Y<T = u32> {}
|
||||
| ^
|
||||
|
|
||||
help: try removing this bound
|
||||
|
|
||||
LL - fn f4() -> impl X + Y<T = u32> {}
|
||||
LL + fn f4() -> impl Y<T = u32> {}
|
||||
|
|
||||
|
||||
error: this bound is already specified as the supertrait of `Y<T = u32>`
|
||||
--> $DIR/implied_bounds_in_impls.rs:150:21
|
||||
|
|
||||
LL | fn f5() -> impl X<U = String> + Y<T = u32> {}
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
help: try removing this bound
|
||||
|
|
||||
LL - fn f5() -> impl X<U = String> + Y<T = u32> {}
|
||||
LL + fn f5() -> impl Y<T = u32, U = String> {}
|
||||
|
|
||||
|
||||
error: aborting due to 19 previous errors
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user