| // This test examines the error spans reported when a generic `impl` fails. |
| // For example, if a function wants an `Option<T>` where `T: Copy` but you pass `Some(vec![1, 2])`, |
| // then we want to point at the `vec![1, 2]` and not the `Some( ... )` expression. |
| |
| trait T1 {} |
| trait T2 {} |
| trait T3 {} |
| trait T4 {} |
| |
| impl T2 for i32 {} |
| impl T3 for i32 {} |
| |
| struct Wrapper<W> { |
| value: W, |
| } |
| impl<B: T2> T1 for Wrapper<B> {} |
| |
| struct Burrito<F> { |
| spicy: bool, |
| filling: F, |
| } |
| impl<A: T3> T2 for Burrito<A> {} |
| |
| struct BurritoTuple<F>(F); |
| impl<C: T3> T2 for BurritoTuple<C> {} |
| |
| enum BurritoKinds<G> { |
| SmallBurrito { spicy: bool, small_filling: G }, |
| LargeBurrito { spicy: bool, large_filling: G }, |
| MultiBurrito { first_filling: G, second_filling: G }, |
| } |
| impl<D: T3> T2 for BurritoKinds<D> {} |
| |
| struct Taco<H>(bool, H); |
| impl<E: T3> T2 for Taco<E> {} |
| |
| enum TacoKinds<H> { |
| OneTaco(bool, H), |
| TwoTacos(bool, H, H), |
| } |
| impl<F: T3> T2 for TacoKinds<F> {} |
| |
| struct GenericBurrito<Spiciness, Filling> { |
| spiciness: Spiciness, |
| filling: Filling, |
| } |
| impl<X, Y: T3> T2 for GenericBurrito<X, Y> {} |
| struct NotSpicy; |
| |
| impl<A: T3, B: T3> T2 for (A, B) {} |
| impl<A: T2, B: T2> T1 for (A, B) {} |
| |
| fn want<V: T1>(_x: V) {} |
| |
| // Some more-complex examples: |
| type AliasBurrito<T> = GenericBurrito<T, T>; |
| |
| // The following example is fairly confusing. The idea is that we want to "misdirect" the location |
| // of the error. |
| |
| struct Two<A, B> { |
| a: A, |
| b: B, |
| } |
| |
| impl<X, Y: T1, Z> T1 for Two<Two<X, Y>, Z> {} |
| |
| struct DoubleWrapper<T> { |
| item: Wrapper<T>, |
| } |
| |
| impl<T: T1> T1 for DoubleWrapper<T> {} |
| |
| impl<'a, T: T2> T1 for &'a T {} |
| |
| fn example<Q>(q: Q) { |
| // In each of the following examples, we expect the error span to point at the 'q' variable, |
| // since the missing constraint is `Q: T3`. |
| |
| // Verifies for struct: |
| want(Wrapper { value: Burrito { spicy: false, filling: q } }); |
| //~^ ERROR the trait bound `Q: T3` is not satisfied [E0277] |
| |
| // Verifies for enum with named fields in variant: |
| want(Wrapper { value: BurritoKinds::SmallBurrito { spicy: true, small_filling: q } }); |
| //~^ ERROR the trait bound `Q: T3` is not satisfied [E0277] |
| |
| // Verifies for tuple struct: |
| want(Wrapper { value: Taco(false, q) }); |
| //~^ ERROR the trait bound `Q: T3` is not satisfied [E0277] |
| |
| // Verifies for tuple enum variant: |
| want(Wrapper { value: TacoKinds::OneTaco(false, q) }); |
| //~^ ERROR the trait bound `Q: T3` is not satisfied [E0277] |
| |
| // Verifies for generic type with multiple parameters: |
| want(Wrapper { value: GenericBurrito { spiciness: NotSpicy, filling: q } }); |
| //~^ ERROR the trait bound `Q: T3` is not satisfied [E0277] |
| |
| // Verifies for tuple: |
| want((3, q)); |
| //~^ ERROR the trait bound `Q: T2` is not satisfied [E0277] |
| |
| // Verifies for nested tuple: |
| want(Wrapper { value: (3, q) }); |
| //~^ ERROR the trait bound `Q: T3` is not satisfied [E0277] |
| |
| // Verifies for nested tuple: |
| want(((3, q), 5)); |
| //~^ ERROR the trait bound `Q: T3` is not satisfied [E0277] |
| |
| want(DoubleWrapper { item: Wrapper { value: q } }); |
| //~^ ERROR the trait bound `Q: T1` is not satisfied [E0277] |
| |
| want(DoubleWrapper { item: Wrapper { value: DoubleWrapper { item: Wrapper { value: q } } } }); |
| //~^ ERROR the trait bound `Q: T1` is not satisfied [E0277] |
| |
| // Verifies for type alias to struct: |
| want(Wrapper { value: AliasBurrito { spiciness: q, filling: q } }); |
| //~^ ERROR the trait bound `Q: T3` is not satisfied [E0277] |
| |
| want(Two { a: Two { a: (), b: q }, b: () }); |
| //~^ ERROR the trait bound `Q: T1` is not satisfied [E0277] |
| |
| // We *should* blame the 'q'. |
| // FIXME: Right now, the wrong field is blamed. |
| want( |
| Two { a: Two { a: (), b: Two { a: Two { a: (), b: q }, b: () } }, b: () }, |
| //~^ ERROR the trait bound `Q: T1` is not satisfied [E0277] |
| ); |
| |
| // Verifies for reference: |
| want(&Burrito { spicy: false, filling: q }); |
| //~^ ERROR the trait bound `Q: T3` is not satisfied [E0277] |
| } |
| |
| fn main() {} |