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 + Sync
trait WhereSendAlias = where Self: Send
trait 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.rs
trait 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 = 'static
as describes in "only lifetimes"