Skip to content

Commit 7449d63

Browse files
committed
fix(or_fun_call): respect MSRV for Result::unwrap_or_default suggestion
1 parent 5317b7b commit 7449d63

File tree

8 files changed

+72
-6
lines changed

8 files changed

+72
-6
lines changed

book/src/lint_configuration.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -883,6 +883,7 @@ The minimum rust version that the project supports. Defaults to the `rust-versio
883883
* [`needless_borrow`](https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow)
884884
* [`non_std_lazy_statics`](https://rust-lang.github.io/rust-clippy/master/index.html#non_std_lazy_statics)
885885
* [`option_as_ref_deref`](https://rust-lang.github.io/rust-clippy/master/index.html#option_as_ref_deref)
886+
* [`or_fun_call`](https://rust-lang.github.io/rust-clippy/master/index.html#or_fun_call)
886887
* [`ptr_as_ptr`](https://rust-lang.github.io/rust-clippy/master/index.html#ptr_as_ptr)
887888
* [`question_mark`](https://rust-lang.github.io/rust-clippy/master/index.html#question_mark)
888889
* [`redundant_field_names`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_field_names)

clippy_config/src/conf.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,7 @@ define_Conf! {
779779
needless_borrow,
780780
non_std_lazy_statics,
781781
option_as_ref_deref,
782+
or_fun_call,
782783
ptr_as_ptr,
783784
question_mark,
784785
redundant_field_names,

clippy_lints/src/methods/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4854,7 +4854,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
48544854
},
48554855
ExprKind::MethodCall(method_call, receiver, args, _) => {
48564856
let method_span = method_call.ident.span;
4857-
or_fun_call::check(cx, expr, method_span, method_call.ident.name, receiver, args);
4857+
or_fun_call::check(cx, expr, method_span, method_call.ident.name, receiver, args, self.msrv);
48584858
expect_fun_call::check(
48594859
cx,
48604860
&self.format_args,

clippy_lints/src/methods/or_fun_call.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::ops::ControlFlow;
33
use clippy_utils::diagnostics::span_lint_and_sugg;
44
use clippy_utils::eager_or_lazy::switch_to_lazy_eval;
55
use clippy_utils::higher::VecArgs;
6+
use clippy_utils::msrvs::{self, Msrv};
67
use clippy_utils::source::snippet_with_context;
78
use clippy_utils::ty::{expr_type_is_certain, implements_trait, is_type_diagnostic_item};
89
use clippy_utils::visitors::for_each_expr;
@@ -25,6 +26,7 @@ pub(super) fn check<'tcx>(
2526
name: Symbol,
2627
receiver: &'tcx hir::Expr<'_>,
2728
args: &'tcx [hir::Expr<'_>],
29+
msrv: Msrv,
2830
) {
2931
if let [arg] = args {
3032
let inner_arg = peel_blocks(arg);
@@ -45,11 +47,11 @@ pub(super) fn check<'tcx>(
4547
};
4648
(!inner_fun_has_args
4749
&& !is_nested_expr
48-
&& check_unwrap_or_default(cx, name, receiver, fun, Some(ex), expr.span, method_span))
50+
&& check_unwrap_or_default(cx, name, receiver, fun, Some(ex), expr.span, method_span, msrv))
4951
|| check_or_fn_call(cx, name, method_span, receiver, arg, None, expr.span, fun_span)
5052
},
5153
hir::ExprKind::Path(..) | hir::ExprKind::Closure(..) if !is_nested_expr => {
52-
check_unwrap_or_default(cx, name, receiver, ex, None, expr.span, method_span)
54+
check_unwrap_or_default(cx, name, receiver, ex, None, expr.span, method_span, msrv)
5355
},
5456
hir::ExprKind::Index(..) | hir::ExprKind::MethodCall(..) => {
5557
check_or_fn_call(cx, name, method_span, receiver, arg, None, expr.span, None)
@@ -97,6 +99,7 @@ pub(super) fn check<'tcx>(
9799
/// `or_insert(T::new())` or `or_insert(T::default())`.
98100
/// Similarly checks for `unwrap_or_else(T::new)`, `unwrap_or_else(T::default)`,
99101
/// `or_insert_with(T::new)` or `or_insert_with(T::default)`.
102+
#[expect(clippy::too_many_arguments)]
100103
fn check_unwrap_or_default(
101104
cx: &LateContext<'_>,
102105
name: Symbol,
@@ -105,7 +108,15 @@ fn check_unwrap_or_default(
105108
call_expr: Option<&hir::Expr<'_>>,
106109
span: Span,
107110
method_span: Span,
111+
msrv: Msrv,
108112
) -> bool {
113+
let receiver_ty = cx.typeck_results().expr_ty_adjusted(receiver).peel_refs();
114+
115+
// Check MSRV, but only for `Result::unwrap_or_default`
116+
if is_type_diagnostic_item(cx, receiver_ty, sym::Result) && !msrv.meets(cx, msrvs::RESULT_UNWRAP_OR_DEFAULT) {
117+
return false;
118+
}
119+
109120
if !expr_type_is_certain(cx, receiver) {
110121
return false;
111122
}
@@ -137,7 +148,6 @@ fn check_unwrap_or_default(
137148
_ => return false,
138149
};
139150

140-
let receiver_ty = cx.typeck_results().expr_ty_adjusted(receiver).peel_refs();
141151
let Some(suggested_method_def_id) = receiver_ty.ty_adt_def().and_then(|adt_def| {
142152
cx.tcx
143153
.inherent_impls(adt_def.did())

clippy_utils/src/msrvs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ msrv_aliases! {
7777
1,24,0 { IS_ASCII_DIGIT, PTR_NULL }
7878
1,18,0 { HASH_MAP_RETAIN, HASH_SET_RETAIN }
7979
1,17,0 { FIELD_INIT_SHORTHAND, STATIC_IN_CONST, EXPECT_ERR }
80-
1,16,0 { STR_REPEAT }
80+
1,16,0 { STR_REPEAT, RESULT_UNWRAP_OR_DEFAULT }
8181
1,15,0 { MAYBE_BOUND_IN_WHERE }
8282
1,13,0 { QUESTION_MARK_OPERATOR }
8383
}

tests/ui/or_fun_call.fixed

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,4 +478,19 @@ fn test_result_and() {
478478
//~^ or_fun_call
479479
}
480480

481+
#[clippy::msrv = "1.15"]
482+
fn below_msrv(opt: Option<i32>, res: Result<i32, ()>) {
483+
let _ = opt.unwrap_or_default();
484+
//~^ unwrap_or_default
485+
let _ = res.unwrap_or_else(|_| Default::default());
486+
//~^ or_fun_call
487+
}
488+
489+
#[clippy::msrv = "1.16"]
490+
fn above_msrv(opt: Option<i32>, res: Result<i32, ()>) {
491+
let _ = opt.unwrap_or_default();
492+
//~^ unwrap_or_default
493+
let _ = res.unwrap_or_default();
494+
//~^ unwrap_or_default
495+
}
481496
fn main() {}

tests/ui/or_fun_call.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,4 +478,19 @@ fn test_result_and() {
478478
//~^ or_fun_call
479479
}
480480

481+
#[clippy::msrv = "1.15"]
482+
fn below_msrv(opt: Option<i32>, res: Result<i32, ()>) {
483+
let _ = opt.unwrap_or(Default::default());
484+
//~^ unwrap_or_default
485+
let _ = res.unwrap_or(Default::default());
486+
//~^ or_fun_call
487+
}
488+
489+
#[clippy::msrv = "1.16"]
490+
fn above_msrv(opt: Option<i32>, res: Result<i32, ()>) {
491+
let _ = opt.unwrap_or(Default::default());
492+
//~^ unwrap_or_default
493+
let _ = res.unwrap_or(Default::default());
494+
//~^ unwrap_or_default
495+
}
481496
fn main() {}

tests/ui/or_fun_call.stderr

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,5 +288,29 @@ error: function call inside of `and`
288288
LL | let _ = x.and(g());
289289
| ^^^^^^^^ help: try: `and_then(|_| g())`
290290

291-
error: aborting due to 45 previous errors
291+
error: use of `unwrap_or` to construct default value
292+
--> tests/ui/or_fun_call.rs:483:17
293+
|
294+
LL | let _ = opt.unwrap_or(Default::default());
295+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
296+
297+
error: function call inside of `unwrap_or`
298+
--> tests/ui/or_fun_call.rs:485:17
299+
|
300+
LL | let _ = res.unwrap_or(Default::default());
301+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|_| Default::default())`
302+
303+
error: use of `unwrap_or` to construct default value
304+
--> tests/ui/or_fun_call.rs:491:17
305+
|
306+
LL | let _ = opt.unwrap_or(Default::default());
307+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
308+
309+
error: use of `unwrap_or` to construct default value
310+
--> tests/ui/or_fun_call.rs:493:17
311+
|
312+
LL | let _ = res.unwrap_or(Default::default());
313+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
314+
315+
error: aborting due to 49 previous errors
292316

0 commit comments

Comments
 (0)