From 4644c3a6aa0ff0ad394175a029f5531728ecff31 Mon Sep 17 00:00:00 2001 From: hgallagher1993 Date: Thu, 28 Mar 2019 13:54:29 -0400 Subject: [PATCH] Add check for when left and right overlap and change span for explanation to point at operator --- src/librustc_typeck/check/op.rs | 13 ++++++++----- ...erives-span-PartialEq-enum-struct-variant.stderr | 6 ------ .../ui/derives/derives-span-PartialEq-enum.stderr | 6 ------ .../ui/derives/derives-span-PartialEq-struct.stderr | 6 ------ .../derives-span-PartialEq-tuple-struct.stderr | 6 ------ .../deriving-no-inner-impl-error-message.stderr | 6 ------ src/test/ui/issues/issue-47377.stderr | 7 +++---- src/test/ui/issues/issue-47380.stderr | 7 +++---- src/test/ui/span/issue-39018.stderr | 7 +++---- 9 files changed, 17 insertions(+), 47 deletions(-) diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index f8212659f02..d6932094ddd 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -306,7 +306,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let Some(missing_trait) = missing_trait { if op.node == hir::BinOpKind::Add && self.check_str_addition(expr, lhs_expr, rhs_expr, lhs_ty, - rhs_ty, &mut err, true) { + rhs_ty, &mut err, true, op) { // This has nothing here because it means we did string // concatenation (e.g., "Hello " += "World!"). This means // we don't want the note in the else clause to be emitted @@ -332,8 +332,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { op.node.as_str(), lhs_ty); - err.span_label(lhs_expr.span, lhs_ty.to_string()); - err.span_label(rhs_expr.span, rhs_ty.to_string()); + if !lhs_expr.span.eq(&rhs_expr.span) { + err.span_label(lhs_expr.span, lhs_ty.to_string()); + err.span_label(rhs_expr.span, rhs_ty.to_string()); + } let mut suggested_deref = false; if let Ref(_, mut rty, _) = lhs_ty.sty { @@ -384,7 +386,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let Some(missing_trait) = missing_trait { if op.node == hir::BinOpKind::Add && self.check_str_addition(expr, lhs_expr, rhs_expr, lhs_ty, - rhs_ty, &mut err, false) { + rhs_ty, &mut err, false, op) { // This has nothing here because it means we did string // concatenation (e.g., "Hello " + "World!"). This means // we don't want the note in the else clause to be emitted @@ -422,6 +424,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { rhs_ty: Ty<'tcx>, err: &mut errors::DiagnosticBuilder<'_>, is_assign: bool, + op: hir::BinOp, ) -> bool { let source_map = self.tcx.sess.source_map(); let msg = "`to_owned()` can be used to create an owned `String` \ @@ -435,7 +438,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { (&Ref(_, l_ty, _), &Ref(_, r_ty, _)) if l_ty.sty == Str && r_ty.sty == Str => { if !is_assign { - err.span_label(expr.span, + err.span_label(op.span, "`+` can't be used to concatenate two `&str` strings"); match source_map.span_to_snippet(lhs_expr.span) { Ok(lstring) => err.span_suggestion( diff --git a/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr index 673f23d29eb..ed5468cc4da 100644 --- a/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr +++ b/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr @@ -3,9 +3,6 @@ error[E0369]: binary operation `==` cannot be applied to type `Error` | LL | x: Error | ^^^^^^^^ - | | - | Error - | Error | = note: an implementation of `std::cmp::PartialEq` might be missing for `Error` @@ -14,9 +11,6 @@ error[E0369]: binary operation `!=` cannot be applied to type `Error` | LL | x: Error | ^^^^^^^^ - | | - | Error - | Error | = note: an implementation of `std::cmp::PartialEq` might be missing for `Error` diff --git a/src/test/ui/derives/derives-span-PartialEq-enum.stderr b/src/test/ui/derives/derives-span-PartialEq-enum.stderr index 6ab18b45b73..06a88c03f58 100644 --- a/src/test/ui/derives/derives-span-PartialEq-enum.stderr +++ b/src/test/ui/derives/derives-span-PartialEq-enum.stderr @@ -3,9 +3,6 @@ error[E0369]: binary operation `==` cannot be applied to type `Error` | LL | Error | ^^^^^ - | | - | Error - | Error | = note: an implementation of `std::cmp::PartialEq` might be missing for `Error` @@ -14,9 +11,6 @@ error[E0369]: binary operation `!=` cannot be applied to type `Error` | LL | Error | ^^^^^ - | | - | Error - | Error | = note: an implementation of `std::cmp::PartialEq` might be missing for `Error` diff --git a/src/test/ui/derives/derives-span-PartialEq-struct.stderr b/src/test/ui/derives/derives-span-PartialEq-struct.stderr index bdd12942b47..b8481048361 100644 --- a/src/test/ui/derives/derives-span-PartialEq-struct.stderr +++ b/src/test/ui/derives/derives-span-PartialEq-struct.stderr @@ -3,9 +3,6 @@ error[E0369]: binary operation `==` cannot be applied to type `Error` | LL | x: Error | ^^^^^^^^ - | | - | Error - | Error | = note: an implementation of `std::cmp::PartialEq` might be missing for `Error` @@ -14,9 +11,6 @@ error[E0369]: binary operation `!=` cannot be applied to type `Error` | LL | x: Error | ^^^^^^^^ - | | - | Error - | Error | = note: an implementation of `std::cmp::PartialEq` might be missing for `Error` diff --git a/src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr b/src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr index 9f60b2ea816..4398d252125 100644 --- a/src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr +++ b/src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr @@ -3,9 +3,6 @@ error[E0369]: binary operation `==` cannot be applied to type `Error` | LL | Error | ^^^^^ - | | - | Error - | Error | = note: an implementation of `std::cmp::PartialEq` might be missing for `Error` @@ -14,9 +11,6 @@ error[E0369]: binary operation `!=` cannot be applied to type `Error` | LL | Error | ^^^^^ - | | - | Error - | Error | = note: an implementation of `std::cmp::PartialEq` might be missing for `Error` diff --git a/src/test/ui/derives/deriving-no-inner-impl-error-message.stderr b/src/test/ui/derives/deriving-no-inner-impl-error-message.stderr index 4baf27c520c..3206eecbe30 100644 --- a/src/test/ui/derives/deriving-no-inner-impl-error-message.stderr +++ b/src/test/ui/derives/deriving-no-inner-impl-error-message.stderr @@ -3,9 +3,6 @@ error[E0369]: binary operation `==` cannot be applied to type `NoCloneOrEq` | LL | x: NoCloneOrEq | ^^^^^^^^^^^^^^ - | | - | NoCloneOrEq - | NoCloneOrEq | = note: an implementation of `std::cmp::PartialEq` might be missing for `NoCloneOrEq` @@ -14,9 +11,6 @@ error[E0369]: binary operation `!=` cannot be applied to type `NoCloneOrEq` | LL | x: NoCloneOrEq | ^^^^^^^^^^^^^^ - | | - | NoCloneOrEq - | NoCloneOrEq | = note: an implementation of `std::cmp::PartialEq` might be missing for `NoCloneOrEq` diff --git a/src/test/ui/issues/issue-47377.stderr b/src/test/ui/issues/issue-47377.stderr index f782ad42fcb..88466131e31 100644 --- a/src/test/ui/issues/issue-47377.stderr +++ b/src/test/ui/issues/issue-47377.stderr @@ -2,11 +2,10 @@ error[E0369]: binary operation `+` cannot be applied to type `&str` --> $DIR/issue-47377.rs:4:14 | LL | let _a = b + ", World!"; - | --^----------- - | | | - | | &str + | - ^ ---------- &str + | | | + | | `+` can't be used to concatenate two `&str` strings | &str - | `+` can't be used to concatenate two `&str` strings help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left | LL | let _a = b.to_owned() + ", World!"; diff --git a/src/test/ui/issues/issue-47380.stderr b/src/test/ui/issues/issue-47380.stderr index 753892c97e7..d69101eab4c 100644 --- a/src/test/ui/issues/issue-47380.stderr +++ b/src/test/ui/issues/issue-47380.stderr @@ -2,11 +2,10 @@ error[E0369]: binary operation `+` cannot be applied to type `&str` --> $DIR/issue-47380.rs:3:35 | LL | println!("🦀🦀🦀🦀🦀"); let _a = b + ", World!"; - | --^----------- - | | | - | | &str + | - ^ ---------- &str + | | | + | | `+` can't be used to concatenate two `&str` strings | &str - | `+` can't be used to concatenate two `&str` strings help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left | LL | println!("🦀🦀🦀🦀🦀"); let _a = b.to_owned() + ", World!"; diff --git a/src/test/ui/span/issue-39018.stderr b/src/test/ui/span/issue-39018.stderr index 6e475483987..a5b91f090d2 100644 --- a/src/test/ui/span/issue-39018.stderr +++ b/src/test/ui/span/issue-39018.stderr @@ -2,11 +2,10 @@ error[E0369]: binary operation `+` cannot be applied to type `&str` --> $DIR/issue-39018.rs:2:22 | LL | let x = "Hello " + "World!"; - | ---------^--------- - | | | - | | &str + | -------- ^ -------- &str + | | | + | | `+` can't be used to concatenate two `&str` strings | &str - | `+` can't be used to concatenate two `&str` strings help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left | LL | let x = "Hello ".to_owned() + "World!";