Add let_else_ok_or lint#17207
Open
sylvestre wants to merge 2 commits into
Open
Conversation
Collaborator
|
rustbot has assigned @samueltardieu. Use Why was this reviewer chosen?The reviewer was selected based on:
|
|
Lintcheck changes for 05c9949
This comment will be updated if you push new changes |
This comment has been minimized.
This comment has been minimized.
samueltardieu
requested changes
Jun 11, 2026
Member
There was a problem hiding this comment.
The lint will suggest code that doesn't compile in const contexts, such as:
const fn f(a: Option<u32>) -> Result<u32, ()> {
let Some(a) = a else {
return Err(());
};
Ok(a)
}You should check that:
- either you are not in a
constcontext - or the three features
const_try,const_trait_implandconst_option_opsare enabled (you can do the test once and store the result in theLetElseOkOrstruct, and useimpl_lint_pass!instead ofdeclare_lint_pass!)
Collaborator
|
Reminder, once the PR becomes ready for a review, use |
New `style` lint that detects `let...else` statements binding the payload
of an `Option` whose `else` branch only does `return Err(<expr>)`, and
suggests the more concise `Option::ok_or`/`ok_or_else` with the `?`
operator:
let Some(value) = opt else {
return Err("missing");
};
// ->
let value = opt.ok_or("missing")?;
`ok_or_else` is suggested when the error value is non-trivial, to preserve
the laziness of the original `else` branch. The lint bails on `ref`
bindings, comments or `#[cfg]` in the `else` branch, and `return Err(..)`
expressions produced by a macro expansion (e.g. `anyhow::bail!`), where
the error value cannot be rendered into a sound suggestion.
`ok_or`/`ok_or_else` move the error value unconditionally, whereas the
`else` branch only runs on `None`. When the error value moves a non-`Copy`
local that is still used on the `Some` path (or could be moved again across
a loop iteration), the rewrite would reference a moved value and not
compile, so the suggestion is downgraded to non-machine-applicable in that
case (values that are merely borrowed, e.g. `Err(format!("{x}"))`, stay
machine-applicable). The error snippet is rendered through the statement's
context so an error value that is itself a macro call (`format!(..)`) is
shown as written instead of leaking its expansion internals.
c849920 to
87b80a6
Compare
Collaborator
|
This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
New
stylelint that detectslet...elsestatements binding the payload of anOptionwhoseelsebranch only doesreturn Err(<expr>), and suggests the more conciseOption::ok_or/ok_or_elsewith the?operator:ok_or_elseis suggested when the error value is non-trivial, to preserve the laziness of the originalelsebranch. The lint bails onrefbindings, comments or#[cfg]in theelsebranch, andreturn Err(..)expressions produced by a macro expansion (e.g.anyhow::bail!), where the error value cannot be rendered into a sound suggestion.changelog: Add
let_else_ok_orlint