Skip to content

Commit 8e8fe61

Browse files
authored
Introduce helper functions for Some(x)/None patterns and expressions (#15930)
Reduces boilerplate a bit changelog: none
2 parents 31d8210 + 605cc87 commit 8e8fe61

18 files changed

+127
-142
lines changed

clippy_lints/src/if_then_some_else_none.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@ use clippy_config::Conf;
22
use clippy_utils::diagnostics::span_lint_and_then;
33
use clippy_utils::eager_or_lazy::switch_to_eager_eval;
44
use clippy_utils::msrvs::{self, Msrv};
5-
use clippy_utils::res::{MaybeDef, MaybeQPath};
65
use clippy_utils::source::{snippet_with_applicability, snippet_with_context, walk_span_to_context};
76
use clippy_utils::sugg::Sugg;
87
use clippy_utils::{
9-
contains_return, expr_adjustment_requires_coercion, higher, is_else_clause, is_in_const_context, peel_blocks, sym,
8+
as_some_expr, contains_return, expr_adjustment_requires_coercion, higher, is_else_clause, is_in_const_context,
9+
is_none_expr, peel_blocks, sym,
1010
};
1111
use rustc_errors::Applicability;
12-
use rustc_hir::LangItem::{OptionNone, OptionSome};
1312
use rustc_hir::{Expr, ExprKind};
1413
use rustc_lint::{LateContext, LateLintPass};
1514
use rustc_session::impl_lint_pass;
@@ -70,11 +69,10 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone {
7069
}) = higher::If::hir(expr)
7170
&& let ExprKind::Block(then_block, _) = then.kind
7271
&& let Some(then_expr) = then_block.expr
73-
&& let ExprKind::Call(then_call, [then_arg]) = then_expr.kind
72+
&& let Some(then_arg) = as_some_expr(cx, then_expr)
7473
&& !expr.span.from_expansion()
7574
&& !then_expr.span.from_expansion()
76-
&& then_call.res(cx).ctor_parent(cx).is_lang_item(cx, OptionSome)
77-
&& peel_blocks(els).res(cx).ctor_parent(cx).is_lang_item(cx, OptionNone)
75+
&& is_none_expr(cx, peel_blocks(els))
7876
&& !is_else_clause(cx.tcx, expr)
7977
&& !is_in_const_context(cx)
8078
&& self.msrv.meets(cx, msrvs::BOOL_THEN)

clippy_lints/src/loops/manual_find.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use clippy_utils::res::{MaybeDef, MaybeQPath, MaybeResPath};
55
use clippy_utils::source::snippet_with_applicability;
66
use clippy_utils::ty::implements_trait;
77
use clippy_utils::usage::contains_return_break_continue_macro;
8-
use clippy_utils::{higher, peel_blocks_with_stmt};
8+
use clippy_utils::{as_some_expr, higher, peel_blocks_with_stmt};
99
use rustc_errors::Applicability;
1010
use rustc_hir::lang_items::LangItem;
1111
use rustc_hir::{BindingMode, Block, Expr, ExprKind, HirId, Node, Pat, PatKind, Stmt, StmtKind};
@@ -33,8 +33,7 @@ pub(super) fn check<'tcx>(
3333
&& let [stmt] = block.stmts
3434
&& let StmtKind::Semi(semi) = stmt.kind
3535
&& let ExprKind::Ret(Some(ret_value)) = semi.kind
36-
&& let ExprKind::Call(ctor, [inner_ret]) = ret_value.kind
37-
&& ctor.res(cx).ctor_parent(cx).is_lang_item(cx, LangItem::OptionSome)
36+
&& let Some(inner_ret) = as_some_expr(cx, ret_value)
3837
&& inner_ret.res_local_id() == Some(binding_id)
3938
&& !contains_return_break_continue_macro(cond)
4039
&& let Some((last_stmt, last_ret)) = last_stmt_and_ret(cx, expr)

