Skip to content

Commit 74c40db

Browse files
committed
Fix 13018: self should be T
with `Option::unwrap_or(self, T) -> T`.
1 parent e864519 commit 74c40db

File tree

4 files changed

+27
-16
lines changed

4 files changed

+27
-16
lines changed

clippy_lints/src/matches/manual_unwrap_or.rs

+11
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,17 @@ pub(super) fn check_if_let<'tcx>(
3535
else_expr: &'tcx Expr<'_>,
3636
) {
3737
let ty = cx.typeck_results().expr_ty(let_expr);
38+
let then_ty = cx.typeck_results().expr_ty(then_expr);
39+
// The signatue of `Option::unwrap_or` is `unwrap_or(self, default: T) -> T`.
40+
// In case of `expr_adjustments().is_empty()`, `self` should be `T`.
41+
// FIXME: Could we use some helpers from `dereference::Dereferencing`?
42+
if cx.typeck_results().expr_adjustments(then_expr).is_empty()
43+
&& let rustc_middle::ty::Adt(_did, args) = ty.kind()
44+
&& let Some(some_ty) = args.first().and_then(|arg| arg.as_type())
45+
&& some_ty != then_ty
46+
{
47+
return;
48+
}
3849
check_and_lint(cx, expr, let_pat, let_expr, then_expr, peel_blocks(else_expr), ty);
3950
}
4051

tests/ui/manual_unwrap_or.fixed

+8-1
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,14 @@ mod issue_13018 {
239239

240240
type RefName = i32;
241241
pub fn get(index: &HashMap<usize, Vec<RefName>>, id: usize) -> &[RefName] {
242-
index.get(&id).unwrap_or(&[])
242+
if let Some(names) = index.get(&id) { names } else { &[] }
243+
}
244+
245+
pub fn get_match(index: &HashMap<usize, Vec<RefName>>, id: usize) -> &[RefName] {
246+
match index.get(&id) {
247+
Some(names) => names,
248+
None => &[],
249+
}
243250
}
244251
}
245252

tests/ui/manual_unwrap_or.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -289,10 +289,13 @@ mod issue_13018 {
289289

290290
type RefName = i32;
291291
pub fn get(index: &HashMap<usize, Vec<RefName>>, id: usize) -> &[RefName] {
292-
if let Some(names) = index.get(&id) {
293-
names
294-
} else {
295-
&[]
292+
if let Some(names) = index.get(&id) { names } else { &[] }
293+
}
294+
295+
pub fn get_match(index: &HashMap<usize, Vec<RefName>>, id: usize) -> &[RefName] {
296+
match index.get(&id) {
297+
Some(names) => names,
298+
None => &[],
296299
}
297300
}
298301
}

tests/ui/manual_unwrap_or.stderr

+1-11
Original file line numberDiff line numberDiff line change
@@ -172,15 +172,5 @@ LL | | None => 0,
172172
LL | | };
173173
| |_________^ help: replace with: `some_macro!().unwrap_or(0)`
174174

175-
error: this pattern reimplements `Option::unwrap_or`
176-
--> tests/ui/manual_unwrap_or.rs:292:9
177-
|
178-
LL | / if let Some(names) = index.get(&id) {
179-
LL | | names
180-
LL | | } else {
181-
LL | | &[]
182-
LL | | }
183-
| |_________^ help: replace with: `index.get(&id).unwrap_or(&[])`
184-
185-
error: aborting due to 17 previous errors
175+
error: aborting due to 16 previous errors
186176

0 commit comments

Comments
 (0)