about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-09-24 19:06:01 -0700
committerbors <bors@rust-lang.org>2013-09-24 19:06:01 -0700
commit512f7781fe86cde003132969e7fed5aea649bf13 (patch)
tree60a15740ec3bd011889a493fe803ac065f85ee36 /src/libsyntax/parse
parent893ba18cd16ca5922f827e38291de809915fca57 (diff)
parent2661b633c50f6c43b95aca1381f25fc314544331 (diff)
downloadrust-512f7781fe86cde003132969e7fed5aea649bf13.tar.gz
rust-512f7781fe86cde003132969e7fed5aea649bf13.zip
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?
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/lexer.rs49
1 files changed, 28 insertions, 21 deletions
diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs
index d3b0866d4a7..c848f52b3ea 100644
--- a/src/libsyntax/parse/lexer.rs
+++ b/src/libsyntax/parse/lexer.rs
@@ -747,27 +747,34 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token {
         }
 
         // Otherwise it is a character constant:
-        if c2 == '\\' {
-            // '\X' for some X must be a character constant:
-            let escaped = rdr.curr;
-            let escaped_pos = rdr.last_pos;
-            bump(rdr);
-            match escaped {
-              'n' => { c2 = '\n'; }
-              'r' => { c2 = '\r'; }
-              't' => { c2 = '\t'; }
-              '\\' => { c2 = '\\'; }
-              '\'' => { c2 = '\''; }
-              '"' => { c2 = '"'; }
-              '0' => { c2 = '\x00'; }
-              'x' => { c2 = scan_numeric_escape(rdr, 2u); }
-              'u' => { c2 = scan_numeric_escape(rdr, 4u); }
-              'U' => { c2 = scan_numeric_escape(rdr, 8u); }
-              c2 => {
-                fatal_span_char(rdr, escaped_pos, rdr.last_pos,
-                                ~"unknown character escape", c2);
-              }
+        match c2 {
+            '\\' => {
+                // '\X' for some X must be a character constant:
+                let escaped = rdr.curr;
+                let escaped_pos = rdr.last_pos;
+                bump(rdr);
+                match escaped {
+                    'n' => { c2 = '\n'; }
+                    'r' => { c2 = '\r'; }
+                    't' => { c2 = '\t'; }
+                    '\\' => { c2 = '\\'; }
+                    '\'' => { c2 = '\''; }
+                    '"' => { c2 = '"'; }
+                    '0' => { c2 = '\x00'; }
+                    'x' => { c2 = scan_numeric_escape(rdr, 2u); }
+                    'u' => { c2 = scan_numeric_escape(rdr, 4u); }
+                    'U' => { c2 = scan_numeric_escape(rdr, 8u); }
+                    c2 => {
+                        fatal_span_char(rdr, escaped_pos, rdr.last_pos,
+                                        ~"unknown character escape", c2);
+                    }
+                }
+            }
+            '\t' | '\n' | '\r' | '\'' => {
+                fatal_span_char(rdr, start, rdr.last_pos,
+                                ~"character constant must be escaped", c2);
             }
+            _ => {}
         }
         if rdr.curr != '\'' {
             fatal_span_verbose(rdr,
@@ -973,7 +980,7 @@ mod test {
     }
 
     #[test] fn character_escaped() {
-        let env = setup(@"'\n'");
+        let env = setup(@"'\\n'");
         let TokenAndSpan {tok, sp: _} =
             env.string_reader.next_token();
         assert_eq!(tok, token::LIT_CHAR('\n' as u32));