Fix incorrect suggestions for E0605
This commit is contained in:
parent
bacf770f29
commit
71d1b2a009
7 changed files with 74 additions and 17 deletions
|
|
@ -35,6 +35,7 @@ use crate::type_error_struct;
|
|||
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorReported};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_middle::mir::Mutability;
|
||||
use rustc_middle::ty::adjustment::AllowTwoPhase;
|
||||
use rustc_middle::ty::cast::{CastKind, CastTy};
|
||||
use rustc_middle::ty::error::TypeError;
|
||||
|
|
@ -347,15 +348,52 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||
fcx.ty_to_string(self.cast_ty)
|
||||
);
|
||||
let mut sugg = None;
|
||||
let mut sugg_mutref = false;
|
||||
if let ty::Ref(reg, _, mutbl) = *self.cast_ty.kind() {
|
||||
if fcx
|
||||
.try_coerce(
|
||||
self.expr,
|
||||
fcx.tcx.mk_ref(reg, TypeAndMut { ty: self.expr_ty, mutbl }),
|
||||
self.cast_ty,
|
||||
AllowTwoPhase::No,
|
||||
)
|
||||
.is_ok()
|
||||
if let ty::RawPtr(TypeAndMut { ty: expr_ty, .. }) = *self.expr_ty.kind() {
|
||||
if fcx
|
||||
.try_coerce(
|
||||
self.expr,
|
||||
fcx.tcx.mk_ref(
|
||||
&ty::RegionKind::ReErased,
|
||||
TypeAndMut { ty: expr_ty, mutbl },
|
||||
),
|
||||
self.cast_ty,
|
||||
AllowTwoPhase::No,
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
sugg = Some(format!("&{}*", mutbl.prefix_str()));
|
||||
}
|
||||
} else if let ty::Ref(expr_reg, expr_ty, expr_mutbl) = *self.expr_ty.kind() {
|
||||
if expr_mutbl == Mutability::Not
|
||||
&& mutbl == Mutability::Mut
|
||||
&& fcx
|
||||
.try_coerce(
|
||||
self.expr,
|
||||
fcx.tcx.mk_ref(
|
||||
expr_reg,
|
||||
TypeAndMut { ty: expr_ty, mutbl: Mutability::Mut },
|
||||
),
|
||||
self.cast_ty,
|
||||
AllowTwoPhase::No,
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
sugg_mutref = true;
|
||||
}
|
||||
}
|
||||
|
||||
if !sugg_mutref
|
||||
&& sugg == None
|
||||
&& fcx
|
||||
.try_coerce(
|
||||
self.expr,
|
||||
fcx.tcx.mk_ref(reg, TypeAndMut { ty: self.expr_ty, mutbl }),
|
||||
self.cast_ty,
|
||||
AllowTwoPhase::No,
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
sugg = Some(format!("&{}", mutbl.prefix_str()));
|
||||
}
|
||||
|
|
@ -375,11 +413,15 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||
sugg = Some(format!("&{}", mutbl.prefix_str()));
|
||||
}
|
||||
}
|
||||
if let Some(sugg) = sugg {
|
||||
if sugg_mutref {
|
||||
err.span_label(self.span, "invalid cast");
|
||||
err.span_note(self.expr.span, "this reference is immutable");
|
||||
err.span_note(self.cast_span, "trying to cast to a mutable reference type");
|
||||
} else if let Some(sugg) = sugg {
|
||||
err.span_label(self.span, "invalid cast");
|
||||
err.span_suggestion_verbose(
|
||||
self.expr.span.shrink_to_lo(),
|
||||
"borrow the value for the cast to be valid",
|
||||
"consider borrowing the value",
|
||||
sugg,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ error[E0605]: non-primitive cast: `Something` as `*const Something`
|
|||
LL | let _pointer_to_something = something as *const Something;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid cast
|
||||
|
|
||||
help: borrow the value for the cast to be valid
|
||||
help: consider borrowing the value
|
||||
|
|
||||
LL | let _pointer_to_something = &something as *const Something;
|
||||
| ^
|
||||
|
|
@ -15,7 +15,7 @@ error[E0605]: non-primitive cast: `Something` as `*mut Something`
|
|||
LL | let _mut_pointer_to_something = something as *mut Something;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid cast
|
||||
|
|
||||
help: borrow the value for the cast to be valid
|
||||
help: consider borrowing the value
|
||||
|
|
||||
LL | let _mut_pointer_to_something = &mut something as *mut Something;
|
||||
| ^^^^
|
||||
|
|
|
|||
|
|
@ -8,7 +8,12 @@ error[E0605]: non-primitive cast: `*const u8` as `&u8`
|
|||
--> $DIR/E0605.rs:6:5
|
||||
|
|
||||
LL | v as &u8;
|
||||
| ^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
|
||||
| ^^^^^^^^ invalid cast
|
||||
|
|
||||
help: consider borrowing the value
|
||||
|
|
||||
LL | &*v as &u8;
|
||||
| ^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ error[E0605]: non-primitive cast: `i32` as `&(dyn Any + 'static)`
|
|||
LL | 0 as &dyn std::any::Any;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ invalid cast
|
||||
|
|
||||
help: borrow the value for the cast to be valid
|
||||
help: consider borrowing the value
|
||||
|
|
||||
LL | &0 as &dyn std::any::Any;
|
||||
| ^
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ error[E0605]: non-primitive cast: `Self` as `&dyn Index<usize, Output = <Self as
|
|||
LL | let indexer = &(*self as &dyn Index<usize, Output = <Self as Index<usize>>::Output>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid cast
|
||||
|
|
||||
help: borrow the value for the cast to be valid
|
||||
help: consider borrowing the value
|
||||
|
|
||||
LL | let indexer = &(&*self as &dyn Index<usize, Output = <Self as Index<usize>>::Output>);
|
||||
| ^
|
||||
|
|
|
|||
|
|
@ -2,7 +2,12 @@ error[E0605]: non-primitive cast: `*const isize` as `&isize`
|
|||
--> $DIR/issue-2995.rs:2:22
|
||||
|
|
||||
LL | let _q: &isize = p as &isize;
|
||||
| ^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
|
||||
| ^^^^^^^^^^^ invalid cast
|
||||
|
|
||||
help: consider borrowing the value
|
||||
|
|
||||
LL | let _q: &isize = &*p as &isize;
|
||||
| ^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,12 @@ error[E0605]: non-primitive cast: `*const u8` as `&u8`
|
|||
--> $DIR/cast-rfc0401.rs:29:13
|
||||
|
|
||||
LL | let _ = v as &u8;
|
||||
| ^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
|
||||
| ^^^^^^^^ invalid cast
|
||||
|
|
||||
help: consider borrowing the value
|
||||
|
|
||||
LL | let _ = &*v as &u8;
|
||||
| ^^
|
||||
|
||||
error[E0605]: non-primitive cast: `*const u8` as `E`
|
||||
--> $DIR/cast-rfc0401.rs:30:13
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue