about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Markeffsky <@>2023-01-15 17:49:34 +0100
committerLukas Markeffsky <@>2023-01-20 20:16:37 +0100
commit31443c63b520cc97a551fb7168d77abbe160b2ef (patch)
treebef2e699e835f563d95c6d17b91cc0a5bac2812d
parentb9e8286c85aa83fd7ff36603d394082024887dc9 (diff)
preserve delim spans during `macro_rules!` expansion if able
-rw-r--r--compiler/rustc_expand/src/mbe/macro_rules.rs24
-rw-r--r--tests/ui/const-generics/min_const_generics/macro-fail.stderr23
-rw-r--r--tests/ui/imports/import-prefix-macro-1.stderr2
-rw-r--r--tests/ui/parser/issues/issue-44406.stderr4
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 4ebd75f0185..cd431f57019 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::<Vec<_>>();
             // 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 9f73b91aabe..cc629fd920f 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<gimme_a_const!(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::<gimme_a_const!(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)
 
 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::<external_macro!()>;
-   |                           -----------------
-   |                           |
-   |                           this macro call doesn't expand to a type
-   |                           in this macro invocation
+LL |   let _fail = Example::<external_macro!()>;
+   |                         -----------------
+   |                         |
+   |                         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 8868ee3aeaa..a6a5b1393da 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 1f0c1ea4c2f..de02ea85b27 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)