-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
Add #[must_bind] attribute and lint #78715
Conversation
r? @davidtwco (rust_highfive has picked a reviewer for you, use r? to override) |
/// [the reference]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_bind-attribute | ||
pub UNUSED_MUST_BIND, | ||
Warn, | ||
"Bogus `_` binding of a type flagged as `#[must_bind]`. Use something like `_guard`.", |
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.
"Bogus `_` binding of a type flagged as `#[must_bind]`. Use something like `_guard`.", | |
"types marked as `#[must_bind]` should be assigned to a variable, not dropped immediately", |
Did not know I general (not necessarily with |
I'm going to nominate for lang team because while I tend to think this is not the right fix (it's too similar to must_use, IMO), I think it may be worth trying to get a brief discussion at least on the |
|
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.
As Mark as noted, needs lang team involvement but w/r/t implementation:
In addition to the changes you've noted in the MR description, I've added some nitpicks below - but the implementation looks broadly correct to me.
descr_post_path | ||
), | ||
WhatAttrToCheck::MustBind => format!( | ||
"Bogus `let _ =` binding of {}`{}`{}. Use something like `let _guard =`.", |
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.
This should be changed to the same message suggested by this comment.
let (expr, attr_to_check) = match s.kind { | ||
hir::StmtKind::Semi(ref expr) => (&**expr, WhatAttrToCheck::MustUse), | ||
hir::StmtKind::Local(ref local) => { | ||
match local.pat.kind { |
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.
I'd prefer a guard in the match arm: if !matches!(local.pat.kind, hir::PatKind::Wild)
}); | ||
op_warned = true; | ||
} | ||
match attr_to_check { |
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.
if matches!(attr_to_check, WhatAttrToCheck::MustUse)
would be preferable
}); | ||
true | ||
} | ||
ty::Closure(..) => match attr_to_check { |
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.
I'd prefer a guard in the match arm: if matches!(attr_to_check, WhatAttrToCheck::MustUse)
} | ||
_ => false, | ||
}, | ||
ty::Generator(..) => match attr_to_check { |
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.
Likewise, guard in match arm.
let expr = match s.kind { | ||
hir::StmtKind::Semi(ref expr) => &**expr, | ||
#[derive(Clone, Copy)] | ||
enum WhatAttrToCheck { |
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.
I'd rename this to something like UnusedResultsAttr
(bikeshedding welcome) and I prefer it declared outside of the function and impl.
Note: |
@vi I think this change is small enough you don't have to worry about it, the author of |
We discussed this change in the last language team meeting. I think the general feeling is that we agree that this is a problem worth solving, but this does not quite feel like the right solution, or at least a broader exploration of the design space would be warranted first. The next step here is likely to close this PR in favor of a future project group, which would explore the solution space a bit more before proposing a concrete solution. If you'd be interested in driving this project group, please start a thread in I'm leaving this PR open and nominated as an informed "Final comment period" on the suggested path above, and unless there's further discussion taking us in a different path the lang team will likely close this during next triage. Thanks @vi! |
Thanks! We've discussed a bit more over Zulip since then, and the current consensus remains that we would like to see an exploration of the design space some more perhaps targeted at solving the underlying problems rather than patching over it. Going to go ahead and close this PR for the time being, though. |
Prototype implementation of https://internals.rust-lang.org/t/pre-rfc-must-bind/12658
Like
#[must_use]
, but also catcheslet _ =
.Intended to be used on semaphore guards and similar things where RAII guard is detached from the protected resource.
Beginner users often think that
_
is just a funny variable name and the guard will be dropped at the end of block instead of immediately. This may introduce silent logic error into the code.TODO:
#[feature]
instead of insta-stable#[must_bind]
without#[must_use]
as error.cargo fix
Is this idea worth pursuing further or it's unlikely to go through even with the TODOs resolved?