//! Checks that associated type defaults are properly validated. //! //! This means: //! * Default types are checked against where clauses on the assoc. type //! (eg. `type Assoc: Clone = NotClone`) #![feature(associated_type_defaults)] struct NotClone; // Assoc. type bounds must hold for the default type trait Tr { type Ty: Clone = NotClone; //~^ ERROR the trait bound `NotClone: Clone` is not satisfied } // Where-clauses defined on the trait must also be considered trait Tr2 where Self::Ty: Clone, { type Ty = NotClone; //~^ ERROR the trait bound `NotClone: Clone` is not satisfied } // Involved type parameters must fulfill all bounds required by defaults that mention them trait Foo { type Bar: Clone = Vec; //~^ ERROR the trait bound `T: Clone` is not satisfied } trait Bar: Sized { // `(): Foo` might hold for some possible impls but not all. type Assoc: Foo = (); //~^ ERROR the trait bound `(): Foo` is not satisfied } trait IsU8 {} impl IsU8 for T {} // Test that mentioning the assoc. type inside where clauses is not allowed trait C where Vec: Clone, Self::Assoc: IsU8, bool: IsU8, { type Assoc = u8; } // Test that we get all expected errors if that default is unsuitable trait D where Vec: Clone, Self::Assoc: IsU8, bool: IsU8, { type Assoc = NotClone; //~^ ERROR the trait bound `NotClone: IsU8` is not satisfied } // Test behavior of the check when defaults refer to other defaults: // Shallow substitution rejects this trait since `Baz` isn't guaranteed to be // `Clone`. trait Foo2 { type Bar: Clone = Vec; //~^ ERROR the trait bound `>::Baz: Clone` is not satisfied type Baz = T; } // Adding a `T: Clone` bound doesn't help since the requirement doesn't see `T` // because of the shallow substitution. If we did a deep substitution instead, // this would be accepted. trait Foo25 { type Bar: Clone = Vec; //~^ ERROR the trait bound `>::Baz: Clone` is not satisfied type Baz = T; } // Adding the `Baz: Clone` bound isn't enough since the default is type // parameter `T`, which also might not be `Clone`. trait Foo3 where Self::Bar: Clone, Self::Baz: Clone, { type Bar = Vec; type Baz = T; //~^ ERROR the trait bound `T: Clone` is not satisfied } // This one finally works, with `Clone` bounds on all assoc. types and the type // parameter. trait Foo4 where T: Clone, { type Bar: Clone = Vec; type Baz: Clone = T; } fn main() {}