Skip to content

Commit 127d243

Browse files
committed
[wip] fixed some error, added missing test
1 parent ecedf44 commit 127d243

File tree

3 files changed

+77
-75
lines changed

3 files changed

+77
-75
lines changed

src/librustc_typeck/check/op.rs

+60-73
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
246246
Err(()) => {
247247
// error types are considered "builtin"
248248
if !lhs_ty.references_error() {
249-
match is_assign{
249+
let codemap = self.tcx.sess.codemap();
250+
match is_assign {
250251
IsAssign::Yes => {
251252
let mut err = struct_span_err!(self.tcx.sess, expr.span, E0368,
252253
"binary assignment operation `{}=` \
@@ -256,19 +257,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
256257
err.span_label(lhs_expr.span,
257258
format!("cannot use `{}=` on type `{}`",
258259
op.node.as_str(), lhs_ty));
259-
let missing_trait = match op.node {
260-
hir::BiAdd => Some("std::ops::AddAssign"),
261-
hir::BiSub => Some("std::ops::SubAssign"),
262-
hir::BiMul => Some("std::ops::MulAssign"),
263-
hir::BiDiv => Some("std::ops::DivAssign"),
264-
hir::BiRem => Some("std::ops::RemAssign"),
265-
hir::BiBitAnd => Some("std::ops::BitAndAssign"),
266-
hir::BiBitXor => Some("std::ops::BitXorAssign"),
267-
hir::BiBitOr => Some("std::ops::BitOrAssign"),
268-
hir::BiShl => Some("std::ops::ShlAssign"),
269-
hir::BiShr => Some("std::ops::ShrAssign"),
270-
_ => None
271-
};
272260
let mut suggested_deref = false;
273261
if let TyRef(_, ref ty_mut) = lhs_ty.sty {
274262
if {
@@ -280,22 +268,31 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
280268
Op::Binary(op, is_assign))
281269
.is_ok()
282270
} {
283-
let codemap = self.tcx.sess.codemap();
284-
match codemap.span_to_snippet(lhs_expr.span) {
285-
Ok(lstring) =>{
286-
let msg = &format!(
271+
if let Ok(lstring) = codemap.span_to_snippet(lhs_expr.span) {
272+
let msg = &format!(
287273
"`{}=` can be used on '{}', you can \
288274
dereference `{2}`: `*{2}`",
289275
op.node.as_str(), ty_mut.ty, lstring);
290-
err.help(msg);
291-
suggested_deref = true;
292-
},
293-
_ => {}
294-
};
276+
err.help(msg);
277+
suggested_deref = true;
278+
}
295279
}
296280
}
281+
let missing_trait = match op.node {
282+
hir::BiAdd => Some("std::ops::AddAssign"),
283+
hir::BiSub => Some("std::ops::SubAssign"),
284+
hir::BiMul => Some("std::ops::MulAssign"),
285+
hir::BiDiv => Some("std::ops::DivAssign"),
286+
hir::BiRem => Some("std::ops::RemAssign"),
287+
hir::BiBitAnd => Some("std::ops::BitAndAssign"),
288+
hir::BiBitXor => Some("std::ops::BitXorAssign"),
289+
hir::BiBitOr => Some("std::ops::BitOrAssign"),
290+
hir::BiShl => Some("std::ops::ShlAssign"),
291+
hir::BiShr => Some("std::ops::ShrAssign"),
292+
_ => None
293+
};
297294
if let Some(missing_trait) = missing_trait {
298-
if missing_trait == "std::ops::AddAssign" &&
295+
if op.node == hir::BiAdd &&
299296
self.check_str_addition(expr, lhs_expr, rhs_expr, lhs_ty,
300297
rhs_ty, &mut err) {
301298
// This has nothing here because it means we did string
@@ -306,13 +303,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
306303
err.note(
307304
&format!("`{}` might need a bound for `{}`",
308305
lhs_ty, missing_trait));
309-
} else {
310-
if !suggested_deref{
311-
err.note(
312-
&format!("an implementation of `{}` might \
313-
be missing for `{}`",
314-
missing_trait, lhs_ty));
315-
}
306+
} else if !suggested_deref {
307+
err.note(
308+
&format!("an implementation of `{}` might \
309+
be missing for `{}`",
310+
missing_trait, lhs_ty));
316311
}
317312
}
318313
err.emit();
@@ -322,22 +317,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
322317
"binary operation `{}` cannot be applied to type `{}`",
323318
op.node.as_str(),
324319
lhs_ty);
325-
let missing_trait = match op.node {
326-
hir::BiAdd => Some("std::ops::Add"),
327-
hir::BiSub => Some("std::ops::Sub"),
328-
hir::BiMul => Some("std::ops::Mul"),
329-
hir::BiDiv => Some("std::ops::Div"),
330-
hir::BiRem => Some("std::ops::Rem"),
331-
hir::BiBitAnd => Some("std::ops::BitAnd"),
332-
hir::BiBitXor => Some("std::ops::BitXor"),
333-
hir::BiBitOr => Some("std::ops::BitOr"),
334-
hir::BiShl => Some("std::ops::Shl"),
335-
hir::BiShr => Some("std::ops::Shr"),
336-
hir::BiEq | hir::BiNe => Some("std::cmp::PartialEq"),
337-
hir::BiLt | hir::BiLe | hir::BiGt | hir::BiGe =>
338-
Some("std::cmp::PartialOrd"),
339-
_ => None
340-
};
341320
let mut suggested_deref = false;
342321
if let TyRef(_, ref ty_mut) = lhs_ty.sty {
343322
if {
@@ -349,22 +328,34 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
349328
Op::Binary(op, is_assign))
350329
.is_ok()
351330
} {
352-
let codemap = self.tcx.sess.codemap();
353-
match codemap.span_to_snippet(lhs_expr.span) {
354-
Ok(lstring) =>{
355-
let msg = &format!(
331+
if let Ok(lstring) = codemap.span_to_snippet(lhs_expr.span) {
332+
let msg = &format!(
356333
"`{}` can be used on '{}', you can \
357334
dereference `{2}`: `*{2}`",
358335
op.node.as_str(), ty_mut.ty, lstring);
359-
err.help(msg);
360-
suggested_deref = true;
361-
},
362-
_ =>{}
336+
err.help(msg);
337+
suggested_deref = true;
363338
}
364339
}
365340
}
341+
let missing_trait = match op.node {
342+
hir::BiAdd => Some("std::ops::Add"),
343+
hir::BiSub => Some("std::ops::Sub"),
344+
hir::BiMul => Some("std::ops::Mul"),
345+
hir::BiDiv => Some("std::ops::Div"),
346+
hir::BiRem => Some("std::ops::Rem"),
347+
hir::BiBitAnd => Some("std::ops::BitAnd"),
348+
hir::BiBitXor => Some("std::ops::BitXor"),
349+
hir::BiBitOr => Some("std::ops::BitOr"),
350+
hir::BiShl => Some("std::ops::Shl"),
351+
hir::BiShr => Some("std::ops::Shr"),
352+
hir::BiEq | hir::BiNe => Some("std::cmp::PartialEq"),
353+
hir::BiLt | hir::BiLe | hir::BiGt | hir::BiGe =>
354+
Some("std::cmp::PartialOrd"),
355+
_ => None
356+
};
366357
if let Some(missing_trait) = missing_trait {
367-
if missing_trait == "std::ops::Add" &&
358+
if op.node == hir::BiAdd &&
368359
self.check_str_addition(expr, lhs_expr, rhs_expr, lhs_ty,
369360
rhs_ty, &mut err) {
370361
// This has nothing here because it means we did string
@@ -375,13 +366,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
375366
err.note(
376367
&format!("`{}` might need a bound for `{}`",
377368
lhs_ty, missing_trait));
378-
} else {
379-
if !suggested_deref{
380-
err.note(
381-
&format!("an implementation of `{}` might \
382-
be missing for `{}`",
383-
missing_trait, lhs_ty));
384-
}
369+
} else if !suggested_deref {
370+
err.note(
371+
&format!("an implementation of `{}` might \
372+
be missing for `{}`",
373+
missing_trait, lhs_ty));
385374
}
386375
}
387376
err.emit();
@@ -468,20 +457,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
468457
op.as_str(), actual);
469458
err.span_label(ex.span, format!("cannot apply unary \
470459
operator `{}`", op.as_str()));
471-
let missing_trait = match op {
472-
hir::UnNeg => "std::ops::Neg",
473-
hir::UnNot => "std::ops::Not",
474-
hir::UnDeref => "std::ops::UnDerf"
475-
};
476-
match actual.sty{
477-
TyUint(_) => {
478-
if op == hir::UnNeg{
479-
err.note(&format!("unsigned values cannot be negated"));
480-
}
460+
match actual.sty {
461+
TyUint(_) if op == hir::UnNeg => {
462+
err.note(&format!("unsigned values cannot be negated"));
481463
},
482464
TyStr | TyNever | TyChar | TyTuple(_) | TyArray(_,_) => {},
483465
TyRef(_, ref lty) if lty.ty.sty == TyStr => {},
484466
_ => {
467+
let missing_trait = match op {
468+
hir::UnNeg => "std::ops::Neg",
469+
hir::UnNot => "std::ops::Not",
470+
hir::UnDeref => "std::ops::UnDerf"
471+
};
485472
err.note(&format!("an implementation of `{}` might \
486473
be missing for `{}`",
487474
missing_trait, operand_ty));

src/test/ui/type-check/missing_trait_impl.rs

+4
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,7 @@ fn main() {
1414
fn foo<T>(x: T, y: T) {
1515
let z = x + y; //~ ERROR binary operation `+` cannot be applied to type `T`
1616
}
17+
18+
fn bar<T>(x: T) {
19+
x += x; //~ ERROR binary assignment operation `+=` cannot be applied to type `T`
20+
}

src/test/ui/type-check/missing_trait_impl.stderr

+13-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,17 @@ LL | let z = x + y; //~ ERROR binary operation `+` cannot be applied to type
66
|
77
= note: `T` might need a bound for `std::ops::Add`
88

9-
error: aborting due to previous error
9+
error[E0368]: binary assignment operation `+=` cannot be applied to type `T`
10+
--> $DIR/missing_trait_impl.rs:19:5
11+
|
12+
LL | x += x; //~ ERROR binary assignment operation `+=` cannot be applied to type `T`
13+
| -^^^^^
14+
| |
15+
| cannot use `+=` on type `T`
16+
|
17+
= note: `T` might need a bound for `std::ops::AddAssign`
18+
19+
error: aborting due to 2 previous errors
1020

11-
For more information about this error, try `rustc --explain E0369`.
21+
Some errors occurred: E0368, E0369.
22+
For more information about an error, try `rustc --explain E0368`.

0 commit comments

Comments
 (0)