From 2835ace4ca1901b60678484ece129a4f60bd1887 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Wed, 12 Jan 2022 22:04:39 -0800 Subject: [PATCH 1/6] Improve suggestions for type errors with string concatenation Now, multipart suggestions are used instead of `span_to_snippet`, which improves code quality, makes the suggestion work even without access to source code, and, most importantly, improves the rendering of the suggestion. --- compiler/rustc_typeck/src/check/op.rs | 78 +++++++------------ src/test/ui/issues/issue-47377.stderr | 2 +- src/test/ui/issues/issue-47380.stderr | 2 +- src/test/ui/span/issue-39018.stderr | 26 ++++--- .../ui/str/str-concat-on-double-ref.stderr | 2 +- ...non-1-width-unicode-multiline-label.stderr | 2 +- 6 files changed, 47 insertions(+), 65 deletions(-) diff --git a/compiler/rustc_typeck/src/check/op.rs b/compiler/rustc_typeck/src/check/op.rs index 8ebfcdd539b..838f8b0a61d 100644 --- a/compiler/rustc_typeck/src/check/op.rs +++ b/compiler/rustc_typeck/src/check/op.rs @@ -549,7 +549,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { is_assign: IsAssign, op: hir::BinOp, ) -> bool { - let source_map = self.tcx.sess.source_map(); let remove_borrow_msg = "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"; @@ -574,31 +573,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) => { if let IsAssign::No = is_assign { // Do not supply this message if `&str += &str` - err.span_label( - op.span, - "`+` cannot be used to concatenate two `&str` strings", - ); - match source_map.span_to_snippet(lhs_expr.span) { - Ok(lstring) => { - err.span_suggestion( - lhs_expr.span, - if lstring.starts_with('&') { - remove_borrow_msg - } else { - msg - }, - if let Some(stripped) = lstring.strip_prefix('&') { - // let a = String::new(); - // let _ = &a + "bar"; - stripped.to_string() - } else { - format!("{}.to_owned()", lstring) - }, - Applicability::MachineApplicable, - ) - } - _ => err.help(msg), - }; + err.span_label(op.span, "`+` cannot be used to concatenate two `&str` strings"); + if let hir::ExprKind::AddrOf(_,_,lhs_inner_expr) = lhs_expr.kind { + err.span_suggestion( + lhs_expr.span.until(lhs_inner_expr.span), + remove_borrow_msg, + "".to_owned(), + Applicability::MachineApplicable + ); + } else { + err.span_suggestion( + lhs_expr.span.shrink_to_hi(), + msg, + ".to_owned()".to_owned(), + Applicability::MachineApplicable + ); + } } true } @@ -609,32 +599,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { op.span, "`+` cannot be used to concatenate a `&str` with a `String`", ); - match ( - source_map.span_to_snippet(lhs_expr.span), - source_map.span_to_snippet(rhs_expr.span), - is_assign, - ) { - (Ok(l), Ok(r), IsAssign::No) => { - let to_string = if let Some(stripped) = l.strip_prefix('&') { - // let a = String::new(); let b = String::new(); - // let _ = &a + b; - stripped.to_string() - } else { - format!("{}.to_owned()", l) - }; - err.multipart_suggestion( - msg, - vec![ - (lhs_expr.span, to_string), - (rhs_expr.span, format!("&{}", r)), - ], - Applicability::MachineApplicable, - ); + match is_assign { + IsAssign::No => { + let suggestions = vec![ + if let hir::ExprKind::AddrOf(_, _, lhs_inner_expr) = lhs_expr.kind { + (lhs_expr.span.until(lhs_inner_expr.span), "".to_owned()) + } else { + (lhs_expr.span.shrink_to_hi(), ".to_owned()".to_owned()) + }, + (rhs_expr.span.shrink_to_lo(), "&".to_owned()), + ]; + err.multipart_suggestion(msg, suggestions, Applicability::MachineApplicable); } - _ => { + IsAssign::Yes => { err.help(msg); } - }; + } true } _ => false, diff --git a/src/test/ui/issues/issue-47377.stderr b/src/test/ui/issues/issue-47377.stderr index a7b8b1ca861..2c17a19779f 100644 --- a/src/test/ui/issues/issue-47377.stderr +++ b/src/test/ui/issues/issue-47377.stderr @@ -10,7 +10,7 @@ LL | let _a = b + ", World!"; 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!"; - | ~~~~~~~~~~~~ + | +++++++++++ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-47380.stderr b/src/test/ui/issues/issue-47380.stderr index f6222c77e2e..417206e6cc4 100644 --- a/src/test/ui/issues/issue-47380.stderr +++ b/src/test/ui/issues/issue-47380.stderr @@ -10,7 +10,7 @@ LL | println!("🦀🦀🦀🦀🦀"); let _a = b + ", World!"; 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!"; - | ~~~~~~~~~~~~ + | +++++++++++ error: aborting due to previous error diff --git a/src/test/ui/span/issue-39018.stderr b/src/test/ui/span/issue-39018.stderr index 92e86bf5d6c..444d037571e 100644 --- a/src/test/ui/span/issue-39018.stderr +++ b/src/test/ui/span/issue-39018.stderr @@ -10,7 +10,7 @@ LL | let x = "Hello " + "World!"; 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!"; - | ~~~~~~~~~~~~~~~~~~~ + | +++++++++++ error[E0369]: cannot add `World` to `World` --> $DIR/issue-39018.rs:8:26 @@ -49,7 +49,7 @@ LL | let x = "Hello " + "World!".to_owned(); 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!".to_owned(); - | ~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~ + | +++++++++++ + error[E0369]: cannot add `&String` to `&String` --> $DIR/issue-39018.rs:26:16 @@ -62,8 +62,9 @@ LL | let _ = &a + &b; | help: 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; - | ~ +LL - let _ = &a + &b; +LL + let _ = a + &b; + | error[E0369]: cannot add `String` to `&String` --> $DIR/issue-39018.rs:27:16 @@ -76,8 +77,9 @@ LL | let _ = &a + b; | 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; - | ~ ~~ +LL - let _ = &a + b; +LL + let _ = a + &b; + | error[E0308]: mismatched types --> $DIR/issue-39018.rs:29:17 @@ -100,7 +102,7 @@ LL | let _ = e + b; 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 _ = e.to_owned() + &b; - | ~~~~~~~~~~~~ ~~ + | +++++++++++ + error[E0369]: cannot add `&String` to `&String` --> $DIR/issue-39018.rs:31:15 @@ -114,7 +116,7 @@ LL | let _ = e + &b; 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 _ = e.to_owned() + &b; - | ~~~~~~~~~~~~ + | +++++++++++ error[E0369]: cannot add `&str` to `&String` --> $DIR/issue-39018.rs:32:15 @@ -128,7 +130,7 @@ LL | let _ = e + d; 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 _ = e.to_owned() + d; - | ~~~~~~~~~~~~ + | +++++++++++ error[E0369]: cannot add `&&str` to `&String` --> $DIR/issue-39018.rs:33:15 @@ -142,7 +144,7 @@ LL | let _ = e + &d; 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 _ = e.to_owned() + &d; - | ~~~~~~~~~~~~ + | +++++++++++ error[E0369]: cannot add `&&str` to `&&str` --> $DIR/issue-39018.rs:34:16 @@ -172,7 +174,7 @@ LL | let _ = c + &d; 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 _ = c.to_owned() + &d; - | ~~~~~~~~~~~~ + | +++++++++++ error[E0369]: cannot add `&str` to `&str` --> $DIR/issue-39018.rs:37:15 @@ -186,7 +188,7 @@ LL | let _ = c + d; 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 _ = c.to_owned() + d; - | ~~~~~~~~~~~~ + | +++++++++++ error: aborting due to 14 previous errors diff --git a/src/test/ui/str/str-concat-on-double-ref.stderr b/src/test/ui/str/str-concat-on-double-ref.stderr index dee28897f4d..cc9456be901 100644 --- a/src/test/ui/str/str-concat-on-double-ref.stderr +++ b/src/test/ui/str/str-concat-on-double-ref.stderr @@ -10,7 +10,7 @@ LL | let c = a + b; 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 c = a.to_owned() + b; - | ~~~~~~~~~~~~ + | +++++++++++ error: aborting due to previous error diff --git a/src/test/ui/terminal-width/non-1-width-unicode-multiline-label.stderr b/src/test/ui/terminal-width/non-1-width-unicode-multiline-label.stderr index 480f442fedd..2da3db4a7fa 100644 --- a/src/test/ui/terminal-width/non-1-width-unicode-multiline-label.stderr +++ b/src/test/ui/terminal-width/non-1-width-unicode-multiline-label.stderr @@ -10,7 +10,7 @@ LL | ...ཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔ 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 _ = "ༀ༁༂༃༄༅༆༇༈༉༊་༌།༎༏༐༑༒༓༔༕༖༗༘༙༚༛༜༝༞༟༠༡༢༣༤༥༦༧༨༩༪༫༬༭༮༯༰༱༲༳༴༵༶༷༸༹༺༻༼༽༾༿ཀཁགགྷངཅཆཇ཈ཉཊཋཌཌྷཎཏཐདདྷནཔཕབབྷམཙཚཛཛྷཝཞཟའཡརལཤཥསཧཨཀྵཪཫཬ཭཮཯཰ཱཱཱིིུུྲྀཷླྀཹེཻོཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗ྘ྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྽྾྿࿀࿁࿂࿃࿄࿅࿆࿇࿈࿉࿊࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun.to_owned() + " really fun!"; - | ~~~~~~~~~~~~~~~~~~~~~~~~~ + | +++++++++++ error: aborting due to previous error From 69db5e2c8c8bca8bc513cbe4ffa37dff234ad508 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Wed, 12 Jan 2022 22:20:13 -0800 Subject: [PATCH 2/6] Split up very long message This should make it easier to read. --- compiler/rustc_typeck/src/check/op.rs | 37 ++++++++++--------- src/test/ui/issues/issue-47377.stderr | 3 +- src/test/ui/issues/issue-47380.stderr | 3 +- src/test/ui/span/issue-39018.stderr | 31 +++++++++------- .../ui/str/str-concat-on-double-ref.stderr | 3 +- ...non-1-width-unicode-multiline-label.stderr | 3 +- 6 files changed, 44 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_typeck/src/check/op.rs b/compiler/rustc_typeck/src/check/op.rs index 838f8b0a61d..8bb0613f456 100644 --- a/compiler/rustc_typeck/src/check/op.rs +++ b/compiler/rustc_typeck/src/check/op.rs @@ -549,15 +549,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { is_assign: IsAssign, op: hir::BinOp, ) -> bool { - let remove_borrow_msg = "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"; - - let msg = "`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"; + let str_concat_note = "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."; + let rm_borrow_msg = "remove the borrow to obtain an owned `String`"; + let to_owned_msg = "use `to_owned()` to create an owned `String` from a string reference"; let string_type = self.tcx.get_diagnostic_item(sym::String); let is_std_string = |ty: Ty<'tcx>| match ty.ty_adt_def() { @@ -574,17 +570,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { if let IsAssign::No = is_assign { // Do not supply this message if `&str += &str` err.span_label(op.span, "`+` cannot be used to concatenate two `&str` strings"); + err.note(str_concat_note); if let hir::ExprKind::AddrOf(_,_,lhs_inner_expr) = lhs_expr.kind { err.span_suggestion( lhs_expr.span.until(lhs_inner_expr.span), - remove_borrow_msg, + rm_borrow_msg, "".to_owned(), Applicability::MachineApplicable ); } else { err.span_suggestion( lhs_expr.span.shrink_to_hi(), - msg, + to_owned_msg, ".to_owned()".to_owned(), Applicability::MachineApplicable ); @@ -601,18 +598,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); match is_assign { IsAssign::No => { + let sugg_msg; + let lhs_sugg = if let hir::ExprKind::AddrOf(_, _, lhs_inner_expr) = lhs_expr.kind { + sugg_msg = "remove the borrow on the left and add one on the right"; + (lhs_expr.span.until(lhs_inner_expr.span), "".to_owned()) + } else { + sugg_msg = "call `.to_owned()` on the left and add a borrow on the right"; + (lhs_expr.span.shrink_to_hi(), ".to_owned()".to_owned()) + }; let suggestions = vec![ - if let hir::ExprKind::AddrOf(_, _, lhs_inner_expr) = lhs_expr.kind { - (lhs_expr.span.until(lhs_inner_expr.span), "".to_owned()) - } else { - (lhs_expr.span.shrink_to_hi(), ".to_owned()".to_owned()) - }, + lhs_sugg, (rhs_expr.span.shrink_to_lo(), "&".to_owned()), ]; - err.multipart_suggestion(msg, suggestions, Applicability::MachineApplicable); + err.multipart_suggestion(sugg_msg, suggestions, Applicability::MachineApplicable); } IsAssign::Yes => { - err.help(msg); + err.note(str_concat_note); } } true diff --git a/src/test/ui/issues/issue-47377.stderr b/src/test/ui/issues/issue-47377.stderr index 2c17a19779f..2e00de84087 100644 --- a/src/test/ui/issues/issue-47377.stderr +++ b/src/test/ui/issues/issue-47377.stderr @@ -7,7 +7,8 @@ LL | let _a = b + ", World!"; | | `+` cannot be used to concatenate two `&str` strings | &str | -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 + = note: 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. +help: use `to_owned()` to create an owned `String` from a string reference | 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 417206e6cc4..fec64009444 100644 --- a/src/test/ui/issues/issue-47380.stderr +++ b/src/test/ui/issues/issue-47380.stderr @@ -7,7 +7,8 @@ LL | println!("🦀🦀🦀🦀🦀"); let _a = b + ", World!"; | | `+` cannot be used to concatenate two `&str` strings | &str | -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 + = note: 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. +help: use `to_owned()` to create an owned `String` from a string reference | 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 444d037571e..9054dd931ca 100644 --- a/src/test/ui/span/issue-39018.stderr +++ b/src/test/ui/span/issue-39018.stderr @@ -7,7 +7,8 @@ LL | let x = "Hello " + "World!"; | | `+` cannot be used to concatenate two `&str` strings | &str | -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 + = note: 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. +help: use `to_owned()` to create an owned `String` from a string reference | LL | let x = "Hello ".to_owned() + "World!"; | +++++++++++ @@ -46,7 +47,7 @@ LL | let x = "Hello " + "World!".to_owned(); | | `+` cannot be used to concatenate a `&str` with a `String` | &str | -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 +help: call `.to_owned()` on the left and add a borrow on the right | LL | let x = "Hello ".to_owned() + &"World!".to_owned(); | +++++++++++ + @@ -59,12 +60,9 @@ LL | let _ = &a + &b; | | | | | `+` cannot be used to concatenate two `&str` strings | &String + | help: remove the borrow to obtain an owned `String` | -help: 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; -LL + let _ = a + &b; - | + = note: 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. error[E0369]: cannot add `String` to `&String` --> $DIR/issue-39018.rs:27:16 @@ -75,7 +73,7 @@ LL | let _ = &a + b; | | `+` cannot be used to concatenate a `&str` with a `String` | &String | -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 +help: remove the borrow on the left and add one on the right | LL - let _ = &a + b; LL + let _ = a + &b; @@ -99,7 +97,7 @@ LL | let _ = e + b; | | `+` cannot be used to concatenate a `&str` with a `String` | &String | -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 +help: call `.to_owned()` on the left and add a borrow on the right | LL | let _ = e.to_owned() + &b; | +++++++++++ + @@ -113,7 +111,8 @@ LL | let _ = e + &b; | | `+` cannot be used to concatenate two `&str` strings | &String | -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 + = note: 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. +help: use `to_owned()` to create an owned `String` from a string reference | LL | let _ = e.to_owned() + &b; | +++++++++++ @@ -127,7 +126,8 @@ LL | let _ = e + d; | | `+` cannot be used to concatenate two `&str` strings | &String | -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 + = note: 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. +help: use `to_owned()` to create an owned `String` from a string reference | LL | let _ = e.to_owned() + d; | +++++++++++ @@ -141,7 +141,8 @@ LL | let _ = e + &d; | | `+` cannot be used to concatenate two `&str` strings | &String | -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 + = note: 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. +help: use `to_owned()` to create an owned `String` from a string reference | LL | let _ = e.to_owned() + &d; | +++++++++++ @@ -171,7 +172,8 @@ LL | let _ = c + &d; | | `+` cannot be used to concatenate two `&str` strings | &str | -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 + = note: 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. +help: use `to_owned()` to create an owned `String` from a string reference | LL | let _ = c.to_owned() + &d; | +++++++++++ @@ -185,7 +187,8 @@ LL | let _ = c + d; | | `+` cannot be used to concatenate two `&str` strings | &str | -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 + = note: 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. +help: use `to_owned()` to create an owned `String` from a string reference | LL | let _ = c.to_owned() + d; | +++++++++++ diff --git a/src/test/ui/str/str-concat-on-double-ref.stderr b/src/test/ui/str/str-concat-on-double-ref.stderr index cc9456be901..e8b5c2bbd85 100644 --- a/src/test/ui/str/str-concat-on-double-ref.stderr +++ b/src/test/ui/str/str-concat-on-double-ref.stderr @@ -7,7 +7,8 @@ LL | let c = a + b; | | `+` cannot be used to concatenate two `&str` strings | &String | -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 + = note: 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. +help: use `to_owned()` to create an owned `String` from a string reference | LL | let c = a.to_owned() + b; | +++++++++++ diff --git a/src/test/ui/terminal-width/non-1-width-unicode-multiline-label.stderr b/src/test/ui/terminal-width/non-1-width-unicode-multiline-label.stderr index 2da3db4a7fa..72005a88980 100644 --- a/src/test/ui/terminal-width/non-1-width-unicode-multiline-label.stderr +++ b/src/test/ui/terminal-width/non-1-width-unicode-multiline-label.stderr @@ -7,7 +7,8 @@ LL | ...ཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔ | | `+` cannot be used to concatenate two `&str` strings | &str | -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 + = note: 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. +help: use `to_owned()` to create an owned `String` from a string reference | LL | let _ = "ༀ༁༂༃༄༅༆༇༈༉༊་༌།༎༏༐༑༒༓༔༕༖༗༘༙༚༛༜༝༞༟༠༡༢༣༤༥༦༧༨༩༪༫༬༭༮༯༰༱༲༳༴༵༶༷༸༹༺༻༼༽༾༿ཀཁགགྷངཅཆཇ཈ཉཊཋཌཌྷཎཏཐདདྷནཔཕབབྷམཙཚཛཛྷཝཞཟའཡརལཤཥསཧཨཀྵཪཫཬ཭཮཯཰ཱཱཱིིུུྲྀཷླྀཹེཻོཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗ྘ྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྽྾྿࿀࿁࿂࿃࿄࿅࿆࿇࿈࿉࿊࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun.to_owned() + " really fun!"; | +++++++++++ From 935a99a4d1abfb517dfadf11fa29500348cc2b1c Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Wed, 12 Jan 2022 22:23:56 -0800 Subject: [PATCH 3/6] Add line breaks to make message easier to read --- compiler/rustc_typeck/src/check/op.rs | 6 ++-- src/test/ui/issues/issue-47377.stderr | 4 ++- src/test/ui/issues/issue-47380.stderr | 4 ++- src/test/ui/span/issue-39018.stderr | 28 ++++++++++++++----- .../ui/str/str-concat-on-double-ref.stderr | 4 ++- ...non-1-width-unicode-multiline-label.stderr | 4 ++- 6 files changed, 36 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_typeck/src/check/op.rs b/compiler/rustc_typeck/src/check/op.rs index 8bb0613f456..be1b01ae294 100644 --- a/compiler/rustc_typeck/src/check/op.rs +++ b/compiler/rustc_typeck/src/check/op.rs @@ -549,9 +549,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { is_assign: IsAssign, op: hir::BinOp, ) -> bool { - let str_concat_note = "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."; + let str_concat_note = "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."; let rm_borrow_msg = "remove the borrow to obtain an owned `String`"; let to_owned_msg = "use `to_owned()` to create an owned `String` from a string reference"; diff --git a/src/test/ui/issues/issue-47377.stderr b/src/test/ui/issues/issue-47377.stderr index 2e00de84087..97fbb53bd02 100644 --- a/src/test/ui/issues/issue-47377.stderr +++ b/src/test/ui/issues/issue-47377.stderr @@ -7,7 +7,9 @@ LL | let _a = b + ", World!"; | | `+` cannot be used to concatenate two `&str` strings | &str | - = note: 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. + = note: 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. help: use `to_owned()` to create an owned `String` from a string reference | 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 fec64009444..7a73d41a035 100644 --- a/src/test/ui/issues/issue-47380.stderr +++ b/src/test/ui/issues/issue-47380.stderr @@ -7,7 +7,9 @@ LL | println!("🦀🦀🦀🦀🦀"); let _a = b + ", World!"; | | `+` cannot be used to concatenate two `&str` strings | &str | - = note: 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. + = note: 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. help: use `to_owned()` to create an owned `String` from a string reference | 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 9054dd931ca..9e466f3a9a0 100644 --- a/src/test/ui/span/issue-39018.stderr +++ b/src/test/ui/span/issue-39018.stderr @@ -7,7 +7,9 @@ LL | let x = "Hello " + "World!"; | | `+` cannot be used to concatenate two `&str` strings | &str | - = note: 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. + = note: 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. help: use `to_owned()` to create an owned `String` from a string reference | LL | let x = "Hello ".to_owned() + "World!"; @@ -62,7 +64,9 @@ LL | let _ = &a + &b; | &String | help: remove the borrow to obtain an owned `String` | - = note: 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. + = note: 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. error[E0369]: cannot add `String` to `&String` --> $DIR/issue-39018.rs:27:16 @@ -111,7 +115,9 @@ LL | let _ = e + &b; | | `+` cannot be used to concatenate two `&str` strings | &String | - = note: 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. + = note: 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. help: use `to_owned()` to create an owned `String` from a string reference | LL | let _ = e.to_owned() + &b; @@ -126,7 +132,9 @@ LL | let _ = e + d; | | `+` cannot be used to concatenate two `&str` strings | &String | - = note: 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. + = note: 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. help: use `to_owned()` to create an owned `String` from a string reference | LL | let _ = e.to_owned() + d; @@ -141,7 +149,9 @@ LL | let _ = e + &d; | | `+` cannot be used to concatenate two `&str` strings | &String | - = note: 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. + = note: 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. help: use `to_owned()` to create an owned `String` from a string reference | LL | let _ = e.to_owned() + &d; @@ -172,7 +182,9 @@ LL | let _ = c + &d; | | `+` cannot be used to concatenate two `&str` strings | &str | - = note: 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. + = note: 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. help: use `to_owned()` to create an owned `String` from a string reference | LL | let _ = c.to_owned() + &d; @@ -187,7 +199,9 @@ LL | let _ = c + d; | | `+` cannot be used to concatenate two `&str` strings | &str | - = note: 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. + = note: 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. help: use `to_owned()` to create an owned `String` from a string reference | LL | let _ = c.to_owned() + d; diff --git a/src/test/ui/str/str-concat-on-double-ref.stderr b/src/test/ui/str/str-concat-on-double-ref.stderr index e8b5c2bbd85..d239ec0d9fc 100644 --- a/src/test/ui/str/str-concat-on-double-ref.stderr +++ b/src/test/ui/str/str-concat-on-double-ref.stderr @@ -7,7 +7,9 @@ LL | let c = a + b; | | `+` cannot be used to concatenate two `&str` strings | &String | - = note: 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. + = note: 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. help: use `to_owned()` to create an owned `String` from a string reference | LL | let c = a.to_owned() + b; diff --git a/src/test/ui/terminal-width/non-1-width-unicode-multiline-label.stderr b/src/test/ui/terminal-width/non-1-width-unicode-multiline-label.stderr index 72005a88980..55e993db3d3 100644 --- a/src/test/ui/terminal-width/non-1-width-unicode-multiline-label.stderr +++ b/src/test/ui/terminal-width/non-1-width-unicode-multiline-label.stderr @@ -7,7 +7,9 @@ LL | ...ཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔ | | `+` cannot be used to concatenate two `&str` strings | &str | - = note: 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. + = note: 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. help: use `to_owned()` to create an owned `String` from a string reference | LL | let _ = "ༀ༁༂༃༄༅༆༇༈༉༊་༌།༎༏༐༑༒༓༔༕༖༗༘༙༚༛༜༝༞༟༠༡༢༣༤༥༦༧༨༩༪༫༬༭༮༯༰༱༲༳༴༵༶༷༸༹༺༻༼༽༾༿ཀཁགགྷངཅཆཇ཈ཉཊཋཌཌྷཎཏཐདདྷནཔཕབབྷམཙཚཛཛྷཝཞཟའཡརལཤཥསཧཨཀྵཪཫཬ཭཮཯཰ཱཱཱིིུུྲྀཷླྀཹེཻོཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗ྘ྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྽྾྿࿀࿁࿂࿃࿄࿅࿆࿇࿈࿉࿊࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun.to_owned() + " really fun!"; From 6e42bc378fe2225c21d13957c1299ee349fcdfaf Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Wed, 12 Jan 2022 22:25:53 -0800 Subject: [PATCH 4/6] Fix formatting This code is sufficiently complex -- I'm guessing due to the very long `match` guards -- that rustfmt doesn't format it. --- compiler/rustc_typeck/src/check/op.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_typeck/src/check/op.rs b/compiler/rustc_typeck/src/check/op.rs index be1b01ae294..c7bb66f339c 100644 --- a/compiler/rustc_typeck/src/check/op.rs +++ b/compiler/rustc_typeck/src/check/op.rs @@ -571,7 +571,7 @@ This requires ownership of the string on the left."; if let IsAssign::No = is_assign { // Do not supply this message if `&str += &str` err.span_label(op.span, "`+` cannot be used to concatenate two `&str` strings"); err.note(str_concat_note); - if let hir::ExprKind::AddrOf(_,_,lhs_inner_expr) = lhs_expr.kind { + if let hir::ExprKind::AddrOf(_, _, lhs_inner_expr) = lhs_expr.kind { err.span_suggestion( lhs_expr.span.until(lhs_inner_expr.span), rm_borrow_msg, From 7507fb6306d540a6f07f6f325d25925311b037a2 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Tue, 18 Jan 2022 16:32:58 -0800 Subject: [PATCH 5/6] Shorten and improve messages --- compiler/rustc_typeck/src/check/op.rs | 8 +- src/test/ui/issues/issue-47377.stderr | 15 +-- src/test/ui/issues/issue-47380.stderr | 15 +-- src/test/ui/span/issue-39018.stderr | 98 +++++++------------ .../ui/str/str-concat-on-double-ref.stderr | 15 +-- ...non-1-width-unicode-multiline-label.stderr | 19 ++-- 6 files changed, 58 insertions(+), 112 deletions(-) diff --git a/compiler/rustc_typeck/src/check/op.rs b/compiler/rustc_typeck/src/check/op.rs index c7bb66f339c..82da66c09e4 100644 --- a/compiler/rustc_typeck/src/check/op.rs +++ b/compiler/rustc_typeck/src/check/op.rs @@ -549,11 +549,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { is_assign: IsAssign, op: hir::BinOp, ) -> bool { - let str_concat_note = "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."; + let str_concat_note = "string concatenation requires an owned `String` on the left"; let rm_borrow_msg = "remove the borrow to obtain an owned `String`"; - let to_owned_msg = "use `to_owned()` to create an owned `String` from a string reference"; + let to_owned_msg = "create an owned `String` from a string reference"; let string_type = self.tcx.get_diagnostic_item(sym::String); let is_std_string = |ty: Ty<'tcx>| match ty.ty_adt_def() { @@ -603,7 +601,7 @@ This requires ownership of the string on the left."; sugg_msg = "remove the borrow on the left and add one on the right"; (lhs_expr.span.until(lhs_inner_expr.span), "".to_owned()) } else { - sugg_msg = "call `.to_owned()` on the left and add a borrow on the right"; + sugg_msg = "create an owned `String` on the left and add a borrow on the right"; (lhs_expr.span.shrink_to_hi(), ".to_owned()".to_owned()) }; let suggestions = vec![ diff --git a/src/test/ui/issues/issue-47377.stderr b/src/test/ui/issues/issue-47377.stderr index 97fbb53bd02..e4b907070a6 100644 --- a/src/test/ui/issues/issue-47377.stderr +++ b/src/test/ui/issues/issue-47377.stderr @@ -2,18 +2,13 @@ error[E0369]: cannot add `&str` to `&str` --> $DIR/issue-47377.rs:4:14 | LL | let _a = b + ", World!"; - | - ^ ---------- &str - | | | - | | `+` cannot be used to concatenate two `&str` strings + | --^ ---------- &str + | ||| + | ||`+` cannot be used to concatenate two `&str` strings + | |help: create an owned `String` from a string reference: `.to_owned()` | &str | - = note: 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. -help: use `to_owned()` to create an owned `String` from a string reference - | -LL | let _a = b.to_owned() + ", World!"; - | +++++++++++ + = note: string concatenation requires an owned `String` on the left error: aborting due to previous error diff --git a/src/test/ui/issues/issue-47380.stderr b/src/test/ui/issues/issue-47380.stderr index 7a73d41a035..7ad369fcd0e 100644 --- a/src/test/ui/issues/issue-47380.stderr +++ b/src/test/ui/issues/issue-47380.stderr @@ -2,18 +2,13 @@ error[E0369]: cannot add `&str` to `&str` --> $DIR/issue-47380.rs:3:35 | LL | println!("🦀🦀🦀🦀🦀"); let _a = b + ", World!"; - | - ^ ---------- &str - | | | - | | `+` cannot be used to concatenate two `&str` strings + | --^ ---------- &str + | ||| + | ||`+` cannot be used to concatenate two `&str` strings + | |help: create an owned `String` from a string reference: `.to_owned()` | &str | - = note: 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. -help: use `to_owned()` to create an owned `String` from a string reference - | -LL | println!("🦀🦀🦀🦀🦀"); let _a = b.to_owned() + ", World!"; - | +++++++++++ + = note: string concatenation requires an owned `String` on the left error: aborting due to previous error diff --git a/src/test/ui/span/issue-39018.stderr b/src/test/ui/span/issue-39018.stderr index 9e466f3a9a0..9cfb015e753 100644 --- a/src/test/ui/span/issue-39018.stderr +++ b/src/test/ui/span/issue-39018.stderr @@ -2,18 +2,13 @@ error[E0369]: cannot add `&str` to `&str` --> $DIR/issue-39018.rs:2:22 | LL | let x = "Hello " + "World!"; - | -------- ^ -------- &str - | | | - | | `+` cannot be used to concatenate two `&str` strings + | ---------^ -------- &str + | | || + | | |`+` cannot be used to concatenate two `&str` strings + | | help: create an owned `String` from a string reference: `.to_owned()` | &str | - = note: 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. -help: use `to_owned()` to create an owned `String` from a string reference - | -LL | let x = "Hello ".to_owned() + "World!"; - | +++++++++++ + = note: string concatenation requires an owned `String` on the left error[E0369]: cannot add `World` to `World` --> $DIR/issue-39018.rs:8:26 @@ -49,7 +44,7 @@ LL | let x = "Hello " + "World!".to_owned(); | | `+` cannot be used to concatenate a `&str` with a `String` | &str | -help: call `.to_owned()` on the left and add a borrow on the right +help: create an owned `String` on the left and add a borrow on the right | LL | let x = "Hello ".to_owned() + &"World!".to_owned(); | +++++++++++ + @@ -64,9 +59,7 @@ LL | let _ = &a + &b; | &String | help: remove the borrow to obtain an owned `String` | - = note: 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. + = note: string concatenation requires an owned `String` on the left error[E0369]: cannot add `String` to `&String` --> $DIR/issue-39018.rs:27:16 @@ -101,7 +94,7 @@ LL | let _ = e + b; | | `+` cannot be used to concatenate a `&str` with a `String` | &String | -help: call `.to_owned()` on the left and add a borrow on the right +help: create an owned `String` on the left and add a borrow on the right | LL | let _ = e.to_owned() + &b; | +++++++++++ + @@ -110,52 +103,37 @@ error[E0369]: cannot add `&String` to `&String` --> $DIR/issue-39018.rs:31:15 | LL | let _ = e + &b; - | - ^ -- &String - | | | - | | `+` cannot be used to concatenate two `&str` strings + | --^ -- &String + | ||| + | ||`+` cannot be used to concatenate two `&str` strings + | |help: create an owned `String` from a string reference: `.to_owned()` | &String | - = note: 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. -help: use `to_owned()` to create an owned `String` from a string reference - | -LL | let _ = e.to_owned() + &b; - | +++++++++++ + = note: string concatenation requires an owned `String` on the left error[E0369]: cannot add `&str` to `&String` --> $DIR/issue-39018.rs:32:15 | LL | let _ = e + d; - | - ^ - &str - | | | - | | `+` cannot be used to concatenate two `&str` strings + | --^ - &str + | ||| + | ||`+` cannot be used to concatenate two `&str` strings + | |help: create an owned `String` from a string reference: `.to_owned()` | &String | - = note: 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. -help: use `to_owned()` to create an owned `String` from a string reference - | -LL | let _ = e.to_owned() + d; - | +++++++++++ + = note: string concatenation requires an owned `String` on the left error[E0369]: cannot add `&&str` to `&String` --> $DIR/issue-39018.rs:33:15 | LL | let _ = e + &d; - | - ^ -- &&str - | | | - | | `+` cannot be used to concatenate two `&str` strings + | --^ -- &&str + | ||| + | ||`+` cannot be used to concatenate two `&str` strings + | |help: create an owned `String` from a string reference: `.to_owned()` | &String | - = note: 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. -help: use `to_owned()` to create an owned `String` from a string reference - | -LL | let _ = e.to_owned() + &d; - | +++++++++++ + = note: string concatenation requires an owned `String` on the left error[E0369]: cannot add `&&str` to `&&str` --> $DIR/issue-39018.rs:34:16 @@ -177,35 +155,25 @@ error[E0369]: cannot add `&&str` to `&str` --> $DIR/issue-39018.rs:36:15 | LL | let _ = c + &d; - | - ^ -- &&str - | | | - | | `+` cannot be used to concatenate two `&str` strings + | --^ -- &&str + | ||| + | ||`+` cannot be used to concatenate two `&str` strings + | |help: create an owned `String` from a string reference: `.to_owned()` | &str | - = note: 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. -help: use `to_owned()` to create an owned `String` from a string reference - | -LL | let _ = c.to_owned() + &d; - | +++++++++++ + = note: string concatenation requires an owned `String` on the left error[E0369]: cannot add `&str` to `&str` --> $DIR/issue-39018.rs:37:15 | LL | let _ = c + d; - | - ^ - &str - | | | - | | `+` cannot be used to concatenate two `&str` strings + | --^ - &str + | ||| + | ||`+` cannot be used to concatenate two `&str` strings + | |help: create an owned `String` from a string reference: `.to_owned()` | &str | - = note: 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. -help: use `to_owned()` to create an owned `String` from a string reference - | -LL | let _ = c.to_owned() + d; - | +++++++++++ + = note: string concatenation requires an owned `String` on the left error: aborting due to 14 previous errors diff --git a/src/test/ui/str/str-concat-on-double-ref.stderr b/src/test/ui/str/str-concat-on-double-ref.stderr index d239ec0d9fc..251bc7ac0ea 100644 --- a/src/test/ui/str/str-concat-on-double-ref.stderr +++ b/src/test/ui/str/str-concat-on-double-ref.stderr @@ -2,18 +2,13 @@ error[E0369]: cannot add `&str` to `&String` --> $DIR/str-concat-on-double-ref.rs:4:15 | LL | let c = a + b; - | - ^ - &str - | | | - | | `+` cannot be used to concatenate two `&str` strings + | --^ - &str + | ||| + | ||`+` cannot be used to concatenate two `&str` strings + | |help: create an owned `String` from a string reference: `.to_owned()` | &String | - = note: 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. -help: use `to_owned()` to create an owned `String` from a string reference - | -LL | let c = a.to_owned() + b; - | +++++++++++ + = note: string concatenation requires an owned `String` on the left error: aborting due to previous error diff --git a/src/test/ui/terminal-width/non-1-width-unicode-multiline-label.stderr b/src/test/ui/terminal-width/non-1-width-unicode-multiline-label.stderr index 55e993db3d3..a97ecc4ce15 100644 --- a/src/test/ui/terminal-width/non-1-width-unicode-multiline-label.stderr +++ b/src/test/ui/terminal-width/non-1-width-unicode-multiline-label.stderr @@ -1,19 +1,14 @@ error[E0369]: cannot add `&str` to `&str` --> $DIR/non-1-width-unicode-multiline-label.rs:5:260 | -LL | ...ཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗ྘ྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྽྾྿࿀࿁࿂࿃࿄࿅࿆࿇...࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun + " really fun!"; - | -------------- ^ -------------- &str - | | | - | | `+` cannot be used to concatenate two `&str` strings - | &str +LL | ...྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗ྘ྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྽྾྿࿀࿁࿂࿃࿄࿅࿆࿇࿈࿉࿊࿋࿌࿍࿎...࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun + " really fun!"; + | ---------------^ -------------- &str + | | || + | | |`+` cannot be used to concatenate two `&str` strings + | | help: create an owned `String` from a string reference: `.to_owned()` + | &str | - = note: 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. -help: use `to_owned()` to create an owned `String` from a string reference - | -LL | let _ = "ༀ༁༂༃༄༅༆༇༈༉༊་༌།༎༏༐༑༒༓༔༕༖༗༘༙༚༛༜༝༞༟༠༡༢༣༤༥༦༧༨༩༪༫༬༭༮༯༰༱༲༳༴༵༶༷༸༹༺༻༼༽༾༿ཀཁགགྷངཅཆཇ཈ཉཊཋཌཌྷཎཏཐདདྷནཔཕབབྷམཙཚཛཛྷཝཞཟའཡརལཤཥསཧཨཀྵཪཫཬ཭཮཯཰ཱཱཱིིུུྲྀཷླྀཹེཻོཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗ྘ྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྽྾྿࿀࿁࿂࿃࿄࿅࿆࿇࿈࿉࿊࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun.to_owned() + " really fun!"; - | +++++++++++ + = note: string concatenation requires an owned `String` on the left error: aborting due to previous error From 7c4eca06871f83257f9f503c3a91a8946026133a Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Tue, 18 Jan 2022 16:38:06 -0800 Subject: [PATCH 6/6] Make suggestions verbose --- compiler/rustc_typeck/src/check/op.rs | 10 ++- src/test/ui/issues/issue-47377.stderr | 11 +-- src/test/ui/issues/issue-47380.stderr | 11 +-- src/test/ui/span/issue-39018.stderr | 72 ++++++++++++------- .../ui/str/str-concat-on-double-ref.stderr | 11 +-- ...non-1-width-unicode-multiline-label.stderr | 15 ++-- 6 files changed, 84 insertions(+), 46 deletions(-) diff --git a/compiler/rustc_typeck/src/check/op.rs b/compiler/rustc_typeck/src/check/op.rs index 82da66c09e4..81662b752b7 100644 --- a/compiler/rustc_typeck/src/check/op.rs +++ b/compiler/rustc_typeck/src/check/op.rs @@ -570,14 +570,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_label(op.span, "`+` cannot be used to concatenate two `&str` strings"); err.note(str_concat_note); if let hir::ExprKind::AddrOf(_, _, lhs_inner_expr) = lhs_expr.kind { - err.span_suggestion( + err.span_suggestion_verbose( lhs_expr.span.until(lhs_inner_expr.span), rm_borrow_msg, "".to_owned(), Applicability::MachineApplicable ); } else { - err.span_suggestion( + err.span_suggestion_verbose( lhs_expr.span.shrink_to_hi(), to_owned_msg, ".to_owned()".to_owned(), @@ -608,7 +608,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { lhs_sugg, (rhs_expr.span.shrink_to_lo(), "&".to_owned()), ]; - err.multipart_suggestion(sugg_msg, suggestions, Applicability::MachineApplicable); + err.multipart_suggestion_verbose( + sugg_msg, + suggestions, + Applicability::MachineApplicable, + ); } IsAssign::Yes => { err.note(str_concat_note); diff --git a/src/test/ui/issues/issue-47377.stderr b/src/test/ui/issues/issue-47377.stderr index e4b907070a6..4f0fd948e76 100644 --- a/src/test/ui/issues/issue-47377.stderr +++ b/src/test/ui/issues/issue-47377.stderr @@ -2,13 +2,16 @@ error[E0369]: cannot add `&str` to `&str` --> $DIR/issue-47377.rs:4:14 | LL | let _a = b + ", World!"; - | --^ ---------- &str - | ||| - | ||`+` cannot be used to concatenate two `&str` strings - | |help: create an owned `String` from a string reference: `.to_owned()` + | - ^ ---------- &str + | | | + | | `+` cannot be used to concatenate two `&str` strings | &str | = note: string concatenation requires an owned `String` on the left +help: create an owned `String` from a string reference + | +LL | let _a = b.to_owned() + ", World!"; + | +++++++++++ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-47380.stderr b/src/test/ui/issues/issue-47380.stderr index 7ad369fcd0e..b04ac5536c4 100644 --- a/src/test/ui/issues/issue-47380.stderr +++ b/src/test/ui/issues/issue-47380.stderr @@ -2,13 +2,16 @@ error[E0369]: cannot add `&str` to `&str` --> $DIR/issue-47380.rs:3:35 | LL | println!("🦀🦀🦀🦀🦀"); let _a = b + ", World!"; - | --^ ---------- &str - | ||| - | ||`+` cannot be used to concatenate two `&str` strings - | |help: create an owned `String` from a string reference: `.to_owned()` + | - ^ ---------- &str + | | | + | | `+` cannot be used to concatenate two `&str` strings | &str | = note: string concatenation requires an owned `String` on the left +help: create an owned `String` from a string reference + | +LL | println!("🦀🦀🦀🦀🦀"); let _a = b.to_owned() + ", World!"; + | +++++++++++ error: aborting due to previous error diff --git a/src/test/ui/span/issue-39018.stderr b/src/test/ui/span/issue-39018.stderr index 9cfb015e753..e2e7ce1ed18 100644 --- a/src/test/ui/span/issue-39018.stderr +++ b/src/test/ui/span/issue-39018.stderr @@ -2,13 +2,16 @@ error[E0369]: cannot add `&str` to `&str` --> $DIR/issue-39018.rs:2:22 | LL | let x = "Hello " + "World!"; - | ---------^ -------- &str - | | || - | | |`+` cannot be used to concatenate two `&str` strings - | | help: create an owned `String` from a string reference: `.to_owned()` + | -------- ^ -------- &str + | | | + | | `+` cannot be used to concatenate two `&str` strings | &str | = note: string concatenation requires an owned `String` on the left +help: create an owned `String` from a string reference + | +LL | let x = "Hello ".to_owned() + "World!"; + | +++++++++++ error[E0369]: cannot add `World` to `World` --> $DIR/issue-39018.rs:8:26 @@ -57,9 +60,13 @@ LL | let _ = &a + &b; | | | | | `+` cannot be used to concatenate two `&str` strings | &String - | help: remove the borrow to obtain an owned `String` | = note: string concatenation requires an owned `String` on the left +help: remove the borrow to obtain an owned `String` + | +LL - let _ = &a + &b; +LL + let _ = a + &b; + | error[E0369]: cannot add `String` to `&String` --> $DIR/issue-39018.rs:27:16 @@ -103,37 +110,46 @@ error[E0369]: cannot add `&String` to `&String` --> $DIR/issue-39018.rs:31:15 | LL | let _ = e + &b; - | --^ -- &String - | ||| - | ||`+` cannot be used to concatenate two `&str` strings - | |help: create an owned `String` from a string reference: `.to_owned()` + | - ^ -- &String + | | | + | | `+` cannot be used to concatenate two `&str` strings | &String | = note: string concatenation requires an owned `String` on the left +help: create an owned `String` from a string reference + | +LL | let _ = e.to_owned() + &b; + | +++++++++++ error[E0369]: cannot add `&str` to `&String` --> $DIR/issue-39018.rs:32:15 | LL | let _ = e + d; - | --^ - &str - | ||| - | ||`+` cannot be used to concatenate two `&str` strings - | |help: create an owned `String` from a string reference: `.to_owned()` + | - ^ - &str + | | | + | | `+` cannot be used to concatenate two `&str` strings | &String | = note: string concatenation requires an owned `String` on the left +help: create an owned `String` from a string reference + | +LL | let _ = e.to_owned() + d; + | +++++++++++ error[E0369]: cannot add `&&str` to `&String` --> $DIR/issue-39018.rs:33:15 | LL | let _ = e + &d; - | --^ -- &&str - | ||| - | ||`+` cannot be used to concatenate two `&str` strings - | |help: create an owned `String` from a string reference: `.to_owned()` + | - ^ -- &&str + | | | + | | `+` cannot be used to concatenate two `&str` strings | &String | = note: string concatenation requires an owned `String` on the left +help: create an owned `String` from a string reference + | +LL | let _ = e.to_owned() + &d; + | +++++++++++ error[E0369]: cannot add `&&str` to `&&str` --> $DIR/issue-39018.rs:34:16 @@ -155,25 +171,31 @@ error[E0369]: cannot add `&&str` to `&str` --> $DIR/issue-39018.rs:36:15 | LL | let _ = c + &d; - | --^ -- &&str - | ||| - | ||`+` cannot be used to concatenate two `&str` strings - | |help: create an owned `String` from a string reference: `.to_owned()` + | - ^ -- &&str + | | | + | | `+` cannot be used to concatenate two `&str` strings | &str | = note: string concatenation requires an owned `String` on the left +help: create an owned `String` from a string reference + | +LL | let _ = c.to_owned() + &d; + | +++++++++++ error[E0369]: cannot add `&str` to `&str` --> $DIR/issue-39018.rs:37:15 | LL | let _ = c + d; - | --^ - &str - | ||| - | ||`+` cannot be used to concatenate two `&str` strings - | |help: create an owned `String` from a string reference: `.to_owned()` + | - ^ - &str + | | | + | | `+` cannot be used to concatenate two `&str` strings | &str | = note: string concatenation requires an owned `String` on the left +help: create an owned `String` from a string reference + | +LL | let _ = c.to_owned() + d; + | +++++++++++ error: aborting due to 14 previous errors diff --git a/src/test/ui/str/str-concat-on-double-ref.stderr b/src/test/ui/str/str-concat-on-double-ref.stderr index 251bc7ac0ea..bd354679f78 100644 --- a/src/test/ui/str/str-concat-on-double-ref.stderr +++ b/src/test/ui/str/str-concat-on-double-ref.stderr @@ -2,13 +2,16 @@ error[E0369]: cannot add `&str` to `&String` --> $DIR/str-concat-on-double-ref.rs:4:15 | LL | let c = a + b; - | --^ - &str - | ||| - | ||`+` cannot be used to concatenate two `&str` strings - | |help: create an owned `String` from a string reference: `.to_owned()` + | - ^ - &str + | | | + | | `+` cannot be used to concatenate two `&str` strings | &String | = note: string concatenation requires an owned `String` on the left +help: create an owned `String` from a string reference + | +LL | let c = a.to_owned() + b; + | +++++++++++ error: aborting due to previous error diff --git a/src/test/ui/terminal-width/non-1-width-unicode-multiline-label.stderr b/src/test/ui/terminal-width/non-1-width-unicode-multiline-label.stderr index a97ecc4ce15..bf277362dba 100644 --- a/src/test/ui/terminal-width/non-1-width-unicode-multiline-label.stderr +++ b/src/test/ui/terminal-width/non-1-width-unicode-multiline-label.stderr @@ -1,14 +1,17 @@ error[E0369]: cannot add `&str` to `&str` --> $DIR/non-1-width-unicode-multiline-label.rs:5:260 | -LL | ...྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗ྘ྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྽྾྿࿀࿁࿂࿃࿄࿅࿆࿇࿈࿉࿊࿋࿌࿍࿎...࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun + " really fun!"; - | ---------------^ -------------- &str - | | || - | | |`+` cannot be used to concatenate two `&str` strings - | | help: create an owned `String` from a string reference: `.to_owned()` - | &str +LL | ...ཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗ྘ྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྽྾྿࿀࿁࿂࿃࿄࿅࿆࿇...࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun + " really fun!"; + | -------------- ^ -------------- &str + | | | + | | `+` cannot be used to concatenate two `&str` strings + | &str | = note: string concatenation requires an owned `String` on the left +help: create an owned `String` from a string reference + | +LL | let _ = "ༀ༁༂༃༄༅༆༇༈༉༊་༌།༎༏༐༑༒༓༔༕༖༗༘༙༚༛༜༝༞༟༠༡༢༣༤༥༦༧༨༩༪༫༬༭༮༯༰༱༲༳༴༵༶༷༸༹༺༻༼༽༾༿ཀཁགགྷངཅཆཇ཈ཉཊཋཌཌྷཎཏཐདདྷནཔཕབབྷམཙཚཛཛྷཝཞཟའཡརལཤཥསཧཨཀྵཪཫཬ཭཮཯཰ཱཱཱིིུུྲྀཷླྀཹེཻོཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗ྘ྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྽྾྿࿀࿁࿂࿃࿄࿅࿆࿇࿈࿉࿊࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun.to_owned() + " really fun!"; + | +++++++++++ error: aborting due to previous error