-
Couldn't load subscription status.
- Fork 13.9k
unused_must_use: Don't warn on Result<(), Uninhabited> or ControlFlow<Uninhabited, ()>
#147382
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
unused_must_use: Don't warn on Result<(), Uninhabited> or ControlFlow<Uninhabited, ()>
#147382
Conversation
This simplifies the initial conditional, and will allow reusing the variable in subsequent checks.
|
I'll be waiting for the outcome of T-lang's triage meeting before reviewing this since the proposed rules might very well change drastically (e.g., trait-driven vs. not trait-driven; cc Zulip discussion). |
|
Summarizing the Zulip discussion:
|
|
My proposal, here, is that we handle this simple case to make common patterns more usable. This does not rule out the possibility of adding more cases in the future, including general trait-based cases. However, I don't think we should make this common case wait on the more general cases. In particular, this solution does not close any doors on replacing this special case with a general case. This would unblock some planned work in the standard library to make |
|
As a general rule I think this should follow the same rules what |
d9d6c49 to
23a0751
Compare
|
I've updated this to follow the same pattern as other inhabitedness checking, of only caring about I've also updated it to handle |
Result<(), Uninhabited>Result<(), Uninhabited> or ControlFlow<Uninhabited, ()>
|
huh... |
Added, thanks! |
|
Is this the same as "don't Thus it could be phrased as "change the |
|
@scottmcm I don't want to generalize that here yet, because someone might e.g. have some |
|
This makes sense to me, in particular how this helps with @rfcbot fcp merge |
This makes it easier to review without cross-referencing each test function with its invocation.
f4ca5fb to
7aa7ecc
Compare
|
The final comment period, with a disposition to merge, as per the review above, is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. This will be merged soon. |
| // Suppress warnings on `Result<(), Uninhabited>` (e.g. `Result<(), !>`). | ||
| ty::Adt(def, args) | ||
| if cx.tcx.is_diagnostic_item(sym::Result, def.did()) | ||
| && args.type_at(0).is_unit() |
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.
Is there a reason why this checks for T = ()? Result<T, !> is basically T, so I'd expect this to not check for (). In #147854, which I opened because I haven't seen this PR, I just return is_ty_must_use(cx, args.type_at(0), expr, span) here.
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.
@WaffleLapkin I can see the argument for that, but it'd be less clear-cut. Result<(), !> has only one possible value, so there's zero value in checking it at all, and it seems safe to unconditionally make it ignore must_use. Something like Result<u32, !>, on the other hand, would currently be flagged by the must_use on Result, and it would be a potential surprise to people to stop doing that; people might be expecting to have to capture the return value with let Ok(value) = ..., for instance.
If we were going to potentially suppress warnings on Result<T, !>, I think that'd need a separate FCP. We might also want to let people know that they may want to mark the function #[must_use] if they were previously counting on the Result to do that.
Separately from that, if we're checking for T being #[must_use], it'd be nice to have a design where a function returning Result<T, E> produces an unused_must_use warning if you apply a ? and then ignore the T. But that doesn't have to happen right away, and I'm all for incremental results.
One way or another, though, I think that would be an additional change requiring an additional FCP.
…e-result-unit-uninhabited, r=fmease unused_must_use: Don't warn on `Result<(), Uninhabited>` or `ControlFlow<Uninhabited, ()>` This suppresses warnings on things like `Result<(), !>`, which helps simplify code using the common pattern of having an `Error` associated type: code will only have to check the error if there is a possibility of error. This will, for instance, help with future refactorings of `write!` in the standard library. As this is a user-visible change to lint behavior, it'll require a lang FCP. --- My proposal, here, is that we handle this simple case to make common patterns more usable. This does not rule out the possibility of adding more cases in the future, including general trait-based cases. However, I don't think we should make this common case wait on the more general cases. In particular, this solution does not close any doors on replacing this special case with a general case. This would unblock some planned work in the standard library to make `write!` more usable for infallible cases (e.g. writing into a `Vec` or `String`).
Rollup of 3 pull requests Successful merges: - #146167 (Deny-by-default never type lints) - #147382 (unused_must_use: Don't warn on `Result<(), Uninhabited>` or `ControlFlow<Uninhabited, ()>`) - #147821 (Do not GC the current active incremental session directory) r? `@ghost` `@rustbot` modify labels: rollup
Rollup merge of #147382 - joshtriplett:unused-must-use-ignore-result-unit-uninhabited, r=fmease unused_must_use: Don't warn on `Result<(), Uninhabited>` or `ControlFlow<Uninhabited, ()>` This suppresses warnings on things like `Result<(), !>`, which helps simplify code using the common pattern of having an `Error` associated type: code will only have to check the error if there is a possibility of error. This will, for instance, help with future refactorings of `write!` in the standard library. As this is a user-visible change to lint behavior, it'll require a lang FCP. --- My proposal, here, is that we handle this simple case to make common patterns more usable. This does not rule out the possibility of adding more cases in the future, including general trait-based cases. However, I don't think we should make this common case wait on the more general cases. In particular, this solution does not close any doors on replacing this special case with a general case. This would unblock some planned work in the standard library to make `write!` more usable for infallible cases (e.g. writing into a `Vec` or `String`).
This suppresses warnings on things like
Result<(), !>, which helps simplify code using the common pattern of having anErrorassociated type: code will only have to check the error if there is a possibility of error.This will, for instance, help with future refactorings of
write!in the standard library.As this is a user-visible change to lint behavior, it'll require a lang FCP.
My proposal, here, is that we handle this simple case to make common patterns more usable. This does not rule out the possibility of adding more cases in the future, including general trait-based cases. However, I don't think we should make this common case wait on the more general cases. In particular, this solution does not close any doors on replacing this special case with a general case.
This would unblock some planned work in the standard library to make
write!more usable for infallible cases (e.g. writing into aVecorString).