Skip to content

Commit 2f6945c

Browse files
committed
added missing implementation hint
1 parent 4e5a155 commit 2f6945c

File tree

8 files changed

+86
-36
lines changed

8 files changed

+86
-36
lines changed

src/librustc_typeck/check/op.rs

Lines changed: 68 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -280,43 +280,67 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
280280
op.node.as_str()));
281281
}
282282
}
283-
284-
let missing_trait = match op.node {
285-
hir::BiAdd => Some("std::ops::Add"),
286-
hir::BiSub => Some("std::ops::Sub"),
287-
hir::BiMul => Some("std::ops::Mul"),
288-
hir::BiDiv => Some("std::ops::Div"),
289-
hir::BiRem => Some("std::ops::Rem"),
290-
hir::BiBitAnd => Some("std::ops::BitAnd"),
291-
hir::BiBitOr => Some("std::ops::BitOr"),
292-
hir::BiShl => Some("std::ops::Shl"),
293-
hir::BiShr => Some("std::ops::Shr"),
294-
hir::BiEq | hir::BiNe => Some("std::cmp::PartialEq"),
295-
hir::BiLt | hir::BiLe | hir::BiGt | hir::BiGe =>
296-
Some("std::cmp::PartialOrd"),
297-
_ => None
298-
};
299-
300-
if let Some(missing_trait) = missing_trait {
301-
if missing_trait == "std::ops::Add" &&
302-
self.check_str_addition(expr, lhs_expr, rhs_expr, lhs_ty,
303-
rhs_ty, &mut err) {
304-
// This has nothing here because it means we did string
305-
// concatenation (e.g. "Hello " + "World!"). This means
306-
// we don't want the note in the else clause to be emitted
307-
} else if let ty::TyParam(_) = lhs_ty.sty {
308-
// FIXME: point to span of param
309-
err.note(
310-
&format!("`{}` might need a bound for `{}`",
311-
lhs_ty, missing_trait));
312-
} else {
313-
err.note(
314-
&format!("an implementation of `{}` might be missing for `{}`",
315-
missing_trait, lhs_ty));
283+
IsAssign::No => {
284+
let mut err = struct_span_err!(self.tcx.sess, expr.span, E0369,
285+
"binary operation `{}` cannot be applied to type `{}`",
286+
op.node.as_str(),
287+
lhs_ty);
288+
let missing_trait = match op.node {
289+
hir::BiAdd => Some("std::ops::Add"),
290+
hir::BiSub => Some("std::ops::Sub"),
291+
hir::BiMul => Some("std::ops::Mul"),
292+
hir::BiDiv => Some("std::ops::Div"),
293+
hir::BiRem => Some("std::ops::Rem"),
294+
hir::BiBitAnd => Some("std::ops::BitAnd"),
295+
hir::BiBitXor => Some("std::ops::BitXor"),
296+
hir::BiBitOr => Some("std::ops::BitOr"),
297+
hir::BiShl => Some("std::ops::Shl"),
298+
hir::BiShr => Some("std::ops::Shr"),
299+
hir::BiEq | hir::BiNe => Some("std::cmp::PartialEq"),
300+
hir::BiLt | hir::BiLe | hir::BiGt | hir::BiGe =>
301+
Some("std::cmp::PartialOrd"),
302+
_ => None
303+
};
304+
if let TypeVariants::TyRef(_, ref ty_mut) = lhs_ty.sty {
305+
if {
306+
!self.infcx.type_moves_by_default(self.param_env,
307+
ty_mut.ty,
308+
lhs_expr.span) &&
309+
self.lookup_op_method(ty_mut.ty,
310+
&[rhs_ty],
311+
Op::Binary(op, is_assign))
312+
.is_ok()
313+
} {
314+
err.note(
315+
&format!(
316+
"this is a reference to a type that `{}` can be \
317+
applied to; you need to dereference this variable \
318+
once for this operation to work",
319+
op.node.as_str()));
320+
}
316321
}
322+
(err, missing_trait)
323+
}
324+
};
325+
if let Some(missing_trait) = missing_trait {
326+
if missing_trait == "std::ops::Add" &&
327+
self.check_str_addition(expr, lhs_expr, rhs_expr, lhs_ty,
328+
rhs_ty, &mut err) {
329+
// This has nothing here because it means we did string
330+
// concatenation (e.g. "Hello " + "World!"). This means
331+
// we don't want the note in the else clause to be emitted
332+
} else if let ty::TyParam(_) = lhs_ty.sty {
333+
// FIXME: point to span of param
334+
err.note(
335+
&format!("`{}` might need a bound for `{}`",
336+
lhs_ty, missing_trait));
337+
} else {
338+
err.note(
339+
&format!("an implementation of `{}` might be missing for `{}`",
340+
missing_trait, lhs_ty));
317341
}
318-
err.emit();
319342
}
343+
err.emit();
320344
}
321345
self.tcx.types.err
322346
}
@@ -393,9 +417,17 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
393417
Err(()) => {
394418
let actual = self.resolve_type_vars_if_possible(&operand_ty);
395419
if !actual.references_error() {
396-
struct_span_err!(self.tcx.sess, ex.span, E0600,
420+
let mut err = struct_span_err!(self.tcx.sess, ex.span, E0600,
397421
"cannot apply unary operator `{}` to type `{}`",
398-
op.as_str(), actual).emit();
422+
op.as_str(), actual);
423+
let missing_trait = match op {
424+
hir::UnNeg => "std::ops::Neg",
425+
hir::UnNot => "std::ops::Not",
426+
hir::UnDeref => "std::ops::UnDerf"
427+
};
428+
err.note(&format!("an implementation of `{}` might be missing for `{}`",
429+
missing_trait, operand_ty));
430+
err.emit();
399431
}
400432
self.tcx.types.err
401433
}

