Skip to content

Commit

Permalink
Rollup merge of rust-lang#95525 - ohno418:suggest-derivable-trait-E02…
Browse files Browse the repository at this point in the history
…77, r=compiler-errors

Suggest derivable trait on E0277 error

Closes rust-lang#95099 .
  • Loading branch information
Dylan-DPC authored Apr 5, 2022
2 parents 634770c + b831b60 commit e028d93
Show file tree
Hide file tree
Showing 61 changed files with 340 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
);
self.note_version_mismatch(&mut err, &trait_ref);
self.suggest_remove_await(&obligation, &mut err);
self.suggest_derive(&obligation, &mut err, trait_predicate);

if Some(trait_ref.def_id()) == tcx.lang_items().try_trait() {
self.suggest_await_before_try(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,13 @@ pub trait InferCtxtExt<'tcx> {
err: &mut Diagnostic,
trait_ref: &ty::PolyTraitRef<'tcx>,
);

fn suggest_derive(
&self,
obligation: &PredicateObligation<'tcx>,
err: &mut Diagnostic,
trait_pred: ty::PolyTraitPredicate<'tcx>,
);
}

fn predicate_constraint(generics: &hir::Generics<'_>, pred: String) -> (Span, String) {
Expand Down Expand Up @@ -2651,6 +2658,68 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
_ => {}
}
}

fn suggest_derive(
&self,
obligation: &PredicateObligation<'tcx>,
err: &mut Diagnostic,
trait_pred: ty::PolyTraitPredicate<'tcx>,
) {
let Some(diagnostic_name) = self.tcx.get_diagnostic_name(trait_pred.def_id()) else {
return;
};
let (adt, substs) = match trait_pred.skip_binder().self_ty().kind() {
ty::Adt(adt, substs) if adt.did().is_local() => (adt, substs),
_ => return,
};
let can_derive = {
let is_derivable_trait = match diagnostic_name {
sym::Default => !adt.is_enum(),
sym::PartialEq | sym::PartialOrd => {
let rhs_ty = trait_pred.skip_binder().trait_ref.substs.type_at(1);
trait_pred.skip_binder().self_ty() == rhs_ty
}
sym::Eq | sym::Ord | sym::Clone | sym::Copy | sym::Hash | sym::Debug => true,
_ => false,
};
is_derivable_trait &&
// Ensure all fields impl the trait.
adt.all_fields().all(|field| {
let field_ty = field.ty(self.tcx, substs);
let trait_substs = match diagnostic_name {
sym::PartialEq | sym::PartialOrd => {
self.tcx.mk_substs_trait(field_ty, &[field_ty.into()])
}
_ => self.tcx.mk_substs_trait(field_ty, &[]),
};
let trait_pred = trait_pred.map_bound_ref(|tr| ty::TraitPredicate {
trait_ref: ty::TraitRef {
substs: trait_substs,
..trait_pred.skip_binder().trait_ref
},
..*tr
});
let field_obl = Obligation::new(
obligation.cause.clone(),
obligation.param_env,
trait_pred.to_predicate(self.tcx),
);
self.predicate_must_hold_modulo_regions(&field_obl)
})
};
if can_derive {
err.span_suggestion_verbose(
self.tcx.def_span(adt.did()).shrink_to_lo(),
&format!(
"consider annotating `{}` with `#[derive({})]`",
trait_pred.skip_binder().self_ty(),
diagnostic_name.to_string(),
),
format!("#[derive({})]\n", diagnostic_name.to_string()),
Applicability::MaybeIncorrect,
);
}
}
}

/// Collect all the returned expressions within the input expression.
Expand Down
8 changes: 8 additions & 0 deletions src/test/ui/array-slice-vec/repeat_empty_ok.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ LL | let headers = [Header{value: &[]}; 128];
| ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Header<'_>`
|
= note: the `Copy` trait is required because the repeated element will be copied
help: consider annotating `Header<'_>` with `#[derive(Copy)]`
|
LL | #[derive(Copy)]
|

error[E0277]: the trait bound `Header<'_>: Copy` is not satisfied
--> $DIR/repeat_empty_ok.rs:13:19
Expand All @@ -13,6 +17,10 @@ LL | let headers = [Header{value: &[0]}; 128];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Header<'_>`
|
= note: the `Copy` trait is required because the repeated element will be copied
help: consider annotating `Header<'_>` with `#[derive(Copy)]`
|
LL | #[derive(Copy)]
|

error: aborting due to 2 previous errors

