Things to test (all tests are found in src/test/ui/traits/trait-alias unless otherwise noted):
impl TraitAlias for u32 { .. }--trait-alias-impl.rs- Kinds of trait aliases:
trait SendSyncAlias = Send + Synctrait WhereSendAlias = where Self: Sendtrait SendEqAlias<T> = Send where T: PartialEq<Self>- with associated items specified (
trait U32Iterator = Iterator<Item = u32>) - with a lifetime parameter (
trait PartialEqRef<'a, T> = PartialEq<&'a T>or something like that)
- Test (ideally) each kind of where clause in each possible position:
- Type parameter bounds (
struct Foo<T: SendSyncAlias>,impl<T: SendSyncAlias> Foo for T) - Where clauses (
struct Foo<T> where T: SendSyncAlias) - Impl trait (
fn foo(x: &impl SendEqAlias<u32>) { 22_u32 == *x })
- Type parameter bounds (
- On functions, in particular, test each kind of where-clause, e.g., but especially "special stuff":
fn foo<T: U32Iterator>(x: &T) -> Option<u32> { x.next() }fn foo<T: SendEqAlias<u32>>(x: &T) -> bool { 22_u32 == *x }fn foo<T: SendSyncAlias>() { is_send_and_sync::<T>(); } fn is_send_and_sync<T: Send + Sync>() { }
- Trait object:
trait Alias = Eq,&dyn Alias-- should fail object safety check, tested intrait-alias-objects.rs&dyn Alias-- check that it works, document behaviorimpl dyn Alias-- check that it works, document behavior- Test that it implements the relevant traits:
trait Alias = Debug; fn foo(x: &dyn Debug) { bar(x); } fn bar<T: ?Sized + Debug>(x: &T) { }
- with associated items specified:
trait U32Iterator = Iterator<Item = u32>; &dyn U32Iterator
- without associated items specified:
trait Alias = Iterator; &dyn Alias-- tested intrait-alias-objects.rs
- Well-formedness conditions on alias definitions:
trait Foo<T: Send> {f } trait Bar<T> = Foo<T>;-- tested intrait-alias-wf.rstrait Foo<'a, T: 'a> { } trait Bar<'a, T> = Foo<T: 'a>;-- tested intrait-alias-wf-region.rs
- Extra conditions on trait aliases:
- given
trait Foo<T> { } trait Bar<T: Display> = Foo<T>;then:fn is_foo<T: Bar<U>, U>() { /* ok */ }fn is_bar<T: Bar<U>, U>() { /* NOT ok */ }fn is_bar2<T: Bar<U>, U: Display>() { /* ok */ }
- given
- Associated type constraints:
- given
trait MyIterator = Iterator:fn foo<T: MyIterator<Item = u32>>() { /* ok */ }fn foo<T: MyIterator<Something = u32>>() { /* not ok */ }
- given
trait Foo { type Assoc; } trait Bar { type Assoc; } trait FooBar = Foo + Bar:fn foo<T: FooBar<Assoc = u32>> { /* not ok */ }- (or take example from ambiguous constraints section)
- given
- Other situations:
trait Static = 'staticas describes in "only lifetimes"