From 26282ac33777e3e7b3b483cdd2546a76807215d7 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Mon, 10 Nov 2014 21:58:03 +1100 Subject: Add more "help: ..."'s to the parser. Adds a method for printing a fatal error and also a help message to the parser and uses this in a variety of places to improve error messages. Closes #12213. --- src/libsyntax/parse/parser.rs | 61 +++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 23 deletions(-) (limited to 'src/libsyntax/parse/parser.rs') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 6873c015fd5..5cea74f0b96 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -66,6 +66,7 @@ use ast_util::{as_prec, ident_to_path, operator_prec}; use ast_util; use codemap::{Span, BytePos, Spanned, spanned, mk_sp}; use codemap; +use diagnostic; use ext::tt::macro_parser; use parse; use parse::attr::ParserAttr; @@ -940,6 +941,11 @@ impl<'a> Parser<'a> { pub fn span_fatal(&mut self, sp: Span, m: &str) -> ! { self.sess.span_diagnostic.span_fatal(sp, m) } + pub fn span_fatal_help(&mut self, sp: Span, m: &str, help: &str) -> ! { + self.span_err(sp, m); + self.span_help(sp, help); + panic!(diagnostic::FatalError); + } pub fn span_note(&mut self, sp: Span, m: &str) { self.sess.span_diagnostic.span_note(sp, m) } @@ -3702,7 +3708,14 @@ impl<'a> Parser<'a> { maybe_whole!(no_clone self, NtBlock); let lo = self.span.lo; - self.expect(&token::OpenDelim(token::Brace)); + + if !self.eat(&token::OpenDelim(token::Brace)) { + let sp = self.span; + let tok = self.this_token_to_string(); + self.span_fatal_help(sp, + format!("expected `{{`, found `{}`", tok).as_slice(), + "place this code inside a block"); + } return self.parse_block_tail_(lo, DefaultBlock, Vec::new()); } @@ -4693,9 +4706,10 @@ impl<'a> Parser<'a> { _ => { let span = self.span; let token_str = self.this_token_to_string(); - self.span_fatal(span, - format!("expected `,`, or `}}`, found `{}`", - token_str).as_slice()) + self.span_fatal_help(span, + format!("expected `,`, or `}}`, found `{}`", + token_str).as_slice(), + "struct fields should be separated by commas") } } a_var @@ -4897,19 +4911,24 @@ impl<'a> Parser<'a> { (true, false) => (default_path, false), (false, true) => (secondary_path, true), (false, false) => { - self.span_fatal(id_sp, - format!("file not found for module \ - `{}`", - mod_name).as_slice()); + self.span_fatal_help(id_sp, + format!("file not found for module `{}`", + mod_name).as_slice(), + format!("name the file either {} or {} inside \ + the directory {}", + default_path_str, + secondary_path_str, + dir_path.display()).as_slice()); } (true, true) => { - self.span_fatal( + self.span_fatal_help( id_sp, format!("file for module `{}` found at both {} \ and {}", mod_name, default_path_str, - secondary_path_str).as_slice()); + secondary_path_str).as_slice(), + "delete or rename one of them to remove the ambiguity"); } } } @@ -5062,9 +5081,10 @@ impl<'a> Parser<'a> { // skip the ident if there is one if self.token.is_ident() { self.bump(); } - self.span_err(span, - format!("expected `;`, found `as`; perhaps you meant \ - to enclose the crate name `{}` in a string?", + self.span_err(span, "expected `;`, found `as`"); + self.span_help(span, + format!("perhaps you meant to enclose the crate name `{}` in \ + a string?", the_ident.as_str()).as_slice()); None } else { @@ -5574,16 +5594,12 @@ impl<'a> Parser<'a> { } // FAILURE TO PARSE ITEM - if visibility != Inherited { - let mut s = String::from_str("unmatched visibility `"); - if visibility == Public { - s.push_str("pub") - } else { - s.push_str("priv") + match visibility { + Inherited => {} + Public => { + let last_span = self.last_span; + self.span_fatal(last_span, "unmatched visibility `pub`"); } - s.push('`'); - let last_span = self.last_span; - self.span_fatal(last_span, s.as_slice()); } return IoviNone(attrs); } @@ -5905,4 +5921,3 @@ impl<'a> Parser<'a> { } } } - -- cgit 1.4.1-3-g733a5 From 661598cef0ffafb0a5446d4b2b2aea89466102ec Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Mon, 10 Nov 2014 22:07:36 +1100 Subject: Use the correct span for out-of-range int literals. This corrects the error message to point at the literal, not the next token. Closes #17123. --- src/libsyntax/parse/parser.rs | 3 ++- src/test/compile-fail/int-literal-too-large-span.rs | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 src/test/compile-fail/int-literal-too-large-span.rs (limited to 'src/libsyntax/parse/parser.rs') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 5cea74f0b96..cffd204ac27 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1646,7 +1646,8 @@ impl<'a> Parser<'a> { token::LitByte(i) => LitByte(parse::byte_lit(i.as_str()).val0()), token::LitChar(i) => LitChar(parse::char_lit(i.as_str()).val0()), token::LitInteger(s) => parse::integer_lit(s.as_str(), - &self.sess.span_diagnostic, self.span), + &self.sess.span_diagnostic, + self.last_span), token::LitFloat(s) => parse::float_lit(s.as_str()), token::LitStr(s) => { LitStr(token::intern_and_get_ident(parse::str_lit(s.as_str()).as_slice()), diff --git a/src/test/compile-fail/int-literal-too-large-span.rs b/src/test/compile-fail/int-literal-too-large-span.rs new file mode 100644 index 00000000000..8a496c934b9 --- /dev/null +++ b/src/test/compile-fail/int-literal-too-large-span.rs @@ -0,0 +1,17 @@ +// Copyright 2014 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. + +// issue #17123 + +fn main() { + 100000000000000000000000000000000 //~ ERROR int literal is too large + + ; // the span shouldn't point to this. +} -- cgit 1.4.1-3-g733a5