@@ -307,9 +307,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
307
307
if let Some ( missing_trait) = missing_trait {
308
308
if op. node == hir:: BinOpKind :: Add &&
309
309
self . check_str_addition ( expr, lhs_expr, rhs_expr, lhs_ty,
310
- rhs_ty, & mut err) {
310
+ rhs_ty, & mut err, true ) {
311
311
// This has nothing here because it means we did string
312
- // concatenation (e.g. "Hello " + "World!"). This means
312
+ // concatenation (e.g. "Hello " += "World!"). This means
313
313
// we don't want the note in the else clause to be emitted
314
314
} else if let ty:: TyParam ( _) = lhs_ty. sty {
315
315
// FIXME: point to span of param
@@ -381,7 +381,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
381
381
if let Some ( missing_trait) = missing_trait {
382
382
if op. node == hir:: BinOpKind :: Add &&
383
383
self . check_str_addition ( expr, lhs_expr, rhs_expr, lhs_ty,
384
- rhs_ty, & mut err) {
384
+ rhs_ty, & mut err, false ) {
385
385
// This has nothing here because it means we did string
386
386
// concatenation (e.g. "Hello " + "World!"). This means
387
387
// we don't want the note in the else clause to be emitted
@@ -410,13 +410,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
410
410
( lhs_ty, rhs_ty, return_ty)
411
411
}
412
412
413
- fn check_str_addition ( & self ,
414
- expr : & ' gcx hir:: Expr ,
415
- lhs_expr : & ' gcx hir:: Expr ,
416
- rhs_expr : & ' gcx hir:: Expr ,
417
- lhs_ty : Ty < ' tcx > ,
418
- rhs_ty : Ty < ' tcx > ,
419
- err : & mut errors:: DiagnosticBuilder ) -> bool {
413
+ fn check_str_addition (
414
+ & self ,
415
+ expr : & ' gcx hir:: Expr ,
416
+ lhs_expr : & ' gcx hir:: Expr ,
417
+ rhs_expr : & ' gcx hir:: Expr ,
418
+ lhs_ty : Ty < ' tcx > ,
419
+ rhs_ty : Ty < ' tcx > ,
420
+ err : & mut errors:: DiagnosticBuilder ,
421
+ is_assign : bool ,
422
+ ) -> bool {
420
423
let codemap = self . tcx . sess . codemap ( ) ;
421
424
let msg = "`to_owned()` can be used to create an owned `String` \
422
425
from a string reference. String concatenation \
@@ -428,34 +431,36 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
428
431
match ( & lhs_ty. sty , & rhs_ty. sty ) {
429
432
( & TyRef ( _, l_ty, _) , & TyRef ( _, r_ty, _) )
430
433
if l_ty. sty == TyStr && r_ty. sty == TyStr => {
431
- err. span_label ( expr. span ,
432
- "`+` can't be used to concatenate two `&str` strings" ) ;
433
- match codemap. span_to_snippet ( lhs_expr. span ) {
434
- Ok ( lstring) => err. span_suggestion ( lhs_expr. span ,
435
- msg,
436
- format ! ( "{}.to_owned()" , lstring) ) ,
437
- _ => err. help ( msg) ,
438
- } ;
434
+ if !is_assign {
435
+ err. span_label ( expr. span ,
436
+ "`+` can't be used to concatenate two `&str` strings" ) ;
437
+ match codemap. span_to_snippet ( lhs_expr. span ) {
438
+ Ok ( lstring) => err. span_suggestion ( lhs_expr. span ,
439
+ msg,
440
+ format ! ( "{}.to_owned()" , lstring) ) ,
441
+ _ => err. help ( msg) ,
442
+ } ;
443
+ }
439
444
true
440
445
}
441
446
( & TyRef ( _, l_ty, _) , & TyAdt ( ..) )
442
447
if l_ty. sty == TyStr && & format ! ( "{:?}" , rhs_ty) == "std::string::String" => {
443
448
err. span_label ( expr. span ,
444
449
"`+` can't be used to concatenate a `&str` with a `String`" ) ;
445
- match codemap. span_to_snippet ( lhs_expr. span ) {
446
- Ok ( lstring) => err. span_suggestion ( lhs_expr. span ,
447
- msg,
448
- format ! ( "{}.to_owned()" , lstring) ) ,
449
- _ => err. help ( msg) ,
450
- } ;
451
- match codemap. span_to_snippet ( rhs_expr. span ) {
452
- Ok ( rstring) => {
453
- err. span_suggestion ( rhs_expr. span ,
454
- "you also need to borrow the `String` on the right to \
455
- get a `&str`",
456
- format ! ( "&{}" , rstring) ) ;
450
+ match (
451
+ codemap. span_to_snippet ( lhs_expr. span ) ,
452
+ codemap. span_to_snippet ( rhs_expr. span ) ,
453
+ is_assign,
454
+ ) {
455
+ ( Ok ( l) , Ok ( r) , false ) => {
456
+ err. multipart_suggestion ( msg, vec ! [
457
+ ( lhs_expr. span, format!( "{}.to_owned()" , l) ) ,
458
+ ( rhs_expr. span, format!( "&{}" , r) ) ,
459
+ ] ) ;
460
+ }
461
+ _ => {
462
+ err. help ( msg) ;
457
463
}
458
- _ => { }
459
464
} ;
460
465
true
461
466
}
0 commit comments