-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New lint: drop_for_static
#16464
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
base: master
Are you sure you want to change the base?
New lint: drop_for_static
#16464
Conversation
|
This could be implemented as just: if let ItemKind::Static(_, ident, ..) = item.kind
&& cx.tcx.type_of(item.owner_id.def_id).instantiate_identity().has_drop(cx.tcx, cx.typing_env())
{
// lint
}Note you should be using the ident's span when emitting the lint to avoid an overly large span being printed with the diagnostic. |
|
@Jarcho thank you for your quick response and suggestions ! Just tried your approach, but it does work recursively as I originally intended. static A1: FooWithDrop = FooWithDrop;and does not identify the presence of the static A3: &FooWithDrop = &FooWithDrop;
static A5: (FooWithoutDrop, FooWithDrop) = (FooWithoutDrop, FooWithDrop);
static A7: [FooWithDrop; 1] = [FooWithDrop];
static A9: &[FooWithDrop] = &[FooWithDrop];
etc.Suggested implementation. if let ItemKind::Static(_, _, _, _) = item.kind
&& let ty = cx.tcx.type_of(item.owner_id.def_id).instantiate_identity()
&& has_drop(cx, ty)
{
// lint
}Or maybe I am missing something. |
clippy_lints/src/drop_for_static.rs
Outdated
| if let Some(def_id) = path.res.opt_def_id() { | ||
| let ty = self.cx.tcx.type_of(def_id).instantiate_identity(); | ||
| if has_drop(self.cx, ty) { | ||
| self.drop_for_static_found = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It could be nice to store the span of at least the first such type, so that the final lint message could put a label1 on it -- something like:
error: static items with drop implementation
--> tests/ui/drop_for_static.rs:36:8
|
LL | static B1: Nested<FooWithDrop> = Nested(FooWithDrop, ());
| ^^ ^^^^^^^^^^^ type with drop implementation here
Or maybe just nest all the way and collect at all of them -- after all, that's what we end up doing when there isn't a type-with-drop. This would reduce the annoyance of the lint triggering again after you fix it
Footnotes
-
using
Diag::span_label↩
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for suggestion !
Already applied it.
But using span_label makes it like
LL | static A1: FooWithDrop = FooWithDrop;
| ^^ ----------- type with drop implementation hereHave not found an alternative to print exactly how you've mentioned.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well done!
Don't worry about the underline type, I just misremembered it:)
Or maybe just nest all the way and collect at all of them -- after all, that's what we end up doing when there isn't a type-with-drop. This would reduce the annoyance of the lint triggering again after you fix it
I still think this would be a good idea.. let's see what the maintainers think
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, I was also thinking about that. And didn't do that because was concerned to not bee too annoying with the lint messages.
But in any case would be happy to add it as you mentioned.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One small thing, otherwise LGTM:)
Now we just need to wait for an actual maintainer
|
Sorry, had had the wrong name. You want |
Co-authored-by: Ada Alakbarova <58857108+ada4a@users.noreply.github.com>
|
@Jarcho got it, will take a look how to use
I am not entirely agree, because it could be the following scenario, for which one we want to emit lint in my opinion. struct FooWithDrop;
impl Drop for FooWithDrop {
fn drop(&mut self) {}
}
static A: &FooWithDrop = &FooWithDrop; |
|
r? clippy |
|
Lintcheck changes for 2489ce9
This comment will be updated if you push new changes |
This case is not due to the type of the static, but due to lifetime extension in the initializer's body. Currently you'll lint on things like static FOO: NeedsDrop = NeedsDrop; // should lint
static FOO_REF: &NeedsDrop = &FOO; // shouldn't lintLinting undropped temporaries in the initializer is fine, but that should probably be it's own lint. |
|
@Jarcho I see - agree, missed that. |
|
@Jarcho so just to clarify static A1: FooWithDrop = FooWithDrop;
static A2: (FooWithoutDrop, FooWithDrop) = (FooWithoutDrop, FooWithDrop);
static A3: [FooWithDrop; 1] = [FooWithDrop];
static A4: Nested<FooWithDrop> = Nested(FooWithDrop, ());
static A5: Nested<FooWithoutDrop, Nested<FooWithDrop>> = Nested(FooWithoutDrop, Nested(FooWithDrop, ()));
static A6: Nested<(FooWithoutDrop, FooWithDrop)> = Nested((FooWithoutDrop, FooWithDrop), ());
static A7: Nested<[FooWithDrop; 1]> = Nested([FooWithDrop], ());And in these we dont static A1: &FooWithDrop = &FooWithDrop;
static A2: &[FooWithDrop] = &[FooWithDrop]; |
Description
This PR introduces a new lint to notify users when a static item contains a type that implements the
Droptrait.As per the Rust Reference, static variables have a 'static lifetime and are never destroyed. Consequently, the
Drop::dropmethod is never executed for these items.Rational
In scenarios where
dropis used for critical resource management. Such as closing file handles, releasing external locks, or performing a "graceful" shutdown of a subsystem, relying on a static item can lead to subtle resource leaks or unexpected behaviour. Since the programmer might expect the destructor to run at the end of the program's execution, providing a diagnostic when this won't happen helps prevent "silent" failures in resource cleanup.changelog: new lint:
drop_for_static