@@ -2387,39 +2387,135 @@ impl Copy for &'static Bar { } // error
23872387"## ,
23882388
23892389E0207 : r##"
2390- You declared an unused type parameter when implementing a trait on an object.
2391- Erroneous code example:
2390+ Any type parameter or lifetime parameter of an `impl` must meet at least one of
2391+ the following criteria:
2392+
2393+ - it appears in the self type of the impl
2394+ - for a trait impl, it appears in the trait reference
2395+ - it is bound as an associated type
2396+
2397+ ### Error example 1
2398+
2399+ Suppose we have a struct `Foo` and we would like to define some methods for it.
2400+ The following definition leads to a compiler error:
23922401
23932402```compile_fail
2394- trait MyTrait {
2395- fn get(&self) -> usize;
2403+ struct Foo;
2404+
2405+ impl<T: Default> Foo {
2406+ // error: the type parameter `T` is not constrained by the impl trait, self
2407+ // type, or predicates [E0207]
2408+ fn get(&self) -> T {
2409+ <T as Default>::default()
2410+ }
23962411}
2412+ ```
2413+
2414+ The problem is that the parameter `T` does not appear in the self type (`Foo`)
2415+ of the impl. In this case, we can fix the error by moving the type parameter
2416+ from the `impl` to the method `get`:
2417+
23972418
2419+ ```
23982420struct Foo;
23992421
2400- impl<T> MyTrait for Foo {
2401- fn get(&self) -> usize {
2402- 0
2422+ // Move the type parameter from the impl to the method
2423+ impl Foo {
2424+ fn get<T: Default>(&self) -> T {
2425+ <T as Default>::default()
24032426 }
24042427}
24052428```
24062429
2407- Please check your object definition and remove unused type
2408- parameter(s). Example:
2430+ ### Error example 2
24092431
2432+ As another example, suppose we have a `Maker` trait and want to establish a
2433+ type `FooMaker` that makes `Foo`s:
2434+
2435+ ```compile_fail
2436+ trait Maker {
2437+ type Item;
2438+ fn make(&mut self) -> Self::Item;
2439+ }
2440+
2441+ struct Foo<T> {
2442+ foo: T
2443+ }
2444+
2445+ struct FooMaker;
2446+
2447+ impl<T: Default> Maker for FooMaker {
2448+ // error: the type parameter `T` is not constrained by the impl trait, self
2449+ // type, or predicates [E0207]
2450+ type Item = Foo<T>;
2451+
2452+ fn make(&mut self) -> Foo<T> {
2453+ Foo { foo: <T as Default>::default() }
2454+ }
2455+ }
24102456```
2411- trait MyTrait {
2412- fn get(&self) -> usize;
2457+
2458+ This fails to compile because `T` does not appear in the trait or in the
2459+ implementing type.
2460+
2461+ One way to work around this is to introduce a phantom type parameter into
2462+ `FooMaker`, like so:
2463+
2464+ ```
2465+ use std::marker::PhantomData;
2466+
2467+ trait Maker {
2468+ type Item;
2469+ fn make(&mut self) -> Self::Item;
24132470}
24142471
2415- struct Foo;
2472+ struct Foo<T> {
2473+ foo: T
2474+ }
24162475
2417- impl MyTrait for Foo {
2418- fn get(&self) -> usize {
2419- 0
2476+ // Add a type parameter to `FooMaker`
2477+ struct FooMaker<T> {
2478+ phantom: PhantomData<T>,
2479+ }
2480+
2481+ impl<T: Default> Maker for FooMaker<T> {
2482+ type Item = Foo<T>;
2483+
2484+ fn make(&mut self) -> Foo<T> {
2485+ Foo {
2486+ foo: <T as Default>::default(),
2487+ }
2488+ }
2489+ }
2490+ ```
2491+
2492+ Another way is to do away with the associated type in `Maker` and use an input
2493+ type parameter instead:
2494+
2495+ ```
2496+ // Use a type parameter instead of an associated type here
2497+ trait Maker<Item> {
2498+ fn make(&mut self) -> Item;
2499+ }
2500+
2501+ struct Foo<T> {
2502+ foo: T
2503+ }
2504+
2505+ struct FooMaker;
2506+
2507+ impl<T: Default> Maker<Foo<T>> for FooMaker {
2508+ fn make(&mut self) -> Foo<T> {
2509+ Foo { foo: <T as Default>::default() }
24202510 }
24212511}
24222512```
2513+
2514+ ### Additional information
2515+
2516+ For more information, please see [RFC 447].
2517+
2518+ [RFC 447]: https://github.com/rust-lang/rfcs/blob/master/text/0447-no-unused-impl-parameters.md
24232519"## ,
24242520
24252521E0210 : r##"
0 commit comments