clippy_lints/src/loops/while_let_on_iterator.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
55
use clippy_utils::res::{MaybeDef, MaybeTypeckRes};
66
use clippy_utils::source::snippet_with_applicability;
77
use clippy_utils::visitors::is_res_used;
8-
use clippy_utils::{get_enclosing_loop_or_multi_call_closure, higher, is_refutable};
8+
use clippy_utils::{as_some_pattern, get_enclosing_loop_or_multi_call_closure, higher, is_refutable};
99
use rustc_errors::Applicability;
1010
use rustc_hir::def::Res;
1111
use rustc_hir::intravisit::{Visitor, walk_expr};
12-
use rustc_hir::{Closure, Expr, ExprKind, HirId, LangItem, LetStmt, Mutability, PatKind, UnOp};
12+
use rustc_hir::{Closure, Expr, ExprKind, HirId, LetStmt, Mutability, UnOp};
1313
use rustc_lint::LateContext;
1414
use rustc_middle::hir::nested_filter::OnlyBodies;
1515
use rustc_middle::ty::adjustment::Adjust;
@@ -19,8 +19,7 @@ use rustc_span::symbol::sym;
1919
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
2020
if let Some(higher::WhileLet { if_then, let_pat, let_expr, label, .. }) = higher::WhileLet::hir(expr)
2121
// check for `Some(..)` pattern
22-
&& let PatKind::TupleStruct(ref pat_path, some_pat, _) = let_pat.kind
23-
&& cx.qpath_res(pat_path, let_pat.hir_id).ctor_parent(cx).is_lang_item(cx, LangItem::OptionSome)
22+
&& let Some(some_pat) = as_some_pattern(cx, let_pat)
2423
// check for call to `Iterator::next`
2524
&& let ExprKind::MethodCall(method_name, iter_expr, [], _) = let_expr.kind
2625
&& method_name.ident.name == sym::next

clippy_lints/src/manual_option_as_slice.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@ use clippy_utils::diagnostics::span_lint_and_then;
33
use clippy_utils::msrvs::Msrv;
44
use clippy_utils::res::{MaybeDef, MaybeQPath, MaybeResPath};
55
use clippy_utils::source::snippet_with_context;
6-
use clippy_utils::{is_none_pattern, msrvs, peel_hir_expr_refs, sym};
6+
use clippy_utils::{as_some_pattern, is_none_pattern, msrvs, peel_hir_expr_refs, sym};
77
use rustc_errors::Applicability;
8-
use rustc_hir::def::{DefKind, Res};
9-
use rustc_hir::{Arm, Expr, ExprKind, LangItem, Pat, PatKind, QPath, is_range_literal};
8+
use rustc_hir::{Arm, Expr, ExprKind, Pat, PatKind, QPath, is_range_literal};
109
use rustc_lint::{LateContext, LateLintPass};
1110
use rustc_session::impl_lint_pass;
1211
use rustc_span::{Span, Symbol};
@@ -154,10 +153,8 @@ fn check_as_ref(cx: &LateContext<'_>, expr: &Expr<'_>, span: Span, msrv: Msrv) {
154153
}
155154

