Skip to content

dead code (+ unused assignment, etc) warnings in macros do more harm than good #24580

Open
@pnkfelix

Description

@pnkfelix

(imported from improperly closed bug #17427)

Consider the following code:

fn g(x: u8) -> u8 {
    1 - x
}

fn main() {
    let mut x = 1u8;
    macro_rules! m {
        () => {{ x = g(x);
                 if x == 0 { x = 1; }
        }}
    }

    m!();
    g(1/x);
    m!();
}

playpen

The unused_assignments lint fires from the expansion of the second occurrence of m!(). But if you follow the advice of the lint and remove the assignment, you discover that the assignment was in fact significant, because when you remove the assignment, the side effect from the first occurrence of m!() is lost, and so the call to g divides by zero.

There are a number of different ways to handle this.

  • This simplest would be to disable such lints for code with spans that are inside macro definitions, as was essentially the original suggestion of Allow dead assignments in macros by default. #17427
  • Another option would be to revise our strategy for such lints, and to warn about an unused assignment (or other dead code) for a given span only if ALL such occurrences trigger the warning. I.e. as soon as one expansion proves that that code in the macro is useful, then you do not get any warning about it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.A-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)C-bugCategory: This is a bug.P-lowLow priorityT-langRelevant to the language team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions