Skip to content

Commit 301f8ab

Browse files
authored
Merge pull request #283 from dtolnay/lexspan
Add span to lex errors
2 parents 068bd59 + b120971 commit 301f8ab

File tree

4 files changed

+67
-10
lines changed

4 files changed

+67
-10
lines changed

src/fallback.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,15 @@ pub(crate) struct TokenStream {
3535
}
3636

3737
#[derive(Debug)]
38-
pub(crate) struct LexError;
38+
pub(crate) struct LexError {
39+
pub(crate) span: Span,
40+
}
41+
42+
impl LexError {
43+
pub(crate) fn span(&self) -> Span {
44+
self.span
45+
}
46+
}
3947

4048
impl TokenStream {
4149
pub fn new() -> TokenStream {

src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,12 @@ impl Debug for TokenStream {
250250
}
251251
}
252252

253+
impl LexError {
254+
pub fn span(&self) -> Span {
255+
Span::_new(self.inner.span())
256+
}
257+
}
258+
253259
impl Debug for LexError {
254260
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
255261
Debug::fmt(&self.inner, f)

src/parse.rs

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,17 @@ pub(crate) fn token_stream(mut input: Cursor) -> Result<TokenStream, LexError> {
167167

168168
let first = match input.bytes().next() {
169169
Some(first) => first,
170-
None if stack.is_empty() => return Ok(TokenStream { inner: trees }),
171-
None => return Err(LexError),
170+
None => match stack.last() {
171+
None => return Ok(TokenStream { inner: trees }),
172+
#[cfg(span_locations)]
173+
Some((lo, _frame)) => {
174+
return Err(LexError {
175+
span: Span { lo: *lo, hi: *lo },
176+
})
177+
}
178+
#[cfg(not(span_locations))]
179+
Some(_frame) => return Err(LexError { span: Span {} }),
180+
},
172181
};
173182

174183
if let Some(open_delimiter) = match first {
@@ -189,14 +198,17 @@ pub(crate) fn token_stream(mut input: Cursor) -> Result<TokenStream, LexError> {
189198
b'}' => Some(Delimiter::Brace),
190199
_ => None,
191200
} {
192-
input = input.advance(1);
193-
let frame = stack.pop().ok_or(LexError)?;
201+
let frame = match stack.pop() {
202+
Some(frame) => frame,
203+
None => return Err(lex_error(input)),
204+
};
194205
#[cfg(span_locations)]
195206
let (lo, frame) = frame;
196207
let (open_delimiter, outer) = frame;
197208
if open_delimiter != close_delimiter {
198-
return Err(LexError);
209+
return Err(lex_error(input));
199210
}
211+
input = input.advance(1);
200212
let mut g = Group::new(open_delimiter, TokenStream { inner: trees });
201213
g.set_span(Span {
202214
#[cfg(span_locations)]
@@ -209,7 +221,7 @@ pub(crate) fn token_stream(mut input: Cursor) -> Result<TokenStream, LexError> {
209221
} else {
210222
let (rest, mut tt) = match leaf_token(input) {
211223
Ok((rest, tt)) => (rest, tt),
212-
Err(Reject) => return Err(LexError),
224+
Err(Reject) => return Err(lex_error(input)),
213225
};
214226
tt.set_span(crate::Span::_new_stable(Span {
215227
#[cfg(span_locations)]
@@ -223,6 +235,19 @@ pub(crate) fn token_stream(mut input: Cursor) -> Result<TokenStream, LexError> {
223235
}
224236
}
225237

238+
fn lex_error(cursor: Cursor) -> LexError {
239+
#[cfg(not(span_locations))]
240+
let _ = cursor;
241+
LexError {
242+
span: Span {
243+
#[cfg(span_locations)]
244+
lo: cursor.off,
245+
#[cfg(span_locations)]
246+
hi: cursor.off,
247+
},
248+
}
249+
}
250+
226251
fn leaf_token(input: Cursor) -> PResult<TokenTree> {
227252
if let Ok((input, l)) = literal(input) {
228253
// must be parsed before ident

src/wrapper.rs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,12 @@ impl FromStr for TokenStream {
107107

108108
// Work around https://github.com/rust-lang/rust/issues/58736.
109109
fn proc_macro_parse(src: &str) -> Result<proc_macro::TokenStream, LexError> {
110-
panic::catch_unwind(|| src.parse().map_err(LexError::Compiler))
111-
.unwrap_or(Err(LexError::Fallback(fallback::LexError)))
110+
let result = panic::catch_unwind(|| src.parse().map_err(LexError::Compiler));
111+
result.unwrap_or_else(|_| {
112+
Err(LexError::Fallback(fallback::LexError {
113+
span: fallback::Span::call_site(),
114+
}))
115+
})
112116
}
113117

114118
impl Display for TokenStream {
@@ -243,6 +247,15 @@ impl Debug for TokenStream {
243247
}
244248
}
245249

250+
impl LexError {
251+
pub(crate) fn span(&self) -> Span {
252+
match self {
253+
LexError::Compiler(_) => Span::call_site(),
254+
LexError::Fallback(e) => Span::Fallback(e.span()),
255+
}
256+
}
257+
}
258+
246259
impl From<proc_macro::LexError> for LexError {
247260
fn from(e: proc_macro::LexError) -> LexError {
248261
LexError::Compiler(e)
@@ -270,7 +283,12 @@ impl Display for LexError {
270283
#[cfg(lexerror_display)]
271284
LexError::Compiler(e) => Display::fmt(e, f),
272285
#[cfg(not(lexerror_display))]
273-
LexError::Compiler(_e) => Display::fmt(&fallback::LexError, f),
286+
LexError::Compiler(_e) => Display::fmt(
287+
&fallback::LexError {
288+
span: fallback::Span::call_site(),
289+
},
290+
f,
291+
),
274292
LexError::Fallback(e) => Display::fmt(e, f),
275293
}
276294
}

0 commit comments

Comments
 (0)