| //! Comprehensive test for type parameter constraints in trait implementations | |
| //! | |
| //! This tests various scenarios of type parameter usage in trait implementations: | |
| //! - Properly constrained parameters through trait bounds | |
| //! - Unconstrained parameters that should cause compilation errors | |
| //! - Complex constraint scenarios with `where` clauses and associated types | |
| //! - Conflicting implementations detection | |
| trait Foo<A> { | |
| fn get(&self, A: &A) {} | |
| } | |
| trait Bar { | |
| type Out; | |
| } | |
| impl<T> Foo<T> for [isize; 0] { | |
| // OK: T is used in the trait bound `Foo<T>` | |
| } | |
| impl<T, U> Foo<T> for [isize; 1] { | |
| //~^ ERROR the type parameter `U` is not constrained | |
| // T is constrained by `Foo<T>`, but U is completely unused | |
| } | |
| impl<T, U> Foo<T> for [isize; 2] | |
| where | |
| T: Bar<Out = U>, | |
| { | |
| // OK: T is constrained by `Foo<T>`, U is constrained by the where clause | |
| } | |
| impl<T: Bar<Out = U>, U> Foo<T> for [isize; 3] { | |
| // OK: Same as above but using bound syntax instead of where clause | |
| } | |
| impl<T, U> Foo<T> for U { | |
| //~^ ERROR conflicting implementations of trait `Foo<_>` for type `[isize; 0]` | |
| // This conflicts with the first impl when U = [isize; 0] | |
| } | |
| impl<T, U> Bar for T { | |
| //~^ ERROR the type parameter `U` is not constrained | |
| type Out = U; | |
| // Using U only in associated type definition is insufficient for constraint | |
| } | |
| impl<T, U> Bar for T | |
| where | |
| T: Bar<Out = U>, | |
| { | |
| //~^^^^ ERROR the type parameter `U` is not constrained by the impl trait, self type, or predicates | |
| //~| ERROR conflicting implementations of trait `Bar` | |
| // Self-referential constraint doesn't properly constrain U | |
| } | |
| impl<T, U, V> Foo<T> for T | |
| where | |
| (T, U): Bar<Out = V>, | |
| { | |
| //~^^^^ ERROR the type parameter `U` is not constrained | |
| //~| ERROR the type parameter `V` is not constrained | |
| //~| ERROR conflicting implementations of trait `Foo<[isize; 0]>` for type `[isize; 0]` | |
| // V is bound through output type, but U and V are not properly constrained as inputs | |
| } | |
| impl<T, U, V> Foo<(T, U)> for T | |
| where | |
| (T, U): Bar<Out = V>, | |
| { | |
| //~^^^^ ERROR conflicting implementations of trait `Foo<([isize; 0], _)>` for type `[isize; 0]` | |
| // Both T and U are constrained through `Foo<(T, U)>`, but creates conflicting impl | |
| } | |
| fn main() {} |