156155
fn extract_ident_from_some_pat(cx: &LateContext<'_>, pat: &Pat<'_>) -> Option<Symbol> {
157-
if let PatKind::TupleStruct(QPath::Resolved(None, path), [binding], _) = pat.kind
158-
&& let Res::Def(DefKind::Ctor(..), def_id) = path.res
156+
if let Some([binding]) = as_some_pattern(cx, pat)
159157
&& let PatKind::Binding(_mode, _hir_id, ident, _inner_pat) = binding.kind
160-
&& clippy_utils::is_lang_item_or_ctor(cx, def_id, LangItem::OptionSome)
161158
{
162159
Some(ident.name)
163160
} else {

clippy_lints/src/match_result_ok.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
22
use clippy_utils::res::MaybeDef;
33
use clippy_utils::source::snippet_with_context;
4-
use clippy_utils::{higher, sym};
4+
use clippy_utils::{as_some_pattern, higher, sym};
55
use rustc_errors::Applicability;
6-
use rustc_hir::{Expr, ExprKind, LangItem, PatKind};
6+
use rustc_hir::{Expr, ExprKind};
77
use rustc_lint::{LateContext, LateLintPass};
88
use rustc_session::declare_lint_pass;
99

@@ -55,10 +55,9 @@ impl<'tcx> LateLintPass<'tcx> for MatchResultOk {
5555
};
5656

5757
if let ExprKind::MethodCall(ok_path, recv, [], ..) = let_expr.kind //check is expr.ok() has type Result<T,E>.ok(, _)
58-
&& let PatKind::TupleStruct(ref pat_path, [ok_pat], _) = let_pat.kind //get operation
5958
&& ok_path.ident.name == sym::ok
6059
&& cx.typeck_results().expr_ty(recv).is_diag_item(cx, sym::Result)
61-
&& cx.qpath_res(pat_path, let_pat.hir_id).ctor_parent(cx).is_lang_item(cx, LangItem::OptionSome)
60+
&& let Some([ok_pat]) = as_some_pattern(cx, let_pat) //get operation
6261
&& let ctxt = expr.span.ctxt()
6362
&& let_expr.span.ctxt() == ctxt
6463
&& let_pat.span.ctxt() == ctxt

clippy_lints/src/matches/manual_filter.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
use clippy_utils::as_some_expr;
12
use clippy_utils::diagnostics::span_lint_and_sugg;
23
use clippy_utils::res::{MaybeDef, MaybeQPath, MaybeResPath};
34
use clippy_utils::visitors::contains_unsafe_block;
45

5-
use rustc_hir::LangItem::{OptionNone, OptionSome};
6+
use rustc_hir::LangItem::OptionNone;
67
use rustc_hir::{Arm, Expr, ExprKind, HirId, Pat, PatKind};
78
use rustc_lint::LateContext;
89
use rustc_span::{SyntaxContext, sym};
@@ -52,21 +53,19 @@ fn peels_blocks_incl_unsafe<'a>(expr: &'a Expr<'a>) -> &'a Expr<'a> {
5253
peels_blocks_incl_unsafe_opt(expr).unwrap_or(expr)
5354
}
5455

55-
// function called for each <expr> expression:
56+
/// Checks whether <expr> resolves to `Some(target)`
57+
// NOTE: called for each <expr> expression:
5658
// Some(x) => if <cond> {
5759
// <expr>
5860
// } else {
5961
// <expr>
6062
// }
61-
// Returns true if <expr> resolves to `Some(x)`, `false` otherwise
6263
fn is_some_expr(cx: &LateContext<'_>, target: HirId, ctxt: SyntaxContext, expr: &Expr<'_>) -> bool {
6364
if let Some(inner_expr) = peels_blocks_incl_unsafe_opt(expr)
6465
// there can be not statements in the block as they would be removed when switching to `.filter`
65-
&& let ExprKind::Call(callee, [arg]) = inner_expr.kind
66+
&& let Some(arg) = as_some_expr(cx, inner_expr)
6667
{
67-
return ctxt == expr.span.ctxt()
68-
&& callee.res(cx).ctor_parent(cx).is_lang_item(cx, OptionSome)
69-
&& arg.res_local_id() == Some(target);
68+
return ctxt == expr.span.ctxt() && arg.res_local_id() == Some(target);
7069
}
7170
false
7271
}

clippy_lints/src/matches/manual_ok_err.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
2-
use clippy_utils::res::{MaybeDef, MaybeQPath};
2+
use clippy_utils::res::MaybeDef;
33
use clippy_utils::source::{indent_of, reindent_multiline};
44
use clippy_utils::sugg::Sugg;
55
use clippy_utils::ty::{option_arg_ty, peel_and_count_ty_refs};
6-
use clippy_utils::{get_parent_expr, peel_blocks, span_contains_comment};
6+
use clippy_utils::{as_some_expr, get_parent_expr, is_none_expr, peel_blocks, span_contains_comment};
77
use rustc_ast::{BindingMode, Mutability};
88
use rustc_errors::Applicability;
9-
use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr};
9+
use rustc_hir::LangItem::ResultErr;
1010
use rustc_hir::def::{DefKind, Res};
1111
use rustc_hir::{Arm, Expr, ExprKind, Pat, PatExpr, PatExprKind, PatKind, Path, QPath};
1212
use rustc_lint::{LateContext, LintContext};
@@ -106,8 +106,7 @@ fn is_ok_or_err<'hir>(cx: &LateContext<'_>, pat: &Pat<'hir>) -> Option<(bool, &'
106106

