Skip to content

Commit e163e79

Browse files
authored
Merge pull request dtolnay#378 from dtolnay/literalspan
Create meaningful span for Literal in FromStr
2 parents 287979f + da4c83d commit e163e79

File tree

3 files changed

+46
-9
lines changed

3 files changed

+46
-9
lines changed

src/fallback.rs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,20 +1020,30 @@ impl Literal {
10201020
impl FromStr for Literal {
10211021
type Err = LexError;
10221022

1023-
fn from_str(mut repr: &str) -> Result<Self, Self::Err> {
1024-
let negative = repr.starts_with('-');
1023+
fn from_str(repr: &str) -> Result<Self, Self::Err> {
1024+
let mut cursor = get_cursor(repr);
1025+
#[cfg(span_locations)]
1026+
let lo = cursor.off;
1027+
1028+
let negative = cursor.starts_with_char('-');
10251029
if negative {
1026-
repr = &repr[1..];
1027-
if !repr.starts_with(|ch: char| ch.is_ascii_digit()) {
1030+
cursor = cursor.advance(1);
1031+
if !cursor.starts_with_fn(|ch| ch.is_ascii_digit()) {
10281032
return Err(LexError::call_site());
10291033
}
10301034
}
1031-
let cursor = get_cursor(repr);
1032-
if let Ok((_rest, mut literal)) = parse::literal(cursor) {
1033-
if literal.repr.len() == repr.len() {
1035+
1036+
if let Ok((rest, mut literal)) = parse::literal(cursor) {
1037+
if rest.is_empty() {
10341038
if negative {
10351039
literal.repr.insert(0, '-');
10361040
}
1041+
literal.span = Span {
1042+
#[cfg(span_locations)]
1043+
lo,
1044+
#[cfg(span_locations)]
1045+
hi: rest.off,
1046+
};
10371047
return Ok(literal);
10381048
}
10391049
}

src/parse.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,18 @@ impl<'a> Cursor<'a> {
2727
self.rest.starts_with(s)
2828
}
2929

30-
fn starts_with_char(&self, ch: char) -> bool {
30+
pub fn starts_with_char(&self, ch: char) -> bool {
3131
self.rest.starts_with(ch)
3232
}
3333

34-
fn is_empty(&self) -> bool {
34+
pub fn starts_with_fn<Pattern>(&self, f: Pattern) -> bool
35+
where
36+
Pattern: FnMut(char) -> bool,
37+
{
38+
self.rest.starts_with(f)
39+
}
40+
41+
pub fn is_empty(&self) -> bool {
3542
self.rest.is_empty()
3643
}
3744

tests/test.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,26 @@ fn literal_parse() {
264264
assert!("-\"\"".parse::<Literal>().is_err());
265265
}
266266

267+
#[test]
268+
fn literal_span() {
269+
let positive = "0.1".parse::<Literal>().unwrap();
270+
let negative = "-0.1".parse::<Literal>().unwrap();
271+
272+
#[cfg(not(span_locations))]
273+
{
274+
let _ = positive;
275+
let _ = negative;
276+
}
277+
278+
#[cfg(span_locations)]
279+
{
280+
assert_eq!(positive.span().start().column, 0);
281+
assert_eq!(positive.span().end().column, 3);
282+
assert_eq!(negative.span().start().column, 0);
283+
assert_eq!(negative.span().end().column, 4);
284+
}
285+
}
286+
267287
#[test]
268288
fn roundtrip() {
269289
fn roundtrip(p: &str) {

0 commit comments

Comments
 (0)