From 31443c63b520cc97a551fb7168d77abbe160b2ef Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Sun, 15 Jan 2023 17:49:34 +0100 Subject: [PATCH] preserve delim spans during `macro_rules!` expansion if able --- compiler/rustc_expand/src/mbe/macro_rules.rs | 24 ++++++++++++++----- .../min_const_generics/macro-fail.stderr | 23 +++++++----------- tests/ui/imports/import-prefix-macro-1.stderr | 2 +- tests/ui/parser/issues/issue-44406.stderr | 4 ++-- 4 files changed, 30 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 4ebd75f01856..cd431f570195 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -10,7 +10,7 @@ use crate::mbe::transcribe::transcribe; use rustc_ast as ast; use rustc_ast::token::{self, Delimiter, NonterminalKind, Token, TokenKind, TokenKind::*}; -use rustc_ast::tokenstream::{DelimSpan, TokenStream}; +use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree}; use rustc_ast::{NodeId, DUMMY_NODE_ID}; use rustc_ast_pretty::pprust; use rustc_attr::{self as attr, TransparencyError}; @@ -212,7 +212,6 @@ fn expand_macro<'cx>( }; let arm_span = rhses[i].span(); - let rhs_spans = rhs.tts.iter().map(|t| t.span()).collect::>(); // rhs has holes ( `$id` and `$(...)` that need filled) let mut tts = match transcribe(cx, &named_matches, &rhs, rhs_span, transparency) { Ok(tts) => tts, @@ -224,12 +223,25 @@ fn expand_macro<'cx>( // Replace all the tokens for the corresponding positions in the macro, to maintain // proper positions in error reporting, while maintaining the macro_backtrace. - if rhs_spans.len() == tts.len() { + if tts.len() == rhs.tts.len() { tts = tts.map_enumerated(|i, tt| { let mut tt = tt.clone(); - let mut sp = rhs_spans[i]; - sp = sp.with_ctxt(tt.span().ctxt()); - tt.set_span(sp); + let rhs_tt = &rhs.tts[i]; + let ctxt = tt.span().ctxt(); + match (&mut tt, rhs_tt) { + // preserve the delim spans if able + ( + TokenTree::Delimited(target_sp, ..), + mbe::TokenTree::Delimited(source_sp, ..), + ) => { + target_sp.open = source_sp.open.with_ctxt(ctxt); + target_sp.close = source_sp.close.with_ctxt(ctxt); + } + _ => { + let sp = rhs_tt.span().with_ctxt(ctxt); + tt.set_span(sp); + } + } tt }); } diff --git a/tests/ui/const-generics/min_const_generics/macro-fail.stderr b/tests/ui/const-generics/min_const_generics/macro-fail.stderr index 9f73b91aabeb..cc629fd920fa 100644 --- a/tests/ui/const-generics/min_const_generics/macro-fail.stderr +++ b/tests/ui/const-generics/min_const_generics/macro-fail.stderr @@ -8,7 +8,7 @@ LL | fn make_marker() -> impl Marker { | in this macro invocation ... LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type + | ^ expected type | = note: this error originates in the macro `gimme_a_const` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -22,26 +22,21 @@ LL | Example:: | in this macro invocation ... LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type + | ^ expected type | = note: this error originates in the macro `gimme_a_const` (in Nightly builds, run with -Z macro-backtrace for more info) error: expected type, found `{` --> $DIR/macro-fail.rs:4:10 | -LL | () => {{ - | __________^ -LL | | -LL | | const X: usize = 1337; -LL | | X -LL | | }} - | |___^ expected type +LL | () => {{ + | ^ expected type ... -LL | let _fail = Example::; - | ----------------- - | | - | this macro call doesn't expand to a type - | in this macro invocation +LL | let _fail = Example::; + | ----------------- + | | + | this macro call doesn't expand to a type + | in this macro invocation | = note: this error originates in the macro `external_macro` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/imports/import-prefix-macro-1.stderr b/tests/ui/imports/import-prefix-macro-1.stderr index 8868ee3aeaad..a6a5b1393dae 100644 --- a/tests/ui/imports/import-prefix-macro-1.stderr +++ b/tests/ui/imports/import-prefix-macro-1.stderr @@ -2,7 +2,7 @@ error: expected one of `::`, `;`, or `as`, found `{` --> $DIR/import-prefix-macro-1.rs:11:27 | LL | ($p: path) => (use $p {S, Z}); - | ^^^^^^ expected one of `::`, `;`, or `as` + | ^ expected one of `::`, `;`, or `as` ... LL | import! { a::b::c } | ------------------- in this macro invocation diff --git a/tests/ui/parser/issues/issue-44406.stderr b/tests/ui/parser/issues/issue-44406.stderr index 1f0c1ea4c2f1..de02ea85b27b 100644 --- a/tests/ui/parser/issues/issue-44406.stderr +++ b/tests/ui/parser/issues/issue-44406.stderr @@ -21,8 +21,8 @@ LL | foo!(true); = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) help: if `bar` is a struct, use braces as delimiters | -LL | bar { } - | ~ +LL | bar { baz: $rest } + | ~ ~ help: if `bar` is a function, use the arguments directly | LL - bar(baz: $rest)