Skip to content

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

Closed
@shepmaster

Description

@shepmaster
Member

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

FabianWolff

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.

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
shepmaster

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.

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: Indicates that prioritization has been requested for this issue.
on Jan 12, 2022
camelid

camelid commented on Jan 12, 2022

@camelid
Member

Not a regression AFAIK, but seems like worth prioritizing.

shepmaster

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.

camelid

camelid commented on Jan 12, 2022

@camelid
Member

Thanks for checking!

FabianWolff

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

camelid

camelid commented on Jan 12, 2022

@camelid
Member

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

danielhenrymantilla

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

shepmaster

shepmaster commented on Jan 12, 2022

@shepmaster
MemberAuthor
apiraino

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

added and removed
I-prioritizeIssue: Indicates that prioritization has been requested for this issue.
on Jan 13, 2022
rcls

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.

added a commit that references this issue on Aug 2, 2022

Rollup merge of rust-lang#95977 - FabianWolff:issue-92790-dead-tuple,…

ea26159
added a commit that references this issue on Aug 5, 2022

Auto merge of rust-lang#95977 - FabianWolff:issue-92790-dead-tuple, r…

9bbbf60
shepmaster

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

    Participants

    @shepmaster@rcls@apiraino@danielhenrymantilla@FabianWolff

    Issue actions

      dead_code lint does not trigger for tuple structs with unread fields · Issue #92790 · rust-lang/rust