Skip to content

Commit d41058e

Browse files
committed
Don't require mutable StringReader to emit lexer errors
Teach StringReader how to emit errors for arbitrary spans, so we don't need to modify peek_span. This allows for emitting errors without having a &mut borrow of the StringReader.
1 parent 0f481db commit d41058e

File tree

1 file changed

+52
-42
lines changed
  • src/libsyntax/parse/lexer

1 file changed

+52
-42
lines changed

src/libsyntax/parse/lexer/mod.rs

+52-42
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,10 @@ impl<'a> Reader for StringReader<'a> {
7070
ret_val
7171
}
7272
fn fatal(&self, m: &str) -> ! {
73-
self.span_diagnostic.span_fatal(self.peek_span, m)
73+
self.fatal_span(self.peek_span, m)
7474
}
7575
fn err(&self, m: &str) {
76-
self.span_diagnostic.span_err(self.peek_span, m)
76+
self.err_span(self.peek_span, m)
7777
}
7878
fn peek(&self) -> TokenAndSpan {
7979
// FIXME(pcwalton): Bad copy!
@@ -137,43 +137,52 @@ impl<'a> StringReader<'a> {
137137
self.curr == Some(c)
138138
}
139139

140-
/// Report a lexical error spanning [`from_pos`, `to_pos`)
141-
fn fatal_span(&mut self, from_pos: BytePos, to_pos: BytePos, m: &str) -> ! {
142-
self.peek_span = codemap::mk_sp(from_pos, to_pos);
143-
self.fatal(m);
140+
/// Report a fatal lexical error with a given span.
141+
pub fn fatal_span(&self, sp: Span, m: &str) -> ! {
142+
self.span_diagnostic.span_fatal(sp, m)
144143
}
145144

146-
fn err_span(&mut self, from_pos: BytePos, to_pos: BytePos, m: &str) {
147-
self.peek_span = codemap::mk_sp(from_pos, to_pos);
148-
self.err(m);
145+
/// Report a lexical error with a given span.
146+
pub fn err_span(&self, sp: Span, m: &str) {
147+
self.span_diagnostic.span_err(sp, m)
148+
}
149+
150+
/// Report a fatal error spanning [`from_pos`, `to_pos`).
151+
fn fatal_span_(&self, from_pos: BytePos, to_pos: BytePos, m: &str) -> ! {
152+
self.fatal_span(codemap::mk_sp(from_pos, to_pos), m)
153+
}
154+
155+
/// Report a lexical error spanning [`from_pos`, `to_pos`).
156+
fn err_span_(&self, from_pos: BytePos, to_pos: BytePos, m: &str) {
157+
self.err_span(codemap::mk_sp(from_pos, to_pos), m)
149158
}
150159

151160
/// Report a lexical error spanning [`from_pos`, `to_pos`), appending an
152161
/// escaped character to the error message
153-
fn fatal_span_char(&mut self, from_pos: BytePos, to_pos: BytePos, m: &str, c: char) -> ! {
162+
fn fatal_span_char(&self, from_pos: BytePos, to_pos: BytePos, m: &str, c: char) -> ! {
154163
let mut m = m.to_string();
155164
m.push_str(": ");
156165
char::escape_default(c, |c| m.push_char(c));
157-
self.fatal_span(from_pos, to_pos, m.as_slice());
166+
self.fatal_span_(from_pos, to_pos, m.as_slice());
158167
}
159168

160169
/// Report a lexical error spanning [`from_pos`, `to_pos`), appending an
161170
/// escaped character to the error message
162-
fn err_span_char(&mut self, from_pos: BytePos, to_pos: BytePos, m: &str, c: char) {
171+
fn err_span_char(&self, from_pos: BytePos, to_pos: BytePos, m: &str, c: char) {
163172
let mut m = m.to_string();
164173
m.push_str(": ");
165174
char::escape_default(c, |c| m.push_char(c));
166-
self.err_span(from_pos, to_pos, m.as_slice());
175+
self.err_span_(from_pos, to_pos, m.as_slice());
167176
}
168177

169178
/// Report a lexical error spanning [`from_pos`, `to_pos`), appending the
170179
/// offending string to the error message
171-
fn fatal_span_verbose(&mut self, from_pos: BytePos, to_pos: BytePos, mut m: String) -> ! {
180+
fn fatal_span_verbose(&self, from_pos: BytePos, to_pos: BytePos, mut m: String) -> ! {
172181
m.push_str(": ");
173182
let from = self.byte_offset(from_pos).to_uint();
174183
let to = self.byte_offset(to_pos).to_uint();
175184
m.push_str(self.filemap.src.as_slice().slice(from, to));
176-
self.fatal_span(from_pos, to_pos, m.as_slice());
185+
self.fatal_span_(from_pos, to_pos, m.as_slice());
177186
}
178187

179188
/// Advance peek_tok and peek_span to refer to the next token, and
@@ -369,7 +378,7 @@ impl<'a> StringReader<'a> {
369378
"unterminated block comment"
370379
};
371380
let last_bpos = self.last_pos;
372-
self.fatal_span(start_bpos, last_bpos, msg);
381+
self.fatal_span_(start_bpos, last_bpos, msg);
373382
} else if self.curr_is('/') && self.nextch_is('*') {
374383
level += 1;
375384
self.bump();
@@ -421,7 +430,7 @@ impl<'a> StringReader<'a> {
421430
return Some(rslt);
422431
} else {
423432
let last_bpos = self.last_pos;
424-
self.err_span(start_bpos, last_bpos, "scan_exponent: bad fp literal");
433+
self.err_span_(start_bpos, last_bpos, "scan_exponent: bad fp literal");
425434
rslt.push_str("1"); // arbitrary placeholder exponent
426435
return Some(rslt);
427436
}
@@ -447,9 +456,10 @@ impl<'a> StringReader<'a> {
447456

448457
fn check_float_base(&mut self, start_bpos: BytePos, last_bpos: BytePos, base: uint) {
449458
match base {
450-
16u => self.err_span(start_bpos, last_bpos, "hexadecimal float literal is not supported"),
451-
8u => self.err_span(start_bpos, last_bpos, "octal float literal is not supported"),
452-
2u => self.err_span(start_bpos, last_bpos, "binary float literal is not supported"),
459+
16u => self.err_span_(start_bpos, last_bpos,
460+
"hexadecimal float literal is not supported"),
461+
8u => self.err_span_(start_bpos, last_bpos, "octal float literal is not supported"),
462+
2u => self.err_span_(start_bpos, last_bpos, "binary float literal is not supported"),
453463
_ => ()
454464
}
455465
}
@@ -509,15 +519,15 @@ impl<'a> StringReader<'a> {
509519
}
510520
if num_str.len() == 0u {
511521
let last_bpos = self.last_pos;
512-
self.err_span(start_bpos, last_bpos, "no valid digits found for number");
522+
self.err_span_(start_bpos, last_bpos, "no valid digits found for number");
513523
num_str = "1".to_string();
514524
}
515525
let parsed = match from_str_radix::<u64>(num_str.as_slice(),
516526
base as uint) {
517527
Some(p) => p,
518528
None => {
519529
let last_bpos = self.last_pos;
520-
self.err_span(start_bpos, last_bpos, "int literal is too large");
530+
self.err_span_(start_bpos, last_bpos, "int literal is too large");
521531
1
522532
}
523533
};
@@ -573,7 +583,7 @@ impl<'a> StringReader<'a> {
573583
return token::LIT_FLOAT(str_to_ident(num_str.as_slice()), ast::TyF128);
574584
}
575585
let last_bpos = self.last_pos;
576-
self.err_span(start_bpos, last_bpos, "expected `f32`, `f64` or `f128` suffix");
586+
self.err_span_(start_bpos, last_bpos, "expected `f32`, `f64` or `f128` suffix");
577587
}
578588
if is_float {
579589
let last_bpos = self.last_pos;
@@ -583,15 +593,15 @@ impl<'a> StringReader<'a> {
583593
} else {
584594
if num_str.len() == 0u {
585595
let last_bpos = self.last_pos;
586-
self.err_span(start_bpos, last_bpos, "no valid digits found for number");
596+
self.err_span_(start_bpos, last_bpos, "no valid digits found for number");
587597
num_str = "1".to_string();
588598
}
589599
let parsed = match from_str_radix::<u64>(num_str.as_slice(),
590600
base as uint) {
591601
Some(p) => p,
592602
None => {
593603
let last_bpos = self.last_pos;
594-
self.err_span(start_bpos, last_bpos, "int literal is too large");
604+
self.err_span_(start_bpos, last_bpos, "int literal is too large");
595605
1
596606
}
597607
};
@@ -609,11 +619,11 @@ impl<'a> StringReader<'a> {
609619
for _ in range(0, n_hex_digits) {
610620
if self.is_eof() {
611621
let last_bpos = self.last_pos;
612-
self.fatal_span(start_bpos, last_bpos, "unterminated numeric character escape");
622+
self.fatal_span_(start_bpos, last_bpos, "unterminated numeric character escape");
613623
}
614624
if self.curr_is(delim) {
615625
let last_bpos = self.last_pos;
616-
self.err_span(start_bpos, last_bpos, "numeric character escape is too short");
626+
self.err_span_(start_bpos, last_bpos, "numeric character escape is too short");
617627
break;
618628
}
619629
let c = self.curr.unwrap_or('\x00');
@@ -630,7 +640,7 @@ impl<'a> StringReader<'a> {
630640
Some(x) => x,
631641
None => {
632642
let last_bpos = self.last_pos;
633-
self.err_span(start_bpos, last_bpos, "illegal numeric character escape");
643+
self.err_span_(start_bpos, last_bpos, "illegal numeric character escape");
634644
'?'
635645
}
636646
}
@@ -856,16 +866,16 @@ impl<'a> StringReader<'a> {
856866
let last_bpos = self.last_pos;
857867
if token::is_keyword(token::keywords::Self,
858868
keyword_checking_token) {
859-
self.err_span(start,
860-
last_bpos,
861-
"invalid lifetime name: 'self \
862-
is no longer a special lifetime");
869+
self.err_span_(start,
870+
last_bpos,
871+
"invalid lifetime name: 'self \
872+
is no longer a special lifetime");
863873
} else if token::is_any_keyword(keyword_checking_token) &&
864874
!token::is_keyword(token::keywords::Static,
865875
keyword_checking_token) {
866-
self.err_span(start,
867-
last_bpos,
868-
"invalid lifetime name");
876+
self.err_span_(start,
877+
last_bpos,
878+
"invalid lifetime name");
869879
}
870880
return token::LIFETIME(ident);
871881
}
@@ -922,8 +932,8 @@ impl<'a> StringReader<'a> {
922932
while !self_.curr_is('"') {
923933
if self_.is_eof() {
924934
let last_pos = self_.last_pos;
925-
self_.fatal_span(start, last_pos,
926-
"unterminated double quote byte string");
935+
self_.fatal_span_(start, last_pos,
936+
"unterminated double quote byte string");
927937
}
928938

929939
let ch_start = self_.last_pos;
@@ -947,7 +957,7 @@ impl<'a> StringReader<'a> {
947957

948958
if self_.is_eof() {
949959
let last_pos = self_.last_pos;
950-
self_.fatal_span(start_bpos, last_pos, "unterminated raw string");
960+
self_.fatal_span_(start_bpos, last_pos, "unterminated raw string");
951961
} else if !self_.curr_is('"') {
952962
let last_pos = self_.last_pos;
953963
let ch = self_.curr.unwrap();
@@ -963,7 +973,7 @@ impl<'a> StringReader<'a> {
963973
match self_.curr {
964974
None => {
965975
let last_pos = self_.last_pos;
966-
self_.fatal_span(start_bpos, last_pos, "unterminated raw string")
976+
self_.fatal_span_(start_bpos, last_pos, "unterminated raw string")
967977
},
968978
Some('"') => {
969979
content_end_bpos = self_.last_pos;
@@ -997,7 +1007,7 @@ impl<'a> StringReader<'a> {
9971007
while !self.curr_is('"') {
9981008
if self.is_eof() {
9991009
let last_bpos = self.last_pos;
1000-
self.fatal_span(start_bpos, last_bpos, "unterminated double quote string");
1010+
self.fatal_span_(start_bpos, last_bpos, "unterminated double quote string");
10011011
}
10021012

10031013
let ch_start = self.last_pos;
@@ -1020,7 +1030,7 @@ impl<'a> StringReader<'a> {
10201030

10211031
if self.is_eof() {
10221032
let last_bpos = self.last_pos;
1023-
self.fatal_span(start_bpos, last_bpos, "unterminated raw string");
1033+
self.fatal_span_(start_bpos, last_bpos, "unterminated raw string");
10241034
} else if !self.curr_is('"') {
10251035
let last_bpos = self.last_pos;
10261036
let curr_char = self.curr.unwrap();
@@ -1035,7 +1045,7 @@ impl<'a> StringReader<'a> {
10351045
'outer: loop {
10361046
if self.is_eof() {
10371047
let last_bpos = self.last_pos;
1038-
self.fatal_span(start_bpos, last_bpos, "unterminated raw string");
1048+
self.fatal_span_(start_bpos, last_bpos, "unterminated raw string");
10391049
}
10401050
if self.curr_is('"') {
10411051
content_end_bpos = self.last_pos;

0 commit comments

Comments
 (0)