Make implementation generic

This commit is contained in:
Lucas Kent 2022-02-12 17:43:21 +11:00
parent 8610edd014
commit ae212402d6
5 changed files with 45 additions and 37 deletions

View File

@ -1196,10 +1196,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Some(adt) if adt.did.is_local() => adt, Some(adt) if adt.did.is_local() => adt,
_ => continue, _ => continue,
}; };
let diagnostic_name = self.tcx.get_diagnostic_name(trait_pred.def_id()); if let Some(diagnostic_name) = self.tcx.get_diagnostic_name(trait_pred.def_id()) {
let can_derive = match diagnostic_name { let can_derive = match diagnostic_name {
Some(sym::Default) => !adt.is_enum(), sym::Default => !adt.is_enum(),
Some(
sym::Eq sym::Eq
| sym::PartialEq | sym::PartialEq
| sym::Ord | sym::Ord
@ -1207,24 +1206,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
| sym::Clone | sym::Clone
| sym::Copy | sym::Copy
| sym::Hash | sym::Hash
| sym::Debug, | sym::Debug => true,
) => true,
_ => false, _ => false,
}; };
if can_derive { if can_derive {
let self_name = trait_pred.self_ty().to_string(); let self_name = trait_pred.self_ty().to_string();
let self_span = self.tcx.def_span(adt.did); let self_span = self.tcx.def_span(adt.did);
if let Some(sym::Ord) = diagnostic_name { use crate::rustc_middle::ty::ToPolyTraitRef;
derives.push((self_name.clone(), self_span.clone(), "PartialOrd".to_string())); if let Some(poly_trait_ref) = pred.to_opt_poly_trait_pred() {
} for super_trait in rustc_middle::traits::util::supertraits(
if let Some(sym::Eq) = diagnostic_name { self.tcx,
derives.push((self_name.clone(), self_span.clone(), "PartialEq".to_string())); poly_trait_ref.to_poly_trait_ref(),
} ) {
if let Some(parent_diagnostic_name) =
self.tcx.get_diagnostic_name(super_trait.def_id())
{
derives.push(( derives.push((
self_name, self_name.clone(),
self_span, self_span.clone(),
trait_pred.trait_ref.print_only_trait_name().to_string(), parent_diagnostic_name.to_string(),
)); ));
}
}
}
derives.push((self_name, self_span, diagnostic_name.to_string()));
} else {
traits.push(self.tcx.def_span(trait_pred.def_id()));
}
} else { } else {
traits.push(self.tcx.def_span(trait_pred.def_id())); traits.push(self.tcx.def_span(trait_pred.def_id()));
} }

View File

@ -272,9 +272,9 @@ note: an implementation of `PartialOrd<_>` might be missing for `A`
| |
LL | struct A; LL | struct A;
| ^^^^^^^^^ must implement `PartialOrd<_>` | ^^^^^^^^^ must implement `PartialOrd<_>`
help: consider annotating `A` with `#[derive(PartialOrd)]` help: consider annotating `A` with `#[derive(PartialEq, PartialOrd)]`
| |
LL | #[derive(PartialOrd)] LL | #[derive(PartialEq, PartialOrd)]
| |
error[E0369]: binary operation `<=` cannot be applied to type `A` error[E0369]: binary operation `<=` cannot be applied to type `A`
@ -290,9 +290,9 @@ note: an implementation of `PartialOrd<_>` might be missing for `A`
| |
LL | struct A; LL | struct A;
| ^^^^^^^^^ must implement `PartialOrd<_>` | ^^^^^^^^^ must implement `PartialOrd<_>`
help: consider annotating `A` with `#[derive(PartialOrd)]` help: consider annotating `A` with `#[derive(PartialEq, PartialOrd)]`
| |
LL | #[derive(PartialOrd)] LL | #[derive(PartialEq, PartialOrd)]
| |
error[E0369]: binary operation `>` cannot be applied to type `A` error[E0369]: binary operation `>` cannot be applied to type `A`
@ -308,9 +308,9 @@ note: an implementation of `PartialOrd<_>` might be missing for `A`
| |
LL | struct A; LL | struct A;
| ^^^^^^^^^ must implement `PartialOrd<_>` | ^^^^^^^^^ must implement `PartialOrd<_>`
help: consider annotating `A` with `#[derive(PartialOrd)]` help: consider annotating `A` with `#[derive(PartialEq, PartialOrd)]`
| |
LL | #[derive(PartialOrd)] LL | #[derive(PartialEq, PartialOrd)]
| |
error[E0369]: binary operation `>=` cannot be applied to type `A` error[E0369]: binary operation `>=` cannot be applied to type `A`
@ -326,9 +326,9 @@ note: an implementation of `PartialOrd<_>` might be missing for `A`
| |
LL | struct A; LL | struct A;
| ^^^^^^^^^ must implement `PartialOrd<_>` | ^^^^^^^^^ must implement `PartialOrd<_>`
help: consider annotating `A` with `#[derive(PartialOrd)]` help: consider annotating `A` with `#[derive(PartialEq, PartialOrd)]`
| |
LL | #[derive(PartialOrd)] LL | #[derive(PartialEq, PartialOrd)]
| |
error: aborting due to 15 previous errors error: aborting due to 15 previous errors

