Only apply dereference-removing special case for actual references

This commit is contained in:
Jakub Beránek 2024-07-12 13:04:35 +02:00
parent 062b66d45c
commit e9852cc7c9
No known key found for this signature in database
GPG key ID: 909CD0D26483516B
4 changed files with 222 additions and 29 deletions

View file

@ -227,9 +227,22 @@ fn build_sugg<'tcx>(
match call_kind {
CallKind::Method => {
let receiver_sugg = if let ExprKind::Unary(hir::UnOp::Deref, ref_expr) = lhs.kind {
// `*lhs = self_expr.clone();` -> `lhs.clone_from(self_expr)`
Sugg::hir_with_applicability(cx, ref_expr, "_", app)
// If `ref_expr` is a reference, we can remove the dereference operator (`*`) to make
// the generated code a bit simpler. In other cases, we don't do this special case, to avoid
// having to deal with Deref (https://github.com/rust-lang/rust-clippy/issues/12437).
let ty = cx.typeck_results().expr_ty(ref_expr);
if ty.is_ref() {
// Apply special case, remove `*`
// `*lhs = self_expr.clone();` -> `lhs.clone_from(self_expr)`
Sugg::hir_with_applicability(cx, ref_expr, "_", app)
} else {
// Keep the original lhs
// `*lhs = self_expr.clone();` -> `(*lhs).clone_from(self_expr)`
Sugg::hir_with_applicability(cx, lhs, "_", app)
}
} else {
// Keep the original lhs
// `lhs = self_expr.clone();` -> `lhs.clone_from(self_expr)`
Sugg::hir_with_applicability(cx, lhs, "_", app)
}
@ -249,8 +262,16 @@ fn build_sugg<'tcx>(
},
CallKind::Ufcs => {
let self_sugg = if let ExprKind::Unary(hir::UnOp::Deref, ref_expr) = lhs.kind {
// `*lhs = Clone::clone(self_expr);` -> `Clone::clone_from(lhs, self_expr)`
Sugg::hir_with_applicability(cx, ref_expr, "_", app)
// See special case of removing `*` in method handling above
let ty = cx.typeck_results().expr_ty(ref_expr);
if ty.is_ref() {
// `*lhs = Clone::clone(self_expr);` -> `Clone::clone_from(lhs, self_expr)`
Sugg::hir_with_applicability(cx, ref_expr, "_", app)
} else {
// `*lhs = Clone::clone(self_expr);` -> `Clone::clone_from(&mut *lhs, self_expr)`
// mut_addr_deref is used to avoid unnecessary parentheses around `*lhs`
Sugg::hir_with_applicability(cx, ref_expr, "_", app).mut_addr_deref()
}
} else {
// `lhs = Clone::clone(self_expr);` -> `Clone::clone_from(&mut lhs, self_expr)`
Sugg::hir_with_applicability(cx, lhs, "_", app).mut_addr()