1 // check-pass
2 
3 #![feature(associated_type_defaults)]
4 
5 // Having a cycle in assoc. type defaults is okay, as long as there's no impl
6 // that retains it.
7 trait Tr {
8     type A = Vec<Self::B>;
9     type B = Box<Self::A>;
10 
f()11     fn f();
12 }
13 
14 // An impl has to break the cycle to be accepted.
15 impl Tr for u8 {
16     type A = u8;
17 
f()18     fn f() {
19         // Check that the type propagates as expected (seen from inside the impl)
20         let _: Self::A = 0u8;
21         let _: Self::B = Box::new(0u8);
22     }
23 }
24 
25 impl Tr for String {
26     type B = ();
27 
f()28     fn f() {
29         // Check that the type propagates as expected (seen from inside the impl)
30         let _: Self::A = Vec::<()>::new();
31         let _: Self::B = ();
32     }
33 }
34 
35 impl Tr for () {
36     type A = Vec<()>;
37     type B = u8;
38 
f()39     fn f() {
40         // Check that the type propagates as expected (seen from inside the impl)
41         let _: Self::A = Vec::<()>::new();
42         let _: Self::B = 0u8;
43     }
44 }
45 
main()46 fn main() {
47     // Check that both impls now have the right types (seen from outside the impls)
48     let _: <u8 as Tr>::A = 0u8;
49     let _: <u8 as Tr>::B = Box::new(0u8);
50 
51     let _: <String as Tr>::A = Vec::<()>::new();
52     let _: <String as Tr>::B = ();
53 
54     let _: <() as Tr>::A = Vec::<()>::new();
55     let _: <() as Tr>::B = 0u8;
56 }
57