View File

@ -51,9 +51,9 @@ LL | foo.use_ord();
| |
= note: the following trait bounds were not satisfied: = note: the following trait bounds were not satisfied:
`NoDerives: Ord` `NoDerives: Ord`
help: consider annotating `NoDerives` with `#[derive(Ord, PartialOrd)]` help: consider annotating `NoDerives` with `#[derive(Eq, Ord, PartialEq, PartialOrd)]`
| |
LL | #[derive(Ord, PartialOrd)] LL | #[derive(Eq, Ord, PartialEq, PartialOrd)]
| |
error[E0599]: the method `use_ord_and_partial_ord` exists for struct `Object<NoDerives>`, but its trait bounds were not satisfied error[E0599]: the method `use_ord_and_partial_ord` exists for struct `Object<NoDerives>`, but its trait bounds were not satisfied
@ -74,9 +74,9 @@ LL | foo.use_ord_and_partial_ord();
= note: the following trait bounds were not satisfied: = note: the following trait bounds were not satisfied:
`NoDerives: Ord` `NoDerives: Ord`
`NoDerives: PartialOrd` `NoDerives: PartialOrd`
help: consider annotating `NoDerives` with `#[derive(Ord, PartialOrd)]` help: consider annotating `NoDerives` with `#[derive(Eq, Ord, PartialEq, PartialOrd)]`
| |
LL | #[derive(Ord, PartialOrd)] LL | #[derive(Eq, Ord, PartialEq, PartialOrd)]
| |
error: aborting due to 4 previous errors error: aborting due to 4 previous errors

View File

@ -16,9 +16,9 @@ LL | let w = u.clone();
= note: the following trait bounds were not satisfied: = note: the following trait bounds were not satisfied:
`CloneNoCopy: Copy` `CloneNoCopy: Copy`
which is required by `U5<CloneNoCopy>: Clone` which is required by `U5<CloneNoCopy>: Clone`
help: consider annotating `CloneNoCopy` with `#[derive(Copy)]` help: consider annotating `CloneNoCopy` with `#[derive(Clone, Copy)]`
| |
LL | #[derive(Copy)] LL | #[derive(Clone, Copy)]
| |
error[E0277]: the trait bound `U1: Copy` is not satisfied error[E0277]: the trait bound `U1: Copy` is not satisfied

View File

@ -16,9 +16,9 @@ LL | let w = u.clone();
= note: the following trait bounds were not satisfied: = note: the following trait bounds were not satisfied:
`CloneNoCopy: Copy` `CloneNoCopy: Copy`
which is required by `U5<CloneNoCopy>: Clone` which is required by `U5<CloneNoCopy>: Clone`
help: consider annotating `CloneNoCopy` with `#[derive(Copy)]` help: consider annotating `CloneNoCopy` with `#[derive(Clone, Copy)]`
| |
LL | #[derive(Copy)] LL | #[derive(Clone, Copy)]
| |
error[E0277]: the trait bound `U1: Copy` is not satisfied error[E0277]: the trait bound `U1: Copy` is not satisfied