]> git.lizzy.rs Git - rust.git/blob - src/librustc_error_codes/error_codes/E0207.md
Rollup merge of #66576 - pnkfelix:more-robust-gdb-vec-printer, r=alexcrichton
[rust.git] / src / librustc_error_codes / error_codes / E0207.md
1 Any type parameter or lifetime parameter of an `impl` must meet at least one of
2 the following criteria:
3
4  - it appears in the _implementing type_ of the impl, e.g. `impl<T> Foo<T>`
5  - for a trait impl, it appears in the _implemented trait_, e.g.
6    `impl<T> SomeTrait<T> for Foo`
7  - it is bound as an associated type, e.g. `impl<T, U> SomeTrait for T
8    where T: AnotherTrait<AssocType=U>`
9
10 ### Error example 1
11
12 Suppose we have a struct `Foo` and we would like to define some methods for it.
13 The following definition leads to a compiler error:
14
15 ```compile_fail,E0207
16 struct Foo;
17
18 impl<T: Default> Foo {
19 // error: the type parameter `T` is not constrained by the impl trait, self
20 // type, or predicates [E0207]
21     fn get(&self) -> T {
22         <T as Default>::default()
23     }
24 }
25 ```
26
27 The problem is that the parameter `T` does not appear in the implementing type
28 (`Foo`) of the impl. In this case, we can fix the error by moving the type
29 parameter from the `impl` to the method `get`:
30
31
32 ```
33 struct Foo;
34
35 // Move the type parameter from the impl to the method
36 impl Foo {
37     fn get<T: Default>(&self) -> T {
38         <T as Default>::default()
39     }
40 }
41 ```
42
43 ### Error example 2
44
45 As another example, suppose we have a `Maker` trait and want to establish a
46 type `FooMaker` that makes `Foo`s:
47
48 ```compile_fail,E0207
49 trait Maker {
50     type Item;
51     fn make(&mut self) -> Self::Item;
52 }
53
54 struct Foo<T> {
55     foo: T
56 }
57
58 struct FooMaker;
59
60 impl<T: Default> Maker for FooMaker {
61 // error: the type parameter `T` is not constrained by the impl trait, self
62 // type, or predicates [E0207]
63     type Item = Foo<T>;
64
65     fn make(&mut self) -> Foo<T> {
66         Foo { foo: <T as Default>::default() }
67     }
68 }
69 ```
70
71 This fails to compile because `T` does not appear in the trait or in the
72 implementing type.
73
74 One way to work around this is to introduce a phantom type parameter into
75 `FooMaker`, like so:
76
77 ```
78 use std::marker::PhantomData;
79
80 trait Maker {
81     type Item;
82     fn make(&mut self) -> Self::Item;
83 }
84
85 struct Foo<T> {
86     foo: T
87 }
88
89 // Add a type parameter to `FooMaker`
90 struct FooMaker<T> {
91     phantom: PhantomData<T>,
92 }
93
94 impl<T: Default> Maker for FooMaker<T> {
95     type Item = Foo<T>;
96
97     fn make(&mut self) -> Foo<T> {
98         Foo {
99             foo: <T as Default>::default(),
100         }
101     }
102 }
103 ```
104
105 Another way is to do away with the associated type in `Maker` and use an input
106 type parameter instead:
107
108 ```
109 // Use a type parameter instead of an associated type here
110 trait Maker<Item> {
111     fn make(&mut self) -> Item;
112 }
113
114 struct Foo<T> {
115     foo: T
116 }
117
118 struct FooMaker;
119
120 impl<T: Default> Maker<Foo<T>> for FooMaker {
121     fn make(&mut self) -> Foo<T> {
122         Foo { foo: <T as Default>::default() }
123     }
124 }
125 ```
126
127 ### Additional information
128
129 For more information, please see [RFC 447].
130
131 [RFC 447]: https://github.com/rust-lang/rfcs/blob/master/text/0447-no-unused-impl-parameters.md