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

Support for format args capture #180

Merged
merged 5 commits into from
Nov 3, 2021
Merged

Support for format args capture #180

merged 5 commits into from
Nov 3, 2021

Conversation

dtolnay
Copy link
Owner

@dtolnay dtolnay commented Nov 3, 2021

Required in order for rust-lang/rust#90473 to be usable inside the macro argument.

let var = ...;
let error = anyhow!("interpolate {var}");  // equivalent to anyhow!("interpolate {var}", var=var)

Stringifying a non-string $:literal for passing into the format_args
call is incompatible with format args capture: "to avoid ambiguity,
`format_args!` cannot capture variables when the format string is
expanded from a macro".

    error: there is no argument named `var`"
     --> src/main.rs:3:26
      |
    3 |     let _ = format_args!(concat!("{var}"));
      |                          ^^^^^^^^^^^^^^^^
      |
      = note: did you intend to capture a variable `var` from the surrounding scope?
      = note: to avoid ambiguity, `format_args!` cannot capture variables when the format string is expanded from a macro
@dtolnay dtolnay merged commit 8546f4c into master Nov 3, 2021
@dtolnay dtolnay deleted the capture branch November 3, 2021 02:29
@m-ou-se
Copy link

m-ou-se commented Nov 3, 2021

Using as_str().is_none() like this might become a bit of an issue in the future: It would subtly break when things like rust-lang/rust#78356 get implemented. That issue is about making things like format_args!("hello {}", "world") return Some("hello world") from as_str() by evaluating as much of a format string as possible at compile time. If we do more advanced const/inlining stuff, format_args!("hello {SOME_CONST}").as_str() might also return Some("hello world"). But then anyhow!("hello {SOME_CONST}") would use the message "hello {SOME_CONST}" instead of "hello world", since it uses the original string literal instead of the result from as_str().

(And right now it also means that anyhow!("{") is an error, but escaping it like anyhow!("{{") produces two braces instead of one.)

Also thanks for making and maintaining this crate! It's great.

@dtolnay
Copy link
Owner Author

dtolnay commented Nov 5, 2021

Good call — fixed in #184 + #185.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants