Use impl generics when suggesting fix on copy impl
This commit is contained in:
parent
6dbae3ad19
commit
1390220ff2
@ -94,14 +94,6 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
|
||||
|
||||
// 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 errors: BTreeMap<_, Vec<_>> = Default::default();
|
||||
let mut bounds = vec![];
|
||||
|
||||
@ -163,16 +155,14 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
|
||||
&format!("the `Copy` impl for `{}` requires that `{}`", ty, error_predicate),
|
||||
);
|
||||
}
|
||||
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)
|
||||
}),
|
||||
);
|
||||
}
|
||||
suggest_constraining_type_params(
|
||||
tcx,
|
||||
tcx.hir().get_generics(impl_did).expect("impls always have generics"),
|
||||
&mut err,
|
||||
bounds.iter().map(|(param, constraint, def_id)| {
|
||||
(param.as_str(), constraint.as_str(), *def_id)
|
||||
}),
|
||||
);
|
||||
err.emit();
|
||||
}
|
||||
Err(CopyImplementationError::NotAnAdt) => {
|
||||
|
@ -0,0 +1,19 @@
|
||||
// run-rustfix
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Wrapper<T>(T);
|
||||
|
||||
struct OnlyCopyIfDisplay<T>(std::marker::PhantomData<T>);
|
||||
|
||||
impl<T: std::fmt::Display> Clone for OnlyCopyIfDisplay<T> {
|
||||
fn clone(&self) -> Self {
|
||||
OnlyCopyIfDisplay(std::marker::PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: std::fmt::Display> Copy for OnlyCopyIfDisplay<T> {}
|
||||
|
||||
impl<S: std::fmt::Display> Copy for Wrapper<OnlyCopyIfDisplay<S>> {}
|
||||
//~^ ERROR the trait `Copy` may not be implemented for this type
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,19 @@
|
||||
// run-rustfix
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Wrapper<T>(T);
|
||||
|
||||
struct OnlyCopyIfDisplay<T>(std::marker::PhantomData<T>);
|
||||
|
||||
impl<T: std::fmt::Display> Clone for OnlyCopyIfDisplay<T> {
|
||||
fn clone(&self) -> Self {
|
||||
OnlyCopyIfDisplay(std::marker::PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: std::fmt::Display> Copy for OnlyCopyIfDisplay<T> {}
|
||||
|
||||
impl<S> Copy for Wrapper<OnlyCopyIfDisplay<S>> {}
|
||||
//~^ ERROR the trait `Copy` may not be implemented for this type
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,22 @@
|
||||
error[E0204]: the trait `Copy` may not be implemented for this type
|
||||
--> $DIR/missing-bound-in-manual-copy-impl-2.rs:16:9
|
||||
|
|
||||
LL | struct Wrapper<T>(T);
|
||||
| - this field does not implement `Copy`
|
||||
...
|
||||
LL | impl<S> Copy for Wrapper<OnlyCopyIfDisplay<S>> {}
|
||||
| ^^^^
|
||||
|
|
||||
note: the `Copy` impl for `OnlyCopyIfDisplay<S>` requires that `S: std::fmt::Display`
|
||||
--> $DIR/missing-bound-in-manual-copy-impl-2.rs:4:19
|
||||
|
|
||||
LL | struct Wrapper<T>(T);
|
||||
| ^
|
||||
help: consider restricting type parameter `S`
|
||||
|
|
||||
LL | impl<S: std::fmt::Display> Copy for Wrapper<OnlyCopyIfDisplay<S>> {}
|
||||
| +++++++++++++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0204`.
|
@ -0,0 +1,9 @@
|
||||
// run-rustfix
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Wrapper<T>(T);
|
||||
|
||||
impl<S: Copy> Copy for Wrapper<S> {}
|
||||
//~^ ERROR the trait `Copy` may not be implemented for this type
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,9 @@
|
||||
// run-rustfix
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Wrapper<T>(T);
|
||||
|
||||
impl<S> Copy for Wrapper<S> {}
|
||||
//~^ ERROR the trait `Copy` may not be implemented for this type
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,17 @@
|
||||
error[E0204]: the trait `Copy` may not be implemented for this type
|
||||
--> $DIR/missing-bound-in-manual-copy-impl.rs:6:9
|
||||
|
|
||||
LL | struct Wrapper<T>(T);
|
||||
| - this field does not implement `Copy`
|
||||
LL |
|
||||
LL | impl<S> Copy for Wrapper<S> {}
|
||||
| ^^^^
|
||||
|
|
||||
help: consider restricting type parameter `S`
|
||||
|
|
||||
LL | impl<S: Copy> Copy for Wrapper<S> {}
|
||||
| ++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0204`.
|
Loading…
x
Reference in New Issue
Block a user