// This test examines the error spans reported when a generic `impl` fails. // For example, if a function wants an `Option` 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 { value: W, } impl T1 for Wrapper {} struct Burrito { spicy: bool, filling: F, } impl T2 for Burrito {} struct BurritoTuple(F); impl T2 for BurritoTuple {} enum BurritoKinds { SmallBurrito { spicy: bool, small_filling: G }, LargeBurrito { spicy: bool, large_filling: G }, MultiBurrito { first_filling: G, second_filling: G }, } impl T2 for BurritoKinds {} struct Taco(bool, H); impl T2 for Taco {} enum TacoKinds { OneTaco(bool, H), TwoTacos(bool, H, H), } impl T2 for TacoKinds {} struct GenericBurrito { spiciness: Spiciness, filling: Filling, } impl T2 for GenericBurrito {} struct NotSpicy; impl T2 for (A, B) {} impl T1 for (A, B) {} fn want(_x: V) {} // Some more-complex examples: type AliasBurrito = GenericBurrito; // The following example is fairly confusing. The idea is that we want to "misdirect" the location // of the error. struct Two { a: A, b: B, } impl T1 for Two, Z> {} struct DoubleWrapper { item: Wrapper, } impl T1 for DoubleWrapper {} impl<'a, T: T2> T1 for &'a T {} fn example(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() {}