diff --git a/clippy_lints/src/matches/manual_unwrap_or.rs b/clippy_lints/src/matches/manual_unwrap_or.rs index 0940fc321..85a08f81c 100644 --- a/clippy_lints/src/matches/manual_unwrap_or.rs +++ b/clippy_lints/src/matches/manual_unwrap_or.rs @@ -35,6 +35,17 @@ pub(super) fn check_if_let<'tcx>( else_expr: &'tcx Expr<'_>, ) { let ty = cx.typeck_results().expr_ty(let_expr); + let then_ty = cx.typeck_results().expr_ty(then_expr); + // The signature is `fn unwrap_or(self: Option, default: T) -> T`. + // When `expr_adjustments(then_expr).is_empty()`, `T` should equate to `default`'s type. + // Otherwise, type error will occur. + if cx.typeck_results().expr_adjustments(then_expr).is_empty() + && let rustc_middle::ty::Adt(_did, args) = ty.kind() + && let Some(some_ty) = args.first().and_then(|arg| arg.as_type()) + && some_ty != then_ty + { + return; + } check_and_lint(cx, expr, let_pat, let_expr, then_expr, peel_blocks(else_expr), ty); } diff --git a/tests/ui/manual_unwrap_or.fixed b/tests/ui/manual_unwrap_or.fixed index 2899c3518..07e4bdd48 100644 --- a/tests/ui/manual_unwrap_or.fixed +++ b/tests/ui/manual_unwrap_or.fixed @@ -239,7 +239,14 @@ mod issue_13018 { type RefName = i32; pub fn get(index: &HashMap>, id: usize) -> &[RefName] { - index.get(&id).unwrap_or(&[]) + if let Some(names) = index.get(&id) { names } else { &[] } + } + + pub fn get_match(index: &HashMap>, id: usize) -> &[RefName] { + match index.get(&id) { + Some(names) => names, + None => &[], + } } } diff --git a/tests/ui/manual_unwrap_or.rs b/tests/ui/manual_unwrap_or.rs index e2c04b01e..cdbe51a41 100644 --- a/tests/ui/manual_unwrap_or.rs +++ b/tests/ui/manual_unwrap_or.rs @@ -289,10 +289,13 @@ mod issue_13018 { type RefName = i32; pub fn get(index: &HashMap>, id: usize) -> &[RefName] { - if let Some(names) = index.get(&id) { - names - } else { - &[] + if let Some(names) = index.get(&id) { names } else { &[] } + } + + pub fn get_match(index: &HashMap>, id: usize) -> &[RefName] { + match index.get(&id) { + Some(names) => names, + None => &[], } } } diff --git a/tests/ui/manual_unwrap_or.stderr b/tests/ui/manual_unwrap_or.stderr index 28b59df16..c93a8952a 100644 --- a/tests/ui/manual_unwrap_or.stderr +++ b/tests/ui/manual_unwrap_or.stderr @@ -172,15 +172,5 @@ LL | | None => 0, LL | | }; | |_________^ help: replace with: `some_macro!().unwrap_or(0)` -error: this pattern reimplements `Option::unwrap_or` - --> tests/ui/manual_unwrap_or.rs:292:9 - | -LL | / if let Some(names) = index.get(&id) { -LL | | names -LL | | } else { -LL | | &[] -LL | | } - | |_________^ help: replace with: `index.get(&id).unwrap_or(&[])` - -error: aborting due to 17 previous errors +error: aborting due to 16 previous errors