mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-26 14:43:24 +00:00
On E0204 suggest missing type param bounds
``` error[E0204]: the trait `Copy` may not be implemented for this type --> f42.rs:9:17 | 9 | #[derive(Debug, Copy, Clone)] | ^^^^ 10 | pub struct AABB<K>{ 11 | pub loc: Vector2<K>, | ------------------- this field does not implement `Copy` 12 | pub size: Vector2<K> | -------------------- this field does not implement `Copy` | note: the `Copy` impl for `Vector2<K>` requires that `K: Debug` --> f42.rs:11:5 | 11 | pub loc: Vector2<K>, | ^^^^^^^^^^^^^^^^^^^ note: the `Copy` impl for `Vector2<K>` requires that `K: Debug` --> f42.rs:12:5 | 12 | pub size: Vector2<K> | ^^^^^^^^^^^^^^^^^^^^ = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider restricting type parameter `K` | 10 | pub struct AABB<K: Debug>{ | +++++++ ``` Fix #89137.
This commit is contained in:
parent
395a09c3da
commit
8567b686f9
@ -272,7 +272,10 @@ pub fn suggest_constraining_type_params<'a>(
|
||||
continue;
|
||||
}
|
||||
|
||||
let constraint = constraints.iter().map(|&(c, _)| c).collect::<Vec<_>>().join(" + ");
|
||||
let mut constraint = constraints.iter().map(|&(c, _)| c).collect::<Vec<_>>();
|
||||
constraint.sort();
|
||||
constraint.dedup();
|
||||
let constraint = constraint.join(" + ");
|
||||
let mut suggest_restrict = |span, bound_list_non_empty| {
|
||||
suggestions.push((
|
||||
span,
|
||||
|
@ -11,8 +11,7 @@ use rustc_infer::infer;
|
||||
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
||||
use rustc_infer::infer::{RegionckMode, TyCtxtInferExt};
|
||||
use rustc_middle::ty::adjustment::CoerceUnsizedInfo;
|
||||
use rustc_middle::ty::TypeFoldable;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, suggest_constraining_type_params, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::misc::{can_type_implement_copy, CopyImplementationError};
|
||||
use rustc_trait_selection::traits::predicate_for_trait_def;
|
||||
@ -91,6 +90,19 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
|
||||
E0204,
|
||||
"the trait `Copy` may not be implemented for this type"
|
||||
);
|
||||
|
||||
// We'll try to suggest constraining type parameters to fulfill the requirements of
|
||||
// their `Copy` implementation.
|
||||
let mut generics = None;
|
||||
if let ty::Adt(def, _substs) = self_type.kind() {
|
||||
let self_def_id = def.did();
|
||||
if let Some(local) = self_def_id.as_local() {
|
||||
let self_item = tcx.hir().expect_item(local);
|
||||
generics = self_item.kind.generics();
|
||||
}
|
||||
}
|
||||
let mut bounds = vec![];
|
||||
|
||||
for (field, ty) in fields {
|
||||
let field_span = tcx.def_span(field.did);
|
||||
err.span_label(field_span, "this field does not implement `Copy`");
|
||||
@ -123,9 +135,34 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
|
||||
),
|
||||
);
|
||||
}
|
||||
if let ty::PredicateKind::Trait(ty::TraitPredicate {
|
||||
trait_ref,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
..
|
||||
}) = error_predicate.kind().skip_binder()
|
||||
{
|
||||
let ty = trait_ref.self_ty();
|
||||
if let ty::Param(_) = ty.kind() {
|
||||
bounds.push((
|
||||
format!("{ty}"),
|
||||
trait_ref.print_only_trait_path().to_string(),
|
||||
Some(trait_ref.def_id),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if let Some(generics) = generics {
|
||||
suggest_constraining_type_params(
|
||||
tcx,
|
||||
generics,
|
||||
&mut err,
|
||||
bounds.iter().map(|(param, constraint, def_id)| {
|
||||
(param.as_str(), constraint.as_str(), *def_id)
|
||||
}),
|
||||
);
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
Err(CopyImplementationError::NotAnAdt) => {
|
||||
|
@ -21,7 +21,7 @@ fn duplicate_tup2<A: Copy, B: Copy>(t: (A, B)) -> ((A, B), (A, B)) {
|
||||
(t, t) //~ use of moved value: `t`
|
||||
}
|
||||
|
||||
fn duplicate_custom<T: Trait + Copy>(t: S<T>) -> (S<T>, S<T>) {
|
||||
fn duplicate_custom<T: Copy + Trait>(t: S<T>) -> (S<T>, S<T>) {
|
||||
//~^ HELP consider restricting type parameter `T`
|
||||
(t, t) //~ use of moved value: `t`
|
||||
}
|
||||
@ -39,14 +39,14 @@ trait A {}
|
||||
trait B {}
|
||||
|
||||
// Test where bounds are added with different bound placements
|
||||
fn duplicate_custom_1<T: Trait + Copy>(t: S<T>) -> (S<T>, S<T>) where {
|
||||
fn duplicate_custom_1<T: Copy + Trait>(t: S<T>) -> (S<T>, S<T>) where {
|
||||
//~^ HELP consider restricting type parameter `T`
|
||||
(t, t) //~ use of moved value: `t`
|
||||
}
|
||||
|
||||
fn duplicate_custom_2<T>(t: S<T>) -> (S<T>, S<T>)
|
||||
where
|
||||
T: A + Trait + Copy,
|
||||
T: A + Copy + Trait,
|
||||
//~^ HELP consider further restricting this bound
|
||||
{
|
||||
(t, t) //~ use of moved value: `t`
|
||||
@ -54,14 +54,14 @@ where
|
||||
|
||||
fn duplicate_custom_3<T>(t: S<T>) -> (S<T>, S<T>)
|
||||
where
|
||||
T: A + Trait + Copy,
|
||||
T: A + Copy + Trait,
|
||||
//~^ HELP consider further restricting this bound
|
||||
T: B,
|
||||
{
|
||||
(t, t) //~ use of moved value: `t`
|
||||
}
|
||||
|
||||
fn duplicate_custom_4<T: A + Trait + Copy>(t: S<T>) -> (S<T>, S<T>)
|
||||
fn duplicate_custom_4<T: A + Copy + Trait>(t: S<T>) -> (S<T>, S<T>)
|
||||
//~^ HELP consider further restricting this bound
|
||||
where
|
||||
T: B,
|
||||
|
@ -75,7 +75,7 @@ LL | (t, t)
|
||||
|
|
||||
help: consider restricting type parameter `T`
|
||||
|
|
||||
LL | fn duplicate_custom<T: Trait + Copy>(t: S<T>) -> (S<T>, S<T>) {
|
||||
LL | fn duplicate_custom<T: Copy + Trait>(t: S<T>) -> (S<T>, S<T>) {
|
||||
| ++++++++++++++
|
||||
|
||||
error[E0382]: use of moved value: `t`
|
||||
@ -91,7 +91,7 @@ LL | (t, t)
|
||||
|
|
||||
help: consider restricting type parameter `T`
|
||||
|
|
||||
LL | fn duplicate_custom_1<T: Trait + Copy>(t: S<T>) -> (S<T>, S<T>) where {
|
||||
LL | fn duplicate_custom_1<T: Copy + Trait>(t: S<T>) -> (S<T>, S<T>) where {
|
||||
| ++++++++++++++
|
||||
|
||||
error[E0382]: use of moved value: `t`
|
||||
@ -107,7 +107,7 @@ LL | (t, t)
|
||||
|
|
||||
help: consider further restricting this bound
|
||||
|
|
||||
LL | T: A + Trait + Copy,
|
||||
LL | T: A + Copy + Trait,
|
||||
| ++++++++++++++
|
||||
|
||||
error[E0382]: use of moved value: `t`
|
||||
@ -123,7 +123,7 @@ LL | (t, t)
|
||||
|
|
||||
help: consider further restricting this bound
|
||||
|
|
||||
LL | T: A + Trait + Copy,
|
||||
LL | T: A + Copy + Trait,
|
||||
| ++++++++++++++
|
||||
|
||||
error[E0382]: use of moved value: `t`
|
||||
@ -139,7 +139,7 @@ LL | (t, t)
|
||||
|
|
||||
help: consider further restricting this bound
|
||||
|
|
||||
LL | fn duplicate_custom_4<T: A + Trait + Copy>(t: S<T>) -> (S<T>, S<T>)
|
||||
LL | fn duplicate_custom_4<T: A + Copy + Trait>(t: S<T>) -> (S<T>, S<T>)
|
||||
| ++++++++++++++
|
||||
|
||||
error[E0382]: use of moved value: `t`
|
||||
|
@ -0,0 +1,16 @@
|
||||
// run-rustfix
|
||||
use std::fmt::Debug;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Vector2<T: Debug + Copy + Clone>{
|
||||
pub x: T,
|
||||
pub y: T
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct AABB<K: Debug + std::marker::Copy>{
|
||||
pub loc: Vector2<K>, //~ ERROR the trait bound `K: Copy` is not satisfied
|
||||
pub size: Vector2<K>
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,16 @@
|
||||
// run-rustfix
|
||||
use std::fmt::Debug;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Vector2<T: Debug + Copy + Clone>{
|
||||
pub x: T,
|
||||
pub y: T
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct AABB<K: Debug>{
|
||||
pub loc: Vector2<K>, //~ ERROR the trait bound `K: Copy` is not satisfied
|
||||
pub size: Vector2<K>
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,19 @@
|
||||
error[E0277]: the trait bound `K: Copy` is not satisfied
|
||||
--> $DIR/missing-bound-in-derive-copy-impl-2.rs:12:14
|
||||
|
|
||||
LL | pub loc: Vector2<K>,
|
||||
| ^^^^^^^^^^ the trait `Copy` is not implemented for `K`
|
||||
|
|
||||
note: required by a bound in `Vector2`
|
||||
--> $DIR/missing-bound-in-derive-copy-impl-2.rs:5:31
|
||||
|
|
||||
LL | pub struct Vector2<T: Debug + Copy + Clone>{
|
||||
| ^^^^ required by this bound in `Vector2`
|
||||
help: consider further restricting this bound
|
||||
|
|
||||
LL | pub struct AABB<K: Debug + std::marker::Copy>{
|
||||
| +++++++++++++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
@ -0,0 +1,16 @@
|
||||
//run-rustfix
|
||||
use std::fmt::Debug;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Vector2<T: Debug + Copy + Clone>{
|
||||
pub x: T,
|
||||
pub y: T
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)] //~ ERROR the trait `Copy` may not be implemented for this type
|
||||
pub struct AABB<K: Copy + Debug>{
|
||||
pub loc: Vector2<K>,
|
||||
pub size: Vector2<K>
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,16 @@
|
||||
//run-rustfix
|
||||
use std::fmt::Debug;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Vector2<T: Debug + Copy + Clone>{
|
||||
pub x: T,
|
||||
pub y: T
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)] //~ ERROR the trait `Copy` may not be implemented for this type
|
||||
pub struct AABB<K: Copy>{
|
||||
pub loc: Vector2<K>,
|
||||
pub size: Vector2<K>
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,30 @@
|
||||
error[E0204]: the trait `Copy` may not be implemented for this type
|
||||
--> $DIR/missing-bound-in-derive-copy-impl-3.rs:10:17
|
||||
|
|
||||
LL | #[derive(Debug, Copy, Clone)]
|
||||
| ^^^^
|
||||
LL | pub struct AABB<K: Copy>{
|
||||
LL | pub loc: Vector2<K>,
|
||||
| ------------------- this field does not implement `Copy`
|
||||
LL | pub size: Vector2<K>
|
||||
| -------------------- this field does not implement `Copy`
|
||||
|
|
||||
note: the `Copy` impl for `Vector2<K>` requires that `K: Debug`
|
||||
--> $DIR/missing-bound-in-derive-copy-impl-3.rs:12:5
|
||||
|
|
||||
LL | pub loc: Vector2<K>,
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
note: the `Copy` impl for `Vector2<K>` requires that `K: Debug`
|
||||
--> $DIR/missing-bound-in-derive-copy-impl-3.rs:13:5
|
||||
|
|
||||
LL | pub size: Vector2<K>
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
= note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider further restricting this bound
|
||||
|
|
||||
LL | pub struct AABB<K: Copy + Debug>{
|
||||
| +++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0204`.
|
15
src/test/ui/suggestions/missing-bound-in-derive-copy-impl.rs
Normal file
15
src/test/ui/suggestions/missing-bound-in-derive-copy-impl.rs
Normal file
@ -0,0 +1,15 @@
|
||||
use std::fmt::Debug;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Vector2<T: Debug + Copy + Clone>{
|
||||
pub x: T,
|
||||
pub y: T
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)] //~ ERROR the trait `Copy` may not be implemented for this type
|
||||
pub struct AABB<K>{
|
||||
pub loc: Vector2<K>,
|
||||
pub size: Vector2<K>
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,30 @@
|
||||
error[E0204]: the trait `Copy` may not be implemented for this type
|
||||
--> $DIR/missing-bound-in-derive-copy-impl.rs:9:17
|
||||
|
|
||||
LL | #[derive(Debug, Copy, Clone)]
|
||||
| ^^^^
|
||||
LL | pub struct AABB<K>{
|
||||
LL | pub loc: Vector2<K>,
|
||||
| ------------------- this field does not implement `Copy`
|
||||
LL | pub size: Vector2<K>
|
||||
| -------------------- this field does not implement `Copy`
|
||||
|
|
||||
note: the `Copy` impl for `Vector2<K>` requires that `K: Debug`
|
||||
--> $DIR/missing-bound-in-derive-copy-impl.rs:11:5
|
||||
|
|
||||
LL | pub loc: Vector2<K>,
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
note: the `Copy` impl for `Vector2<K>` requires that `K: Debug`
|
||||
--> $DIR/missing-bound-in-derive-copy-impl.rs:12:5
|
||||
|
|
||||
LL | pub size: Vector2<K>
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
= note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider restricting type parameter `K`
|
||||
|
|
||||
LL | pub struct AABB<K: Debug>{
|
||||
| +++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0204`.
|
Loading…
Reference in New Issue
Block a user