-
-
Notifications
You must be signed in to change notification settings - Fork 14.1k
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 |
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 MR contains the following updates: | Package | Update | Change | |---|---|---| | [rust](https://github.com/rust-lang/rust) | minor | `1.91.1` -> `1.92.0` | MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot). **Proposed changes to behavior should be submitted there as MRs.** --- ### Release Notes <details> <summary>rust-lang/rust (rust)</summary> ### [`v1.92.0`](https://github.com/rust-lang/rust/blob/HEAD/RELEASES.md#Version-1920-2025-12-11) [Compare Source](rust-lang/rust@1.91.1...1.92.0) \========================== <a id="1.92.0-Language"></a> ## Language - [Document `MaybeUninit` representation and validity](rust-lang/rust#140463) - [Allow `&raw [mut | const]` for union field in safe code](rust-lang/rust#141469) - [Prefer item bounds of associated types over where-bounds for auto-traits and `Sized`](rust-lang/rust#144064) - [Do not materialize `X` in `[X; 0]` when `X` is unsizing a const](rust-lang/rust#145277) - [Support combining `#[track_caller]` and `#[no_mangle]` (requires every declaration specifying `#[track_caller]` as well)](rust-lang/rust#145724) - [Make never type lints `never_type_fallback_flowing_into_unsafe` and `dependency_on_unit_never_type_fallback` deny-by-default](rust-lang/rust#146167) - [Allow specifying multiple bounds for same associated item, except in trait objects](rust-lang/rust#146593) - [Slightly strengthen higher-ranked region handling in coherence](rust-lang/rust#146725) - [The `unused_must_use` lint no longer warns on `Result<(), Uninhabited>` (for instance, `Result<(), !>`), or `ControlFlow<Uninhabited, ()>`](rust-lang/rust#147382). This avoids having to check for an error that can never happen. <a id="1.92.0-Compiler"></a> ## Compiler - [Make `mips64el-unknown-linux-muslabi64` link dynamically](rust-lang/rust#146858) - [Remove current code for embedding command-line args in PDB](rust-lang/rust#147022) Command-line information is typically not needed by debugging tools, and the removed code was causing problems for incremental builds even on targets that don't use PDB debuginfo. <a id="1.92.0-Libraries"></a> ## Libraries - [Specialize `Iterator::eq{_by}` for `TrustedLen` iterators](rust-lang/rust#137122) - [Simplify `Extend` for tuples](rust-lang/rust#138799) - [Added details to `Debug` for `EncodeWide`](rust-lang/rust#140153). - [`iter::Repeat::last`](rust-lang/rust#147258) and [`count`](rust-lang/rust#146410) will now panic, rather than looping infinitely. <a id="1.92.0-Stabilized-APIs"></a> ## Stabilized APIs - [`NonZero<u{N}>::div_ceil`](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.div_ceil) - [`Location::file_as_c_str`](https://doc.rust-lang.org/stable/std/panic/struct.Location.html#method.file_as_c_str) - [`RwLockWriteGuard::downgrade`](https://doc.rust-lang.org/stable/std/sync/struct.RwLockWriteGuard.html#method.downgrade) - [`Box::new_zeroed`](https://doc.rust-lang.org/stable/std/boxed/struct.Box.html#method.new_zeroed) - [`Box::new_zeroed_slice`](https://doc.rust-lang.org/stable/std/boxed/struct.Box.html#method.new_zeroed_slice) - [`Rc::new_zeroed`](https://doc.rust-lang.org/stable/std/rc/struct.Rc.html#method.new_zeroed) - [`Rc::new_zeroed_slice`](https://doc.rust-lang.org/stable/std/rc/struct.Rc.html#method.new_zeroed_slice) - [`Arc::new_zeroed`](https://doc.rust-lang.org/stable/std/sync/struct.Arc.html#method.new_zeroed) - [`Arc::new_zeroed_slice`](https://doc.rust-lang.org/stable/std/sync/struct.Arc.html#method.new_zeroed_slice) - [`btree_map::Entry::insert_entry`](https://doc.rust-lang.org/stable/std/collections/btree_map/enum.Entry.html#method.insert_entry) - [`btree_map::VacantEntry::insert_entry`](https://doc.rust-lang.org/stable/std/collections/btree_map/struct.VacantEntry.html#method.insert_entry) - [`impl Extend<proc_macro::Group> for proc_macro::TokenStream`](https://doc.rust-lang.org/stable/proc_macro/struct.TokenStream.html#impl-Extend%3CGroup%3E-for-TokenStream) - [`impl Extend<proc_macro::Literal> for proc_macro::TokenStream`](https://doc.rust-lang.org/stable/proc_macro/struct.TokenStream.html#impl-Extend%3CLiteral%3E-for-TokenStream) - [`impl Extend<proc_macro::Punct> for proc_macro::TokenStream`](https://doc.rust-lang.org/stable/proc_macro/struct.TokenStream.html#impl-Extend%3CPunct%3E-for-TokenStream) - [`impl Extend<proc_macro::Ident> for proc_macro::TokenStream`](https://doc.rust-lang.org/stable/proc_macro/struct.TokenStream.html#impl-Extend%3CIdent%3E-for-TokenStream) These previously stable APIs are now stable in const contexts: - [`<[_]>::rotate_left`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.rotate_left) - [`<[_]>::rotate_right`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.rotate_right) <a id="1.92.0-Cargo"></a> ## Cargo - [Added a new chapter](rust-lang/cargo#16119) to the Cargo book, ["Optimizing Build Performance"](https://doc.rust-lang.org/stable/cargo/guide/build-performance.html). <a id="1.92.0-Rustdoc"></a> ## Rustdoc - [If a trait item appears in rustdoc search, hide the corresponding impl items](rust-lang/rust#145898). Previously a search for "last" would show both `Iterator::last` as well as impl methods like `std::vec::IntoIter::last`. Now these impl methods will be hidden, freeing up space for inherent methods like `BTreeSet::last`. - [Relax rules for identifiers in search](rust-lang/rust#147860). Previously you could only search for identifiers that were valid in rust code, now searches only need to be valid as part of an identifier. For example, you can now perform a search that starts with a digit. <a id="1.92.0-Compatibility-Notes"></a> ## Compatibility Notes - [Fix backtraces with `-C panic=abort` on Linux by generating unwind tables by default](rust-lang/rust#143613). Build with `-C force-unwind-tables=no` to keep omitting unwind tables. * As part of the larger effort refactoring compiler built-in attributes and their diagnostics, [the future-compatibility lint `invalid_macro_export_arguments` is upgraded to deny-by-default and will be reported in dependencies too.](rust-lang/rust#143857) * [Update the minimum external LLVM to 20](rust-lang/rust#145071) * [Prevent downstream `impl DerefMut for Pin<LocalType>`](rust-lang/rust#145608) * [Don't apply temporary lifetime extension rules to the arguments of non-extended `pin!` and formatting macros](rust-lang/rust#145838) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this MR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box --- This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0Mi40Ny4wIiwidXBkYXRlZEluVmVyIjoiNDIuNDcuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiUmVub3ZhdGUgQm90Il19-->
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).