-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
dead_code
in 1.77 lints against tuple fields with Drop implementations and suggests removing them
#122833
Comments
I also got this on my project, several structs holding MutexGuard's were flagged and I didn't know how to please the compiler but using allow[dead_code], which feels like the wrong thing to do since the code is not dead. |
Thanks for writing this up, I'm seeing this as well on 1.77, except instead of a tuple-struct it's with a tuple-style enum member like: enum Foo {
Bar(Option<DroppableType>),
} |
This is currently consistent across struct kinds in 1.77: struct SignificantDrop {
a: usize,
}
struct AnythingElse {
a: u8,
b: SignificantDrop,
}
impl Drop for SignificantDrop {
fn drop(&mut self) {
println!("Doing something important to {}", self.a);
}
}
struct OwnsResource(u8, SignificantDrop);
fn main() {
let s = OwnsResource(17, SignificantDrop { a: 999 });
let b = AnythingElse {
a: 18,
b: SignificantDrop { a: 1000 },
};
println!("{}", s.0);
println!("{}", b.a);
} The fact that you were able to use tuple structs, specifically, to squirm around this, was a bug. Not in the sense that it should be linting on this, but that it should be linting or not linting consistently regardless of whether the fields are given letters or numbers to name them. |
In that sense, this is arguably a duplicate of #112290 but I will leave this issue open because I expect it to accumulate quite a few more comments in any case, and people will open a new copy of this issue if I do close it, so. |
Thanks for keeping the issue open. Consider the following example: struct MyUserdata(Arc<()>);
let rc = Arc::new(());
// Move userdata into Lua
lua.globals.set("userdata", MyUserdata(rc.clone()));
assert_eq!(Arc::strong_count(&rc), 2);
lua.globals.remove("userdata");
lua.gc_collect();
// Check that userdata is dropped
assert_eq!(Arc::strong_count(&rc), 1); Using |
I believe this is also the same issue as #119645. |
@khvzak This is a question with a deeply subjective answer, but: You say, as I understand it, that struct MyUserdata(
#[allow(drop_only_field)] Arc<()>,
); I am asking because I have not formed an opinion yet on whether the lint is correct to, in fact, lint at all, or whether this should be indicated some other way. |
@clechasseur #119645 is subtly different because it's about "auto traits", whereas |
It was me that was confused then, because I posted about the Drop behavior in that other issue - sorry about that.
If I may offer my opinion: I don't think it would be better (IMHO). I realize that conceptually, lints applied to structs with named fields should also apply to structs with unnamed fields. However, in the case of Drop-only fields, if the field has a name, there's an easy way out that is generally well-understood (prepend an underscore to the name). For unnamed fields however, that's not possible so you have to silence the lint "manually". This in fact makes the experience of structs with named fields different from the experience of structs with unnamed fields. |
I discovered that adding
What is really confusing, is the lint advice:
both suggested options are wrong as would break the program. |
I'm experiencing a similar issue, even though it isn't directly related to Imagine having something like: #[derive(Debug)]
struct ErrorA;
fn doA() -> Result<(), ErrorA> {
todo!()
}
#[derive(Debug)]
struct ErrorB;
fn doB() -> Result<(), ErrorB> {
todo!()
}
#[derive(Debug)]
enum ErrorAB {
A(ErrorA),
B(ErrorB),
}
fn doAB() -> Result<(), ErrorAB> {
doA().map_err(ErrorAB::A)?;
doB().map_err(ErrorAB::B)?;
} I'm only interested in With the new change, it will complain that It would be best if we could introduce I believe this arrangement may be a good solution also for the issue described here. What do you think? |
@workingjubilee Even if a field has a custom drop, it might still be an oversight to not use it anywhere else. |
|
Code
I tried this code:
Current output
Desired output
If the unused field has a drop implementation it should at least not suggest removing it entirely. I'm not sure what the best option is. For private types converting it to a struct and naming the field with an underscore works, but that doesn't work for public types.
Rationale and extra context
I use this pattern in a few cases in GUI code to ensure that an event handler is cleaned up when the containing tuple gets dropped. I can avoid the finding, but if I had just accepted the suggestion I'd have accidentally cleaned up my event handlers.
Other cases
For a struct the output is a more reasonable
field
bis never read (rustc dead_code)
without a suggestion to remove it. I think this could, still, benefit from detecting if Drop is implemented since it might have side effects.Rust Version
Anything else?
No response
The text was updated successfully, but these errors were encountered: