Skip to content

Detect likely attempts to use interpolation in string literals #100584

Closed

Description

@estebank

Given

fn foo(x: &str) {
    let _ = "{x}";
}

we currently emit a warning about x being unused.

We should additionally point at the x inside the string literal and mention that if we wanted string interpolation, it's not gonna work because it needs to be inside of a format!() invocation.

https://www.reddit.com/r/rust/comments/wo3id0/media_noob_question_why_are_my_parameters_unused/

Activity

  1. added
    A-diagnosticsArea: Messages for errors, warnings, and lints
    P-lowLow priority
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    A-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`
    D-papercutDiagnostics: An error or lint that needs small tweaks.
    D-newcomer-roadblockDiagnostics: Confusing error or lint; hard to understand for new users.
    D-terseDiagnostics: An error or lint that doesn't give enough information about the problem at hand.
    on Aug 15, 2022
  2. lyming2007 commented on Aug 16, 2022

    @lyming2007

    Do you mean, we should emit like this?

    warning: unused variable: `x`
     --> main.rs:1:8
      |
    1 | fn foo(x: &str) {
      |        let _ = "{x}";
      |                     ======= x needs to be inside of a format!() invocation
      |
      = note: `#[warn(unused_variables)]` on by default
    
    
  3. estebank commented on Aug 16, 2022

    @estebank
    ContributorAuthor

    Ideally, it would look something like this:

    warning: unused variable: `x`
     --> main.rs:1:8
      |
    1 | fn foo(x: &str) {
      |        ^ unused variable
    2 |        let _ = "{x}";
      |                  - you might have meant to use string interpolation in this string literal
    help: string interpolation only works in `format!` invocations
      |
    2 |        let _ = format!("{x}");
      |                ++++++++     +
      |
      = note: `#[warn(unused_variables)]` on by default
    
  4. lyming2007 commented on Aug 16, 2022

    @lyming2007

    @rustbot claim

  5. lyming2007 commented on Aug 24, 2022

    @lyming2007
    cat main.rs
    fn foo(xyza: &str) {
        let _ = "{xyza}";
    }
    
    
    fn main() {
      foo("aaa");
    }
    

    Current output is:

    warning: unused variable: `xyza`
     --> main.rs:1:8
      |
    1 | fn foo(xyza: &str) {
      |        ^^^^ help: if this is intentional, prefix it with an underscore: `_xyza`
      |
      = note: `#[warn(unused_variables)]` on by default
    
    warning: 1 warning emitted
    
    

    With my fix https://github.com/lyming2007/rust/pull/new/issue-100584

    The output looks like:

    warning: unused variable: `xyza`
     --> main.rs:1:8
      |
    1 | fn foo(xyza: &str) {
      |        ^^^^
      |        |
      |        unused variable
      |        help: if this is intentional, prefix it with an underscore: `_xyza`
    2 |     let _ = "{xyza}";
      |             -------- you might have meant to use string interpolation in this string literal
      |
      = note: `#[warn(unused_variables)]` on by default
      = help: string interpolation only works in `format!` invocations
    
    warning: 1 warning emitted
    

    There are still 2 issues for me.
    #1 I am not able to emit something like

     |
    2 |        let _ = format!("{x}");
      |                ++++++++     +
      |
    

    please give me an example, then I can look how the compiler deal with it.

    #2 I can't upload a specific test case for this issue, because the test script will opt out the unused variable. Here is the script I got:

    /home/lym/rust3/rust/build/x86_64-unknown-linux-gnu/stage1/bin/rustc /home/lym/rust3/rust/src/test/ui/type/issue-100584.rs -Zthreads=1 --target=x86_64-unknown-linux-gnu --error-format json --json future-incompat -Ccodegen-units=1 -Zui-testing -Zdeduplicate-diagnostics=no -Cstrip=debuginfo --emit metadata -C prefer-dynamic --out-dir /home/lym/rust3/rust/build/x86_64-unknown-linux-gnu/test/ui/type/issue-100584 -A unused -Crpath -Cdebuginfo=0 -Lnative=/home/lym/rust3/rust/build/x86_64-unknown-linux-gnu/native/rust-test-helpers -L /home/lym/rust3/rust/build/x86_64-unknown-linux-gnu/test/ui/type/issue-100584/auxiliary
    

    So it will always output nothing to stderr and make the test failed.
    @estebank please advise

  6. estebank commented on Aug 24, 2022

    @estebank
    ContributorAuthor

    You'd have to use:

    err.multipart_suggestion(
        vec![
            (lit_expr.span.shrink_to_lo(), "format!(".to_string()),
            (lit_expr.span.shrink_to_hi(), ")".to_string()),
        ],
        "if you meant to use string interpolation in the string literal, use the `format!` marco",
        Applicability::MachineApplicable,
    );

    Have you run python3 x.py test src/test/ui/type/issue-100584.rs --bless?

  7. lyming2007 commented on Aug 29, 2022

    @lyming2007

    thanks. please see my fix:
    #100941
    @estebank

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsA-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`D-newcomer-roadblockDiagnostics: Confusing error or lint; hard to understand for new users.D-papercutDiagnostics: An error or lint that needs small tweaks.D-terseDiagnostics: An error or lint that doesn't give enough information about the problem at hand.P-lowLow priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions