Rollup merge of #95197 - frank-king:feat/unary_op_type_constrain, r=petrochenkov
Suggest constraining param for unary ops when missing trait impl This PR adds a suggestion of constraining param for unary ops `-` and `!` when the corresponding trait implementation is missing. Fixs #94543. BTW, this is my first time to touch rustc, please correct me if I did anything wrong.
This commit is contained in:
commit
0e80a7ab59
3 changed files with 57 additions and 2 deletions
|
@ -672,6 +672,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
ex.span,
|
ex.span,
|
||||||
format!("cannot apply unary operator `{}`", op.as_str()),
|
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);
|
let sp = self.tcx.sess.source_map().start_point(ex.span);
|
||||||
if let Some(sp) =
|
if let Some(sp) =
|
||||||
|
|
|
@ -8,3 +8,9 @@ fn foo<T>(x: T, y: T) {
|
||||||
fn bar<T>(x: T) {
|
fn bar<T>(x: T) {
|
||||||
x += x; //~ ERROR binary assignment operation `+=` cannot be applied to type `T`
|
x += x; //~ ERROR binary assignment operation `+=` cannot be applied to type `T`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn baz<T>(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
|
||||||
|
}
|
||||||
|
|
|
@ -24,7 +24,35 @@ help: consider restricting type parameter `T`
|
||||||
LL | fn bar<T: std::ops::AddAssign>(x: T) {
|
LL | fn bar<T: std::ops::AddAssign>(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<T: std::ops::Neg<Output = T>>(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<T: std::ops::Not<Output = T>>(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`.
|
For more information about an error, try `rustc --explain E0368`.
|
||||||
|
|
Loading…
Add table
Reference in a new issue