@@ -280,43 +280,67 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
280
280
op. node. as_str( ) ) ) ;
281
281
}
282
282
}
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
+ }
316
321
}
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) ) ;
317
341
}
318
- err. emit ( ) ;
319
342
}
343
+ err. emit ( ) ;
320
344
}
321
345
self . tcx . types . err
322
346
}
@@ -393,9 +417,17 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
393
417
Err ( ( ) ) => {
394
418
let actual = self . resolve_type_vars_if_possible ( & operand_ty) ;
395
419
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 ,
397
421
"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 ( ) ;
399
431
}
400
432
self . tcx . types . err
401
433
}
0 commit comments