]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_error_codes/src/error_codes/E0207.md
Re-use std::sealed::Sealed in os/linux/process.
[rust.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