107107
/// Check if `expr` contains `Some(ident)`, possibly as a block
108108
fn is_some_ident<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, ident: &Ident, ty: Ty<'tcx>) -> bool {
109-
if let ExprKind::Call(body_callee, [body_arg]) = peel_blocks(expr).kind
110-
&& body_callee.res(cx).ctor_parent(cx).is_lang_item(cx, OptionSome)
109+
if let Some(body_arg) = as_some_expr(cx, peel_blocks(expr))
111110
&& cx.typeck_results().expr_ty(body_arg) == ty
112111
&& let ExprKind::Path(QPath::Resolved(
113112
_,
@@ -124,7 +123,7 @@ fn is_some_ident<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, ident: &Ident, t
124123

125124
/// Check if `expr` is `None`, possibly as a block
126125
fn is_none(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
127-
peel_blocks(expr).res(cx).ctor_parent(cx).is_lang_item(cx, OptionNone)
126+
is_none_expr(cx, peel_blocks(expr))
128127
}
129128

130129
/// Suggest replacing `expr` by `scrutinee.METHOD()`, where `METHOD` is either `ok` or

clippy_lints/src/matches/manual_utils.rs

Lines changed: 14 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
use crate::map_unit_fn::OPTION_MAP_UNIT_FN;
22
use crate::matches::MATCH_AS_REF;
3-
use clippy_utils::res::{MaybeDef, MaybeQPath, MaybeResPath};
3+
use clippy_utils::res::{MaybeDef, MaybeResPath};
44
use clippy_utils::source::{snippet_with_applicability, snippet_with_context};
55
use clippy_utils::sugg::Sugg;
66
use clippy_utils::ty::{is_copy, is_unsafe_fn, peel_and_count_ty_refs};
77
use clippy_utils::{
8-
CaptureKind, can_move_expr_to_closure, expr_requires_coercion, is_else_clause, is_lint_allowed, peel_blocks,
9-
peel_hir_expr_refs, peel_hir_expr_while,
8+
CaptureKind, as_some_pattern, can_move_expr_to_closure, expr_requires_coercion, is_else_clause, is_lint_allowed,
9+
is_none_expr, is_none_pattern, peel_blocks, peel_hir_expr_refs, peel_hir_expr_while,
1010
};
1111
use rustc_ast::util::parser::ExprPrecedence;
1212
use rustc_errors::Applicability;
13-
use rustc_hir::LangItem::{OptionNone, OptionSome};
1413
use rustc_hir::def::Res;
15-
use rustc_hir::{BindingMode, Expr, ExprKind, HirId, Mutability, Pat, PatExpr, PatExprKind, PatKind, Path, QPath};
14+
use rustc_hir::{BindingMode, Expr, ExprKind, HirId, Mutability, Pat, PatKind, Path, QPath};
1615
use rustc_lint::LateContext;
1716
use rustc_span::{SyntaxContext, sym};
1817

@@ -44,16 +43,16 @@ where
4443
try_parse_pattern(cx, then_pat, expr_ctxt),
4544
else_pat.map_or(Some(OptionPat::Wild), |p| try_parse_pattern(cx, p, expr_ctxt)),
4645
) {
47-
(Some(OptionPat::Wild), Some(OptionPat::Some { pattern, ref_count })) if is_none_expr(cx, then_body) => {
46+
(Some(OptionPat::Wild), Some(OptionPat::Some { pattern, ref_count })) if is_none_arm_body(cx, then_body) => {
4847
(else_body, pattern, ref_count, true)
4948
},
50-
(Some(OptionPat::None), Some(OptionPat::Some { pattern, ref_count })) if is_none_expr(cx, then_body) => {
49+
(Some(OptionPat::None), Some(OptionPat::Some { pattern, ref_count })) if is_none_arm_body(cx, then_body) => {
5150
(else_body, pattern, ref_count, false)
5251
},
53-
(Some(OptionPat::Some { pattern, ref_count }), Some(OptionPat::Wild)) if is_none_expr(cx, else_body) => {
52+
(Some(OptionPat::Some { pattern, ref_count }), Some(OptionPat::Wild)) if is_none_arm_body(cx, else_body) => {
5453
(then_body, pattern, ref_count, true)
5554
},
56-
(Some(OptionPat::Some { pattern, ref_count }), Some(OptionPat::None)) if is_none_expr(cx, else_body) => {
55+
(Some(OptionPat::Some { pattern, ref_count }), Some(OptionPat::None)) if is_none_arm_body(cx, else_body) => {
5756
(then_body, pattern, ref_count, false)
5857
},
5958
_ => return None,
@@ -255,23 +254,9 @@ pub(super) fn try_parse_pattern<'tcx>(
255254
match pat.kind {
256255
PatKind::Wild => Some(OptionPat::Wild),
257256
PatKind::Ref(pat, _) => f(cx, pat, ref_count + 1, ctxt),
258-
PatKind::Expr(PatExpr {
259-
kind: PatExprKind::Path(qpath),
260-
hir_id,
261-
..
262-
}) if cx
263-
.qpath_res(qpath, *hir_id)
264-
.ctor_parent(cx)
265-
.is_lang_item(cx, OptionNone) =>
266-
{
267-
Some(OptionPat::None)
268-
},
269-
PatKind::TupleStruct(ref qpath, [pattern], _)
270-
if cx
271-
.qpath_res(qpath, pat.hir_id)
272-
.ctor_parent(cx)
273-
.is_lang_item(cx, OptionSome)
274-
&& pat.span.ctxt() == ctxt =>
257+
_ if is_none_pattern(cx, pat) => Some(OptionPat::None),
258+
_ if let Some([pattern]) = as_some_pattern(cx, pat)
259+
&& pat.span.ctxt() == ctxt =>
275260
{
276261
Some(OptionPat::Some { pattern, ref_count })
277262
},
@@ -281,7 +266,7 @@ pub(super) fn try_parse_pattern<'tcx>(
281266
f(cx, pat, 0, ctxt)
282267
}
283268

284-
// Checks for the `None` value.
285-
fn is_none_expr(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
286-
peel_blocks(expr).res(cx).ctor_parent(cx).is_lang_item(cx, OptionNone)
269+
/// Checks for the `None` value, possibly in a block.
270+
fn is_none_arm_body(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
271+
is_none_expr(cx, peel_blocks(expr))
287272
}

clippy_lints/src/matches/match_as_ref.rs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
use clippy_utils::diagnostics::span_lint_and_then;
2-
use clippy_utils::res::{MaybeDef, MaybeQPath};
32
use clippy_utils::sugg::Sugg;
43
use clippy_utils::ty::option_arg_ty;
5-
use clippy_utils::{is_none_arm, peel_blocks};
4+
use clippy_utils::{as_some_expr, as_some_pattern, is_none_arm, peel_blocks};
65
use rustc_errors::Applicability;
7-
use rustc_hir::{Arm, BindingMode, ByRef, Expr, ExprKind, LangItem, Mutability, PatKind, QPath};
6+
use rustc_hir::{Arm, BindingMode, ByRef, Expr, ExprKind, Mutability, PatKind, QPath};
87
use rustc_lint::LateContext;
98
use rustc_middle::ty;
109

@@ -82,14 +81,9 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr:
8281

8382
// Checks if arm has the form `Some(ref v) => Some(v)` (checks for `ref` and `ref mut`)
8483
fn as_ref_some_arm(cx: &LateContext<'_>, arm: &Arm<'_>) -> Option<Mutability> {
85-
if let PatKind::TupleStruct(ref qpath, [first_pat, ..], _) = arm.pat.kind
86-
&& cx
87-
.qpath_res(qpath, arm.pat.hir_id)
88-
.ctor_parent(cx)
89-
.is_lang_item(cx, LangItem::OptionSome)
84+
if let Some([first_pat, ..]) = as_some_pattern(cx, arm.pat)
9085
&& let PatKind::Binding(BindingMode(ByRef::Yes(mutabl), _), .., ident, _) = first_pat.kind
91-
&& let ExprKind::Call(e, [arg]) = peel_blocks(arm.body).kind
92-
&& e.res(cx).ctor_parent(cx).is_lang_item(cx, LangItem::OptionSome)
86+
&& let Some(arg) = as_some_expr(cx, peel_blocks(arm.body))
9387
&& let ExprKind::Path(QPath::Resolved(_, path2)) = arg.kind
9488
&& path2.segments.len() == 1
9589
&& ident.name == path2.segments[0].ident.name

clippy_lints/src/mem_replace.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
use clippy_config::Conf;
22
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg, span_lint_and_then};
33
use clippy_utils::msrvs::{self, Msrv};
4-
use clippy_utils::res::{MaybeDef, MaybeQPath};
4+
use clippy_utils::res::MaybeDef;
55
use clippy_utils::source::{snippet_with_applicability, snippet_with_context};
66
use clippy_utils::sugg::Sugg;
77
use clippy_utils::ty::is_non_aggregate_primitive_type;
8-
use clippy_utils::{is_default_equivalent, is_expr_used_or_unified, peel_ref_operators, std_or_core};
8+
use clippy_utils::{
9+
as_some_expr, is_default_equivalent, is_expr_used_or_unified, is_none_expr, peel_ref_operators, std_or_core,
10+
};
911
use rustc_errors::Applicability;
10-
use rustc_hir::LangItem::{OptionNone, OptionSome};
1112
use rustc_hir::{Expr, ExprKind};
1213
use rustc_lint::{LateContext, LateLintPass};
1314
use rustc_session::impl_lint_pass;
@@ -128,7 +129,7 @@ impl_lint_pass!(MemReplace =>
128129
[MEM_REPLACE_OPTION_WITH_NONE, MEM_REPLACE_OPTION_WITH_SOME, MEM_REPLACE_WITH_UNINIT, MEM_REPLACE_WITH_DEFAULT]);
129130

130131
fn check_replace_option_with_none(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<'_>, expr_span: Span) -> bool {
131-
if src.res(cx).ctor_parent(cx).is_lang_item(cx, OptionNone) {
132+
if is_none_expr(cx, src) {
132133
// Since this is a late pass (already type-checked),
133134
// and we already know that the second argument is an
134135
// `Option`, we do not need to check the first
@@ -161,8 +162,7 @@ fn check_replace_option_with_some(
161162
expr_span: Span,
162163
msrv: Msrv,
163164
) -> bool {
164-
if let ExprKind::Call(src_func, [src_arg]) = src.kind
165-
&& src_func.res(cx).ctor_parent(cx).is_lang_item(cx, OptionSome)
165+
if let Some(src_arg) = as_some_expr(cx, src)
166166
&& msrv.meets(cx, msrvs::OPTION_REPLACE)
167167
{
168168
// We do not have to check for a `const` context here, because `core::mem::replace()` and

0 commit comments

Comments
 (0)