Skip to content

Handle Result<T, !> and ControlFlow<!, T> as T wrt #[must_use]#16353

Merged
Jarcho merged 1 commit intorust-lang:masterfrom
samueltardieu:issues/rustc-148214
Feb 21, 2026
Merged

Handle Result<T, !> and ControlFlow<!, T> as T wrt #[must_use]#16353
Jarcho merged 1 commit intorust-lang:masterfrom
samueltardieu:issues/rustc-148214

Conversation

@samueltardieu
Copy link
Member

There is a proposal to change the behaviour of rustc's must_use lint to consider Result<T, U> and ControlFlow<U, T> as T when U is uninhabited. See rust-lang/rust#148214.

This might make the user adding extra #[must_use] attributes to functions returning Result<T, !> or ControlFlow<!, T>, which would trigger the double_must_use lint in Clippy without the current change.

changelog: [double_muse_use, drop_non_drop, let_underscore_must_use]: consider Result<T, U> and ControlFlow<U, T> as T wrt the #[must_use] attribute if U is uninhabited.

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Jan 7, 2026
@rustbot
Copy link
Collaborator

rustbot commented Jan 7, 2026

r? @dswij

rustbot has assigned @dswij.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@github-actions
Copy link

github-actions bot commented Jan 7, 2026

Lintcheck changes for 5137bb3

Lint Added Removed Changed
clippy::must_use_candidate 1 0 0

This comment will be updated if you push new changes

@samueltardieu
Copy link
Member Author

samueltardieu commented Jan 7, 2026

The second push was made to prevent suggesting using #[must_use] on types that are already #[must_use] even though they will be treated otherwise by rustc in the future (this is the key part). This was detected by lint check on the first iteration.

@samueltardieu
Copy link
Member Author

r? clippy

@rustbot rustbot assigned flip1995 and unassigned dswij Jan 26, 2026
// Returns whether the `ty` has `#[must_use]` attribute. If `simplify_uninhabited` is set and
// `ty` is a `Result`/`ControlFlow` whose `Err`/`Break` payload is an uninhabited type,
// the `Ok`/`Continue` payload type will be used instead. See <https://github.com/rust-lang/rust/pull/148214>.
pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, simplify_uninhabited: bool) -> bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What cases are handled by simplify_uninhabited = false?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See answer for both questions below.

Comment on lines 212 to 214
// The `simplify_uninhabited` argument can be later changed to `true` when
// rustc's `must_use` lint handles `Result<T, !>` and `ControlFlow<!, T>` as `T`.
|| is_must_use_ty(cx, return_ty(cx, item_id), false)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since rustc will be changing how it handles must_use shouldn't we just change the recommendation now?

Copy link
Member Author

@samueltardieu samueltardieu Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now it doesn't, and thus has not documented this. This would lead us to suggest adding #[must_use] to with_result() in:

pub struct S;

pub fn with_result() -> Result<S, std::convert::Infallible> {
    Ok(S)
}

while for the time being Result<_, _> is always must_use.

At first, I was worried about us triggering double_must_use if we suggest adding #[must_use] here and the user does it, but we won't because this PR modifies double_must_use. So we could suggest adding #[must_use], but that would still be confusing for the user since Result<_, _> is always must_use for the time being.

When it is implemented and documented that Result<T, E> is must_use only when T is in the case where E is uninhabited, we can suggest adding the attribute to the function.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It isn't needed now, but it will be needed in the future. Since it's going to change in the near future we should be telling people to change things now so an update to the new compiler still warns. I would add a note to the diagnostic about this, but we should still lint.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@flip1995
Copy link
Member

r? Jarcho

@rustbot rustbot assigned Jarcho and unassigned flip1995 Feb 19, 2026
There is a proposal to change the behaviour of rustc's `must_use` lint
to consider `Result<T, U>` and `ControlFlow<U, T>` as `T` when `U` is
uninhabited. See <rust-lang/rust#148214>.

This might make the user adding extra `#[must_use]` attributes to
functions returning `Result<T, !>` or `ControlFlow<!, T>`, which would
trigger the `double_must_use` lint in Clippy without the current change.
Copy link
Contributor

@Jarcho Jarcho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Jarcho Jarcho added this pull request to the merge queue Feb 21, 2026
Merged via the queue into rust-lang:master with commit 349e809 Feb 21, 2026
11 checks passed
@rustbot rustbot removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Feb 21, 2026
@samueltardieu
Copy link
Member Author

@flip1995 I don't know where you stand regarding the current rustup, but if you get a chance to include this PR in it, it would allow this change to be present in Rust 1.95, and unblock rust-lang/rust#148214 for Rust 1.96.

Otherwise we can also do a beta backport once the beta branch is cut, even though it would be great to do this near the start of the beta release cycle.

@samueltardieu samueltardieu deleted the issues/rustc-148214 branch February 21, 2026 18:10
@flip1995
Copy link
Member

Same as for the other PR :) I hope I can get back to the sync this evening/night.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants