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.
This commit is contained in:
Samuel Tardieu 2025-01-28 00:03:00 +01:00
parent 83bde363b6
commit 16e2196fc2
3 changed files with 23 additions and 6 deletions

View file

@ -55,12 +55,19 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, call_name: &str,
let (base_res_ty, res_depth) = walk_ptrs_ty_depth(res_ty);
let (base_rcv_ty, rcv_depth) = walk_ptrs_ty_depth(rcv_ty);
if base_rcv_ty == base_res_ty && rcv_depth >= res_depth {
// allow the `as_ref` or `as_mut` if it is followed by another method call
if let Some(parent) = get_parent_expr(cx, expr)
&& let hir::ExprKind::MethodCall(segment, ..) = parent.kind
&& segment.ident.span != expr.span
{
return;
if let Some(parent) = get_parent_expr(cx, expr) {
// allow the `as_ref` or `as_mut` if it is followed by another method call
if let hir::ExprKind::MethodCall(segment, ..) = parent.kind
&& segment.ident.span != expr.span
{
return;
}
// allow the `as_ref` or `as_mut` if they belong to a closure that changes
// the number of references
if matches!(parent.kind, hir::ExprKind::Closure(..)) && rcv_depth != res_depth {
return;
}
}
let mut applicability = Applicability::MachineApplicable;

View file

@ -198,6 +198,11 @@ fn issue_12528() {
let _ = opt.as_ref().map(RcWeak::clone);
}
fn issue_14088() {
let s = Some("foo");
let _: Option<&str> = s.as_ref().map(|x| x.as_ref());
}
fn main() {
not_ok();
ok();

View file

@ -198,6 +198,11 @@ fn issue_12528() {
let _ = opt.as_ref().map(RcWeak::clone);
}
fn issue_14088() {
let s = Some("foo");
let _: Option<&str> = s.as_ref().map(|x| x.as_ref());
}
fn main() {
not_ok();
ok();