about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-06-22 03:24:36 +0000
committerbors <bors@rust-lang.org>2018-06-22 03:24:36 +0000
commit4b17d31f1147f840231c43b1ac1478a497af20df (patch)
tree3cff794968a43e808778ff252480eb4d6dd73f50 /src/libsyntax/parse
parent0b8d817404325c6bd777b38dec31428bc33f2746 (diff)
parent28cea50a46f4669b94d8332bf64d07e7e5a02d79 (diff)
downloadrust-4b17d31f1147f840231c43b1ac1478a497af20df.tar.gz
rust-4b17d31f1147f840231c43b1ac1478a497af20df.zip
Auto merge of #51463 - estebank:error-codes, r=nikomatsakis
Various changes to existing diagnostics

* [Add code to `invalid ABI` error, add span label, move list to help to make message shorter](https://github.com/rust-lang/rust/pull/51463/commits/23ae5af274defa9ff884f593e44a2bbcaf814a02):
```
error[E0697]: invalid ABI: found `路濫狼á́́`
  --> $DIR/unicode.rs:11:8
   |
LL | extern "路濫狼á́́" fn foo() {} //~ ERROR invalid ABI
   |        ^^^^^^^^^ invalid ABI
   |
   = help: valid ABIs: cdecl, stdcall, fastcall, vectorcall, thiscall, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, Rust, C, system, rust-intrinsic, rust-call, platform-intrinsic, unadjusted
```
* [Add code to incorrect `pub` restriction error](https://github.com/rust-lang/rust/pull/51463/commits/e96fdea8a38f39f99f8b9a4000a689187a457e08)
* [Add message to `rustc_on_unimplemented` attributes in core to have them set a custom message _and_ label](https://github.com/rust-lang/rust/pull/51463/commits/2cc7e5ed307aee936c20479cfdc7409d6b52a464):
```
error[E0277]: `W` does not have a constant size known at compile-time
  --> $DIR/unsized-enum2.rs:33:8
   |
LL |     VA(W),
   |        ^ `W` does not have a constant size known at compile-time
   |
   = help: the trait `std::marker::Sized` is not implemented for `W`
   = help: consider adding a `where W: std::marker::Sized` bound
   = note: no field of an enum variant may have a dynamically sized type
```
```
error[E0277]: `Foo` cannot be sent between threads safely
  --> $DIR/E0277-2.rs:26:5
   |
LL |     is_send::<Foo>();
   |     ^^^^^^^^^^^^^^ `Foo` cannot be sent between threads safely
   |
   = help: the trait `std::marker::Send` is not implemented for `Foo`
```
```
error[E0277]: can't compare `{integer}` with `std::string::String`
  --> $DIR/binops.rs:16:7
   |
LL |     5 < String::new();
   |       ^ no implementation for `{integer} < std::string::String` and `{integer} > std::string::String`
   |
   = help: the trait `std::cmp::PartialOrd<std::string::String>` is not implemented for `{integer}`
```
```
error[E0277]: can't compare `{integer}` with `std::result::Result<{integer}, _>`
  --> $DIR/binops.rs:17:7
   |
LL |     6 == Ok(1);
   |       ^^ no implementation for `{integer} == std::result::Result<{integer}, _>`
   |
   = help: the trait `std::cmp::PartialEq<std::result::Result<{integer}, _>>` is not implemented for `{integer}`
```
```
error[E0277]: a collection of type `i32` cannot be built from an iterator over elements of type `i32`
  --> $DIR/type-check-defaults.rs:16:19
   |
LL | struct WellFormed<Z = Foo<i32, i32>>(Z);
   |                   ^ a collection of type `i32` cannot be built from `std::iter::Iterator<Item=i32>`
   |
   = help: the trait `std::iter::FromIterator<i32>` is not implemented for `i32`
note: required by `Foo`
  --> $DIR/type-check-defaults.rs:15:1
   |
LL | struct Foo<T, U: FromIterator<T>>(T, U);
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
* [Add link to book for `Sized` errors](https://github.com/rust-lang/rust/pull/51463/commits/1244dc7c283323aea1a3457a4458d590a3e160c8):
```
error[E0277]: `std::fmt::Debug + std::marker::Sync + 'static` does not have a constant size known at compile-time
  --> $DIR/const-unsized.rs:13:29
   |
LL | const CONST_0: Debug+Sync = *(&0 as &(Debug+Sync));
   |                             ^^^^^^^^^^^^^^^^^^^^^^ `std::fmt::Debug + std::marker::Sync + 'static` does not have a constant size known at compile-time
   |
   = help: the trait `std::marker::Sized` is not implemented for `std::fmt::Debug + std::marker::Sync + 'static`
   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
   = note: constant expressions must have a statically known size
```
* [Point to previous line for single expected token not found](https://github.com/rust-lang/rust/pull/51463/commits/48165168fb0f059d8536cd4a2276b609d4a7f721) (if the current token is in a different line)
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/parser.rs49
1 files changed, 32 insertions, 17 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 6f78ae9ebca..3955ccb4c42 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -638,7 +638,26 @@ impl<'a> Parser<'a> {
                 let mut err = self.fatal(&format!("expected `{}`, found `{}`",
                                                   token_str,
                                                   this_token_str));
-                err.span_label(self.span, format!("expected `{}`", token_str));
+
+                let sp = if self.token == token::Token::Eof {
+                    // EOF, don't want to point at the following char, but rather the last token
+                    self.prev_span
+                } else {
+                    self.sess.codemap().next_point(self.prev_span)
+                };
+                let label_exp = format!("expected `{}`", token_str);
+                let cm = self.sess.codemap();
+                match (cm.lookup_line(self.span.lo()), cm.lookup_line(sp.lo())) {
+                    (Ok(ref a), Ok(ref b)) if a.line == b.line => {
+                        // When the spans are in the same line, it means that the only content
+                        // between them is whitespace, point only at the found token.
+                        err.span_label(self.span, label_exp);
+                    }
+                    _ => {
+                        err.span_label(sp, label_exp);
+                        err.span_label(self.span, "unexpected token");
+                    }
+                }
                 Err(err)
             }
         } else {
@@ -1205,14 +1224,6 @@ impl<'a> Parser<'a> {
     fn span_fatal_err<S: Into<MultiSpan>>(&self, sp: S, err: Error) -> DiagnosticBuilder<'a> {
         err.span_err(sp, self.diagnostic())
     }
-    fn span_fatal_help<S: Into<MultiSpan>>(&self,
-                                            sp: S,
-                                            m: &str,
-                                            help: &str) -> DiagnosticBuilder<'a> {
-        let mut err = self.sess.span_diagnostic.struct_span_fatal(sp, m);
-        err.help(help);
-        err
-    }
     fn bug(&self, m: &str) -> ! {
         self.sess.span_diagnostic.span_bug(self.span, m)
     }
@@ -5985,12 +5996,13 @@ impl<'a> Parser<'a> {
 `pub(super)`: visible only in the current module's parent
 `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 sp = self.prev_span;
                 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);
+                let mut err = struct_span_err!(self.sess.span_diagnostic, sp, E0704, "{}", msg);
+                err.help(suggestion);
                 err.span_suggestion_with_applicability(
-                    path_span, &help_msg, format!("in {}", path), Applicability::MachineApplicable
+                    sp, &help_msg, format!("in {}", path), Applicability::MachineApplicable
                 );
                 err.emit();  // emit diagnostic, but continue with public visibility
             }
@@ -6534,12 +6546,15 @@ impl<'a> Parser<'a> {
                     Some(abi) => Ok(Some(abi)),
                     None => {
                         let prev_span = self.prev_span;
-                        self.span_err(
+                        let mut err = struct_span_err!(
+                            self.sess.span_diagnostic,
                             prev_span,
-                            &format!("invalid ABI: expected one of [{}], \
-                                     found `{}`",
-                                    abi::all_names().join(", "),
-                                    s));
+                            E0703,
+                            "invalid ABI: found `{}`",
+                            s);
+                        err.span_label(prev_span, "invalid ABI");
+                        err.help(&format!("valid ABIs: {}", abi::all_names().join(", ")));
+                        err.emit();
                         Ok(None)
                     }
                 }