Closed
Description
The latest nightly (rustc 1.57.0-nightly (8c2b6ea 2021-09-11)) introduces a new warning that I consider to be invalid.
Given the following code: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=14d790d2f286f58543c42d915f60e182
#[derive(Debug)]
struct Foo {
a: String,
}
fn main() {
let foo = Foo {
a: "hello".to_string(),
};
println!("{:?}", foo);
}
The current output is:
warning: field is never read: `a`
--> src/main.rs:3:5
|
3 | a: String,
| ^^^^^^^^^
|
= note: `#[warn(dead_code)]` on by default
warning: `playground` (bin "playground") generated 1 warning
Finished dev [unoptimized + debuginfo] target(s) in 1.56s
This feels very wrong to me. It means any struct created with the intent to be printed is "invalid" according to the compiler. This warning is not actionable. My only option is to suppress it, live with it, or insert some sort of "dummy read". This has broken our CI builds for Bevy (because we treat warnings as errors).
Metadata
Metadata
Assignees
Labels
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
hellow554 commentedon Sep 13, 2021
First off: Denying warnings is considered harmful [0] [1] [2] [3] and should not be default in a project. You may use it for testing purposes, but not actively as a blocker.
Second: I can see, that you might think that the lint is wrong, but it is actually right. You never read the field
a
.It is used in the Debug output, yes, but not actively in your code.
For the warning to silence you can prepend a underscore (e.g.
_a
) but that's it.The same goes for
Clone
btw.Here's the relevant PR + a lot of discussion: #85200
cart commentedon Sep 13, 2021
deny(warnings)
, we pass in-D warnings
as a rustc flag as part of our CI, which doesn't suffer from the "forward compatibility" issues called out in the four links you shared. I think most people would agree that warnings should be either resolved or suppressed, especially in public libraries.Foo
type, I wouldn't get the warning. This isn't about whether or not I directly touch the field. Its about whether something uses the field. As discussed in Ignore derived Clone and Debug implementations during dead code analysis #85200, the fact that Debug doesn't count is a new exception to a rule that applies to literally everything else.It sounds like ignoring Debug impls was a pragmatic choice to make this lint more useful. Debug is a common / recommended derive for structs, which meant that most structs weren't getting "unused field" lints. Working around this seems reasonable.
However I think it is worth calling out that this specific case is relatively common / many people would consider it "valid". At the very least, I imagine some users would be confused, especially given that this isn't consistent with other traits and printing debug derives is super common. Warnings should be actionable. It is the compiler telling the user that something should be fixed / isn't recommended. In my ideal world either:
Of course both of those solutions are complicated / controversial and I'm sure this was supposed to be an easy win. I'm not demanding any action here / this isn't a high priority for me. I'm just reporting a confusing / unintuitive new behavior. I doubt I'll be the last person to hit this.
llogiq commentedon Sep 13, 2021
We have another datapoint at synth. In our case, the code in question is not derived; the
type_name
field is actually read in a trait impl (though to be fair it's in anasync fn
, so there may be expansion involved, too).Mark-Simulacrum commentedon Sep 13, 2021
Nominating this for T-lang awareness, and possible discussion.
FabianWolff commentedon Sep 13, 2021
@llogiq The piece of code that you link to reads the
data_type
field, not thetype_name
field, so the latter may very well be unused.In general, only automatically derived impls should be ignored; if you find an exception to this, it's a bug (whereas ignoring derived implementations is intended).
cynecx commentedon Sep 14, 2021
I’ve been getting these warnings as well. The struct actually contains a Child (tokio::process::Child) handle. So at drop time of the struct the Child handle drops and eventually cleanups the child process. So it’s not technically true that the field is never read, because the drop glue certainly does.
Edit: On second thought, this warning might have been lurking there all along because the struct has a Debug derive.
FabianWolff commentedon Sep 14, 2021
That's what I was going to say. Nothing was changed with regards to the
Drop
trait, so the behavior you're complaining about must have been there before (it was just hidden by theDebug
derive).tmandry commentedon Sep 14, 2021
For those wondering about disruptiveness of the change, we had to add this to
93153 fields in the main Fuchsia repo. I'd say this is among the most disruptive warnings changes we've had to fix. Most of these structs seem to only deriveDebug
; I haven't dug into what they're used for or whether these fields should exist yet.https://fuchsia-review.googlesource.com/c/fuchsia/+/581062
https://fuchsia-review.googlesource.com/c/fuchsia/+/581066
64 remaining items