Skip to content

Commit 512f778

Browse files
committed
auto merge of #9335 : alexcrichton/rust/issue-7945, r=thestinger
As documented in issue #7945, these literal identifiers are all accepted by rust today, but they should probably be disallowed (especially `'''`). This changes all escapable sequences to being *required* to be escaped. Closes #7945 I wanted to write the tests with more exact spans, but I think #9308 will be fixing that?
2 parents 893ba18 + 2661b63 commit 512f778

File tree

5 files changed

+89
-21
lines changed

5 files changed

+89
-21
lines changed

src/libsyntax/parse/lexer.rs

+28-21
Original file line numberDiff line numberDiff line change
@@ -747,27 +747,34 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token {
747747
}
748748

749749
// Otherwise it is a character constant:
750-
if c2 == '\\' {
751-
// '\X' for some X must be a character constant:
752-
let escaped = rdr.curr;
753-
let escaped_pos = rdr.last_pos;
754-
bump(rdr);
755-
match escaped {
756-
'n' => { c2 = '\n'; }
757-
'r' => { c2 = '\r'; }
758-
't' => { c2 = '\t'; }
759-
'\\' => { c2 = '\\'; }
760-
'\'' => { c2 = '\''; }
761-
'"' => { c2 = '"'; }
762-
'0' => { c2 = '\x00'; }
763-
'x' => { c2 = scan_numeric_escape(rdr, 2u); }
764-
'u' => { c2 = scan_numeric_escape(rdr, 4u); }
765-
'U' => { c2 = scan_numeric_escape(rdr, 8u); }
766-
c2 => {
767-
fatal_span_char(rdr, escaped_pos, rdr.last_pos,
768-
~"unknown character escape", c2);
769-
}
750+
match c2 {
751+
'\\' => {
752+
// '\X' for some X must be a character constant:
753+
let escaped = rdr.curr;
754+
let escaped_pos = rdr.last_pos;
755+
bump(rdr);
756+
match escaped {
757+
'n' => { c2 = '\n'; }
758+
'r' => { c2 = '\r'; }
759+
't' => { c2 = '\t'; }
760+
'\\' => { c2 = '\\'; }
761+
'\'' => { c2 = '\''; }
762+
'"' => { c2 = '"'; }
763+
'0' => { c2 = '\x00'; }
764+
'x' => { c2 = scan_numeric_escape(rdr, 2u); }
765+
'u' => { c2 = scan_numeric_escape(rdr, 4u); }
766+
'U' => { c2 = scan_numeric_escape(rdr, 8u); }
767+
c2 => {
768+
fatal_span_char(rdr, escaped_pos, rdr.last_pos,
769+
~"unknown character escape", c2);
770+
}
771+
}
772+
}
773+
'\t' | '\n' | '\r' | '\'' => {
774+
fatal_span_char(rdr, start, rdr.last_pos,
775+
~"character constant must be escaped", c2);
770776
}
777+
_ => {}
771778
}
772779
if rdr.curr != '\'' {
773780
fatal_span_verbose(rdr,
@@ -973,7 +980,7 @@ mod test {
973980
}
974981

975982
#[test] fn character_escaped() {
976-
let env = setup(@"'\n'");
983+
let env = setup(@"'\\n'");
977984
let TokenAndSpan {tok, sp: _} =
978985
env.string_reader.next_token();
979986
assert_eq!(tok, token::LIT_CHAR('\n' as u32));
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() {
12+
// these literals are just silly.
13+
''';
14+
//~^ ERROR: character constant must be escaped
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() {
12+
// note that this is a literal "\n" byte
13+
'
14+
';
15+
//~^^ ERROR: character constant must be escaped
16+
}

src/test/compile-fail/bad-char-literals3.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() {
12+
// note that this is a literal "\r" byte
13+
'';
14+
//~^ ERROR: character constant must be escaped
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() {
12+
// note that this is a literal tab character here
13+
' ';
14+
//~^ ERROR: character constant must be escaped
15+
}

0 commit comments

Comments
 (0)