src/test/ui/codemap_tests/issue-28308.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ error[E0600]: cannot apply unary operator `!` to type `&'static str`
33
|
44
LL | assert!("foo");
55
| ^^^^^^^^^^^^^^^
6+
|
7+
= note: an implementation of `std::ops::Not` might be missing for `&'static str`
68

79
error: aborting due to previous error
810

src/test/ui/error-codes/E0067.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ LL | LinkedList::new() += 1; //~ ERROR E0368
55
| -----------------^^^^^
66
| |
77
| cannot use `+=` on type `std::collections::LinkedList<_>`
8+
|
9+
= note: an implementation of `std::ops::AddAssign` might be missing for `std::collections::LinkedList<_>`
810

911
error[E0067]: invalid left-hand side expression
1012
--> $DIR/E0067.rs:14:5

src/test/ui/error-codes/E0600.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ error[E0600]: cannot apply unary operator `!` to type `&'static str`
33
|
44
LL | !"a"; //~ ERROR E0600
55
| ^^^^
6+
|
7+
= note: an implementation of `std::ops::Not` might be missing for `&'static str`
68

79
error: aborting due to previous error
810

src/test/ui/error-festival.stderr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ LL | x += 2;
1717
| -^^^^^
1818
| |
1919
| cannot use `+=` on type `&str`
20+
|
21+
= note: an implementation of `std::ops::AddAssign` might be missing for `&str`
2022

2123
error[E0599]: no method named `z` found for type `&str` in the current scope
2224
--> $DIR/error-festival.rs:26:7
@@ -29,6 +31,8 @@ error[E0600]: cannot apply unary operator `!` to type `Question`
2931
|
3032
LL | !Question::Yes;
3133
| ^^^^^^^^^^^^^^
34+
|
35+
= note: an implementation of `std::ops::Not` might be missing for `Question`
3236

3337
error[E0604]: only `u8` can be cast as `char`, not `u32`
3438
--> $DIR/error-festival.rs:35:5

src/test/ui/feature-gate-negate-unsigned.stderr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@ error[E0600]: cannot apply unary operator `-` to type `usize`
33
|
44
LL | let _max: usize = -1;
55
| ^^
6+
|
7+
= note: an implementation of `std::ops::Neg` might be missing for `usize`
68

79
error[E0600]: cannot apply unary operator `-` to type `u8`
810
--> $DIR/feature-gate-negate-unsigned.rs:24:14
911
|
1012
LL | let _y = -x;
1113
| ^^
14+
|
15+
= note: an implementation of `std::ops::Neg` might be missing for `u8`
1216

1317
error: aborting due to 2 previous errors
1418

src/test/ui/issue-5239-1.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ LL | let x = |ref x: isize| { x += 1; };
55
| -^^^^^
66
| |
77
| cannot use `+=` on type `&isize`
8+
|
9+
= note: an implementation of `std::ops::AddAssign` might be missing for `&isize`
810

911
error: aborting due to previous error
1012

src/test/ui/reachable/expr_unary.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ error[E0600]: cannot apply unary operator `!` to type `!`
33
|
44
LL | let x: ! = ! { return; }; //~ ERROR unreachable
55
| ^^^^^^^^^^^^^
6+
|
7+
= note: an implementation of `std::ops::Not` might be missing for `!`
68

79
error: unreachable expression
810
--> $DIR/expr_unary.rs:17:16

0 commit comments

Comments
 (0)