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
This commit is contained in:
parent
d3c83fef24
commit
acc9428c6a
6 changed files with 81 additions and 16 deletions
|
@ -1195,6 +1195,7 @@ impl<'a> StringReader<'a> {
|
||||||
}
|
}
|
||||||
'\'' => {
|
'\'' => {
|
||||||
// Either a character constant 'a' OR a lifetime name 'abc
|
// Either a character constant 'a' OR a lifetime name 'abc
|
||||||
|
let start_with_quote = self.last_pos;
|
||||||
self.bump();
|
self.bump();
|
||||||
let start = self.last_pos;
|
let start = self.last_pos;
|
||||||
|
|
||||||
|
@ -1208,6 +1209,14 @@ impl<'a> StringReader<'a> {
|
||||||
while ident_continue(self.curr) {
|
while ident_continue(self.curr) {
|
||||||
self.bump();
|
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
|
// Include the leading `'` in the real identifier, for macro
|
||||||
// expansion purposes. See #12512 for the gory details of why
|
// 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) {
|
!keyword_checking_token.is_keyword(token::keywords::Static) {
|
||||||
self.err_span_(start, last_bpos, "invalid lifetime name");
|
self.err_span_(start, last_bpos, "invalid lifetime name");
|
||||||
}
|
}
|
||||||
|
|
||||||
return token::Lifetime(ident);
|
return token::Lifetime(ident);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise it is a character constant:
|
|
||||||
let valid = self.scan_char_or_byte(start,
|
let valid = self.scan_char_or_byte(start,
|
||||||
c2,
|
c2,
|
||||||
// ascii_only =
|
// ascii_only =
|
||||||
false,
|
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 \
|
if !self.curr_is('\'') {
|
||||||
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 {
|
let id = if valid {
|
||||||
self.name_from(start)
|
self.name_from(start)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -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
|
// file at the top-level directory of this distribution and at
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
//
|
//
|
||||||
|
@ -25,8 +25,3 @@ static s: &'static str =
|
||||||
"\●" //~ ERROR: unknown character escape
|
"\●" //~ ERROR: unknown character escape
|
||||||
;
|
;
|
||||||
|
|
||||||
// THIS MUST BE LAST, since it kills the lexer
|
|
||||||
|
|
||||||
static c: char =
|
|
||||||
'● //~ ERROR: character literal may only contain one codepoint
|
|
||||||
;
|
|
17
src/test/parse-fail/lex-bad-char-literals-2.rs
Normal file
17
src/test/parse-fail/lex-bad-char-literals-2.rs
Normal file
|
@ -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 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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'
|
||||||
|
;
|
||||||
|
|
16
src/test/parse-fail/lex-bad-char-literals-3.rs
Normal file
16
src/test/parse-fail/lex-bad-char-literals-3.rs
Normal file
|
@ -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 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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: '●
|
||||||
|
;
|
16
src/test/parse-fail/lex-bad-char-literals-4.rs
Normal file
16
src/test/parse-fail/lex-bad-char-literals-4.rs
Normal file
|
@ -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 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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: '●
|
||||||
|
;
|
16
src/test/parse-fail/lex-bad-char-literals-5.rs
Normal file
16
src/test/parse-fail/lex-bad-char-literals-5.rs
Normal file
|
@ -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 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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
|
||||||
|
;
|
Loading…
Reference in a new issue