Skip to content

Instantly share code, notes, and snippets.

@Centril
Last active April 1, 2019 11:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Centril/d23d5fa9e24af9bce8d1074fc63e1606 to your computer and use it in GitHub Desktop.
Save Centril/d23d5fa9e24af9bce8d1074fc63e1606 to your computer and use it in GitHub Desktop.
Tests for trait alias expansion
// run-pass
// The purpose of this test is to demonstrate that so long as no more than the
// first expanded trait in dyn Bound is an auto-trait, it's all good.
#![feature(trait_alias)]
fn main() {}
trait _0 = Send + Sync;
// Just auto traits:
trait _1 = _0 + Send + Sync;
use core::marker::Unpin;
type _T01 = dyn _0;
type _T02 = dyn _1;
type _T03 = dyn Unpin + _1 + Send + Sync;
// Include object safe traits:
trait Obj {}
type _T10 = dyn Obj + _0;
type _T11 = dyn Obj + _1;
type _T12 = dyn Obj + _1 + _0;
// And when the object safe trait is in a trait alias:
trait _2 = Obj;
type _T20 = dyn _2 + _0;
type _T21 = dyn _2 + _1;
type _T22 = dyn _2 + _1 + _0;
// And it should also work when that trait is has auto traits to the right of it.
trait _3 = Obj + Unpin;
type _T30 = dyn _3 + _0;
type _T31 = dyn _3 + _1;
type _T32 = dyn _3 + _1 + _0;
// Nest the trait deeply:
trait _4 = _3;
trait _5 = _4 + Sync + _0 + Send;
trait _6 = _5 + Send + _1 + Sync;
type _T60 = dyn _6 + _0;
type _T61 = dyn _6 + _1;
type _T62 = dyn _6 + _1 + _0;
// Just nest the trait alone:
trait _7 = _2;
trait _8 = _7;
trait _9 = _8;
type _T9 = dyn _9;
// The purpose of this test is to demonstrate that trait alias expansion
// enforces that the non-auto-trait must come before the auto-trait
// since this is how `dyn Send + Copy` behaves.
#![feature(trait_alias)]
fn main() {}
// Some random object safe trait:
trait Obj {}
trait _0 = Send + Obj;
type _T0 = dyn _0;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
trait _1 = Obj + Send;
trait _2 = Sync + _1;
trait _3 = Send + _3;
type _T1 = dyn _3;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
// The purpose of this test is to demonstrate that duplicating object safe traits
// that are not auto-traits is rejected with trait aliases even though one could
// reasonably accept this.
#![feature(trait_alias)]
fn main() {}
// Some random object safe trait:
trait Obj {}
// Nest a few levels deep:
trait _0 = Obj;
trait _1 = _0;
type _T01 = dyn _0 + _0;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T01 = dyn _1 + _0;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T02 = dyn _1 + _1;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T03 = dyn Obj + _1;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T04 = dyn _1 + Obj;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
// Nest some more and in weird ways:
trait _2 = _0 + _1;
trait _3 = Obj;
trait _4 = _3;
type _T10 = dyn _2 + _3;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T11 = dyn _3 + _2;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T12 = dyn Obj + _2;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T13 = dyn _2 + Obj;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T14 = dyn _1 + _3;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T15 = dyn _3 + _1;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T14 = dyn _1 + _4;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T15 = dyn _4 + _1;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
// Include auto traits:
trait _5 = Obj + Send;
type _T20 = dyn _5 + _5;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T21 = dyn Obj + _5;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T22 = dyn _5 + Obj;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T23 = dyn _5 + Send + Sync + Obj;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
// Also nest:
trait _6 = _5 + _5; // ==> Obj + Send + Obj + Send
type _T30 = dyn _6;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T31 = dyn _6 + Send;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T32 = dyn Send + _6;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
// Nest some more:
use core::marker::Unpin;
trait _7 = _5 + Sync;
trait _8 = Unpin + _7;
type _T40 = dyn _8 + Obj;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T41 = dyn Obj + _8;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T42 = dyn _8 + _4;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T43 = dyn _4 + _8;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T44 = dyn _4 + Send + Sync + _8;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
// Take higher ranked types into account.
// Note that `'a` and `'b` are intentionally different to make sure we consider
// them semantically the same.
trait ObjL<'l> {}
trait _9 = for<'a> ObjL<'a>;
trait _10 = for<'b> ObjL<'b>;
type _T50 = _9 + _10;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
trait ObjT<T> {}
trait _11 = ObjT<for<'a> fn(&'a u8)>;
trait _12 = ObjT<for<'b> fn(&'b u8)>;
type _T60 = _11 + _12;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
// The purpose of this test is to demonstrate that trait alias expansion
// preserves the rule that `dyn Trait` may only reference 1 non-auto-trait.
#![feature(trait_alias)]
fn main() {}
// Some random object safe traits:
trait ObjA {}
trait ObjB {}
// Nest a few levels deep:
trait _0 = ObjA;
trait _1 = _0;
type _T01 = dyn _0 + ObjB;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T01 = dyn ObjB + _0;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T02 = dyn ObjB + _1;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T04 = dyn _1 + ObjB;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
// Nest some more and in weird ways:
trait _2 = ObjB;
trait _3 = _2;
trait _4 = _3;
type _T10 = dyn _2 + _3;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T11 = dyn _3 + _2;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T10 = dyn _2 + _4;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T11 = dyn _4 + _2;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
// Include auto traits:
trait _5 = Sync + ObjB + Send;
type _T20 = dyn _5 + _1;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T21 = dyn _1 + _5;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T22 = dyn _5 + ObjA;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T23 = dyn ObjA + _5;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T24 = dyn Send + _5 + _1 + Sync;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T25 = dyn _1 + Sync + _5 + Send;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T26 = dyn Sync + Send + _5 + ObjA;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T27 = dyn Send + Sync + ObjA + _5;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
// Also nest:
trait _6 = _1 + _5;
trait _7 = _6;
trait _8 = _7;
type _T30 = dyn _6;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T31 = dyn _6 + Send;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T32 = dyn Send + _6;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T33 = dyn _8;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T34 = dyn _8 + Send;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T35 = dyn Send + _8;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
// Nest some more:
use core::marker::Unpin;
trait _9 = _5 + Sync;
trait _10 = Unpin + _9;
type _T40 = dyn _10 + ObjA;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T41 = dyn ObjA + _10;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T42 = dyn _10 + _1;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T43 = dyn Send + _10 + Sync + ObjA;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T44 = dyn ObjA + _10 + Send + Sync;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _T45 = dyn Sync + Send + _10 + _1;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
// We test that `dyn ... + ?Sized + ...` cannot arise from the expansion of trait aliases.
#![feature(trait_alias)]
fn main() {}
trait S = ?Sized;
// Nest a few levels deep:
trait _0 = S;
trait _1 = _0;
// Straight list expansion:
type _T0 = dyn _1;
//~^ ERROR `?Trait` is not permitted in trait object types
// In second position:
type _T1 = dyn Copy + _1;
//~^ ERROR `?Trait` is not permitted in trait object types
// and with an auto trait:
type _T2 = dyn Copy + Send + _1;
//~^ ERROR `?Trait` is not permitted in trait object types
// Twice:
trait _2 = _1 + _1;
type _T3 = dyn _2;
//~^ ERROR `?Trait` is not permitted in trait object types
//~| ERROR `?Trait` is not permitted in trait object types
//~| ERROR only auto traits can be used as additional traits in a trait object [E0225]
// The purpose of this test is to demonstrate that duplicating object safe traits
// that are not auto-traits is rejected even though one could reasonably accept this.
fn main() {}
// Some random object safe trait:
trait Obj {}
// Demonstrate that recursive expansion of trait aliases doesn't affect stable behavior:
type _0 = dyn Obj + Obj;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
// Some variations:
type _1 = dyn Send + Obj + Obj;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _2 = dyn Obj + Send + Obj;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _3 = dyn Obj + Send + Send; // But it is OK to duplicate auto traits.
// Take higher ranked types into account.
// Note that `'a` and `'b` are intentionally different to make sure we consider
// them semantically the same.
trait ObjL<'l> {}
type _4 = dyn for<'a> ObjL<'a> + for<'b> ObjL<'b>;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
trait ObjT<T> {}
type _5 = dyn ObjT<for<'a> fn(&'a u8)> + ObjT<for<'b> fn(&'b u8)>;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
// Ensure that `dyn $($AutoTrait)+ ObjSafe` is not well-formed.
fn main() {}
use core::marker::Unpin;
type _0 = Unpin + Obj;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _1 = Send + Obj;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _2 = Send + Unpin + Obj;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
type _3 = Send + Unpin + Sync + Obj;
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
// The purpose of this test is to demonstrate that duplicating `?Sized`
// isn't allowed in `dyn Trait` and that it isn't allowed at all.
fn main() {}
type _0 = dyn ?Sized;
//~^ ERROR `?Trait` is not permitted in trait object types
type _1 = dyn Copy + ?Sized;
//~^ ERROR `?Trait` is not permitted in trait object types
type _2 = dyn Copy + ?Sized + ?Sized;
//~^ ERROR `?Trait` is not permitted in trait object types
type _3 = dyn ?Sized + Copy;
//~^ ERROR `?Trait` is not permitted in trait object types
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment