diff options
| author | bors <bors@rust-lang.org> | 2017-05-02 01:04:27 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2017-05-02 01:04:27 +0000 |
| commit | 33535afda497e1de8a831e8270ae8099434f662b (patch) | |
| tree | 17b14bd7f6ab382784b26bdf01722525d3bbdb2f /src | |
| parent | de4bdd20f87d95d164c883dc141a2763e4df155a (diff) | |
| parent | d64af4a627532c978ed2682de0e9411aa3a83e75 (diff) | |
| download | rust-33535afda497e1de8a831e8270ae8099434f662b.tar.gz rust-33535afda497e1de8a831e8270ae8099434f662b.zip | |
Auto merge of #40851 - oli-obk:multisugg, r=jonathandturner
Minimize single span suggestions into a label
changes
```
14 | println!("☃{}", tup[0]);
| ^^^^^^
|
help: to access tuple elements, use tuple indexing syntax as shown
| println!("☃{}", tup.0);
```
into
```
14 | println!("☃{}", tup[0]);
| ^^^^^^ to access tuple elements, use `tup.0`
```
Also makes suggestions explicit in the backend in preparation of adding multiple suggestions to a single diagnostic. Currently that's already possible, but results in a full help message + modified code snippet per suggestion, and has no rate limit (might show 100+ suggestions).
Diffstat (limited to 'src')
20 files changed, 155 insertions, 92 deletions
diff --git a/src/librustc_errors/diagnostic.rs b/src/librustc_errors/diagnostic.rs index 9715ace3e2e..38fa35ecb12 100644 --- a/src/librustc_errors/diagnostic.rs +++ b/src/librustc_errors/diagnostic.rs @@ -11,7 +11,6 @@ use CodeSuggestion; use Level; use RenderSpan; -use RenderSpan::Suggestion; use std::fmt; use syntax_pos::{MultiSpan, Span}; use snippet::Style; @@ -24,6 +23,7 @@ pub struct Diagnostic { pub code: Option<String>, pub span: MultiSpan, pub children: Vec<SubDiagnostic>, + pub suggestion: Option<CodeSuggestion>, } /// For example a note attached to an error. @@ -87,6 +87,7 @@ impl Diagnostic { code: code, span: MultiSpan::new(), children: vec![], + suggestion: None, } } @@ -202,19 +203,14 @@ impl Diagnostic { /// Prints out a message with a suggested edit of the code. /// - /// See `diagnostic::RenderSpan::Suggestion` for more information. - pub fn span_suggestion<S: Into<MultiSpan>>(&mut self, - sp: S, - msg: &str, - suggestion: String) - -> &mut Self { - self.sub(Level::Help, - msg, - MultiSpan::new(), - Some(Suggestion(CodeSuggestion { - msp: sp.into(), - substitutes: vec![suggestion], - }))); + /// See `diagnostic::CodeSuggestion` for more information. + pub fn span_suggestion(&mut self, sp: Span, msg: &str, suggestion: String) -> &mut Self { + assert!(self.suggestion.is_none()); + self.suggestion = Some(CodeSuggestion { + msp: sp.into(), + substitutes: vec![suggestion], + msg: msg.to_owned(), + }); self } diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs index 7b27f13951b..9dfd47b8464 100644 --- a/src/librustc_errors/diagnostic_builder.rs +++ b/src/librustc_errors/diagnostic_builder.rs @@ -141,11 +141,11 @@ impl<'a> DiagnosticBuilder<'a> { sp: S, msg: &str) -> &mut Self); - forward!(pub fn span_suggestion<S: Into<MultiSpan>>(&mut self, - sp: S, - msg: &str, - suggestion: String) - -> &mut Self); + forward!(pub fn span_suggestion(&mut self, + sp: Span, + msg: &str, + suggestion: String) + -> &mut Self); forward!(pub fn set_span<S: Into<MultiSpan>>(&mut self, sp: S) -> &mut Self); forward!(pub fn code(&mut self, s: String) -> &mut Self); diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 64652bb308b..1a38018e1b3 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -34,6 +34,27 @@ impl Emitter for EmitterWriter { fn emit(&mut self, db: &DiagnosticBuilder) { let mut primary_span = db.span.clone(); let mut children = db.children.clone(); + + if let Some(sugg) = db.suggestion.clone() { + assert_eq!(sugg.msp.primary_spans().len(), sugg.substitutes.len()); + // don't display multispans as labels + if sugg.substitutes.len() == 1 && + // don't display long messages as labels + sugg.msg.split_whitespace().count() < 10 && + // don't display multiline suggestions as labels + sugg.substitutes[0].find('\n').is_none() { + let msg = format!("help: {} `{}`", sugg.msg, sugg.substitutes[0]); + primary_span.push_span_label(sugg.msp.primary_spans()[0], msg); + } else { + children.push(SubDiagnostic { + level: Level::Help, + message: Vec::new(), + span: MultiSpan::new(), + render_span: Some(Suggestion(sugg)), + }); + } + } + self.fix_multispans_in_std_macros(&mut primary_span, &mut children); self.emit_messages_default(&db.level, &db.styled_message(), @@ -756,7 +777,7 @@ impl EmitterWriter { /// displayed, keeping the provided highlighting. fn msg_to_buffer(&self, buffer: &mut StyledBuffer, - msg: &Vec<(String, Style)>, + msg: &[(String, Style)], padding: usize, label: &str, override_style: Option<Style>) { @@ -1022,7 +1043,6 @@ impl EmitterWriter { fn emit_suggestion_default(&mut self, suggestion: &CodeSuggestion, level: &Level, - msg: &Vec<(String, Style)>, max_line_num_len: usize) -> io::Result<()> { use std::borrow::Borrow; @@ -1034,7 +1054,7 @@ impl EmitterWriter { buffer.append(0, &level.to_string(), Style::Level(level.clone())); buffer.append(0, ": ", Style::HeaderMsg); self.msg_to_buffer(&mut buffer, - msg, + &[(suggestion.msg.to_owned(), Style::NoStyle)], max_line_num_len, "suggestion", Some(Style::HeaderMsg)); @@ -1099,7 +1119,6 @@ impl EmitterWriter { Some(Suggestion(ref cs)) => { match self.emit_suggestion_default(cs, &child.level, - &child.styled_message(), max_line_num_len) { Err(e) => panic!("failed to emit error: {}", e), _ => () diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index cc8012d965a..02d8297dd46 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -67,6 +67,7 @@ pub enum RenderSpan { pub struct CodeSuggestion { pub msp: MultiSpan, pub substitutes: Vec<String>, + pub msg: String, } pub trait CodeMapper { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 8752f82f7ab..5a581788a21 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3883,9 +3883,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let snip = tcx.sess.codemap().span_to_snippet(base.span); if let Ok(snip) = snip { err.span_suggestion(expr.span, - "to access tuple elements, \ - use tuple indexing syntax \ - as shown", + "to access tuple elements, use", format!("{}.{}", snip, i)); needs_note = false; } diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index 4fd0e984c9f..d3d65ce4a62 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -197,7 +197,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // error types are considered "builtin" if !lhs_ty.references_error() { if let IsAssign::Yes = is_assign { - struct_span_err!(self.tcx.sess, lhs_expr.span, E0368, + struct_span_err!(self.tcx.sess, expr.span, E0368, "binary assignment operation `{}=` \ cannot be applied to type `{}`", op.node.as_str(), @@ -207,7 +207,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { op.node.as_str(), lhs_ty)) .emit(); } else { - let mut err = struct_span_err!(self.tcx.sess, lhs_expr.span, E0369, + let mut err = struct_span_err!(self.tcx.sess, expr.span, E0369, "binary operation `{}` cannot be applied to type `{}`", op.node.as_str(), lhs_ty); @@ -245,7 +245,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let Some(missing_trait) = missing_trait { if missing_trait == "std::ops::Add" && self.check_str_addition(expr, lhs_expr, lhs_ty, - rhs_expr, rhs_ty, &mut err) { + rhs_ty, &mut err) { // 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 @@ -269,7 +269,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { expr: &'gcx hir::Expr, lhs_expr: &'gcx hir::Expr, lhs_ty: Ty<'tcx>, - rhs_expr: &'gcx hir::Expr, rhs_ty: Ty<'tcx>, mut err: &mut errors::DiagnosticBuilder) -> bool { // If this function returns true it means a note was printed, so we don't need @@ -278,17 +277,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let TyRef(_, l_ty) = lhs_ty.sty { if let TyRef(_, r_ty) = rhs_ty.sty { if l_ty.ty.sty == TyStr && r_ty.ty.sty == TyStr { - err.note("`+` can't be used to concatenate two `&str` strings"); + err.span_label(expr.span, + &"`+` can't be used to concatenate two `&str` strings"); let codemap = self.tcx.sess.codemap(); let suggestion = - match (codemap.span_to_snippet(lhs_expr.span), - codemap.span_to_snippet(rhs_expr.span)) { - (Ok(lstring), Ok(rstring)) => - format!("{}.to_owned() + {}", lstring, rstring), + match codemap.span_to_snippet(lhs_expr.span) { + Ok(lstring) => format!("{}.to_owned()", lstring), _ => format!("<expression>") }; - err.span_suggestion(expr.span, - &format!("to_owned() can be used to create an owned `String` \ + err.span_suggestion(lhs_expr.span, + &format!("`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 \ diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 2bae6a0d9e1..0f42ee15ecf 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -3181,6 +3181,13 @@ x << 2; // ok! It is also possible to overload most operators for your own type by implementing traits from `std::ops`. + +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. If something should be added to a string literal, move the +literal to the heap by allocating it with `to_owned()` like in +`"Your text".to_owned()`. + "##, E0370: r##" diff --git a/src/libsyntax/json.rs b/src/libsyntax/json.rs index 47b60f0e080..0271ddbccbf 100644 --- a/src/libsyntax/json.rs +++ b/src/libsyntax/json.rs @@ -22,8 +22,9 @@ use codemap::{CodeMap, FilePathMapping}; use syntax_pos::{self, MacroBacktrace, Span, SpanLabel, MultiSpan}; use errors::registry::Registry; -use errors::{DiagnosticBuilder, SubDiagnostic, RenderSpan, CodeSuggestion, CodeMapper}; +use errors::{Level, DiagnosticBuilder, SubDiagnostic, RenderSpan, CodeSuggestion, CodeMapper}; use errors::emitter::Emitter; +use errors::snippet::Style; use std::rc::Rc; use std::io::{self, Write}; @@ -153,12 +154,21 @@ impl Diagnostic { fn from_diagnostic_builder(db: &DiagnosticBuilder, je: &JsonEmitter) -> Diagnostic { + let sugg = db.suggestion.as_ref().map(|sugg| { + SubDiagnostic { + level: Level::Help, + message: vec![(sugg.msg.clone(), Style::NoStyle)], + span: MultiSpan::new(), + render_span: Some(RenderSpan::Suggestion(sugg.clone())), + } + }); + let sugg = sugg.as_ref(); Diagnostic { message: db.message(), code: DiagnosticCode::map_opt_string(db.code.clone(), je), level: db.level.to_str(), spans: DiagnosticSpan::from_multispan(&db.span, je), - children: db.children.iter().map(|c| { + children: db.children.iter().chain(sugg).map(|c| { Diagnostic::from_sub_diagnostic(c, je) }).collect(), rendered: None, diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 84d53dbef7c..d252963274e 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1492,9 +1492,8 @@ impl<'a> Parser<'a> { let bounds = self.parse_ty_param_bounds()?; let sum_span = ty.span.to(self.prev_span); - let mut err = struct_span_err!(self.sess.span_diagnostic, ty.span, E0178, + let mut err = struct_span_err!(self.sess.span_diagnostic, sum_span, E0178, "expected a path on the left-hand side of `+`, not `{}`", pprust::ty_to_string(&ty)); - err.span_label(ty.span, &format!("expected a path")); match ty.node { TyKind::Rptr(ref lifetime, ref mut_ty) => { @@ -1513,9 +1512,11 @@ impl<'a> Parser<'a> { err.span_suggestion(sum_span, "try adding parentheses:", sum_with_parens); } TyKind::Ptr(..) | TyKind::BareFn(..) => { - help!(&mut err, "perhaps you forgot parentheses?"); + err.span_label(sum_span, &"perhaps you forgot parentheses?"); } - _ => {} + _ => { + err.span_label(sum_span, &"expected a path"); + }, } err.emit(); Ok(()) @@ -5131,7 +5132,6 @@ impl<'a> Parser<'a> { } if self.check(&token::OpenDelim(token::Paren)) { - let start_span = self.span; // We don't `self.bump()` the `(` yet because this might be a struct definition where // `()` or a tuple might be allowed. For example, `struct Struct(pub (), pub (usize));`. // Because of this, we only `bump` the `(` if we're assured it is appropriate to do so @@ -5170,12 +5170,9 @@ impl<'a> Parser<'a> { `pub(in path::to::module)`: visible only on the specified path"##; let path = self.parse_path(PathStyle::Mod)?; let path_span = self.prev_span; - let help_msg = format!("to make this visible only to module `{}`, add `in` before \ - the path:", - path); + let help_msg = format!("make this visible only to module `{}` with `in`:", path); self.expect(&token::CloseDelim(token::Paren))?; // `)` - let sp = start_span.to(self.prev_span); - let mut err = self.span_fatal_help(sp, &msg, &suggestion); + let mut err = self.span_fatal_help(path_span, &msg, &suggestion); err.span_suggestion(path_span, &help_msg, format!("in {}", path)); err.emit(); // emit diagnostic, but continue with public visibility } diff --git a/src/test/compile-fail/issue-27842.rs b/src/test/compile-fail/issue-27842.rs index 28050a2ee90..f7cd4e03c3b 100644 --- a/src/test/compile-fail/issue-27842.rs +++ b/src/test/compile-fail/issue-27842.rs @@ -13,7 +13,7 @@ fn main() { // the case where we show a suggestion let _ = tup[0]; //~^ ERROR cannot index a value of type - //~| HELP to access tuple elements, use tuple indexing syntax as shown + //~| HELP to access tuple elements, use //~| SUGGESTION let _ = tup.0 // the case where we show just a general hint diff --git a/src/test/parse-fail/trait-object-polytrait-priority.rs b/src/test/parse-fail/trait-object-polytrait-priority.rs index f0abc678c21..9df4be4595a 100644 --- a/src/test/parse-fail/trait-object-polytrait-priority.rs +++ b/src/test/parse-fail/trait-object-polytrait-priority.rs @@ -13,7 +13,6 @@ trait Trait<'a> {} fn main() { let _: &for<'a> Trait<'a> + 'static; //~^ ERROR expected a path on the left-hand side of `+`, not `& for<'a>Trait<'a>` - //~| NOTE expected a path //~| HELP try adding parentheses //~| SUGGESTION &( for<'a>Trait<'a> + 'static) } diff --git a/src/test/compile-fail/E0178.rs b/src/test/ui/did_you_mean/E0178.rs index 6527465e0b7..8fb6c9815ce 100644 --- a/src/test/compile-fail/E0178.rs +++ b/src/test/ui/did_you_mean/E0178.rs @@ -12,17 +12,9 @@ trait Foo {} struct Bar<'a> { w: &'a Foo + Copy, - //~^ ERROR E0178 - //~| NOTE expected a path x: &'a Foo + 'a, - //~^ ERROR E0178 - //~| NOTE expected a path y: &'a mut Foo + 'a, - //~^ ERROR E0178 - //~| NOTE expected a path z: fn() -> Foo + 'a, - //~^ ERROR E0178 - //~| NOTE expected a path } fn main() { diff --git a/src/test/ui/did_you_mean/E0178.stderr b/src/test/ui/did_you_mean/E0178.stderr new file mode 100644 index 00000000000..15e7131cfd3 --- /dev/null +++ b/src/test/ui/did_you_mean/E0178.stderr @@ -0,0 +1,26 @@ +error[E0178]: expected a path on the left-hand side of `+`, not `&'a Foo` + --> $DIR/E0178.rs:14:8 + | +14 | w: &'a Foo + Copy, + | ^^^^^^^^^^^^^^ help: try adding parentheses: `&'a (Foo + Copy)` + +error[E0178]: expected a path on the left-hand side of `+`, not `&'a Foo` + --> $DIR/E0178.rs:15:8 + | +15 | x: &'a Foo + 'a, + | ^^^^^^^^^^^^ help: try adding parentheses: `&'a (Foo + 'a)` + +error[E0178]: expected a path on the left-hand side of `+`, not `&'a mut Foo` + --> $DIR/E0178.rs:16:8 + | +16 | y: &'a mut Foo + 'a, + | ^^^^^^^^^^^^^^^^ help: try adding parentheses: `&'a mut (Foo + 'a)` + +error[E0178]: expected a path on the left-hand side of `+`, not `fn() -> Foo` + --> $DIR/E0178.rs:17:8 + | +17 | z: fn() -> Foo + 'a, + | ^^^^^^^^^^^^^^^^ perhaps you forgot parentheses? + +error: aborting due to 4 previous errors + diff --git a/src/test/compile-fail/trait-object-reference-without-parens-suggestion.rs b/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.rs index f9f887b78b0..11757abae9c 100644 --- a/src/test/compile-fail/trait-object-reference-without-parens-suggestion.rs +++ b/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.rs @@ -10,12 +10,5 @@ fn main() { let _: &Copy + 'static; - //~^ ERROR expected a path - //~| HELP try adding parentheses - //~| SUGGESTION let _: &(Copy + 'static); - //~| ERROR the trait `std::marker::Copy` cannot be made into an object let _: &'static Copy + 'static; - //~^ ERROR expected a path - //~| HELP try adding parentheses - //~| SUGGESTION let _: &'static (Copy + 'static); } diff --git a/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr b/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr new file mode 100644 index 00000000000..c4858b63c2d --- /dev/null +++ b/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr @@ -0,0 +1,22 @@ +error[E0178]: expected a path on the left-hand side of `+`, not `&Copy` + --> $DIR/trait-object-reference-without-parens-suggestion.rs:12:12 + | +12 | let _: &Copy + 'static; + | ^^^^^^^^^^^^^^^ help: try adding parentheses: `&(Copy + 'static)` + +error[E0178]: expected a path on the left-hand side of `+`, not `&'static Copy` + --> $DIR/trait-object-reference-without-parens-suggestion.rs:13:12 + | +13 | let _: &'static Copy + 'static; + | ^^^^^^^^^^^^^^^^^^^^^^^ help: try adding parentheses: `&'static (Copy + 'static)` + +error[E0038]: the trait `std::marker::Copy` cannot be made into an object + --> $DIR/trait-object-reference-without-parens-suggestion.rs:12:12 + | +12 | let _: &Copy + 'static; + | ^^^^^ the trait `std::marker::Copy` cannot be made into an object + | + = note: the trait cannot require that `Self : Sized` + +error: aborting due to previous error + diff --git a/src/test/ui/pub/pub-restricted.rs b/src/test/ui/pub/pub-restricted.rs index 48e487f71a7..934ad24c167 100644 --- a/src/test/ui/pub/pub-restricted.rs +++ b/src/test/ui/pub/pub-restricted.rs @@ -34,4 +34,8 @@ mod y { } } -fn main() {} \ No newline at end of file +fn main() {} + +// test multichar names +mod xyz {} +pub (xyz) fn xyz() {} diff --git a/src/test/ui/pub/pub-restricted.stderr b/src/test/ui/pub/pub-restricted.stderr index 5bc230e8da3..ae283f1fb63 100644 --- a/src/test/ui/pub/pub-restricted.stderr +++ b/src/test/ui/pub/pub-restricted.stderr @@ -1,41 +1,46 @@ error: incorrect visibility restriction - --> $DIR/pub-restricted.rs:15:5 + --> $DIR/pub-restricted.rs:15:6 | 15 | pub (a) fn afn() {} - | ^^^ + | ^ help: make this visible only to module `a` with `in`: `in a` | = help: some possible visibility restrictions are: `pub(crate)`: visible only on the current crate `pub(super)`: visible only in the current module's parent `pub(in path::to::module)`: visible only on the specified path -help: to make this visible only to module `a`, add `in` before the path: - | pub (in a) fn afn() {} error: incorrect visibility restriction - --> $DIR/pub-restricted.rs:16:5 + --> $DIR/pub-restricted.rs:16:6 | 16 | pub (b) fn bfn() {} - | ^^^ + | ^ help: make this visible only to module `b` with `in`: `in b` | = help: some possible visibility restrictions are: `pub(crate)`: visible only on the current crate `pub(super)`: visible only in the current module's parent `pub(in path::to::module)`: visible only on the specified path -help: to make this visible only to module `b`, add `in` before the path: - | pub (in b) fn bfn() {} error: incorrect visibility restriction - --> $DIR/pub-restricted.rs:32:13 + --> $DIR/pub-restricted.rs:32:14 | 32 | pub (a) invalid: usize, - | ^^^ + | ^ help: make this visible only to module `a` with `in`: `in a` + | + = help: some possible visibility restrictions are: + `pub(crate)`: visible only on the current crate + `pub(super)`: visible only in the current module's parent + `pub(in path::to::module)`: visible only on the specified path + +error: incorrect visibility restriction + --> $DIR/pub-restricted.rs:41:6 + | +41 | pub (xyz) fn xyz() {} + | ^^^ help: make this visible only to module `xyz` with `in`: `in xyz` | = help: some possible visibility restrictions are: `pub(crate)`: visible only on the current crate `pub(super)`: visible only in the current module's parent `pub(in path::to::module)`: visible only on the specified path -help: to make this visible only to module `a`, add `in` before the path: - | pub (in a) invalid: usize, error: visibilities can only be restricted to ancestor modules --> $DIR/pub-restricted.rs:33:17 @@ -43,5 +48,5 @@ error: visibilities can only be restricted to ancestor modules 33 | pub (in x) non_parent_invalid: usize, | ^ -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors diff --git a/src/test/ui/span/issue-39018.stderr b/src/test/ui/span/issue-39018.stderr index 9d6d4570c6b..cd3a41b037c 100644 --- a/src/test/ui/span/issue-39018.stderr +++ b/src/test/ui/span/issue-39018.stderr @@ -2,17 +2,16 @@ error[E0369]: binary operation `+` cannot be applied to type `&'static str` --> $DIR/issue-39018.rs:12:13 | 12 | let x = "Hello " + "World!"; - | ^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ `+` can't be used to concatenate two `&str` strings | - = note: `+` 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. +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. | let x = "Hello ".to_owned() + "World!"; error[E0369]: binary operation `+` cannot be applied to type `World` --> $DIR/issue-39018.rs:17:13 | 17 | let y = World::Hello + World::Goodbye; - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: an implementation of `std::ops::Add` might be missing for `World` diff --git a/src/test/ui/span/suggestion-non-ascii.stderr b/src/test/ui/span/suggestion-non-ascii.stderr index 385c211f393..91e629c44b0 100644 --- a/src/test/ui/span/suggestion-non-ascii.stderr +++ b/src/test/ui/span/suggestion-non-ascii.stderr @@ -2,10 +2,7 @@ error: cannot index a value of type `({integer},)` --> $DIR/suggestion-non-ascii.rs:14:21 | 14 | println!("☃{}", tup[0]); - | ^^^^^^ - | -help: to access tuple elements, use tuple indexing syntax as shown - | println!("☃{}", tup.0); + | ^^^^^^ help: to access tuple elements, use `tup.0` error: aborting due to previous error diff --git a/src/test/ui/suggestions/tuple-float-index.stderr b/src/test/ui/suggestions/tuple-float-index.stderr index abe04dc1aa2..8a121b14536 100644 --- a/src/test/ui/suggestions/tuple-float-index.stderr +++ b/src/test/ui/suggestions/tuple-float-index.stderr @@ -2,10 +2,10 @@ error: unexpected token: `1.1` --> $DIR/tuple-float-index.rs:14:17 | 14 | (1, (2, 3)).1.1; - | ^^^ unexpected token - | -help: try parenthesizing the first index - | ((1, (2, 3)).1).1; + | ------------^^^ + | | | + | | unexpected token + | help: try parenthesizing the first index `((1, (2, 3)).1).1` error: aborting due to previous error |
