Skip to content

dead_code lint does not trigger for tuple structs with unread fields #92790

Description

@shepmaster

This code:

fn main() {
    let _ = Example { u: 0 };
}

struct Example {
    u: u8,
}

Produces this warning:

warning: field is never read: `u`
 --> src/main.rs:6:5
  |
6 |     u: u8,
  |     ^^^^^
  |

However, switching to a tuple struct:

fn main() {
    let _ = Example(0);
}

struct Example(u8);

Does not report a warning.

Original report misleadingly focusing on Debug
fn main() {
    dbg!(Example { a: 0 });
}

#[derive(Debug)]
struct Example {
    a: u8,
}

produces

warning: field is never read: `a`
 --> src/main.rs:7:5
  |
7 |     a: u8,
  |     ^^^^^
  |
  = note: `#[warn(dead_code)]` on by default

However, switching to a tuple struct:

fn main() {
    dbg!(Example(0));
}

#[derive(Debug)]
struct Example(u8);

does not produce the warning.

/cc @FabianWolff
/cc #85200; #84647; #88900

Meta

Rustc 1.57.0 and 1.60.0-nightly (2022-01-10 89b9f7b)

Activity

  1. FabianWolff commented on Jan 11, 2022

    @FabianWolff
    Contributor

    This has nothing to do with the #[derive(Debug)]:

    fn main() {
        let _ = Example { u: 0 };
    }
    
    struct Example {
        u: u8,
    }
    warning: field is never read: `u`
     --> src/main.rs:6:5
      |
    6 |     u: u8,
      |     ^^^^^
      |
    

    but

    fn main() {
        let _ = Example(0);
    }
    
    struct Example(u8);
    

    gives no warning.

  2. changed the title [-]dead_code lint does not ignore Debug for tuple structs[/-] [+]dead_code lint does not trigger for tuple structs with unread fields[/+] on Jan 11, 2022
  3. shepmaster commented on Jan 11, 2022

    @shepmaster
    MemberAuthor

    @FabianWolff oh dear. Thanks! I've updated the title and original post; sorry for the false ping.

  4. added
    A-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    I-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
    on Jan 12, 2022
  5. camelid commented on Jan 12, 2022

    @camelid
    Member

    Not a regression AFAIK, but seems like worth prioritizing.

  6. shepmaster commented on Jan 12, 2022

    @shepmaster
    MemberAuthor

    Not a regression AFAIK

    I agree. I did a quick test across Rust 1.{0,10,20,30,40,50}.0 and none of them reported the lint.

  7. camelid commented on Jan 12, 2022

    @camelid
    Member

    Thanks for checking!

  8. FabianWolff commented on Jan 12, 2022

    @FabianWolff
    Contributor

    This behavior does indeed date back to the very beginning of the detection of dead struct fields (commit 0271224 in 2014). The culprit is line 621 in dead.rs:

    fn should_warn_about_field(&mut self, field: &hir::FieldDef<'_>) -> bool {
    let def_id = self.tcx.hir().local_def_id(field.hir_id);
    let field_type = self.tcx.type_of(def_id);
    !field.is_positional()
    && !self.symbol_is_live(def_id)
    && !field_type.is_phantom_data()
    && !has_allow_dead_code_or_lang_attr(self.tcx, field.hir_id)
    }

    Commenting out this line with the above tuple struct example gives:

    warning: field is never read: `0`
     --> s2.rs:6:16
      |
    6 | struct Example(u8);
      |                ^^
      |
    

    I can open a PR for this, or is there a reason anyone here can think of why dead tuple struct fields shouldn't get a warning?

    @rustbot claim

  9. camelid commented on Jan 12, 2022

    @camelid
    Member

    I can't think of one, so opening a PR seems good.

  10. danielhenrymantilla commented on Jan 12, 2022

    @danielhenrymantilla
    Contributor

    FWIW, I find the example with dbg! to be surprising: dbg! is debug-printing a struct, and thus reading its fields

  11. shepmaster commented on Jan 12, 2022

    @shepmaster
    MemberAuthor
  12. apiraino commented on Jan 13, 2022

    @apiraino
    Contributor

    Assigning priority as discussed in the Zulip thread of the Prioritization Working Group.

    @rustbot label -I-prioritize +P-medium

  13. added and removed
    I-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
    on Jan 13, 2022
  14. rcls commented on Feb 21, 2022

    @rcls

    is there a reason anyone here can think of why dead tuple struct fields shouldn't get a warning?

    One thought is that deleting a dead tuple field may be non-trivial, if it is not the last field. E.g., imagine if someone got:

    struct DeadLive(u8,u8);
    ...
    warning: field is never read: `0`
    

    You can't simply delete the dead field. You have to also renumber all the uses of .1, which might be a non-trivial and error prone task. So the cost v. benefit tradeoff of having a warning is different to the named-field case.

  15. added a commit that references this issue on Aug 2, 2022
    ea26159
  16. added a commit that references this issue on Aug 5, 2022
    9bbbf60
  17. shepmaster commented on Aug 5, 2022

    @shepmaster
    MemberAuthor

    Thank you @FabianWolff !

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

Metadata

Metadata

Assignees

Labels

A-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.C-bugCategory: This is a bug.P-mediumMedium 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