Don't lint explicit_auto_deref when the initial type is neither a reference, nor a receiver

This commit is contained in:
Jason Newcomb 2022-11-30 11:15:49 -05:00
parent 78589ffad2
commit 2d32b40359
3 changed files with 19 additions and 6 deletions

View File

@ -289,23 +289,24 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
let (position, adjustments) = walk_parents(cx, &mut self.possible_borrowers, expr, &self.msrv);
match kind {
RefOp::Deref => {
let sub_ty = typeck.expr_ty(sub_expr);
if let Position::FieldAccess {
name,
of_union: false,
} = position
&& !ty_contains_field(typeck.expr_ty(sub_expr), name)
&& !ty_contains_field(sub_ty, name)
{
self.state = Some((
State::ExplicitDerefField { name },
StateData { span: expr.span, hir_id: expr.hir_id, position },
));
} else if position.is_deref_stable() {
} else if position.is_deref_stable() && sub_ty.is_ref() {
self.state = Some((
State::ExplicitDeref { mutability: None },
StateData { span: expr.span, hir_id: expr.hir_id, position },
));
}
}
},
RefOp::Method(target_mut)
if !is_lint_allowed(cx, EXPLICIT_DEREF_METHODS, expr.hir_id)
&& position.lint_explicit_deref() =>
@ -320,7 +321,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
StateData {
span: expr.span,
hir_id: expr.hir_id,
position
position,
},
));
},
@ -394,7 +395,11 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
msg,
snip_expr,
}),
StateData { span: expr.span, hir_id: expr.hir_id, position },
StateData {
span: expr.span,
hir_id: expr.hir_id,
position,
},
));
} else if position.is_deref_stable()
// Auto-deref doesn't combine with other adjustments
@ -406,7 +411,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
StateData {
span: expr.span,
hir_id: expr.hir_id,
position
position,
},
));
}

View File

@ -277,4 +277,8 @@ fn main() {
unimplemented!()
}
let _: String = takes_assoc(&*String::new());
// Issue #9901
fn takes_ref(_: &i32) {}
takes_ref(*Box::new(&0i32));
}

View File

@ -277,4 +277,8 @@ fn takes_assoc<T: WithAssoc>(_: &T::Assoc) -> T {
unimplemented!()
}
let _: String = takes_assoc(&*String::new());
// Issue #9901
fn takes_ref(_: &i32) {}
takes_ref(*Box::new(&0i32));
}