diff options
| -rw-r--r-- | compiler/rustc_typeck/src/check/method/suggest.rs | 17 | ||||
| -rw-r--r-- | src/test/ui/derives/issue-91550.rs | 29 | ||||
| -rw-r--r-- | src/test/ui/derives/issue-91550.stderr | 84 |
3 files changed, 126 insertions, 4 deletions
diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 81e2b3bc162..5b06cc33302 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -1196,7 +1196,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some(adt) if adt.did.is_local() => adt, _ => continue, }; - let can_derive = match self.tcx.get_diagnostic_name(trait_pred.def_id()) { + let diagnostic_name = self.tcx.get_diagnostic_name(trait_pred.def_id()); + let can_derive = match diagnostic_name { Some(sym::Default) => !adt.is_enum(), Some( sym::Eq @@ -1211,10 +1212,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => false, }; if can_derive { + let self_name = trait_pred.self_ty().to_string(); + let self_span = self.tcx.def_span(adt.did); + if let Some(sym::Ord) = diagnostic_name { + derives.push((self_name.clone(), self_span.clone(), "PartialOrd".to_string())); + } + if let Some(sym::Eq) = diagnostic_name { + derives.push((self_name.clone(), self_span.clone(), "PartialEq".to_string())); + } derives.push(( - format!("{}", trait_pred.self_ty()), - self.tcx.def_span(adt.did), - format!("{}", trait_pred.trait_ref.print_only_trait_name()), + self_name, + self_span, + trait_pred.trait_ref.print_only_trait_name().to_string(), )); } else { traits.push(self.tcx.def_span(trait_pred.def_id())); diff --git a/src/test/ui/derives/issue-91550.rs b/src/test/ui/derives/issue-91550.rs new file mode 100644 index 00000000000..56fd5ffa89e --- /dev/null +++ b/src/test/ui/derives/issue-91550.rs @@ -0,0 +1,29 @@ +use std::collections::HashSet; + +/// natural case from the issue +struct Value(u32); + +fn main() { + let hs = HashSet::<Value>::new(); + hs.insert(Value(0)); //~ ERROR +} + +/// synthetic cases +pub struct NoDerives; + +struct Object<T>(T); +impl<T: Eq> Object<T> { + fn use_eq(&self) {} +} +impl<T: Ord> Object<T> { + fn use_ord(&self) {} +} +impl<T: Ord + PartialOrd> Object<T> { + fn use_ord_and_partial_ord(&self) {} +} + +fn function(foo: Object<NoDerives>) { + foo.use_eq(); //~ ERROR + foo.use_ord(); //~ ERROR + foo.use_ord_and_partial_ord(); //~ ERROR +} diff --git a/src/test/ui/derives/issue-91550.stderr b/src/test/ui/derives/issue-91550.stderr new file mode 100644 index 00000000000..2b88c35c6a3 --- /dev/null +++ b/src/test/ui/derives/issue-91550.stderr @@ -0,0 +1,84 @@ +error[E0599]: the method `insert` exists for struct `HashSet<Value>`, but its trait bounds were not satisfied + --> $DIR/issue-91550.rs:8:8 + | +LL | struct Value(u32); + | ------------------ + | | + | doesn't satisfy `Value: Eq` + | doesn't satisfy `Value: Hash` +... +LL | hs.insert(Value(0)); + | ^^^^^^ method cannot be called on `HashSet<Value>` due to unsatisfied trait bounds + | + = note: the following trait bounds were not satisfied: + `Value: Eq` + `Value: Hash` +help: consider annotating `Value` with `#[derive(Eq, Hash, PartialEq)]` + | +LL | #[derive(Eq, Hash, PartialEq)] + | + +error[E0599]: the method `use_eq` exists for struct `Object<NoDerives>`, but its trait bounds were not satisfied + --> $DIR/issue-91550.rs:26:9 + | +LL | pub struct NoDerives; + | --------------------- doesn't satisfy `NoDerives: Eq` +LL | +LL | struct Object<T>(T); + | -------------------- method `use_eq` not found for this +... +LL | foo.use_eq(); + | ^^^^^^ method cannot be called on `Object<NoDerives>` due to unsatisfied trait bounds + | + = note: the following trait bounds were not satisfied: + `NoDerives: Eq` +help: consider annotating `NoDerives` with `#[derive(Eq, PartialEq)]` + | +LL | #[derive(Eq, PartialEq)] + | + +error[E0599]: the method `use_ord` exists for struct `Object<NoDerives>`, but its trait bounds were not satisfied + --> $DIR/issue-91550.rs:27:9 + | +LL | pub struct NoDerives; + | --------------------- doesn't satisfy `NoDerives: Ord` +LL | +LL | struct Object<T>(T); + | -------------------- method `use_ord` not found for this +... +LL | foo.use_ord(); + | ^^^^^^^ method cannot be called on `Object<NoDerives>` due to unsatisfied trait bounds + | + = note: the following trait bounds were not satisfied: + `NoDerives: Ord` +help: consider annotating `NoDerives` with `#[derive(Ord, PartialOrd)]` + | +LL | #[derive(Ord, PartialOrd)] + | + +error[E0599]: the method `use_ord_and_partial_ord` exists for struct `Object<NoDerives>`, but its trait bounds were not satisfied + --> $DIR/issue-91550.rs:28:9 + | +LL | pub struct NoDerives; + | --------------------- + | | + | doesn't satisfy `NoDerives: Ord` + | doesn't satisfy `NoDerives: PartialOrd` +LL | +LL | struct Object<T>(T); + | -------------------- method `use_ord_and_partial_ord` not found for this +... +LL | foo.use_ord_and_partial_ord(); + | ^^^^^^^^^^^^^^^^^^^^^^^ method cannot be called on `Object<NoDerives>` due to unsatisfied trait bounds + | + = note: the following trait bounds were not satisfied: + `NoDerives: Ord` + `NoDerives: PartialOrd` +help: consider annotating `NoDerives` with `#[derive(Ord, PartialOrd)]` + | +LL | #[derive(Ord, PartialOrd)] + | + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0599`. |
