Rollup merge of #81608 - Aaron1011:macro-res-parse-err, r=davidtwco
Improve handling of spans around macro result parse errors Fixes #81543 After we expand a macro, we try to parse the resulting tokens as a AST node. This commit makes several improvements to how we handle spans when an error occurs: * Only ovewrite the original `Span` if it's a dummy span. This preserves a more-specific span if one is available. * Use `self.prev_token` instead of `self.token` when emitting an error message after encountering EOF, since an EOF token always has a dummy span * Make `SourceMap::next_point` leave dummy spans unused. A dummy span does not have a logical 'next point', since it's a zero-length span. Re-using the span span preserves its 'dummy-ness' for other checks
This commit is contained in:
commit
255e0764c0
6 changed files with 36 additions and 4 deletions
|
@ -896,7 +896,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
fragment
|
fragment
|
||||||
}
|
}
|
||||||
Err(mut err) => {
|
Err(mut err) => {
|
||||||
err.set_span(span);
|
if err.span.is_dummy() {
|
||||||
|
err.set_span(span);
|
||||||
|
}
|
||||||
annotate_err_with_kind(&mut err, kind, span);
|
annotate_err_with_kind(&mut err, kind, span);
|
||||||
err.emit();
|
err.emit();
|
||||||
self.cx.trace_macros_diag();
|
self.cx.trace_macros_diag();
|
||||||
|
|
|
@ -1104,7 +1104,7 @@ impl<'a> Parser<'a> {
|
||||||
let (prev_sp, sp) = match (&self.token.kind, self.subparser_name) {
|
let (prev_sp, sp) = match (&self.token.kind, self.subparser_name) {
|
||||||
// Point at the end of the macro call when reaching end of macro arguments.
|
// Point at the end of the macro call when reaching end of macro arguments.
|
||||||
(token::Eof, Some(_)) => {
|
(token::Eof, Some(_)) => {
|
||||||
let sp = self.sess.source_map().next_point(self.token.span);
|
let sp = self.sess.source_map().next_point(self.prev_token.span);
|
||||||
(sp, sp)
|
(sp, sp)
|
||||||
}
|
}
|
||||||
// We don't want to point at the following span after DUMMY_SP.
|
// We don't want to point at the following span after DUMMY_SP.
|
||||||
|
@ -1721,7 +1721,7 @@ impl<'a> Parser<'a> {
|
||||||
pub(super) fn expected_expression_found(&self) -> DiagnosticBuilder<'a> {
|
pub(super) fn expected_expression_found(&self) -> DiagnosticBuilder<'a> {
|
||||||
let (span, msg) = match (&self.token.kind, self.subparser_name) {
|
let (span, msg) = match (&self.token.kind, self.subparser_name) {
|
||||||
(&token::Eof, Some(origin)) => {
|
(&token::Eof, Some(origin)) => {
|
||||||
let sp = self.sess.source_map().next_point(self.token.span);
|
let sp = self.sess.source_map().next_point(self.prev_token.span);
|
||||||
(sp, format!("expected expression, found end of {}", origin))
|
(sp, format!("expected expression, found end of {}", origin))
|
||||||
}
|
}
|
||||||
_ => (
|
_ => (
|
||||||
|
|
|
@ -799,6 +799,9 @@ impl SourceMap {
|
||||||
|
|
||||||
/// Returns a new span representing the next character after the end-point of this span.
|
/// Returns a new span representing the next character after the end-point of this span.
|
||||||
pub fn next_point(&self, sp: Span) -> Span {
|
pub fn next_point(&self, sp: Span) -> Span {
|
||||||
|
if sp.is_dummy() {
|
||||||
|
return sp;
|
||||||
|
}
|
||||||
let start_of_next_point = sp.hi().0;
|
let start_of_next_point = sp.hi().0;
|
||||||
|
|
||||||
let width = self.find_width_of_character_at_span(sp.shrink_to_hi(), true);
|
let width = self.find_width_of_character_at_span(sp.shrink_to_hi(), true);
|
||||||
|
|
14
src/test/ui/proc-macro/issue-81543-item-parse-err.rs
Normal file
14
src/test/ui/proc-macro/issue-81543-item-parse-err.rs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// aux-build:test-macros.rs
|
||||||
|
|
||||||
|
// Regression test for issue #81543
|
||||||
|
// Tests that we emit a properly spanned error
|
||||||
|
// when the output of a proc-macro cannot be parsed
|
||||||
|
// as the expected AST node kind
|
||||||
|
|
||||||
|
extern crate test_macros;
|
||||||
|
|
||||||
|
test_macros::identity! {
|
||||||
|
fn 32() {} //~ ERROR expected identifier
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
8
src/test/ui/proc-macro/issue-81543-item-parse-err.stderr
Normal file
8
src/test/ui/proc-macro/issue-81543-item-parse-err.stderr
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
error: expected identifier, found `32`
|
||||||
|
--> $DIR/issue-81543-item-parse-err.rs:11:8
|
||||||
|
|
|
||||||
|
LL | fn 32() {}
|
||||||
|
| ^^ expected identifier
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
|
@ -2,7 +2,12 @@ error: expected type, found `'`
|
||||||
--> $DIR/lifetimes.rs:7:10
|
--> $DIR/lifetimes.rs:7:10
|
||||||
|
|
|
|
||||||
LL | type A = single_quote_alone!();
|
LL | type A = single_quote_alone!();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ this macro call doesn't expand to a type
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| expected type
|
||||||
|
| this macro call doesn't expand to a type
|
||||||
|
|
|
||||||
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue