Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Properly allow macro expanded format_args invocations to uses captures #106505

Merged
merged 2 commits into from
Mar 14, 2023

Commits on Mar 14, 2023

  1. Properly allow macro expanded format_args invocations to uses captures

    Originally, this was kinda half-allowed. There were some primitive
    checks in place that looked at the span to see whether the input was
    likely a literal. These "source literal" checks are needed because the
    spans created during `format_args` parsing only make sense when it is
    indeed a literal that was written in the source code directly.
    
    This is orthogonal to the restriction that the first argument must be a
    "direct literal", not being exanpanded from macros. This restriction was
    imposed by [RFC 2795] on the basis of being too confusing. But this was
    only concerned with the argument of the invocation being a literal, not
    whether it was a source literal (maybe in spirit it meant it being a
    source literal, this is not clear to me).
    
    Since the original check only really cared about source literals (which
    is good enough to deny the `format_args!(concat!())` example), macros
    expanding to `format_args` invocations were able to use implicit
    captures if they spanned the string in a way that lead back to a source
    string.
    
    The "source literal" checks were not strict enough and caused ICEs in
    certain cases (see # 106191 (the space is intended to avoid spammy
    backreferences)). So I tightened it up in # 106195 to really only work
    if it's a direct source literal.
    
    This caused the `indoc` crate to break. `indoc` transformed the source
    literal by removing whitespace, which made it not a "source literal"
    anymore (which is required to fix the ICE). But since `indoc` spanned
    the literal in ways that made the old check think that it's a literal,
    it was able to use implicit captures (which is useful and nice for the
    users of `indoc`).
    
    This commit properly seperates the previously introduced concepts of
    "source literal" and "direct literal" and therefore allows `indoc`
    invocations, which don't create "source literals" to use implicit
    captures again.
    
    [RFC 2795]: https://rust-lang.github.io/rfcs/2795-format-args-implicit-identifiers.html#macro-hygiene
    Noratrieb committed Mar 14, 2023
    Configuration menu
    Copy the full SHA
    7291853 View commit details
    Browse the repository at this point in the history
  2. Improve heuristics for format_args literal being suggestable

    Sometimes, we want to create subspans and point at code in the literal
    if possible. But this doesn't always make sense, sometimes the literal
    may come from macro expanded code and isn't actually there in the
    source. Then, we can't really make these suggestions.
    
    This now makes sure that the literal is actually there as we see it so
    that we will not run into ICEs on weird literal transformations.
    Noratrieb committed Mar 14, 2023
    Configuration menu
    Copy the full SHA
    427aceb View commit details
    Browse the repository at this point in the history