-
Notifications
You must be signed in to change notification settings - Fork 1.7k
fix: manual_unwrap_or_default
suggests error when expression is a None variant
#12688
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
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @Jarcho (or someone else) some time within the next two weeks. Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (
|
There are merge commits (commits with multiple parents) in your changes. We have a no merge policy so these commits will need to be removed for this pull request to be merged. You can start a rebase with the following commands:
The following commits are merge commits: |
dcaf974
to
1fd8241
Compare
There are merge commits (commits with multiple parents) in your changes. We have a no merge policy so these commits will need to be removed for this pull request to be merged. You can start a rebase with the following commands:
The following commits are merge commits: |
988b08b
to
c6167c3
Compare
c6167c3
to
c9f0374
Compare
☔ The latest upstream changes (presumably #12897) made this pull request unmergeable. Please resolve the merge conflicts. |
if let Some(none_def_id) = cx.tcx.lang_items().option_none_variant() { | ||
if let ExprKind::Path(QPath::Resolved(_, path)) = &condition.kind { | ||
if let Some(def_id) = path.res.opt_def_id() { | ||
if cx.tcx.parent(def_id) == none_def_id { |
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 is equivalent to path_res(cx, condition).opt_def_id().is_some_and(|id| Some(cx.tcx.parent(id)) == cx.tcx.lang_items().option_none_variant())
// We check if the expression is not a method or function with a unspecified return type | ||
if let ExprKind::MethodCall(_, expr, _, _) = &condition.kind { | ||
if let ty::Adt(_, substs) = cx.typeck_results().expr_ty(expr).kind() { | ||
if let Some(ok_type) = substs.first() { | ||
return span_lint_and_sugg( | ||
cx, | ||
MANUAL_UNWRAP_OR_DEFAULT, | ||
expr.span, | ||
format!("{expr_name} can be simplified with `.unwrap_or_default()`"), | ||
format!("explicit the type {ok_type} and replace your expression with"), | ||
format!("{receiver}.unwrap_or_default()"), | ||
Applicability::Unspecified, | ||
); | ||
} | ||
} | ||
} |
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.
What are you trying to catch with this? This looks like it will just catch any scrutinee that happens to be a method call.
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 catch all methods and functions that return a generic type that can't be inferred from it's arguments (e.g. "1".parse()
) ?
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.
We have clippy_utils::ty::expr_type_is_certain
for that.
expr.span, | ||
format!("{expr_name} can be simplified with `.unwrap_or_default()`"), | ||
"replace it with", | ||
format!("{receiver}::</* Type */>.unwrap_or_default()"), |
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.
You can print any Ty
which will print the type's full name. The following should work:
if let ty::Adt(_, args) = cx.typeck_results().expr_ty(expr).kind()
&& let Some(arg) = args.first()
&& let Some(arg_ty) = arg.as_type()
{
format!("{receiver}::<{}>.unwrap_or_default()", arg_ty)
}
@rustbot author |
Hey this is triage, I'm closing this due to inactivity. If you want to continue this implementation, you're welcome to create a new PR. Thank you for the time, you already put into this! Interested parties are welcome to pick this implementation up as well :) @rustbot label +S-inactive-closed -S-waiting-on-author -S-waiting-on-review |
Hi forks! I would like to pick up this implementation, looks like there aren't much left. |
Suggesting error when expression is none :
None.unwrap_or_default()
raises an error, as explained in the following issue:fixes #12670
changelog: [
manual_unwrap_or_default
]: the lint is ignored when matching None, as theunwrap_or_default
method can't infer the type of a None variant.