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 = Self::B;
9 type B = 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 = 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 = ();
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 = 0u8;
50
51 let _: <String as Tr>::A = ();
52 let _: <String as Tr>::B = ();
53
54 let _: <() as Tr>::A = Vec::<()>::new();
55 let _: <() as Tr>::B = 0u8;
56 }
57