better suggestion for int to wide ptr cast
This commit is contained in:
parent
458262b131
commit
814c18a6dc
5 changed files with 86 additions and 14 deletions
|
@ -165,6 +165,12 @@ pub enum CastError {
|
||||||
NonScalar,
|
NonScalar,
|
||||||
UnknownExprPtrKind,
|
UnknownExprPtrKind,
|
||||||
UnknownCastPtrKind,
|
UnknownCastPtrKind,
|
||||||
|
/// Cast of int to (possibly) fat raw pointer.
|
||||||
|
///
|
||||||
|
/// Argument is the specific name of the metadata in plain words, such as "a vtable"
|
||||||
|
/// or "a length". If this argument is None, then the metadata is unknown, for example,
|
||||||
|
/// when we're typechecking a type parameter with a ?Sized bound.
|
||||||
|
IntToFatCast(Option<&'static str>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ErrorGuaranteed> for CastError {
|
impl From<ErrorGuaranteed> for CastError {
|
||||||
|
@ -522,6 +528,35 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
||||||
.diagnostic()
|
.diagnostic()
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
|
CastError::IntToFatCast(known_metadata) => {
|
||||||
|
let mut err = struct_span_err!(
|
||||||
|
fcx.tcx.sess,
|
||||||
|
self.cast_span,
|
||||||
|
E0606,
|
||||||
|
"cannot cast `{}` to a pointer that {} wide",
|
||||||
|
fcx.ty_to_string(self.expr_ty),
|
||||||
|
if known_metadata.is_some() { "is" } else { "may be" }
|
||||||
|
);
|
||||||
|
|
||||||
|
err.span_label(
|
||||||
|
self.cast_span,
|
||||||
|
format!(
|
||||||
|
"creating a `{}` requires both an address and {}",
|
||||||
|
self.cast_ty,
|
||||||
|
known_metadata.unwrap_or("type-specific metadata"),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
if fcx.tcx.sess.is_nightly_build() {
|
||||||
|
err.span_label(
|
||||||
|
self.expr.span,
|
||||||
|
"consider casting this expression to `*const ()`, \
|
||||||
|
then using `core::ptr::from_raw_parts`",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
err.emit();
|
||||||
|
}
|
||||||
CastError::UnknownCastPtrKind | CastError::UnknownExprPtrKind => {
|
CastError::UnknownCastPtrKind | CastError::UnknownExprPtrKind => {
|
||||||
let unknown_cast_to = match e {
|
let unknown_cast_to = match e {
|
||||||
CastError::UnknownCastPtrKind => true,
|
CastError::UnknownCastPtrKind => true,
|
||||||
|
@ -900,7 +935,13 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
||||||
match fcx.pointer_kind(m_cast.ty, self.span)? {
|
match fcx.pointer_kind(m_cast.ty, self.span)? {
|
||||||
None => Err(CastError::UnknownCastPtrKind),
|
None => Err(CastError::UnknownCastPtrKind),
|
||||||
Some(PointerKind::Thin) => Ok(CastKind::AddrPtrCast),
|
Some(PointerKind::Thin) => Ok(CastKind::AddrPtrCast),
|
||||||
_ => Err(CastError::IllegalCast),
|
Some(PointerKind::Vtable(_)) => Err(CastError::IntToFatCast(Some("a vtable"))),
|
||||||
|
Some(PointerKind::Length) => Err(CastError::IntToFatCast(Some("a length"))),
|
||||||
|
Some(
|
||||||
|
PointerKind::OfProjection(_)
|
||||||
|
| PointerKind::OfOpaque(_, _)
|
||||||
|
| PointerKind::OfParam(_),
|
||||||
|
) => Err(CastError::IntToFatCast(None)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,15 @@ fn main() {
|
||||||
q as *const [i32]; //~ ERROR cannot cast
|
q as *const [i32]; //~ ERROR cannot cast
|
||||||
|
|
||||||
// #21397
|
// #21397
|
||||||
let t: *mut (dyn Trait + 'static) = 0 as *mut _; //~ ERROR casting
|
let t: *mut (dyn Trait + 'static) = 0 as *mut _;
|
||||||
let mut fail: *const str = 0 as *const str; //~ ERROR casting
|
//~^ ERROR cannot cast `usize` to a pointer that is wide
|
||||||
|
let mut fail: *const str = 0 as *const str;
|
||||||
|
//~^ ERROR cannot cast `usize` to a pointer that is wide
|
||||||
|
let mut fail2: *const str = 0isize as *const str;
|
||||||
|
//~^ ERROR cannot cast `isize` to a pointer that is wide
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo<T: ?Sized>() {
|
||||||
|
let s = 0 as *const T;
|
||||||
|
//~^ ERROR cannot cast `usize` to a pointer that may be wide
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,19 +50,39 @@ error[E0607]: cannot cast thin pointer `*const i32` to fat pointer `*const [i32]
|
||||||
LL | q as *const [i32];
|
LL | q as *const [i32];
|
||||||
| ^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0606]: casting `usize` as `*mut (dyn Trait + 'static)` is invalid
|
error[E0606]: cannot cast `usize` to a pointer that is wide
|
||||||
--> $DIR/fat-ptr-cast.rs:22:41
|
--> $DIR/fat-ptr-cast.rs:22:46
|
||||||
|
|
|
|
||||||
LL | let t: *mut (dyn Trait + 'static) = 0 as *mut _;
|
LL | let t: *mut (dyn Trait + 'static) = 0 as *mut _;
|
||||||
| ^^^^^^^^^^^
|
| - ^^^^^^ creating a `*mut (dyn Trait + 'static)` requires both an address and a vtable
|
||||||
|
| |
|
||||||
|
| consider casting this expression to `*const ()`, then using `core::ptr::from_raw_parts`
|
||||||
|
|
||||||
error[E0606]: casting `usize` as `*const str` is invalid
|
error[E0606]: cannot cast `usize` to a pointer that is wide
|
||||||
--> $DIR/fat-ptr-cast.rs:23:32
|
--> $DIR/fat-ptr-cast.rs:24:37
|
||||||
|
|
|
|
||||||
LL | let mut fail: *const str = 0 as *const str;
|
LL | let mut fail: *const str = 0 as *const str;
|
||||||
| ^^^^^^^^^^^^^^^
|
| - ^^^^^^^^^^ creating a `*const str` requires both an address and a length
|
||||||
|
| |
|
||||||
|
| consider casting this expression to `*const ()`, then using `core::ptr::from_raw_parts`
|
||||||
|
|
||||||
error: aborting due to 9 previous errors
|
error[E0606]: cannot cast `isize` to a pointer that is wide
|
||||||
|
--> $DIR/fat-ptr-cast.rs:26:43
|
||||||
|
|
|
||||||
|
LL | let mut fail2: *const str = 0isize as *const str;
|
||||||
|
| ------ ^^^^^^^^^^ creating a `*const str` requires both an address and a length
|
||||||
|
| |
|
||||||
|
| consider casting this expression to `*const ()`, then using `core::ptr::from_raw_parts`
|
||||||
|
|
||||||
|
error[E0606]: cannot cast `usize` to a pointer that may be wide
|
||||||
|
--> $DIR/fat-ptr-cast.rs:31:18
|
||||||
|
|
|
||||||
|
LL | let s = 0 as *const T;
|
||||||
|
| - ^^^^^^^^ creating a `*const T` requires both an address and type-specific metadata
|
||||||
|
| |
|
||||||
|
| consider casting this expression to `*const ()`, then using `core::ptr::from_raw_parts`
|
||||||
|
|
||||||
|
error: aborting due to 11 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0605, E0606, E0607.
|
Some errors have detailed explanations: E0605, E0606, E0607.
|
||||||
For more information about an error, try `rustc --explain E0605`.
|
For more information about an error, try `rustc --explain E0605`.
|
||||||
|
|
|
@ -48,7 +48,7 @@ fn main()
|
||||||
let _ = E::A as *const u8; //~ ERROR is invalid
|
let _ = E::A as *const u8; //~ ERROR is invalid
|
||||||
let _ = 'a' as *const u8; //~ ERROR is invalid
|
let _ = 'a' as *const u8; //~ ERROR is invalid
|
||||||
|
|
||||||
let _ = 42usize as *const [u8]; //~ ERROR is invalid
|
let _ = 42usize as *const [u8]; //~ ERROR cannot cast `usize` to a pointer that is wide
|
||||||
let _ = v as *const [u8]; //~ ERROR cannot cast
|
let _ = v as *const [u8]; //~ ERROR cannot cast
|
||||||
let _ = fat_v as *const dyn Foo; //~ ERROR the size for values of type
|
let _ = fat_v as *const dyn Foo; //~ ERROR the size for values of type
|
||||||
let _ = foo as *const str; //~ ERROR is invalid
|
let _ = foo as *const str; //~ ERROR is invalid
|
||||||
|
|
|
@ -148,11 +148,13 @@ error[E0606]: casting `char` as `*const u8` is invalid
|
||||||
LL | let _ = 'a' as *const u8;
|
LL | let _ = 'a' as *const u8;
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0606]: casting `usize` as `*const [u8]` is invalid
|
error[E0606]: cannot cast `usize` to a pointer that is wide
|
||||||
--> $DIR/cast-rfc0401.rs:51:13
|
--> $DIR/cast-rfc0401.rs:51:24
|
||||||
|
|
|
|
||||||
LL | let _ = 42usize as *const [u8];
|
LL | let _ = 42usize as *const [u8];
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ------- ^^^^^^^^^^^ creating a `*const [u8]` requires both an address and a length
|
||||||
|
| |
|
||||||
|
| consider casting this expression to `*const ()`, then using `core::ptr::from_raw_parts`
|
||||||
|
|
||||||
error[E0607]: cannot cast thin pointer `*const u8` to fat pointer `*const [u8]`
|
error[E0607]: cannot cast thin pointer `*const u8` to fat pointer `*const [u8]`
|
||||||
--> $DIR/cast-rfc0401.rs:52:13
|
--> $DIR/cast-rfc0401.rs:52:13
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue