Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 4c0ba1e

Browse files
committedFeb 18, 2024·
Auto merge of rust-lang#119673 - petrochenkov:dialoc5, r=compiler-errors,cjgillot
macro_rules: Preserve all metavariable spans in a global side table This PR preserves spans of `tt` metavariables used to pass tokens to declarative macros. Such metavariable spans can then be used in span combination operations like `Span::to` to improve all kinds of diagnostics. Spans of non-`tt` metavariables are currently kept in nonterminal tokens, but the long term plan is remove all nonterminal tokens from rustc parser and rely on the proc macro model with invisible delimiters (rust-lang#114647, rust-lang#67062). In particular, `NtIdent` nonterminal (corresponding to `ident` metavariables) becomes easy to remove when this PR lands (rust-lang#119412 does it). The metavariable spans are kept in a global side table keyed by `Span`s of original tokens. The alternative to the side table is keeping them in `SpanData` instead, but the performance regressions would be large because any spans from tokens passed to declarative macros would stop being inline and would work through span interner instead, and the penalty would be paid even if we never use the metavar span for the given original span. (But also see the comment on `fn maybe_use_metavar_location` describing the map collision issues with the side table approach.) There are also other alternatives - keeping the metavar span in `Token` or `TokenTree`, but associating it with `Span` itsel is the most natural choice because metavar spans are used in span combining operations, and those operations are not necessarily tied to tokens.
2 parents 8b21296 + 9f8d05f commit 4c0ba1e

29 files changed

+232
-125
lines changed
 

‎compiler/rustc_expand/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#![feature(if_let_guard)]
77
#![feature(let_chains)]
88
#![feature(macro_metavar_expr)]
9+
#![feature(map_try_insert)]
910
#![feature(proc_macro_diagnostic)]
1011
#![feature(proc_macro_internals)]
1112
#![feature(proc_macro_span)]

‎compiler/rustc_expand/src/mbe/transcribe.rs

+45-10
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rustc_errors::DiagnosticBuilder;
1313
use rustc_errors::{pluralize, PResult};
1414
use rustc_span::hygiene::{LocalExpnId, Transparency};
1515
use rustc_span::symbol::{sym, Ident, MacroRulesNormalizedIdent};
16-
use rustc_span::{Span, SyntaxContext};
16+
use rustc_span::{with_metavar_spans, Span, SyntaxContext};
1717

1818
use smallvec::{smallvec, SmallVec};
1919
use std::mem;
@@ -254,7 +254,8 @@ pub(super) fn transcribe<'a>(
254254
MatchedTokenTree(tt) => {
255255
// `tt`s are emitted into the output stream directly as "raw tokens",
256256
// without wrapping them into groups.
257-
result.push(maybe_use_metavar_location(cx, &stack, sp, tt));
257+
let tt = maybe_use_metavar_location(cx, &stack, sp, tt, &mut marker);
258+
result.push(tt);
258259
}
259260
MatchedNonterminal(nt) => {
260261
// Other variables are emitted into the output stream as groups with
@@ -319,6 +320,17 @@ pub(super) fn transcribe<'a>(
319320
}
320321
}
321322

