about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEzra Shaw <ezrasure@outlook.com>2023-01-18 13:14:56 +1300
committerEzra Shaw <ezrasure@outlook.com>2023-01-18 13:14:56 +1300
commitb73cdf1b29d25d3c6d0cc4f8a7744b08930e86ee (patch)
treea3bdc4dc6325dff8a8b5b26cb2a70fca101ac6ed
parentca1178f02237fd84649a30b74052da4ef265371f (diff)
downloadrust-b73cdf1b29d25d3c6d0cc4f8a7744b08930e86ee.tar.gz
rust-b73cdf1b29d25d3c6d0cc4f8a7744b08930e86ee.zip
special case removing `&` suggestion
-rw-r--r--compiler/rustc_hir/src/hir.rs8
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs24
-rw-r--r--tests/ui/error-codes/E0606.rs3
-rw-r--r--tests/ui/error-codes/E0606.stderr22
4 files changed, 45 insertions, 12 deletions
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 60f5b79de10..5e59475a7bd 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -1787,6 +1787,14 @@ impl Expr<'_> {
         expr
     }
 
+    pub fn peel_borrows(&self) -> &Self {
+        let mut expr = self;
+        while let ExprKind::AddrOf(.., inner) = &expr.kind {
+            expr = inner;
+        }
+        expr
+    }
+
     pub fn can_have_side_effects(&self) -> bool {
         match self.peel_drop_temps().kind {
             ExprKind::Path(_) | ExprKind::Lit(_) => false,
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index b312a3d30af..712f9b87aed 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -31,6 +31,7 @@
 use super::FnCtxt;
 
 use crate::type_error_struct;
+use hir::ExprKind;
 use rustc_errors::{
     struct_span_err, Applicability, DelayDm, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
 };
@@ -237,12 +238,23 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                     fcx,
                 );
 
-                err.span_suggestion_verbose(
-                    self.expr_span.shrink_to_lo(),
-                    "dereference the expression",
-                    "*",
-                    Applicability::MachineApplicable,
-                );
+                if matches!(self.expr.kind, ExprKind::AddrOf(..)) {
+                    // get just the borrow part of the expression
+                    let span = self.expr_span.with_hi(self.expr.peel_borrows().span.lo());
+                    err.span_suggestion_verbose(
+                        span,
+                        "remove the unneeded borrow",
+                        "",
+                        Applicability::MachineApplicable,
+                    );
+                } else {
+                    err.span_suggestion_verbose(
+                        self.expr_span.shrink_to_lo(),
+                        "dereference the expression",
+                        "*",
+                        Applicability::MachineApplicable,
+                    );
+                }
 
                 err.emit();
             }
diff --git a/tests/ui/error-codes/E0606.rs b/tests/ui/error-codes/E0606.rs
index cb0d8cfc31e..6f6c6513846 100644
--- a/tests/ui/error-codes/E0606.rs
+++ b/tests/ui/error-codes/E0606.rs
@@ -1,3 +1,4 @@
 fn main() {
-    &0u8 as u8; //~ ERROR E0606
+    let x = &(&0u8 as u8); //~ ERROR E0606
+    x as u8; //~ casting `&u8` as `u8` is invalid [E0606]
 }
diff --git a/tests/ui/error-codes/E0606.stderr b/tests/ui/error-codes/E0606.stderr
index 586b1f2fd54..2492eb299cc 100644
--- a/tests/ui/error-codes/E0606.stderr
+++ b/tests/ui/error-codes/E0606.stderr
@@ -1,14 +1,26 @@
 error[E0606]: casting `&u8` as `u8` is invalid
-  --> $DIR/E0606.rs:2:5
+  --> $DIR/E0606.rs:2:14
    |
-LL |     &0u8 as u8;
-   |     ^^^^^^^^^^
+LL |     let x = &(&0u8 as u8);
+   |              ^^^^^^^^^^^^
+   |
+help: remove the unneeded borrow
+   |
+LL -     let x = &(&0u8 as u8);
+LL +     let x = &(0u8 as u8);
+   |
+
+error[E0606]: casting `&u8` as `u8` is invalid
+  --> $DIR/E0606.rs:3:5
+   |
+LL |     x as u8;
+   |     ^^^^^^^
    |
 help: dereference the expression
    |
-LL |     *&0u8 as u8;
+LL |     *x as u8;
    |     +
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0606`.