diff --git a/compiler/rustc_typeck/src/check/op.rs b/compiler/rustc_typeck/src/check/op.rs index af154e62a1e..e0dbe027aef 100644 --- a/compiler/rustc_typeck/src/check/op.rs +++ b/compiler/rustc_typeck/src/check/op.rs @@ -672,6 +672,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ex.span, format!("cannot apply unary operator `{}`", op.as_str()), ); + let missing_trait = match op { + hir::UnOp::Deref => unreachable!("check unary op `-` or `!` only"), + hir::UnOp::Not => "std::ops::Not", + hir::UnOp::Neg => "std::ops::Neg", + }; + let mut visitor = TypeParamVisitor(vec![]); + visitor.visit_ty(operand_ty); + if let [ty] = &visitor.0[..] { + if let ty::Param(p) = *operand_ty.kind() { + suggest_constraining_param( + self.tcx, + self.body_id, + &mut err, + *ty, + operand_ty, + missing_trait, + p, + true, + ); + } + } let sp = self.tcx.sess.source_map().start_point(ex.span); if let Some(sp) = diff --git a/src/test/ui/type/type-check/missing_trait_impl.rs b/src/test/ui/type/type-check/missing_trait_impl.rs index f61ada3f63f..0e3e703a2f5 100644 --- a/src/test/ui/type/type-check/missing_trait_impl.rs +++ b/src/test/ui/type/type-check/missing_trait_impl.rs @@ -8,3 +8,9 @@ fn foo(x: T, y: T) { fn bar(x: T) { x += x; //~ ERROR binary assignment operation `+=` cannot be applied to type `T` } + +fn baz(x: T) { + let y = -x; //~ ERROR cannot apply unary operator `-` to type `T` + let y = !x; //~ ERROR cannot apply unary operator `!` to type `T` + let y = *x; //~ ERROR type `T` cannot be dereferenced +} diff --git a/src/test/ui/type/type-check/missing_trait_impl.stderr b/src/test/ui/type/type-check/missing_trait_impl.stderr index 45f2e845735..59b8692dd4d 100644 --- a/src/test/ui/type/type-check/missing_trait_impl.stderr +++ b/src/test/ui/type/type-check/missing_trait_impl.stderr @@ -24,7 +24,35 @@ help: consider restricting type parameter `T` LL | fn bar(x: T) { | +++++++++++++++++++++ -error: aborting due to 2 previous errors +error[E0600]: cannot apply unary operator `-` to type `T` + --> $DIR/missing_trait_impl.rs:13:13 + | +LL | let y = -x; + | ^^ cannot apply unary operator `-` + | +help: consider restricting type parameter `T` + | +LL | fn baz>(x: T) { + | +++++++++++++++++++++++++++ -Some errors have detailed explanations: E0368, E0369. +error[E0600]: cannot apply unary operator `!` to type `T` + --> $DIR/missing_trait_impl.rs:14:13 + | +LL | let y = !x; + | ^^ cannot apply unary operator `!` + | +help: consider restricting type parameter `T` + | +LL | fn baz>(x: T) { + | +++++++++++++++++++++++++++ + +error[E0614]: type `T` cannot be dereferenced + --> $DIR/missing_trait_impl.rs:15:13 + | +LL | let y = *x; + | ^^ + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0368, E0369, E0600, E0614. For more information about an error, try `rustc --explain E0368`.