Skip to content

Commit

Permalink
Auto merge of rust-lang#9421 - xphoniex:fix-rust-lang#9420, r=giraffate
Browse files Browse the repository at this point in the history
Suggest `unwrap_or_default` when closure returns `"".to_string`

Closes rust-lang/rust-clippy#9420

changelog: [`unwrap_or_else_default`]: suggest `unwrap_or_default()` instead of `unwrap_or_else` with a closure that returns an empty `to_string`.
  • Loading branch information
bors committed Sep 6, 2022
2 parents b763b14 + b21d9d3 commit 7babd1b
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 3 deletions.
24 changes: 22 additions & 2 deletions clippy_lints/src/methods/unwrap_or_else_default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ use clippy_utils::{
diagnostics::span_lint_and_sugg, is_default_equivalent_call, source::snippet_with_applicability,
ty::is_type_diagnostic_item,
};
use rustc_ast::ast::LitKind;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_lint::LateContext;
use rustc_span::sym;
use rustc_span::{sym, symbol};

pub(super) fn check<'tcx>(
cx: &LateContext<'tcx>,
Expand All @@ -25,7 +26,7 @@ pub(super) fn check<'tcx>(

if_chain! {
if is_option || is_result;
if is_default_equivalent_call(cx, u_arg);
if closure_body_returns_empty_to_string(cx, u_arg) || is_default_equivalent_call(cx, u_arg);
then {
let mut applicability = Applicability::MachineApplicable;

Expand All @@ -44,3 +45,22 @@ pub(super) fn check<'tcx>(
}
}
}

fn closure_body_returns_empty_to_string(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> bool {
if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = e.kind {
let body = cx.tcx.hir().body(body);

if body.params.is_empty()
&& let hir::Expr{ kind, .. } = &body.value
&& let hir::ExprKind::MethodCall(hir::PathSegment {ident, ..}, [self_arg], _) = kind
&& ident == &symbol::Ident::from_str("to_string")
&& let hir::Expr{ kind, .. } = self_arg
&& let hir::ExprKind::Lit(lit) = kind
&& let LitKind::Str(symbol::kw::Empty, _) = lit.node
{
return true;
}
}

false
}
3 changes: 3 additions & 0 deletions tests/ui/unwrap_or_else_default.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ fn unwrap_or_else_default() {

let with_default_type: Option<Vec<u64>> = None;
with_default_type.unwrap_or_default();

let empty_string = None::<String>;
empty_string.unwrap_or_default();
}

fn main() {}
3 changes: 3 additions & 0 deletions tests/ui/unwrap_or_else_default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ fn unwrap_or_else_default() {

let with_default_type: Option<Vec<u64>> = None;
with_default_type.unwrap_or_else(Vec::new);

let empty_string = None::<String>;
empty_string.unwrap_or_else(|| "".to_string());
}

fn main() {}
8 changes: 7 additions & 1 deletion tests/ui/unwrap_or_else_default.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,11 @@ error: use of `.unwrap_or_else(..)` to construct default value
LL | with_default_type.unwrap_or_else(Vec::new);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `with_default_type.unwrap_or_default()`

error: aborting due to 5 previous errors
error: use of `.unwrap_or_else(..)` to construct default value
--> $DIR/unwrap_or_else_default.rs:74:5
|
LL | empty_string.unwrap_or_else(|| "".to_string());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `empty_string.unwrap_or_default()`

error: aborting due to 6 previous errors

0 comments on commit 7babd1b

Please sign in to comment.