Expand Down
8 changes: 8 additions & 0 deletions src/test/ui/associated-types/defaults-suitability.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ note: required by a bound in `Tr::Ty`
|
LL | type Ty: Clone = NotClone;
| ^^^^^ required by this bound in `Tr::Ty`
help: consider annotating `NotClone` with `#[derive(Clone)]`
|
LL | #[derive(Clone)]
|

error[E0277]: the trait bound `NotClone: Clone` is not satisfied
--> $DIR/defaults-suitability.rs:22:15
Expand All @@ -24,6 +28,10 @@ LL | Self::Ty: Clone,
LL | {
LL | type Ty = NotClone;
| -- required by a bound in this
help: consider annotating `NotClone` with `#[derive(Clone)]`
|
LL | #[derive(Clone)]
|

error[E0277]: the trait bound `T: Clone` is not satisfied
--> $DIR/defaults-suitability.rs:28:23
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ LL | x: Error
| ^^^^^^^^ the trait `Clone` is not implemented for `Error`
|
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `Error` with `#[derive(Clone)]`
|
LL | #[derive(Clone)]
|

error: aborting due to previous error

Expand Down
4 changes: 4 additions & 0 deletions src/test/ui/derives/derives-span-Clone-enum.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ LL | Error
| ^^^^^ the trait `Clone` is not implemented for `Error`
|
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `Error` with `#[derive(Clone)]`
|
LL | #[derive(Clone)]
|

error: aborting due to previous error

Expand Down
4 changes: 4 additions & 0 deletions src/test/ui/derives/derives-span-Clone-struct.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ LL | x: Error
| ^^^^^^^^ the trait `Clone` is not implemented for `Error`
|
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `Error` with `#[derive(Clone)]`
|
LL | #[derive(Clone)]
|

error: aborting due to previous error

Expand Down
4 changes: 4 additions & 0 deletions src/test/ui/derives/derives-span-Clone-tuple-struct.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ LL | Error
| ^^^^^ the trait `Clone` is not implemented for `Error`
|
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `Error` with `#[derive(Clone)]`
|
LL | #[derive(Clone)]
|

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ LL | x: Error
= help: the trait `Debug` is not implemented for `Error`
= note: add `#[derive(Debug)]` to `Error` or manually `impl Debug for Error`
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `Error` with `#[derive(Debug)]`
|
LL | #[derive(Debug)]
|

error: aborting due to previous error

Expand Down
4 changes: 4 additions & 0 deletions src/test/ui/derives/derives-span-Debug-enum.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ LL | Error
= help: the trait `Debug` is not implemented for `Error`
= note: add `#[derive(Debug)]` to `Error` or manually `impl Debug for Error`
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `Error` with `#[derive(Debug)]`
|
LL | #[derive(Debug)]
|

error: aborting due to previous error

Expand Down
4 changes: 4 additions & 0 deletions src/test/ui/derives/derives-span-Debug-struct.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ LL | x: Error
= help: the trait `Debug` is not implemented for `Error`
= note: add `#[derive(Debug)]` to `Error` or manually `impl Debug for Error`
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `Error` with `#[derive(Debug)]`
|
LL | #[derive(Debug)]
|

error: aborting due to previous error

Expand Down
4 changes: 4 additions & 0 deletions src/test/ui/derives/derives-span-Debug-tuple-struct.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ LL | Error
= help: the trait `Debug` is not implemented for `Error`
= note: add `#[derive(Debug)]` to `Error` or manually `impl Debug for Error`
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `Error` with `#[derive(Debug)]`
|
LL | #[derive(Debug)]
|

error: aborting due to previous error

Expand Down
4 changes: 4 additions & 0 deletions src/test/ui/derives/derives-span-Default-struct.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ LL | x: Error
| ^^^^^^^^ the trait `Default` is not implemented for `Error`
|
= note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `Error` with `#[derive(Default)]`
|
LL | #[derive(Default)]
|

error: aborting due to previous error

Expand Down
4 changes: 4 additions & 0 deletions src/test/ui/derives/derives-span-Default-tuple-struct.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ LL | Error
| ^^^^^ the trait `Default` is not implemented for `Error`
|
= note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `Error` with `#[derive(Default)]`
|
LL | #[derive(Default)]
|

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ note: required by a bound in `AssertParamIsEq`
LL | pub struct AssertParamIsEq<T: Eq + ?Sized> {
| ^^ required by this bound in `AssertParamIsEq`
= note: this error originates in the derive macro `Eq` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `Error` with `#[derive(Eq)]`
|
LL | #[derive(Eq)]
|

error: aborting due to previous error

Expand Down
4 changes: 4 additions & 0 deletions src/test/ui/derives/derives-span-Eq-enum.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ note: required by a bound in `AssertParamIsEq`
LL | pub struct AssertParamIsEq<T: Eq + ?Sized> {
| ^^ required by this bound in `AssertParamIsEq`
= note: this error originates in the derive macro `Eq` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `Error` with `#[derive(Eq)]`
|
LL | #[derive(Eq)]
|

error: aborting due to previous error

Expand Down
4 changes: 4 additions & 0 deletions src/test/ui/derives/derives-span-Eq-struct.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ note: required by a bound in `AssertParamIsEq`
LL | pub struct AssertParamIsEq<T: Eq + ?Sized> {
| ^^ required by this bound in `AssertParamIsEq`
= note: this error originates in the derive macro `Eq` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `Error` with `#[derive(Eq)]`
|
LL | #[derive(Eq)]
|

error: aborting due to previous error

Expand Down
4 changes: 4 additions & 0 deletions src/test/ui/derives/derives-span-Eq-tuple-struct.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ note: required by a bound in `AssertParamIsEq`
LL | pub struct AssertParamIsEq<T: Eq + ?Sized> {
| ^^ required by this bound in `AssertParamIsEq`
= note: this error originates in the derive macro `Eq` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `Error` with `#[derive(Eq)]`
|
LL | #[derive(Eq)]
|

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ LL | x: Error
| ^^^^^^^^ the trait `Hash` is not implemented for `Error`
|
= note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `Error` with `#[derive(Hash)]`
|
LL | #[derive(Hash)]
|

error: aborting due to previous error

Expand Down
4 changes: 4 additions & 0 deletions src/test/ui/derives/derives-span-Hash-enum.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ LL | Error
| ^^^^^ the trait `Hash` is not implemented for `Error`
|
= note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `Error` with `#[derive(Hash)]`
|
LL | #[derive(Hash)]
|

error: aborting due to previous error

Expand Down
4 changes: 4 additions & 0 deletions src/test/ui/derives/derives-span-Hash-struct.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ LL | x: Error
| ^^^^^^^^ the trait `Hash` is not implemented for `Error`
|
= note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `Error` with `#[derive(Hash)]`
|
LL | #[derive(Hash)]
|

error: aborting due to previous error

Expand Down
4 changes: 4 additions & 0 deletions src/test/ui/derives/derives-span-Hash-tuple-struct.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ LL | Error
| ^^^^^ the trait `Hash` is not implemented for `Error`
|
= note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `Error` with `#[derive(Hash)]`
|
LL | #[derive(Hash)]
|

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ LL | x: Error
| ^^^^^^^^ the trait `Ord` is not implemented for `Error`
|
= note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `Error` with `#[derive(Ord)]`
|
LL | #[derive(Ord)]
|

error: aborting due to previous error

Expand Down
4 changes: 4 additions & 0 deletions src/test/ui/derives/derives-span-Ord-enum.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ LL | Error
| ^^^^^ the trait `Ord` is not implemented for `Error`
|
= note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `Error` with `#[derive(Ord)]`
|
LL | #[derive(Ord)]
|

error: aborting due to previous error

Expand Down
4 changes: 4 additions & 0 deletions src/test/ui/derives/derives-span-Ord-struct.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ LL | x: Error
| ^^^^^^^^ the trait `Ord` is not implemented for `Error`
|
= note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `Error` with `#[derive(Ord)]`
|
LL | #[derive(Ord)]
|

error: aborting due to previous error

Expand Down
4 changes: 4 additions & 0 deletions src/test/ui/derives/derives-span-Ord-tuple-struct.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ LL | Error
| ^^^^^ the trait `Ord` is not implemented for `Error`
|
= note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `Error` with `#[derive(Ord)]`
|
LL | #[derive(Ord)]
|

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ LL | x: Error
|
= help: the trait `PartialOrd` is not implemented for `Error`
= note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `Error` with `#[derive(PartialOrd)]`
|
LL | #[derive(PartialOrd)]
|

error: aborting due to previous error

Expand Down
4 changes: 4 additions & 0 deletions src/test/ui/derives/derives-span-PartialOrd-enum.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ LL | Error
|
= help: the trait `PartialOrd` is not implemented for `Error`
= note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `Error` with `#[derive(PartialOrd)]`
|
LL | #[derive(PartialOrd)]
|

error: aborting due to previous error

Expand Down
Loading

0 comments on commit e028d93

Please sign in to comment.