Skip to content

Commit 0c2b4ed

Browse files
committed
auto merge of #4847 : nikomatsakis/rust/region-syntax, r=graydon
cc #4846 r? @pcwalton
2 parents f529af0 + 14930fb commit 0c2b4ed

File tree

3 files changed

+90
-22
lines changed

3 files changed

+90
-22
lines changed

Diff for: src/libsyntax/ast.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ macro_rules! interner_key (
2929
(-3 as uint, 0u)))
3030
)
3131

32+
#[deriving_eq]
3233
pub struct ident { repr: uint }
3334

3435
pub impl<S: Encoder> ident: Encodable<S> {
@@ -57,11 +58,6 @@ pub impl<D: Decoder> ident: Decodable<D> {
5758
}
5859
}
5960
60-
pub impl ident: cmp::Eq {
61-
pure fn eq(&self, other: &ident) -> bool { (*self).repr == other.repr }
62-
pure fn ne(&self, other: &ident) -> bool { !(*self).eq(other) }
63-
}
64-
6561
pub impl ident: to_bytes::IterBytes {
6662
pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
6763
self.repr.iter_bytes(lsb0, f)

Diff for: src/libsyntax/parse/lexer.rs

+81-16
Original file line numberDiff line numberDiff line change
@@ -501,18 +501,26 @@ fn scan_numeric_escape(rdr: @mut StringReader, n_hex_digits: uint) -> char {
501501
return accum_int as char;
502502
}
503503

504+
fn ident_start(c: char) -> bool {
505+
(c >= 'a' && c <= 'z')
506+
|| (c >= 'A' && c <= 'Z')
507+
|| c == '_'
508+
|| (c > 'z' && char::is_XID_start(c))
509+
}
510+
511+
fn ident_continue(c: char) -> bool {
512+
(c >= 'a' && c <= 'z')
513+
|| (c >= 'A' && c <= 'Z')
514+
|| (c >= '0' && c <= '9')
515+
|| c == '_'
516+
|| (c > 'z' && char::is_XID_continue(c))
517+
}
518+
504519
fn next_token_inner(rdr: @mut StringReader) -> token::Token {
505520
let mut accum_str = ~"";
506521
let mut c = rdr.curr;
507-
if (c >= 'a' && c <= 'z')
508-
|| (c >= 'A' && c <= 'Z')
509-
|| c == '_'
510-
|| (c > 'z' && char::is_XID_start(c)) {
511-
while (c >= 'a' && c <= 'z')
512-
|| (c >= 'A' && c <= 'Z')
513-
|| (c >= '0' && c <= '9')
514-
|| c == '_'
515-
|| (c > 'z' && char::is_XID_continue(c)) {
522+
if ident_start(c) {
523+
while ident_continue(c) {
516524
str::push_char(&mut accum_str, c);
517525
bump(rdr);
518526
c = rdr.curr;
@@ -617,10 +625,26 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token {
617625
}
618626
}
619627
'\'' => {
628+
// Either a character constant 'a' OR a lifetime name 'abc
620629
bump(rdr);
621630
let mut c2 = rdr.curr;
622631
bump(rdr);
632+
633+
// If the character is an ident start not followed by another single
634+
// quote, then this is a lifetime name:
635+
if ident_start(c2) && rdr.curr != '\'' {
636+
let mut lifetime_name = ~"";
637+
lifetime_name.push_char(c2);
638+
while ident_continue(rdr.curr) {
639+
lifetime_name.push_char(rdr.curr);
640+
bump(rdr);
641+
}
642+
return token::LIFETIME(rdr.interner.intern(@lifetime_name));
643+
}
644+
645+
// Otherwise it is a character constant:
623646
if c2 == '\\' {
647+
// '\X' for some X must be a character constant:
624648
let escaped = rdr.curr;
625649
bump(rdr);
626650
match escaped {
@@ -730,17 +754,29 @@ pub mod test {
730754
use util::interner;
731755
use diagnostic;
732756
use util::testing::{check_equal, check_equal_ptr};
733-
#[tetst] fn t1 () {
734-
let teststr =
735-
@~"/* my source file */
736-
fn main() { io::println(~\"zebra\"); }\n";
757+
758+
struct Env {
759+
interner: @token::ident_interner,
760+
string_reader: @mut StringReader
761+
}
762+
763+
fn setup(teststr: ~str) -> Env {
737764
let cm = CodeMap::new();
738-
let fm = cm.new_filemap(~"zebra.rs",teststr);
765+
let fm = cm.new_filemap(~"zebra.rs", @teststr);
739766
let ident_interner = token::mk_ident_interner(); // interner::mk();
740-
let id = ident_interner.intern(@~"fn");
741767
let span_handler =
742768
diagnostic::mk_span_handler(diagnostic::mk_handler(None),@cm);
743-
let string_reader = new_string_reader(span_handler,fm,ident_interner);
769+
Env {
770+
interner: ident_interner,
771+
string_reader: new_string_reader(span_handler,fm,ident_interner)
772+
}
773+
}
774+
775+
#[test] fn t1 () {
776+
let Env {interner: ident_interner, string_reader} =
777+
setup(~"/* my source file */ \
778+
fn main() { io::println(~\"zebra\"); }\n");
779+
let id = ident_interner.intern(@~"fn");
744780
let tok1 = string_reader.next_token();
745781
let tok2 = TokenAndSpan{
746782
tok:token::IDENT(id, false),
@@ -757,6 +793,35 @@ fn main() { io::println(~\"zebra\"); }\n";
757793
// the lparen is already read:
758794
check_equal (string_reader.last_pos,BytePos(29))
759795
}
796+
797+
#[test] fn character_a() {
798+
let env = setup(~"'a'");
799+
let TokenAndSpan {tok, sp: _} =
800+
env.string_reader.next_token();
801+
assert tok == token::LIT_INT('a' as i64, ast::ty_char);
802+
}
803+
804+
#[test] fn character_space() {
805+
let env = setup(~"' '");
806+
let TokenAndSpan {tok, sp: _} =
807+
env.string_reader.next_token();
808+
assert tok == token::LIT_INT(' ' as i64, ast::ty_char);
809+
}
810+
811+
#[test] fn character_escaped() {
812+
let env = setup(~"'\n'");
813+
let TokenAndSpan {tok, sp: _} =
814+
env.string_reader.next_token();
815+
assert tok == token::LIT_INT('\n' as i64, ast::ty_char);
816+
}
817+
818+
#[test] fn lifetime_name() {
819+
let env = setup(~"'abc");
820+
let TokenAndSpan {tok, sp: _} =
821+
env.string_reader.next_token();
822+
let id = env.interner.intern(@~"abc");
823+
assert tok == token::LIFETIME(id);
824+
}
760825
}
761826

762827
//

Diff for: src/libsyntax/parse/token.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ pub enum Token {
8888
/* Name components */
8989
IDENT(ast::ident, bool),
9090
UNDERSCORE,
91+
LIFETIME(ast::ident),
9192

9293
/* For interpolation */
9394
INTERPOLATED(nonterminal),
@@ -193,7 +194,7 @@ pub fn to_str(in: @ident_interner, t: Token) -> ~str {
193194

194195
/* Name components */
195196
IDENT(s, _) => *in.get(s),
196-
197+
LIFETIME(s) => fmt!("'%s", *in.get(s)),
197198
UNDERSCORE => ~"_",
198199

199200
/* Other */
@@ -760,6 +761,12 @@ impl Token : cmp::Eq {
760761
_ => false
761762
}
762763
}
764+
LIFETIME(e0a) => {
765+
match (*other) {
766+
LIFETIME(e0b) => e0a == e0b,
767+
_ => false
768+
}
769+
}
763770
UNDERSCORE => {
764771
match (*other) {
765772
UNDERSCORE => true,

0 commit comments

Comments
 (0)