-
Notifications
You must be signed in to change notification settings - Fork 12.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Suggest
derive(Trait)
or T: Trait
from transitive obligation in s…
…ome cases With code like the following ```rust struct Ctx<A> { a_map: HashMap<String, B<A>>, } struct B<A> { a: A, } ``` the derived trait will have an implicit restriction on `A: Clone` for both types. When referenced as follows: ```rust fn foo<Z>(ctx: &mut Ctx<Z>) { let a_map = ctx.a_map.clone(); //~ ERROR E0599 } ``` suggest constraining `Z`: ``` error[E0599]: the method `clone` exists for struct `HashMap<String, B<Z>>`, but its trait bounds were not satisfied --> $DIR/type-or-type-param-missing-transitive-trait-contraint.rs:16:27 | LL | struct B<A> { | ----------- doesn't satisfy `B<Z>: Clone` ... LL | let a_map = ctx.a_map.clone(); | ^^^^^ method cannot be called on `HashMap<String, B<Z>>` due to unsatisfied trait bounds | = note: the following trait bounds were not satisfied: `B<Z>: Clone` which is required by `HashMap<String, B<Z>>: Clone` help: consider restricting type parameter `Z` | LL | fn foo<Z: std::clone::Clone>(ctx: &mut Ctx<Z>) { | +++++++++++++++++++ ``` When referenced as follows, with a specific type `S`: ```rust struct S; fn bar(ctx: &mut Ctx<S>) { let a_map = ctx.a_map.clone(); //~ ERROR E0599 } ``` suggest `derive`ing the appropriate trait on the local type: ``` error[E0599]: the method `clone` exists for struct `HashMap<String, B<S>>`, but its trait bounds were not satisfied --> $DIR/type-or-type-param-missing-transitive-trait-contraint.rs:21:27 | LL | struct B<A> { | ----------- doesn't satisfy `B<S>: Clone` ... LL | let a_map = ctx.a_map.clone(); | ^^^^^ method cannot be called on `HashMap<String, B<S>>` due to unsatisfied trait bounds | = note: the following trait bounds were not satisfied: `B<S>: Clone` which is required by `HashMap<String, B<S>>: Clone` help: consider annotating `S` with `#[derive(Clone)]` | LL + #[derive(Clone)] LL | struct S; | ```
- Loading branch information
Showing
5 changed files
with
192 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
25 changes: 25 additions & 0 deletions
25
tests/ui/suggestions/type-or-type-param-missing-transitive-trait-contraint.fixed
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
//@ run-rustfix | ||
#![allow(warnings)] | ||
use std::collections::HashMap; | ||
|
||
#[derive(Clone)] | ||
struct Ctx<A> { | ||
a_map: HashMap<String, B<A>>, | ||
} | ||
|
||
#[derive(Clone)] | ||
struct B<A> { | ||
a: A, | ||
} | ||
|
||
fn foo<Z: std::clone::Clone>(ctx: &mut Ctx<Z>) { | ||
let a_map = ctx.a_map.clone(); //~ ERROR E0599 | ||
} | ||
|
||
#[derive(Clone)] | ||
struct S; | ||
fn bar(ctx: &mut Ctx<S>) { | ||
let a_map = ctx.a_map.clone(); //~ ERROR E0599 | ||
} | ||
|
||
fn main() {} |
24 changes: 24 additions & 0 deletions
24
tests/ui/suggestions/type-or-type-param-missing-transitive-trait-contraint.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
//@ run-rustfix | ||
#![allow(warnings)] | ||
use std::collections::HashMap; | ||
|
||
#[derive(Clone)] | ||
struct Ctx<A> { | ||
a_map: HashMap<String, B<A>>, | ||
} | ||
|
||
#[derive(Clone)] | ||
struct B<A> { | ||
a: A, | ||
} | ||
|
||
fn foo<Z>(ctx: &mut Ctx<Z>) { | ||
let a_map = ctx.a_map.clone(); //~ ERROR E0599 | ||
} | ||
|
||
struct S; | ||
fn bar(ctx: &mut Ctx<S>) { | ||
let a_map = ctx.a_map.clone(); //~ ERROR E0599 | ||
} | ||
|
||
fn main() {} |
38 changes: 38 additions & 0 deletions
38
tests/ui/suggestions/type-or-type-param-missing-transitive-trait-contraint.stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
error[E0599]: the method `clone` exists for struct `HashMap<String, B<Z>>`, but its trait bounds were not satisfied | ||
--> $DIR/type-or-type-param-missing-transitive-trait-contraint.rs:16:27 | ||
| | ||
LL | struct B<A> { | ||
| ----------- doesn't satisfy `B<Z>: Clone` | ||
... | ||
LL | let a_map = ctx.a_map.clone(); | ||
| ^^^^^ method cannot be called on `HashMap<String, B<Z>>` due to unsatisfied trait bounds | ||
| | ||
= note: the following trait bounds were not satisfied: | ||
`B<Z>: Clone` | ||
which is required by `HashMap<String, B<Z>>: Clone` | ||
help: consider restricting type parameter `Z` | ||
| | ||
LL | fn foo<Z: std::clone::Clone>(ctx: &mut Ctx<Z>) { | ||
| +++++++++++++++++++ | ||
|
||
error[E0599]: the method `clone` exists for struct `HashMap<String, B<S>>`, but its trait bounds were not satisfied | ||
--> $DIR/type-or-type-param-missing-transitive-trait-contraint.rs:21:27 | ||
| | ||
LL | struct B<A> { | ||
| ----------- doesn't satisfy `B<S>: Clone` | ||
... | ||
LL | let a_map = ctx.a_map.clone(); | ||
| ^^^^^ method cannot be called on `HashMap<String, B<S>>` due to unsatisfied trait bounds | ||
| | ||
= note: the following trait bounds were not satisfied: | ||
`B<S>: Clone` | ||
which is required by `HashMap<String, B<S>>: Clone` | ||
help: consider annotating `S` with `#[derive(Clone)]` | ||
| | ||
LL + #[derive(Clone)] | ||
LL | struct S; | ||
| | ||
|
||
error: aborting due to 2 previous errors | ||
|
||
For more information about this error, try `rustc --explain E0599`. |