]> git.lizzy.rs Git - rust.git/blob - src/test/ui/associated-types/defaults-suitability.rs
feat(rustdoc): open sidebar menu when links inside it are focused
[rust.git] / src / test / ui / associated-types / defaults-suitability.rs
1 //! Checks that associated type defaults are properly validated.
2 //!
3 //! This means:
4 //! * Default types are checked against where clauses on the assoc. type
5 //!   (eg. `type Assoc: Clone = NotClone`)
6
7 #![feature(associated_type_defaults)]
8
9 struct NotClone;
10
11 // Assoc. type bounds must hold for the default type
12 trait Tr {
13     type Ty: Clone = NotClone;
14     //~^ ERROR the trait bound `NotClone: Clone` is not satisfied
15 }
16
17 // Where-clauses defined on the trait must also be considered
18 trait Tr2
19 where
20     Self::Ty: Clone,
21 {
22     type Ty = NotClone;
23     //~^ ERROR the trait bound `NotClone: Clone` is not satisfied
24 }
25
26 // Involved type parameters must fulfill all bounds required by defaults that mention them
27 trait Foo<T> {
28     type Bar: Clone = Vec<T>;
29     //~^ ERROR the trait bound `T: Clone` is not satisfied
30 }
31
32 trait Bar: Sized {
33     // `(): Foo<Self>` might hold for some possible impls but not all.
34     type Assoc: Foo<Self> = ();
35     //~^ ERROR the trait bound `(): Foo<Self>` is not satisfied
36 }
37
38 trait IsU8<T> {}
39 impl<T> IsU8<u8> for T {}
40
41 // Test that mentioning the assoc. type inside where clauses is not allowed
42 trait C where
43     Vec<Self::Assoc>: Clone,
44     Self::Assoc: IsU8<Self::Assoc>,
45     bool: IsU8<Self::Assoc>,
46 {
47     type Assoc = u8;
48 }
49
50 // Test that we get all expected errors if that default is unsuitable
51 trait D where
52     Vec<Self::Assoc>: Clone,
53     Self::Assoc: IsU8<Self::Assoc>,
54     bool: IsU8<Self::Assoc>,
55 {
56     type Assoc = NotClone;
57     //~^ ERROR the trait bound `NotClone: IsU8<NotClone>` is not satisfied
58 }
59
60 // Test behavior of the check when defaults refer to other defaults:
61
62 // Shallow substitution rejects this trait since `Baz` isn't guaranteed to be
63 // `Clone`.
64 trait Foo2<T> {
65     type Bar: Clone = Vec<Self::Baz>;
66     //~^ ERROR the trait bound `<Self as Foo2<T>>::Baz: Clone` is not satisfied
67     type Baz = T;
68 }
69
70 // Adding a `T: Clone` bound doesn't help since the requirement doesn't see `T`
71 // because of the shallow substitution. If we did a deep substitution instead,
72 // this would be accepted.
73 trait Foo25<T: Clone> {
74     type Bar: Clone = Vec<Self::Baz>;
75     //~^ ERROR the trait bound `<Self as Foo25<T>>::Baz: Clone` is not satisfied
76     type Baz = T;
77 }
78
79 // Adding the `Baz: Clone` bound isn't enough since the default is type
80 // parameter `T`, which also might not be `Clone`.
81 trait Foo3<T>
82 where
83     Self::Bar: Clone,
84     Self::Baz: Clone,
85 {
86     type Bar = Vec<Self::Baz>;
87     type Baz = T;
88     //~^ ERROR the trait bound `T: Clone` is not satisfied
89 }
90
91 // This one finally works, with `Clone` bounds on all assoc. types and the type
92 // parameter.
93 trait Foo4<T>
94 where
95     T: Clone,
96 {
97     type Bar: Clone = Vec<Self::Baz>;
98     type Baz: Clone = T;
99 }
100
101 fn main() {}