summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2023-01-19 11:19:34 +0100
committerGitHub <noreply@github.com>2023-01-19 11:19:34 +0100
commit1a878df2b8d92c702548cb00bcf47b0af8176a97 (patch)
tree35474cd09e777d00750216bcce2ca93d96460db2
parent30ddeefcf09023b5924844bd3a2ac7573c60faf8 (diff)
parentb73cdf1b29d25d3c6d0cc4f8a7744b08930e86ee (diff)
downloadrust-1a878df2b8d92c702548cb00bcf47b0af8176a97.tar.gz
Rollup merge of #106927 - Ezrashaw:e0606-make-machine-applicable, r=estebank
make `CastError::NeedsDeref` create a `MachineApplicable` suggestion Fixes #106903 Simple impl for the linked issue. I also made some other small changes: - `CastError::ErrorGuaranteed` now owns an actual `ErrorGuaranteed`. This better enforces the static guarantees of `ErrorGuaranteed`. - `CastError::NeedDeref` code simplified a bit, we now just suggest the `*`, instead of the whole expression as well.
-rw-r--r--compiler/rustc_hir/src/hir.rs8
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs38
-rw-r--r--tests/ui/error-codes/E0606.rs3
-rw-r--r--tests/ui/error-codes/E0606.stderr28
-rw-r--r--tests/ui/error-festival.stderr10
-rw-r--r--tests/ui/mismatched_types/cast-rfc0401.stderr10
6 files changed, 64 insertions, 33 deletions
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 56f0e0b3e7d..d6566860f81 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 0a230fca107..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,
};
@@ -151,7 +152,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
#[derive(Copy, Clone)]
pub enum CastError {
- ErrorGuaranteed,
+ ErrorGuaranteed(ErrorGuaranteed),
CastToBool,
CastToChar,
@@ -176,8 +177,8 @@ pub enum CastError {
}
impl From<ErrorGuaranteed> for CastError {
- fn from(_: ErrorGuaranteed) -> Self {
- CastError::ErrorGuaranteed
+ fn from(err: ErrorGuaranteed) -> Self {
+ CastError::ErrorGuaranteed(err)
}
}
@@ -225,11 +226,10 @@ impl<'a, 'tcx> CastCheck<'tcx> {
fn report_cast_error(&self, fcx: &FnCtxt<'a, 'tcx>, e: CastError) {
match e {
- CastError::ErrorGuaranteed => {
+ CastError::ErrorGuaranteed(_) => {
// an error has already been reported
}
CastError::NeedDeref => {
- let error_span = self.span;
let mut err = make_invalid_casting_error(
fcx.tcx.sess,
self.span,
@@ -237,21 +237,25 @@ impl<'a, 'tcx> CastCheck<'tcx> {
self.cast_ty,
fcx,
);
- let cast_ty = fcx.ty_to_string(self.cast_ty);
- err.span_label(
- error_span,
- format!("cannot cast `{}` as `{}`", fcx.ty_to_string(self.expr_ty), cast_ty),
- );
- if let Ok(snippet) = fcx.sess().source_map().span_to_snippet(self.expr_span) {
- err.span_suggestion(
- self.expr_span,
- "dereference the expression",
- format!("*{}", snippet),
- Applicability::MaybeIncorrect,
+
+ 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_help(self.expr_span, "dereference the expression with `*`");
+ err.span_suggestion_verbose(
+ self.expr_span.shrink_to_lo(),
+ "dereference the expression",
+ "*",
+ Applicability::MachineApplicable,
+ );
}
+
err.emit();
}
CastError::NeedViaThinPtr | CastError::NeedViaPtr => {
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 fce24886eb0..2492eb299cc 100644
--- a/tests/ui/error-codes/E0606.stderr
+++ b/tests/ui/error-codes/E0606.stderr
@@ -1,12 +1,26 @@
error[E0606]: casting `&u8` as `u8` is invalid
- --> $DIR/E0606.rs:2:5
+ --> $DIR/E0606.rs:2:14
|
-LL | &0u8 as u8;
- | ----^^^^^^
- | |
- | cannot cast `&u8` as `u8`
- | help: dereference the expression: `*&0u8`
+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 | *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`.
diff --git a/tests/ui/error-festival.stderr b/tests/ui/error-festival.stderr
index fe9956b70bd..e8ee1d96942 100644
--- a/tests/ui/error-festival.stderr
+++ b/tests/ui/error-festival.stderr
@@ -69,10 +69,12 @@ error[E0606]: casting `&u8` as `u32` is invalid
--> $DIR/error-festival.rs:37:18
|
LL | let y: u32 = x as u32;
- | -^^^^^^^
- | |
- | cannot cast `&u8` as `u32`
- | help: dereference the expression: `*x`
+ | ^^^^^^^^
+ |
+help: dereference the expression
+ |
+LL | let y: u32 = *x as u32;
+ | +
error[E0607]: cannot cast thin pointer `*const u8` to fat pointer `*const [u8]`
--> $DIR/error-festival.rs:41:5
diff --git a/tests/ui/mismatched_types/cast-rfc0401.stderr b/tests/ui/mismatched_types/cast-rfc0401.stderr
index eab8e8e80c4..2a36a352c73 100644
--- a/tests/ui/mismatched_types/cast-rfc0401.stderr
+++ b/tests/ui/mismatched_types/cast-rfc0401.stderr
@@ -243,10 +243,12 @@ error[E0606]: casting `&{float}` as `f32` is invalid
--> $DIR/cast-rfc0401.rs:71:30
|
LL | vec![0.0].iter().map(|s| s as f32).collect::<Vec<f32>>();
- | -^^^^^^^
- | |
- | cannot cast `&{float}` as `f32`
- | help: dereference the expression: `*s`
+ | ^^^^^^^^
+ |
+help: dereference the expression
+ |
+LL | vec![0.0].iter().map(|s| *s as f32).collect::<Vec<f32>>();
+ | +
error: aborting due to 34 previous errors