From acc9428c6a99d199f35032ec7f794385e4c9fd24 Mon Sep 17 00:00:00 2001 From: Greg Chapple Date: Thu, 7 Jan 2016 16:12:28 +0000 Subject: [PATCH] Display better snippet for invalid char literal Given this code: fn main() { let _ = 'abcd'; } The compiler would give a message like: error: character literal may only contain one codepoint: '; let _ = 'abcd'; ^~ With this change, the message now displays: error: character literal may only contain one codepoint: 'abcd' let _ = 'abcd' ^~~~~~ Fixes #30033 --- src/libsyntax/parse/lexer/mod.rs | 25 +++++++++++-------- ...literals.rs => lex-bad-char-literals-1.rs} | 7 +----- .../parse-fail/lex-bad-char-literals-2.rs | 17 +++++++++++++ .../parse-fail/lex-bad-char-literals-3.rs | 16 ++++++++++++ .../parse-fail/lex-bad-char-literals-4.rs | 16 ++++++++++++ .../parse-fail/lex-bad-char-literals-5.rs | 16 ++++++++++++ 6 files changed, 81 insertions(+), 16 deletions(-) rename src/test/parse-fail/{lex-bad-char-literals.rs => lex-bad-char-literals-1.rs} (78%) create mode 100644 src/test/parse-fail/lex-bad-char-literals-2.rs create mode 100644 src/test/parse-fail/lex-bad-char-literals-3.rs create mode 100644 src/test/parse-fail/lex-bad-char-literals-4.rs create mode 100644 src/test/parse-fail/lex-bad-char-literals-5.rs diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 1402b7888dd10..3183dfbd954f5 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1195,6 +1195,7 @@ impl<'a> StringReader<'a> { } '\'' => { // Either a character constant 'a' OR a lifetime name 'abc + let start_with_quote = self.last_pos; self.bump(); let start = self.last_pos; @@ -1208,6 +1209,14 @@ impl<'a> StringReader<'a> { while ident_continue(self.curr) { self.bump(); } + // lifetimes shouldn't end with a single quote + // if we find one, then this is an invalid character literal + if self.curr_is('\'') { + panic!(self.fatal_span_verbose( + start_with_quote, self.pos, + String::from("character literal may only contain one codepoint"))); + + } // Include the leading `'` in the real identifier, for macro // expansion purposes. See #12512 for the gory details of why @@ -1233,26 +1242,22 @@ impl<'a> StringReader<'a> { !keyword_checking_token.is_keyword(token::keywords::Static) { self.err_span_(start, last_bpos, "invalid lifetime name"); } + return token::Lifetime(ident); } - // Otherwise it is a character constant: let valid = self.scan_char_or_byte(start, c2, // ascii_only = false, '\''); + if !self.curr_is('\'') { - let last_bpos = self.last_pos; - panic!(self.fatal_span_verbose(// Byte offsetting here is okay because the - // character before position `start` is an - // ascii single quote. - start - BytePos(1), - last_bpos, - - String::from("character literal may only \ - contain one codepoint"))); + panic!(self.fatal_span_verbose( + start_with_quote, self.last_pos, + String::from("character literal may only contain one codepoint"))); } + let id = if valid { self.name_from(start) } else { diff --git a/src/test/parse-fail/lex-bad-char-literals.rs b/src/test/parse-fail/lex-bad-char-literals-1.rs similarity index 78% rename from src/test/parse-fail/lex-bad-char-literals.rs rename to src/test/parse-fail/lex-bad-char-literals-1.rs index 6335632455fbd..7e22a11ca970d 100644 --- a/src/test/parse-fail/lex-bad-char-literals.rs +++ b/src/test/parse-fail/lex-bad-char-literals-1.rs @@ -1,4 +1,4 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// 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. // @@ -25,8 +25,3 @@ static s: &'static str = "\●" //~ ERROR: unknown character escape ; -// THIS MUST BE LAST, since it kills the lexer - -static c: char = - '● //~ ERROR: character literal may only contain one codepoint -; diff --git a/src/test/parse-fail/lex-bad-char-literals-2.rs b/src/test/parse-fail/lex-bad-char-literals-2.rs new file mode 100644 index 0000000000000..8bd6808c5ffd4 --- /dev/null +++ b/src/test/parse-fail/lex-bad-char-literals-2.rs @@ -0,0 +1,17 @@ +// 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. + +// compile-flags: -Z parse-only + +// This test needs to the last one appearing in this file as it kills the parser +static c: char = + 'nope' //~ ERROR: character literal may only contain one codepoint: 'nope' +; + diff --git a/src/test/parse-fail/lex-bad-char-literals-3.rs b/src/test/parse-fail/lex-bad-char-literals-3.rs new file mode 100644 index 0000000000000..92432dc8b63eb --- /dev/null +++ b/src/test/parse-fail/lex-bad-char-literals-3.rs @@ -0,0 +1,16 @@ +// 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. + +// compile-flags: -Z parse-only + +// This test needs to the last one appearing in this file as it kills the parser +static c: char = + '●●' //~ ERROR: character literal may only contain one codepoint: '● +; diff --git a/src/test/parse-fail/lex-bad-char-literals-4.rs b/src/test/parse-fail/lex-bad-char-literals-4.rs new file mode 100644 index 0000000000000..b230e62360380 --- /dev/null +++ b/src/test/parse-fail/lex-bad-char-literals-4.rs @@ -0,0 +1,16 @@ +// 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. + +// compile-flags: -Z parse-only +// +// This test needs to the last one appearing in this file as it kills the parser +static c: char = + '● //~ ERROR: character literal may only contain one codepoint: '● +; diff --git a/src/test/parse-fail/lex-bad-char-literals-5.rs b/src/test/parse-fail/lex-bad-char-literals-5.rs new file mode 100644 index 0000000000000..5259175b186f5 --- /dev/null +++ b/src/test/parse-fail/lex-bad-char-literals-5.rs @@ -0,0 +1,16 @@ +// 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. + +// compile-flags: -Z parse-only +// +// This test needs to the last one appearing in this file as it kills the parser +static c: char = + '\x10\x10' //~ ERROR: character literal may only contain one codepoint: '\x10 +;