rustc_expand::mbe::transcribe

Function maybe_use_metavar_location

Source
fn maybe_use_metavar_location(
    psess: &ParseSess,
    stack: &[Frame<'_>],
    metavar_span: Span,
    orig_tt: &TokenTree,
    marker: &mut Marker,
) -> TokenTree
Expand description

Store the metavariable span for this original span into a side table. FIXME: Try to put the metavariable span into SpanData instead of a side table (#118517). An optimal encoding for inlined spans will need to be selected to minimize regressions. The side table approach is relatively good, but not perfect due to collisions. In particular, collisions happen when token is passed as an argument through several macro calls, like in recursive macros. The old heuristic below is used to improve spans in case of collisions, but diagnostics are still degraded sometimes in those cases.

The old heuristic:

Usually metavariables $var produce interpolated tokens, which have an additional place for keeping both the original span and the metavariable span. For tt metavariables that’s not the case however, and there’s no place for keeping a second span. So we try to give the single produced span a location that would be most useful in practice (the hygiene part of the span must not be changed).

Different locations are useful for different purposes:

  • The original location is useful when we need to report a diagnostic for the original token in isolation, without combining it with any surrounding tokens. This case occurs, but it is not very common in practice.
  • The metavariable location is useful when we need to somehow combine the token span with spans of its surrounding tokens. This is the most common way to use token spans.

So this function replaces the original location with the metavariable location in all cases except these two:

  • The metavariable is an element of undelimited sequence $($tt)*. These are typically used for passing larger amounts of code, and tokens in that code usually combine with each other and not with tokens outside of the sequence.
  • The metavariable span comes from a different crate, then we prefer the more local span.