pub trait DeclaredTrait { type Type; } impl DeclaredTrait for i32 { type Type = i32; } pub trait WhereTrait { type Type; } impl WhereTrait for i32 { type Type = i32; } // Make sure we don't add a bound that just shares a name with an associated // type. pub mod module { pub type Type = i32; } #[derive(PartialEq, Debug)] struct PrivateStruct<T>(T); #[derive(PartialEq, Debug)] struct TupleStruct<A, B: DeclaredTrait, C>( module::Type, Option<module::Type>, A, PrivateStruct<A>, B, B::Type, Option<B::Type>, <B as DeclaredTrait>::Type, Option<<B as DeclaredTrait>::Type>, C, C::Type, Option<C::Type>, <C as WhereTrait>::Type, Option<<C as WhereTrait>::Type>, <i32 as DeclaredTrait>::Type, ) where C: WhereTrait; #[derive(PartialEq, Debug)] pub struct Struct<A, B: DeclaredTrait, C> where C: WhereTrait { m1: module::Type, m2: Option<module::Type>, a1: A, a2: PrivateStruct<A>, b: B, b1: B::Type, b2: Option<B::Type>, b3: <B as DeclaredTrait>::Type, b4: Option<<B as DeclaredTrait>::Type>, c: C, c1: C::Type, c2: Option<C::Type>, c3: <C as WhereTrait>::Type, c4: Option<<C as WhereTrait>::Type>, d: <i32 as DeclaredTrait>::Type, } #[derive(PartialEq, Debug)] enum Enum<A, B: DeclaredTrait, C> where C: WhereTrait { Unit, Seq( module::Type, Option<module::Type>, A, PrivateStruct<A>, B, B::Type, Option<B::Type>, <B as DeclaredTrait>::Type, Option<<B as DeclaredTrait>::Type>, C, C::Type, Option<C::Type>, <C as WhereTrait>::Type, Option<<C as WhereTrait>::Type>, <i32 as DeclaredTrait>::Type, ), Map { m1: module::Type, m2: Option<module::Type>, a1: A, a2: PrivateStruct<A>, b: B, b1: B::Type, b2: Option<B::Type>, b3: <B as DeclaredTrait>::Type, b4: Option<<B as DeclaredTrait>::Type>, c: C, c1: C::Type, c2: Option<C::Type>, c3: <C as WhereTrait>::Type, c4: Option<<C as WhereTrait>::Type>, d: <i32 as DeclaredTrait>::Type, }, } fn main() { let e: Enum< i32, i32, i32, > = Enum::Seq( 0, None, 0, PrivateStruct(0), 0, 0, None, 0, None, 0, 0, None, 0, None, 0, ); assert_eq!(e, e); let e: Enum< i32, i32, i32, > = Enum::Map { m1: 0, m2: None, a1: 0, a2: PrivateStruct(0), b: 0, b1: 0, b2: None, b3: 0, b4: None, c: 0, c1: 0, c2: None, c3: 0, c4: None, d: 0, }; assert_eq!(e, e); let e: TupleStruct< i32, i32, i32, > = TupleStruct( 0, None, 0, PrivateStruct(0), 0, 0, None, 0, None, 0, 0, None, 0, None, 0, ); assert_eq!(e, e); let e: Struct< i32, i32, i32, > = Struct { m1: 0, m2: None, a1: 0, a2: PrivateStruct(0), b: 0, b1: 0, b2: None, b3: 0, b4: None, c: 0, c1: 0, c2: None, c3: 0, c4: None, d: 0, }; assert_eq!(e, e); let e = Enum::Unit::<i32, i32, i32>; assert_eq!(e, e); }