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