Skip to content

Commit 90ec92f

Browse files
committed
fix: map_unwrap_or suggests wrongly for empty slice
1 parent 6375703 commit 90ec92f

File tree

3 files changed

+24
-2
lines changed

3 files changed

+24
-2
lines changed

clippy_lints/src/methods/map_unwrap_or.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ pub(super) fn check<'tcx>(
3636

3737
// lint if the caller of `map()` is an `Option`
3838
if is_option || is_result {
39-
if !is_copy(cx, cx.typeck_results().expr_ty(unwrap_arg)) {
39+
let unwrap_arg_ty = cx.typeck_results().expr_ty(unwrap_arg);
40+
if !is_copy(cx, unwrap_arg_ty) {
4041
// Replacing `.map(<f>).unwrap_or(<a>)` with `.map_or(<a>, <f>)` can sometimes lead to
4142
// borrowck errors, see #10579 for one such instance.
4243
// In particular, if `a` causes a move and `f` references that moved binding, then we cannot lint:
@@ -124,6 +125,13 @@ pub(super) fn check<'tcx>(
124125
} else if suggest_is_some_and {
125126
if is_result { "is_ok_and" } else { "is_some_and" }
126127
} else {
128+
let unwrap_arg_ty = unwrap_arg_ty.peel_refs();
129+
if unwrap_arg_ty.is_array()
130+
&& let unwrap_arg_ty_adj = cx.typeck_results().expr_ty_adjusted(unwrap_arg).peel_refs()
131+
&& unwrap_arg_ty_adj.is_slice()
132+
{
133+
return;
134+
}
127135
"map_or"
128136
}),
129137
),

tests/ui/map_unwrap_or.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,3 +156,11 @@ mod issue_10579 {
156156
println!("{y:?}");
157157
}
158158
}
159+
160+
fn issue15752() {
161+
struct Foo<'a>(&'a [u32]);
162+
163+
let x = Some(Foo(&[1, 2, 3]));
164+
x.map(|y| y.0).unwrap_or(&[]);
165+
//~^ map_unwrap_or
166+
}

tests/ui/map_unwrap_or.stderr

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,5 +199,11 @@ LL - let _ = opt.map(|x| x > 5).unwrap_or(false);
199199
LL + let _ = opt.is_some_and(|x| x > 5);
200200
|
201201

202-
error: aborting due to 15 previous errors
202+
error: called `map(<f>).unwrap_or(<a>)` on an `Option` value
203+
--> tests/ui/map_unwrap_or.rs:164:5
204+
|
205+
LL | x.map(|y| y.0).unwrap_or(&[]);
206+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
207+
208+
error: aborting due to 16 previous errors
203209

0 commit comments

Comments
 (0)