From b857a1a39fc29b8f241d8aa4c859ff4105cb160c Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Mon, 27 Mar 2017 13:59:10 +0200 Subject: Update affected tests --- src/libsyntax/parse/parser.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 1baf0d1b54c..53656d8c6c2 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5122,7 +5122,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 @@ -5165,8 +5164,7 @@ impl<'a> Parser<'a> { the path:", 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 } -- cgit 1.4.1-3-g733a5 From 3a5567bad45fbde0962263f484ebc76f750920e4 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Tue, 28 Mar 2017 13:06:01 +0200 Subject: Address PR comments --- src/librustc_errors/emitter.rs | 4 +++- src/librustc_typeck/check/op.rs | 12 +++++++----- src/librustc_typeck/diagnostics.rs | 7 +++++++ src/libsyntax/parse/parser.rs | 4 +--- src/test/ui/pub/pub-restricted.stderr | 8 ++++---- src/test/ui/span/issue-39018.stderr | 7 ++++--- 6 files changed, 26 insertions(+), 16 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 8855859d7c4..085424ef7e6 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -37,7 +37,9 @@ impl Emitter for EmitterWriter { if let Some(sugg) = db.suggestion.clone() { assert_eq!(sugg.msp.primary_spans().len(), sugg.substitutes.len()); - if sugg.substitutes.len() == 1 { + if sugg.substitutes.len() == 1 && // don't display multispans as labels + sugg.msg.split_whitespace().count() < 10 && // don't display long messages as labels + sugg.substitutes[0].find('\n').is_none() { // don't display multiline suggestions as labels let msg = format!("{} `{}`", sugg.msg, sugg.substitutes[0]); primary_span.push_span_label(sugg.msp.primary_spans()[0], msg); } else { diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index 6968a37361a..7d17cee9879 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); @@ -244,7 +244,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(lhs_expr, lhs_ty, + self.check_str_addition(expr, lhs_expr, lhs_ty, rhs_expr, rhs_ty_var, &mut err) { // This has nothing here because it means we did string // concatenation (e.g. "Hello " + "World!"). This means @@ -266,6 +266,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } fn check_str_addition(&self, + expr: &'gcx hir::Expr, lhs_expr: &'gcx hir::Expr, lhs_ty: Ty<'tcx>, rhs_expr: &'gcx hir::Expr, @@ -277,7 +278,8 @@ 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) { @@ -289,7 +291,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { 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:"), suggestion); + requires ownership of the string on the left."), suggestion); is_string_addition = true; } diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 2bae6a0d9e1..54637269bc0 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/parse/parser.rs b/src/libsyntax/parse/parser.rs index 53656d8c6c2..e1fe8f1b2eb 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5160,9 +5160,7 @@ 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 mut err = self.span_fatal_help(path_span, &msg, &suggestion); err.span_suggestion(path_span, &help_msg, format!("in {}", path)); diff --git a/src/test/ui/pub/pub-restricted.stderr b/src/test/ui/pub/pub-restricted.stderr index 7bee1791eab..760df5b5da0 100644 --- a/src/test/ui/pub/pub-restricted.stderr +++ b/src/test/ui/pub/pub-restricted.stderr @@ -2,7 +2,7 @@ error: incorrect visibility restriction --> $DIR/pub-restricted.rs:15:6 | 15 | pub (a) fn afn() {} - | ^ to make this visible only to module `a`, add `in` before the path: `in a` + | ^ 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 @@ -13,7 +13,7 @@ error: incorrect visibility restriction --> $DIR/pub-restricted.rs:16:6 | 16 | pub (b) fn bfn() {} - | ^ to make this visible only to module `b`, add `in` before the path: `in b` + | ^ 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 @@ -24,7 +24,7 @@ error: incorrect visibility restriction --> $DIR/pub-restricted.rs:32:14 | 32 | pub (a) invalid: usize, - | ^ to make this visible only to module `a`, add `in` before the path: `in a` + | ^ 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 @@ -35,7 +35,7 @@ error: incorrect visibility restriction --> $DIR/pub-restricted.rs:41:6 | 41 | pub (xyz) fn xyz() {} - | ^^^ to make this visible only to module `xyz`, add `in` before the path: `in xyz` + | ^^^ 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 diff --git a/src/test/ui/span/issue-39018.stderr b/src/test/ui/span/issue-39018.stderr index b588238202e..cd3a41b037c 100644 --- a/src/test/ui/span/issue-39018.stderr +++ b/src/test/ui/span/issue-39018.stderr @@ -2,15 +2,16 @@ error[E0369]: binary operation `+` cannot be applied to type `&'static str` --> $DIR/issue-39018.rs:12:13 | 12 | let x = "Hello " + "World!"; - | ^^^^^^^^ `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: `"Hello ".to_owned()` + | ^^^^^^^^^^^^^^^^^^^ `+` 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. + | 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` -- cgit 1.4.1-3-g733a5 From f4b1e2af6836bcf30a8be05ff6a44df6f61b19f2 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Tue, 28 Mar 2017 14:10:16 +0200 Subject: Improve E0178 suggestion placement --- src/librustc_errors/emitter.rs | 9 ++++--- src/librustc_typeck/diagnostics.rs | 2 +- src/libsyntax/parse/parser.rs | 9 ++++--- src/test/compile-fail/E0178.rs | 29 ---------------------- ...t-object-reference-without-parens-suggestion.rs | 21 ---------------- src/test/ui/did_you_mean/E0178.rs | 21 ++++++++++++++++ src/test/ui/did_you_mean/E0178.stderr | 26 +++++++++++++++++++ ...t-object-reference-without-parens-suggestion.rs | 14 +++++++++++ ...ject-reference-without-parens-suggestion.stderr | 22 ++++++++++++++++ 9 files changed, 95 insertions(+), 58 deletions(-) delete mode 100644 src/test/compile-fail/E0178.rs delete mode 100644 src/test/compile-fail/trait-object-reference-without-parens-suggestion.rs create mode 100644 src/test/ui/did_you_mean/E0178.rs create mode 100644 src/test/ui/did_you_mean/E0178.stderr create mode 100644 src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.rs create mode 100644 src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr (limited to 'src/libsyntax/parse') diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 085424ef7e6..68e58e230f8 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -37,9 +37,12 @@ impl Emitter for EmitterWriter { if let Some(sugg) = db.suggestion.clone() { assert_eq!(sugg.msp.primary_spans().len(), sugg.substitutes.len()); - if sugg.substitutes.len() == 1 && // don't display multispans as labels - sugg.msg.split_whitespace().count() < 10 && // don't display long messages as labels - sugg.substitutes[0].find('\n').is_none() { // don't display multiline suggestions as labels + // 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!("{} `{}`", sugg.msg, sugg.substitutes[0]); primary_span.push_span_label(sugg.msp.primary_spans()[0], msg); } else { diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 54637269bc0..0f42ee15ecf 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -3185,7 +3185,7 @@ 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 +literal to the heap by allocating it with `to_owned()` like in `"Your text".to_owned()`. "##, diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index e1fe8f1b2eb..55098d77472 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1490,9 +1490,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) => { @@ -1511,9 +1510,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(()) diff --git a/src/test/compile-fail/E0178.rs b/src/test/compile-fail/E0178.rs deleted file mode 100644 index 6527465e0b7..00000000000 --- a/src/test/compile-fail/E0178.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -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/compile-fail/trait-object-reference-without-parens-suggestion.rs b/src/test/compile-fail/trait-object-reference-without-parens-suggestion.rs deleted file mode 100644 index f9f887b78b0..00000000000 --- a/src/test/compile-fail/trait-object-reference-without-parens-suggestion.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -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/E0178.rs b/src/test/ui/did_you_mean/E0178.rs new file mode 100644 index 00000000000..8fb6c9815ce --- /dev/null +++ b/src/test/ui/did_you_mean/E0178.rs @@ -0,0 +1,21 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +trait Foo {} + +struct Bar<'a> { + w: &'a Foo + Copy, + x: &'a Foo + 'a, + y: &'a mut Foo + 'a, + z: fn() -> Foo + 'a, +} + +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..86f51a28a52 --- /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, + | ^^^^^^^^^^^^^^ 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, + | ^^^^^^^^^^^^ 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, + | ^^^^^^^^^^^^^^^^ 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/ui/did_you_mean/trait-object-reference-without-parens-suggestion.rs b/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.rs new file mode 100644 index 00000000000..11757abae9c --- /dev/null +++ b/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.rs @@ -0,0 +1,14 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let _: &Copy + 'static; + 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..cffa0474d22 --- /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; + | ^^^^^^^^^^^^^^^ 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; + | ^^^^^^^^^^^^^^^^^^^^^^^ 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 + -- cgit 1.4.1-3-g733a5