about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-11-14 21:50:39 +0100
committerGitHub <noreply@github.com>2023-11-14 21:50:39 +0100
commit52f3a6fdb2586f61acd47be005d7fd46d93a20c1 (patch)
tree5ef3ffdc2113740f640b189b9a473d6b122ac86c
parent7435887d6ca027c031a40df8857fb625c09faa05 (diff)
parent614ddc969595c412d8db7657e21678283b664d42 (diff)
downloadrust-52f3a6fdb2586f61acd47be005d7fd46d93a20c1.tar.gz
rust-52f3a6fdb2586f61acd47be005d7fd46d93a20c1.zip
Rollup merge of #117893 - sjwang05:issue-52544-take-1, r=wesleywiser
Suggest dereferencing the LHS for binops such as `&T == T`

Fixes #52544
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs60
-rw-r--r--tests/ui/binop/binary-op-suggest-deref.fixed8
-rw-r--r--tests/ui/binop/binary-op-suggest-deref.rs8
-rw-r--r--tests/ui/binop/binary-op-suggest-deref.stderr14
4 files changed, 71 insertions, 19 deletions
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index c43d4932fb9..2e0ab1560f4 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -2326,14 +2326,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         ));
                     }
 
-                    let needs_parens = match expr.kind {
-                        // parenthesize if needed (Issue #46756)
-                        hir::ExprKind::Cast(_, _) | hir::ExprKind::Binary(_, _, _) => true,
-                        // parenthesize borrows of range literals (Issue #54505)
-                        _ if is_range_literal(expr) => true,
-                        _ => false,
-                    };
-
                     if let Some((sugg, msg)) = self.can_use_as_ref(expr) {
                         return Some((
                             sugg,
@@ -2361,18 +2353,48 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         }
                     }
 
-                    let sugg = mutability.ref_prefix_str();
-                    let (sugg, verbose) = if needs_parens {
-                        (
-                            vec![
-                                (sp.shrink_to_lo(), format!("{prefix}{sugg}(")),
-                                (sp.shrink_to_hi(), ")".to_string()),
-                            ],
-                            false,
-                        )
-                    } else {
-                        (vec![(sp.shrink_to_lo(), format!("{prefix}{sugg}"))], true)
+                    let make_sugg = |expr: &Expr<'_>, span: Span, sugg: &str| {
+                        let needs_parens = match expr.kind {
+                            // parenthesize if needed (Issue #46756)
+                            hir::ExprKind::Cast(_, _) | hir::ExprKind::Binary(_, _, _) => true,
+                            // parenthesize borrows of range literals (Issue #54505)
+                            _ if is_range_literal(expr) => true,
+                            _ => false,
+                        };
+
+                        if needs_parens {
+                            (
+                                vec![
+                                    (span.shrink_to_lo(), format!("{prefix}{sugg}(")),
+                                    (span.shrink_to_hi(), ")".to_string()),
+                                ],
+                                false,
+                            )
+                        } else {
+                            (vec![(span.shrink_to_lo(), format!("{prefix}{sugg}"))], true)
+                        }
                     };
+
+                    // Suggest dereferencing the lhs for expressions such as `&T == T`
+                    if let Some(hir::Node::Expr(hir::Expr {
+                        kind: hir::ExprKind::Binary(_, lhs, ..),
+                        ..
+                    })) = self.tcx.hir().find_parent(expr.hir_id)
+                        && let &ty::Ref(..) = self.check_expr(lhs).kind()
+                    {
+                        let (sugg, verbose) = make_sugg(lhs, lhs.span, "*");
+
+                        return Some((
+                            sugg,
+                            "consider dereferencing the borrow".to_string(),
+                            Applicability::MachineApplicable,
+                            verbose,
+                            false,
+                        ));
+                    }
+
+                    let sugg = mutability.ref_prefix_str();
+                    let (sugg, verbose) = make_sugg(expr, sp, sugg);
                     return Some((
                         sugg,
                         format!("consider {}borrowing here", mutability.mutably_str()),
diff --git a/tests/ui/binop/binary-op-suggest-deref.fixed b/tests/ui/binop/binary-op-suggest-deref.fixed
new file mode 100644
index 00000000000..1ff3599137b
--- /dev/null
+++ b/tests/ui/binop/binary-op-suggest-deref.fixed
@@ -0,0 +1,8 @@
+// Issue #52544
+// run-rustfix
+
+fn main() {
+    let i: &i64 = &1;
+    if *i < 0 {}
+    //~^ ERROR mismatched types [E0308]
+}
diff --git a/tests/ui/binop/binary-op-suggest-deref.rs b/tests/ui/binop/binary-op-suggest-deref.rs
new file mode 100644
index 00000000000..12505a9ac27
--- /dev/null
+++ b/tests/ui/binop/binary-op-suggest-deref.rs
@@ -0,0 +1,8 @@
+// Issue #52544
+// run-rustfix
+
+fn main() {
+    let i: &i64 = &1;
+    if i < 0 {}
+    //~^ ERROR mismatched types [E0308]
+}
diff --git a/tests/ui/binop/binary-op-suggest-deref.stderr b/tests/ui/binop/binary-op-suggest-deref.stderr
new file mode 100644
index 00000000000..1b7e45c7724
--- /dev/null
+++ b/tests/ui/binop/binary-op-suggest-deref.stderr
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+  --> $DIR/binary-op-suggest-deref.rs:6:12
+   |
+LL |     if i < 0 {}
+   |            ^ expected `&i64`, found integer
+   |
+help: consider dereferencing the borrow
+   |
+LL |     if *i < 0 {}
+   |        +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.