323+
/// Store the metavariable span for this original span into a side table.
324+
/// FIXME: Try to put the metavariable span into `SpanData` instead of a side table (#118517).
325+
/// An optimal encoding for inlined spans will need to be selected to minimize regressions.
326+
/// The side table approach is relatively good, but not perfect due to collisions.
327+
/// In particular, collisions happen when token is passed as an argument through several macro
328+
/// calls, like in recursive macros.
329+
/// The old heuristic below is used to improve spans in case of collisions, but diagnostics are
330+
/// still degraded sometimes in those cases.
331+
///
332+
/// The old heuristic:
333+
///
322334
/// Usually metavariables `$var` produce interpolated tokens, which have an additional place for
323335
/// keeping both the original span and the metavariable span. For `tt` metavariables that's not the
324336
/// case however, and there's no place for keeping a second span. So we try to give the single
@@ -338,15 +350,12 @@ pub(super) fn transcribe<'a>(
338350
/// These are typically used for passing larger amounts of code, and tokens in that code usually
339351
/// combine with each other and not with tokens outside of the sequence.
340352
/// - The metavariable span comes from a different crate, then we prefer the more local span.
341-
///
342-
/// FIXME: Find a way to keep both original and metavariable spans for all tokens without
343-
/// regressing compilation time too much. Several experiments for adding such spans were made in
344-
/// the past (PR #95580, #118517, #118671) and all showed some regressions.
345353
fn maybe_use_metavar_location(
346354
cx: &ExtCtxt<'_>,
347355
stack: &[Frame<'_>],
348-
metavar_span: Span,
356+
mut metavar_span: Span,
349357
orig_tt: &TokenTree,
358+
marker: &mut Marker,
350359
) -> TokenTree {
351360
let undelimited_seq = matches!(
352361
stack.last(),
@@ -357,18 +366,44 @@ fn maybe_use_metavar_location(
357366
..
358367
})
359368
);
360-
if undelimited_seq || cx.source_map().is_imported(metavar_span) {
369+
if undelimited_seq {
370+
// Do not record metavar spans for tokens from undelimited sequences, for perf reasons.
371+
return orig_tt.clone();
372+
}
373+
374+
let insert = |mspans: &mut FxHashMap<_, _>, s, ms| match mspans.try_insert(s, ms) {
375+
Ok(_) => true,
376+
Err(err) => *err.entry.get() == ms, // Tried to insert the same span, still success
377+
};
378+
marker.visit_span(&mut metavar_span);
379+
let no_collision = match orig_tt {
380+
TokenTree::Token(token, ..) => {
381+
with_metavar_spans(|mspans| insert(mspans, token.span, metavar_span))
382+
}
383+
TokenTree::Delimited(dspan, ..) => with_metavar_spans(|mspans| {
384+
insert(mspans, dspan.open, metavar_span)
385+
&& insert(mspans, dspan.close, metavar_span)
386+
&& insert(mspans, dspan.entire(), metavar_span)
387+
}),
388+
};
389+
if no_collision || cx.source_map().is_imported(metavar_span) {
361390
return orig_tt.clone();
362391
}
363392

393+
// Setting metavar spans for the heuristic spans gives better opportunities for combining them
394+
// with neighboring spans even despite their different syntactic contexts.
364395
match orig_tt {
365396
TokenTree::Token(Token { kind, span }, spacing) => {
366397
let span = metavar_span.with_ctxt(span.ctxt());
398+
with_metavar_spans(|mspans| insert(mspans, span, metavar_span));
367399
TokenTree::Token(Token { kind: kind.clone(), span }, *spacing)
368400
}
369401
TokenTree::Delimited(dspan, dspacing, delimiter, tts) => {
370-
let open = metavar_span.shrink_to_lo().with_ctxt(dspan.open.ctxt());
371-
let close = metavar_span.shrink_to_hi().with_ctxt(dspan.close.ctxt());
402+
let open = metavar_span.with_ctxt(dspan.open.ctxt());
403+
let close = metavar_span.with_ctxt(dspan.close.ctxt());
404+
with_metavar_spans(|mspans| {
405+
insert(mspans, open, metavar_span) && insert(mspans, close, metavar_span)
406+
});
372407
let dspan = DelimSpan::from_pair(open, close);
373408
TokenTree::Delimited(dspan, *dspacing, *delimiter, tts.clone())
374409
}

‎compiler/rustc_span/src/lib.rs

+59-14
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ pub mod fatal_error;
7272

7373
pub mod profiling;
7474

75+
use rustc_data_structures::fx::FxHashMap;
7576
use rustc_data_structures::stable_hasher::{Hash128, Hash64, HashStable, StableHasher};
7677
use rustc_data_structures::sync::{FreezeLock, FreezeWriteGuard, Lock, Lrc};
7778

@@ -98,6 +99,9 @@ mod tests;
9899
pub struct SessionGlobals {
99100
symbol_interner: symbol::Interner,
100101
span_interner: Lock<span_encoding::SpanInterner>,
102+
/// Maps a macro argument token into use of the corresponding metavariable in the macro body.
103+
/// Collisions are possible and processed in `maybe_use_metavar_location` on best effort basis.
104+
metavar_spans: Lock<FxHashMap<Span, Span>>,
101105
hygiene_data: Lock<hygiene::HygieneData>,
102106

103107
/// A reference to the source map in the `Session`. It's an `Option`
@@ -115,6 +119,7 @@ impl SessionGlobals {
115119
SessionGlobals {
116120
symbol_interner: symbol::Interner::fresh(),
117121
span_interner: Lock::new(span_encoding::SpanInterner::default()),
122+
metavar_spans: Default::default(),
118123
hygiene_data: Lock::new(hygiene::HygieneData::new(edition)),
119124
source_map: Lock::new(None),
120125
}
@@ -168,6 +173,11 @@ pub fn create_default_session_globals_then<R>(f: impl FnOnce() -> R) -> R {
168173
// deserialization.
169174
scoped_tls::scoped_thread_local!(static SESSION_GLOBALS: SessionGlobals);
170175

176+
#[inline]
177+
pub fn with_metavar_spans<R>(f: impl FnOnce(&mut FxHashMap<Span, Span>) -> R) -> R {
178+
with_session_globals(|session_globals| f(&mut session_globals.metavar_spans.lock()))
179+
}
180+
171181
// FIXME: We should use this enum or something like it to get rid of the
172182
// use of magic `/rust/1.x/...` paths across the board.
173183
#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Decodable)]
@@ -824,29 +834,64 @@ impl Span {
824834
)
825835
}
826836

837+
/// Check if you can select metavar spans for the given spans to get matching contexts.
838+
fn try_metavars(a: SpanData, b: SpanData, a_orig: Span, b_orig: Span) -> (SpanData, SpanData) {
839+
let get = |mspans: &FxHashMap<_, _>, s| mspans.get(&s).copied();
840+
match with_metavar_spans(|mspans| (get(mspans, a_orig), get(mspans, b_orig))) {
841+
(None, None) => {}
842+
(Some(meta_a), None) => {
843+
let meta_a = meta_a.data();
844+
if meta_a.ctxt == b.ctxt {
845+
return (meta_a, b);
846+
}
847+
}
848+
(None, Some(meta_b)) => {
849+
let meta_b = meta_b.data();
850+
if a.ctxt == meta_b.ctxt {
851+
return (a, meta_b);
852+
}
853+
}
854+
(Some(meta_a), Some(meta_b)) => {
855+
let meta_b = meta_b.data();
856+
if a.ctxt == meta_b.ctxt {
857+
return (a, meta_b);
858+
}
859+
let meta_a = meta_a.data();
860+
if meta_a.ctxt == b.ctxt {
861+
return (meta_a, b);
862+
} else if meta_a.ctxt == meta_b.ctxt {
863+
return (meta_a, meta_b);
864+
}
865+
}
866+
}
867+
868+
(a, b)
869+
}
870+
827871
/// Prepare two spans to a combine operation like `to` or `between`.
828-
/// FIXME: consider using declarative macro metavariable spans for the given spans if they are
829-
/// better suitable for combining (#119412).
830872
fn prepare_to_combine(
831873
a_orig: Span,
832874
b_orig: Span,
833875
) -> Result<(SpanData, SpanData, Option<LocalDefId>), Span> {
834876
let (a, b) = (a_orig.data(), b_orig.data());
877+
if a.ctxt == b.ctxt {
878+
return Ok((a, b, if a.parent == b.parent { a.parent } else { None }));
879+
}
835880

836-
if a.ctxt != b.ctxt {
837-
// Context mismatches usually happen when procedural macros combine spans copied from
838-
// the macro input with spans produced by the macro (`Span::*_site`).
839-
// In that case we consider the combined span to be produced by the macro and return
840-
// the original macro-produced span as the result.
841-
// Otherwise we just fall back to returning the first span.
842-
// Combining locations typically doesn't make sense in case of context mismatches.
843-
// `is_root` here is a fast path optimization.
844-
let a_is_callsite = a.ctxt.is_root() || a.ctxt == b.span().source_callsite().ctxt();
845-
return Err(if a_is_callsite { b_orig } else { a_orig });
881+
let (a, b) = Span::try_metavars(a, b, a_orig, b_orig);
882+
if a.ctxt == b.ctxt {
883+
return Ok((a, b, if a.parent == b.parent { a.parent } else { None }));
846884
}
847885

848-
let parent = if a.parent == b.parent { a.parent } else { None };
849-
Ok((a, b, parent))
886+
// Context mismatches usually happen when procedural macros combine spans copied from
887+
// the macro input with spans produced by the macro (`Span::*_site`).
888+
// In that case we consider the combined span to be produced by the macro and return
889+
// the original macro-produced span as the result.
890+
// Otherwise we just fall back to returning the first span.
891+
// Combining locations typically doesn't make sense in case of context mismatches.
892+
// `is_root` here is a fast path optimization.
893+
let a_is_callsite = a.ctxt.is_root() || a.ctxt == b.span().source_callsite().ctxt();
894+
Err(if a_is_callsite { b_orig } else { a_orig })
850895
}
851896

852897
/// This span, but in a larger context, may switch to the metavariable span if suitable.

‎tests/coverage/no_spans.cov-map

+8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
Function name: no_spans::affected_function
2+
Raw bytes (9): 0x[01, 01, 00, 01, 01, 1a, 1c, 00, 1d]
3+
Number of files: 1
4+
- file 0 => global file 1
5+
Number of expressions: 0
6+
Number of file 0 mappings: 1
7+
- Code(Counter(0)) at (prev + 26, 28) to (start + 0, 29)
8+
19
Function name: no_spans::affected_function::{closure#0}
210
Raw bytes (9): 0x[01, 01, 00, 01, 01, 1b, 0c, 00, 0e]
311
Number of files: 1

‎tests/coverage/no_spans_if_not.cov-map

+12
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
Function name: no_spans_if_not::affected_function
2+
Raw bytes (21): 0x[01, 01, 01, 01, 00, 03, 01, 16, 1c, 01, 12, 02, 02, 0d, 00, 0f, 00, 02, 0d, 00, 0f]
3+
Number of files: 1
4+
- file 0 => global file 1
5+
Number of expressions: 1
6+
- expression 0 operands: lhs = Counter(0), rhs = Zero
7+
Number of file 0 mappings: 3
8+
- Code(Counter(0)) at (prev + 22, 28) to (start + 1, 18)
9+
- Code(Expression(0, Sub)) at (prev + 2, 13) to (start + 0, 15)
10+
= (c0 - Zero)
11+
- Code(Zero) at (prev + 2, 13) to (start + 0, 15)
12+
113
Function name: no_spans_if_not::main
214
Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 01, 02, 02]
315
Number of files: 1

‎tests/ui/anon-params/anon-params-edition-hygiene.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//@ check-pass
12
//@ edition:2018
23
//@ aux-build:anon-params-edition-hygiene.rs
34

@@ -8,7 +9,6 @@
89
extern crate anon_params_edition_hygiene;
910

1011
generate_trait_2015_ident!(u8);
11-
// FIXME: Edition hygiene doesn't work correctly with `tt`s in this case.
12-
generate_trait_2015_tt!(u8); //~ ERROR expected one of `:`, `@`, or `|`, found `)`
12+
generate_trait_2015_tt!(u8);
1313

1414
fn main() {}

‎tests/ui/anon-params/anon-params-edition-hygiene.stderr

-23
This file was deleted.

‎tests/ui/editions/edition-keywords-2018-2018-parsing.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ macro_rules! local_passes_ident {
1616
($i: ident) => ($i) //~ ERROR macro expansion ends with an incomplete expression
1717
}
1818
macro_rules! local_passes_tt {
19-
($i: tt) => ($i) //~ ERROR macro expansion ends with an incomplete expression
19+
($i: tt) => ($i)
2020
}
2121

2222
pub fn check_async() {
@@ -34,7 +34,7 @@ pub fn check_async() {
3434
if passes_tt!(r#async) == 1 {} // OK
3535
if local_passes_ident!(async) == 1 {} // Error reported above in the macro
3636
if local_passes_ident!(r#async) == 1 {} // OK
37-
if local_passes_tt!(async) == 1 {} // Error reported above in the macro
37+
if local_passes_tt!(async) == 1 {} //~ ERROR macro expansion ends with an incomplete expression
3838
if local_passes_tt!(r#async) == 1 {} // OK
3939
module::async(); //~ ERROR expected identifier, found keyword `async`
4040
module::r#async(); // OK

‎tests/ui/editions/edition-keywords-2018-2018-parsing.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,10 @@ LL | ($i: ident) => ($i)
6868
| ^ expected one of `move`, `|`, or `||`
6969

7070
error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||`
71-
--> $DIR/edition-keywords-2018-2018-parsing.rs:19:20
71+
--> $DIR/edition-keywords-2018-2018-parsing.rs:37:30
7272
|
73-
LL | ($i: tt) => ($i)
74-
| ^ expected one of `move`, `|`, or `||`
73+
LL | if local_passes_tt!(async) == 1 {}
74+
| ^ expected one of `move`, `|`, or `||`
7575

7676
error[E0308]: mismatched types
7777
--> $DIR/edition-keywords-2018-2018-parsing.rs:42:33

‎tests/ui/fmt/format-args-capture-first-literal-is-macro.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ extern crate format_string_proc_macro;
66
macro_rules! identity_mbe {
77
($tt:tt) => {
88
$tt
9-
//~^ ERROR there is no argument named `a`
109
};
1110
}
1211

@@ -16,6 +15,7 @@ fn main() {
1615
format!(identity_pm!("{a}"));
1716
//~^ ERROR there is no argument named `a`
1817
format!(identity_mbe!("{a}"));
18+
//~^ ERROR there is no argument named `a`
1919
format!(concat!("{a}"));
2020
//~^ ERROR there is no argument named `a`
2121
}

‎tests/ui/fmt/format-args-capture-first-literal-is-macro.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: there is no argument named `a`
2-
--> $DIR/format-args-capture-first-literal-is-macro.rs:16:26
2+
--> $DIR/format-args-capture-first-literal-is-macro.rs:15:26
33
|
44
LL | format!(identity_pm!("{a}"));
55
| ^^^^^
@@ -8,10 +8,10 @@ LL | format!(identity_pm!("{a}"));
88
= note: to avoid ambiguity, `format_args!` cannot capture variables when the format string is expanded from a macro
99

1010
error: there is no argument named `a`
11-
--> $DIR/format-args-capture-first-literal-is-macro.rs:8:9
11+
--> $DIR/format-args-capture-first-literal-is-macro.rs:17:27
1212
|
13-
LL | $tt
14-
| ^^^
13+
LL | format!(identity_mbe!("{a}"));
14+
| ^^^^^
1515
|
1616
= note: did you intend to capture a variable `a` from the surrounding scope?
1717
= note: to avoid ambiguity, `format_args!` cannot capture variables when the format string is expanded from a macro

‎tests/ui/lint/wide_pointer_comparisons.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,12 @@ fn main() {
110110
{
111111
macro_rules! cmp {
112112
($a:tt, $b:tt) => { $a == $b }
113-
//~^ WARN ambiguous wide pointer comparison
114113
}
115114

115+
// FIXME: This lint uses some custom span combination logic.
116+
// Rewrite it to adapt to the new metavariable span rules.
116117
cmp!(a, b);
118+
//~^ WARN ambiguous wide pointer comparison
117119
}
118120

119121
{

‎tests/ui/lint/wide_pointer_comparisons.stderr

+7-7
Original file line numberDiff line numberDiff line change
@@ -421,18 +421,18 @@ LL | std::ptr::eq(*a, *b)
421421
| ~~~~~~~~~~~~~ ~ +
422422

423423
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
424-
--> $DIR/wide_pointer_comparisons.rs:112:33
424+
--> $DIR/wide_pointer_comparisons.rs:117:14
425425
|
426-
LL | ($a:tt, $b:tt) => { $a == $b }
427-
| ^^^^^^^^
426+
LL | cmp!(a, b);
427+
| ^^^^
428428
|
429429
help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
430430
|
431-
LL | ($a:tt, $b:tt) => { std::ptr::addr_eq($a, $b) }
432-
| ++++++++++++++++++ ~ +
431+
LL | cmp!(std::ptr::addr_eq(a, b));
432+
| ++++++++++++++++++ ~ +
433433

434434
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
435-
--> $DIR/wide_pointer_comparisons.rs:121:39
435+
--> $DIR/wide_pointer_comparisons.rs:123:39
436436
|
437437
LL | ($a:ident, $b:ident) => { $a == $b }
438438
| ^^^^^^^^
@@ -447,7 +447,7 @@ LL | ($a:ident, $b:ident) => { std::ptr::addr_eq($a, $b) }
447447
| ++++++++++++++++++ ~ +
448448

449449
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
450-
--> $DIR/wide_pointer_comparisons.rs:131:37
450+
--> $DIR/wide_pointer_comparisons.rs:133:37
451451
|
452452
LL | ($a:expr, $b:expr) => { $a == $b }
453453
| ^^

‎tests/ui/macros/issue-118786.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
macro_rules! make_macro {
66
($macro_name:tt) => {
77
macro_rules! $macro_name {
8-
//~^ ERROR macros that expand to items must be delimited with braces or followed by a semicolon
9-
//~| ERROR macro expansion ignores token `{` and any following
8+
//~^ ERROR macro expansion ignores token `{` and any following
109
//~| ERROR cannot find macro `macro_rules` in this scope
1110
() => {}
1211
}
1312
}
1413
}
1514

1615
make_macro!((meow));
16+
//~^ ERROR macros that expand to items must be delimited with braces or followed by a semicolon

‎tests/ui/macros/issue-118786.stderr

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error: macros that expand to items must be delimited with braces or followed by a semicolon
2-
--> $DIR/issue-118786.rs:7:22
2+
--> $DIR/issue-118786.rs:15:13
33
|
4-
LL | macro_rules! $macro_name {
5-
| ^^^^^^^^^^^
4+
LL | make_macro!((meow));
5+
| ^^^^^^
66
|
77
help: change the delimiters to curly braces
88
|
9-
LL | macro_rules! {$macro_name} {
10-
| + +
9+
LL | make_macro!({meow});
10+
| ~ ~
1111
help: add a semicolon
1212
|
1313
LL | macro_rules! $macro_name; {

‎tests/ui/methods/method-on-ambiguous-numeric-type.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ LL | local_bar_tt.pow(2);
4747
|
4848
help: you must specify a type for this binding, like `i32`
4949
|
50-
LL | ($tt:tt) => { let $tt: i32 = 42; }
51-
| +++++
50+
LL | local_mac_tt!(local_bar_tt: i32);
51+
| +++++
5252

5353
error[E0689]: can't call method `pow` on ambiguous numeric type `{integer}`
5454
--> $DIR/method-on-ambiguous-numeric-type.rs:37:9

‎tests/ui/parser/issues/issue-44406.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ LL | bar { baz: $rest }
1515
help: if `bar` is a function, use the arguments directly
1616
|
1717
LL - bar(baz: $rest)
18-
LL + bar(: $rest)
18+
LL + bar($rest)
1919
|
2020

2121
error: aborting due to 1 previous error

‎tests/ui/parser/issues/issue-68091-unicode-ident-after-if.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ LL | $($c)ö* {}
55
| ^ - if this block is the condition of the `if` expression, then it must be followed by another block
66
| |
77
| expected condition here
8+
...
9+
LL | x!(if);
10+
| ------ in this macro invocation
11+
|
12+
= note: this error originates in the macro `x` (in Nightly builds, run with -Z macro-backtrace for more info)
813

914
error: aborting due to 1 previous error
1015

Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
macro_rules! x {
22
($($c:tt)*) => {
3-
$($c)ö* //~ ERROR macro expansion ends with an incomplete expression: expected expression
3+
$($c)ö*
44
};
55
}
66

77
fn main() {
8-
x!(!);
8+
x!(!); //~ ERROR macro expansion ends with an incomplete expression: expected expression
99
}
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error: macro expansion ends with an incomplete expression: expected expression
2-
--> $DIR/issue-68092-unicode-ident-after-incomplete-expr.rs:3:13
2+
--> $DIR/issue-68092-unicode-ident-after-incomplete-expr.rs:8:9
33
|
4-
LL | $($c)ö*
5-
| ^ expected expression
4+
LL | x!(!);
5+
| ^ expected expression
66

77
error: aborting due to 1 previous error
88

‎tests/ui/proc-macro/capture-macro-rules-invoke.stdout

+1-1
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ PRINT-BANG INPUT (DEBUG): TokenStream [
271271
span: $DIR/capture-macro-rules-invoke.rs:47:19: 47:20 (#0),
272272
},
273273
],
274-
span: $DIR/capture-macro-rules-invoke.rs:15:60: 15:63 (#0),
274+
span: $DIR/capture-macro-rules-invoke.rs:47:13: 47:22 (#0),
275275
},
276276
Punct {
277277
ch: ',',

‎tests/ui/rust-2018/edition-lint-infer-outlives-macro.fixed

+10-6
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,13 @@ mod everything_outside_with_tt_inner {
111111
mod everything_outside_with_tt_outer {
112112
macro_rules! m {
113113
($b:lifetime $colon:tt $a:tt) => {
114-
struct Foo<$a, $b >(&$a &$b ());
114+
// FIXME: replacement span is corrupted due to a collision in metavar span table.
115+
// struct Foo<$a, $b $colon $a>(&$a &$b ());
116+
// ^ ERROR: outlives requirements can be inferred
117+
struct Bar<$a, $b>(&$a &$b ()) ;
118+
//~^ ERROR: outlives requirements can be inferred
119+
struct Baz<$a, $b>(&$a &$b ()) where (): Sized, ;
115120
//~^ ERROR: outlives requirements can be inferred
116-
struct Bar<$a, $b>(&$a &$b ()) where $b $colon $a;
117-
struct Baz<$a, $b>(&$a &$b ()) where (): Sized, $b $colon $a;
118121
}
119122
}
120123
m!('b: 'a);
@@ -123,9 +126,10 @@ mod everything_outside_with_tt_outer {
123126
mod everything_outside_with_tt_both {
124127
macro_rules! m {
125128
($b:tt $colon:tt $a:tt) => {
126-
struct Foo<$a, $b >(&$a &$b ());
127-
//~^ ERROR: outlives requirements can be inferred
128-
struct Bar<$a, $b>(&$a &$b ()) where ;
129+
// FIXME: replacement span is corrupted due to a collision in metavar span table.
130+
// struct Foo<$a, $b $colon $a>(&$a &$b ());
131+
// ^ ERROR: outlives requirements can be inferred
132+
struct Bar<$a, $b>(&$a &$b ()) ;
129133
//~^ ERROR: outlives requirements can be inferred
130134
struct Baz<$a, $b>(&$a &$b ()) where (): Sized, ;
131135
//~^ ERROR: outlives requirements can be inferred

‎tests/ui/rust-2018/edition-lint-infer-outlives-macro.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,13 @@ mod everything_outside_with_tt_inner {
111111
mod everything_outside_with_tt_outer {
112112
macro_rules! m {
113113
($b:lifetime $colon:tt $a:tt) => {
114-
struct Foo<$a, $b $colon $a>(&$a &$b ());
115-
//~^ ERROR: outlives requirements can be inferred
114+
// FIXME: replacement span is corrupted due to a collision in metavar span table.
115+
// struct Foo<$a, $b $colon $a>(&$a &$b ());
116+
// ^ ERROR: outlives requirements can be inferred
116117
struct Bar<$a, $b>(&$a &$b ()) where $b $colon $a;
118+
//~^ ERROR: outlives requirements can be inferred
117119
struct Baz<$a, $b>(&$a &$b ()) where (): Sized, $b $colon $a;
120+
//~^ ERROR: outlives requirements can be inferred
118121
}
119122
}
120123
m!('b: 'a);
@@ -123,8 +126,9 @@ mod everything_outside_with_tt_outer {
123126
mod everything_outside_with_tt_both {
124127
macro_rules! m {
125128
($b:tt $colon:tt $a:tt) => {
126-
struct Foo<$a, $b $colon $a>(&$a &$b ());
127-
//~^ ERROR: outlives requirements can be inferred
129+
// FIXME: replacement span is corrupted due to a collision in metavar span table.
130+
// struct Foo<$a, $b $colon $a>(&$a &$b ());
131+
// ^ ERROR: outlives requirements can be inferred
128132
struct Bar<$a, $b>(&$a &$b ()) where $b $colon $a;
129133
//~^ ERROR: outlives requirements can be inferred
130134
struct Baz<$a, $b>(&$a &$b ()) where (): Sized, $b $colon $a;

‎tests/ui/rust-2018/edition-lint-infer-outlives-macro.stderr

+24-9
Original file line numberDiff line numberDiff line change
@@ -83,25 +83,40 @@ LL | m!('b: 'a);
8383
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
8484

8585
error: outlives requirements can be inferred
86-
--> $DIR/edition-lint-infer-outlives-macro.rs:114:31
86+
--> $DIR/edition-lint-infer-outlives-macro.rs:117:44
8787
|
88-
LL | struct Foo<$a, $b $colon $a>(&$a &$b ());
89-
| ^^^^^^^^^ help: remove this bound
88+
LL | struct Bar<$a, $b>(&$a &$b ()) where $b $colon $a;
89+
| ^^^^^^^^^^^^^^^^^^ help: remove this bound
90+
...
91+
LL | m!('b: 'a);
92+
| ---------- in this macro invocation
93+
|
94+
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
9095

9196
error: outlives requirements can be inferred
92-
--> $DIR/edition-lint-infer-outlives-macro.rs:126:31
97+
--> $DIR/edition-lint-infer-outlives-macro.rs:119:61
98+
|
99+
LL | struct Baz<$a, $b>(&$a &$b ()) where (): Sized, $b $colon $a;
100+
| ^^^^^^^^^^^^ help: remove this bound
101+
...
102+
LL | m!('b: 'a);
103+
| ---------- in this macro invocation
93104
|
94-
LL | struct Foo<$a, $b $colon $a>(&$a &$b ());
95-
| ^^^^^^^^^ help: remove this bound
105+
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
96106

97107
error: outlives requirements can be inferred
98-
--> $DIR/edition-lint-infer-outlives-macro.rs:128:50
108+
--> $DIR/edition-lint-infer-outlives-macro.rs:132:44
99109
|
100110
LL | struct Bar<$a, $b>(&$a &$b ()) where $b $colon $a;
101-
| ^^^^^^^^^^^^ help: remove this bound
111+
| ^^^^^^^^^^^^^^^^^^ help: remove this bound
112+
...
113+
LL | m!('b: 'a);
114+
| ---------- in this macro invocation
115+
|
116+
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
102117

103118
error: outlives requirements can be inferred
104-
--> $DIR/edition-lint-infer-outlives-macro.rs:130:61
119+
--> $DIR/edition-lint-infer-outlives-macro.rs:134:61
105120
|
106121
LL | struct Baz<$a, $b>(&$a &$b ()) where (): Sized, $b $colon $a;
107122
| ^^^^^^^^^^^^ help: remove this bound

‎tests/ui/span/macro-span-replacement.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44

55
macro_rules! m {
66
($a:tt $b:tt) => {
7-
$b $a; //~ WARN struct `S` is never constructed
7+
$b $a;
88
}
99
}
1010

1111
fn main() {
12-
m!(S struct);
12+
m!(S struct); //~ WARN struct `S` is never constructed
1313
}

‎tests/ui/span/macro-span-replacement.stderr

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
warning: struct `S` is never constructed
2-
--> $DIR/macro-span-replacement.rs:7:12
2+
--> $DIR/macro-span-replacement.rs:12:8
33
|
4-
LL | $b $a;
5-
| ^^
6-
...
74
LL | m!(S struct);
8-
| ------------ in this macro invocation
5+
| ^
96
|
107
note: the lint level is defined here
118
--> $DIR/macro-span-replacement.rs:3:9

‎tests/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error: function can not have more than 65535 arguments
2-
--> $DIR/issue-88577-check-fn-with-more-than-65535-arguments.rs:6:22
2+
--> $DIR/issue-88577-check-fn-with-more-than-65535-arguments.rs:6:17
33
|
44
LL | fn _f($($t: ()),*) {}
5-
| ^
5+
| ^^^^^^
66
...
77
LL | many_args!{[_]########## ######}
88
| -------------------------------- in this macro invocation

‎tests/ui/typeck/issue-116473-ice-wrong-span-variant-args.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,12 @@ macro_rules! nested2_ident {
5858
// instead of the enum variant
5959
macro_rules! nested1_tt_args_in_first_macro {
6060
() => (nested2_tt_args_in_first_macro!(i32, u32));
61+
//~^ ERROR type arguments are not allowed on this type
6162
}
6263

6364
macro_rules! nested2_tt_args_in_first_macro {
6465
($arg1:tt, $arg2:tt) => (if let EnumUnit::VariantB::<$arg1, $arg2> {}
65-
//~^ ERROR type arguments are not allowed on this type
66-
//~| ERROR mismatched types
66+
//~^ ERROR mismatched types
6767
= 5 { true } else { false });
6868
}
6969

‎tests/ui/typeck/issue-116473-ice-wrong-span-variant-args.stderr

+14-12
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
error[E0109]: type arguments are not allowed on this type
22
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:15:51
33
|
4+
LL | () => (recursive_tt!(VariantB));
5+
| -------- not allowed on this type
46
LL | ($variant:tt) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false });
5-
| -------- ^^^ ^^^ type argument not allowed
6-
| |
7-
| not allowed on this type
7+
| ^^^ ^^^ type argument not allowed
88
...
99
LL | recursive_tt!();
1010
| --------------- in this macro invocation
@@ -69,10 +69,11 @@ LL | recursive_ident!();
6969
error[E0109]: type arguments are not allowed on this type
7070
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:38:51
7171
|
72+
LL | () => (nested2_tt!(VariantB));
73+
| -------- not allowed on this type
74+
...
7275
LL | ($variant:tt) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false });
73-
| -------- ^^^ ^^^ type argument not allowed
74-
| |
75-
| not allowed on this type
76+
| ^^^ ^^^ type argument not allowed
7677
...
7778
LL | nested1_tt!();
7879
| ------------- in this macro invocation
@@ -136,12 +137,13 @@ LL | nested1_ident!();
136137
= note: this error originates in the macro `nested2_ident` which comes from the expansion of the macro `nested1_ident` (in Nightly builds, run with -Z macro-backtrace for more info)
137138

138139
error[E0109]: type arguments are not allowed on this type
139-
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:64:58
140+
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:60:44
140141
|
142+
LL | () => (nested2_tt_args_in_first_macro!(i32, u32));
143+
| ^^^ ^^^ type argument not allowed
144+
...
141145
LL | ($arg1:tt, $arg2:tt) => (if let EnumUnit::VariantB::<$arg1, $arg2> {}
142-
| -------- ^^^^^ ^^^^^ type argument not allowed
143-
| |
144-
| not allowed on this type
146+
| -------- not allowed on this type
145147
...
146148
LL | nested1_tt_args_in_first_macro!();
147149
| --------------------------------- in this macro invocation
@@ -155,11 +157,11 @@ LL + ($arg1:tt, $arg2:tt) => (if let EnumUnit::<$arg1, $arg2>::VariantB {}
155157
|
156158

157159
error[E0308]: mismatched types
158-
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:64:37
160+
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:65:37
159161
|
160162
LL | ($arg1:tt, $arg2:tt) => (if let EnumUnit::VariantB::<$arg1, $arg2> {}
161163
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected integer, found `Enum<(), ()>`
162-
...
164+
LL |
163165
LL | = 5 { true } else { false });
164166
| - this expression has type `{integer}`
165167
...

0 commit comments

Comments
 (0)
Please sign in to comment.