Skip to content

Commit 16e2196

Browse files
committed
useless_asref: no lint if in a closure to change the ref depth
Removing the `.as_ref()` or `.as_mut()` as the top-level expression in a closure may change the type of the result. In this case, it may be better not to lint rather than proposing a fix that would not work.
1 parent 83bde36 commit 16e2196

File tree

3 files changed

+23
-6
lines changed

3 files changed

+23
-6
lines changed

clippy_lints/src/methods/useless_asref.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,19 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, call_name: &str,
5555
let (base_res_ty, res_depth) = walk_ptrs_ty_depth(res_ty);
5656
let (base_rcv_ty, rcv_depth) = walk_ptrs_ty_depth(rcv_ty);
5757
if base_rcv_ty == base_res_ty && rcv_depth >= res_depth {
58-
// allow the `as_ref` or `as_mut` if it is followed by another method call
59-
if let Some(parent) = get_parent_expr(cx, expr)
60-
&& let hir::ExprKind::MethodCall(segment, ..) = parent.kind
61-
&& segment.ident.span != expr.span
62-
{
63-
return;
58+
if let Some(parent) = get_parent_expr(cx, expr) {
59+
// allow the `as_ref` or `as_mut` if it is followed by another method call
60+
if let hir::ExprKind::MethodCall(segment, ..) = parent.kind
61+
&& segment.ident.span != expr.span
62+
{
63+
return;
64+
}
65+
66+
// allow the `as_ref` or `as_mut` if they belong to a closure that changes
67+
// the number of references
68+
if matches!(parent.kind, hir::ExprKind::Closure(..)) && rcv_depth != res_depth {
69+
return;
70+
}
6471
}
6572

6673
let mut applicability = Applicability::MachineApplicable;

tests/ui/useless_asref.fixed

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,11 @@ fn issue_12528() {
198198
let _ = opt.as_ref().map(RcWeak::clone);
199199
}
200200

201+
fn issue_14088() {
202+
let s = Some("foo");
203+
let _: Option<&str> = s.as_ref().map(|x| x.as_ref());
204+
}
205+
201206
fn main() {
202207
not_ok();
203208
ok();

tests/ui/useless_asref.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,11 @@ fn issue_12528() {
198198
let _ = opt.as_ref().map(RcWeak::clone);
199199
}
200200

201+
fn issue_14088() {
202+
let s = Some("foo");
203+
let _: Option<&str> = s.as_ref().map(|x| x.as_ref());
204+
}
205+
201206
fn main() {
202207
not_ok();
203208
ok();

0 commit comments

Comments
 (0)