]> git.lizzy.rs Git - rust.git/blob - src/test/ui/associated-types/defaults-specialization.rs
bootstrap: Configurable musl libdir
[rust.git] / src / test / ui / associated-types / defaults-specialization.rs
1 //! Tests the interaction of associated type defaults and specialization.
2
3 #![feature(associated_type_defaults, specialization)]
4
5 trait Tr {
6     type Ty = u8;
7
8     fn make() -> Self::Ty {
9         0u8
10         //~^ error: mismatched types
11     }
12 }
13
14 struct A<T>(T);
15 // In a `default impl`, assoc. types are defaulted as well,
16 // so their values can't be assumed.
17 default impl<T> Tr for A<T> {
18     fn make() -> u8 { 0 }
19     //~^ ERROR method `make` has an incompatible type for trait
20 }
21
22 struct A2<T>(T);
23 // ...same, but in the method body
24 default impl<T> Tr for A2<T> {
25     fn make() -> Self::Ty { 0u8 }
26     //~^ ERROR mismatched types
27 }
28
29 struct B<T>(T);
30 // Explicitly defaulting the type does the same.
31 impl<T> Tr for B<T> {
32     default type Ty = bool;
33
34     fn make() -> bool { true }
35     //~^ ERROR method `make` has an incompatible type for trait
36 }
37
38 struct B2<T>(T);
39 // ...same, but in the method body
40 impl<T> Tr for B2<T> {
41     default type Ty = bool;
42
43     fn make() -> Self::Ty { true }
44     //~^ ERROR mismatched types
45 }
46
47 struct C<T>(T);
48 // Only the method is defaulted, so this is fine.
49 impl<T> Tr for C<T> {
50     type Ty = bool;
51
52     default fn make() -> bool { true }
53 }
54
55 // Defaulted method *can* assume the type, if the default is kept.
56 struct D<T>(T);
57 impl<T> Tr for D<T> {
58     default fn make() -> u8 { 0 }
59 }
60
61 impl Tr for D<bool> {
62     fn make() -> u8 { 255 }
63 }
64
65 struct E<T>(T);
66 impl<T> Tr for E<T> {
67     default type Ty = bool;
68     default fn make() -> Self::Ty { panic!(); }
69 }
70
71 // This impl specializes and sets `Ty`, it can rely on `Ty=String`.
72 impl Tr for E<bool> {
73     type Ty = String;
74
75     fn make() -> String { String::new() }
76 }
77
78 fn main() {
79     // Test that we can assume the right set of assoc. types from outside the impl
80
81     // This is a `default impl`, which does *not* mean that `A`/`A2` actually implement the trait.
82     // cf. https://github.com/rust-lang/rust/issues/48515
83     //let _: <A<()> as Tr>::Ty = 0u8;
84     //let _: <A2<()> as Tr>::Ty = 0u8;
85
86     let _: <B<()> as Tr>::Ty = 0u8;   //~ error: mismatched types
87     let _: <B<()> as Tr>::Ty = true;  //~ error: mismatched types
88     let _: <B2<()> as Tr>::Ty = 0u8;  //~ error: mismatched types
89     let _: <B2<()> as Tr>::Ty = true; //~ error: mismatched types
90
91     let _: <C<()> as Tr>::Ty = true;
92
93     let _: <D<()> as Tr>::Ty = 0u8;
94     let _: <D<bool> as Tr>::Ty = 0u8;
95 }