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