Improve typeck diagnostic messages
Mostly by splitting error messages into proper pairs of errors and helps
This commit is contained in:
parent
77e9228b4a
commit
ffcdf0881b
@ -122,20 +122,21 @@ impl<'tcx> CastCheck<'tcx> {
|
||||
CastError::NeedViaInt |
|
||||
CastError::NeedViaUsize => {
|
||||
fcx.type_error_message(self.span, |actual| {
|
||||
format!("illegal cast; cast through {} first: `{}` as `{}`",
|
||||
match e {
|
||||
CastError::NeedViaPtr => "a raw pointer",
|
||||
CastError::NeedViaInt => "an integer",
|
||||
CastError::NeedViaUsize => "a usize",
|
||||
_ => unreachable!()
|
||||
},
|
||||
format!("casting `{}` as `{}` is invalid",
|
||||
actual,
|
||||
fcx.infcx().ty_to_string(self.cast_ty))
|
||||
}, self.expr_ty, None)
|
||||
}, self.expr_ty, None);
|
||||
fcx.ccx.tcx.sess.fileline_help(self.span,
|
||||
&format!("cast through {} first", match e {
|
||||
CastError::NeedViaPtr => "a raw pointer",
|
||||
CastError::NeedViaInt => "an integer",
|
||||
CastError::NeedViaUsize => "a usize",
|
||||
_ => unreachable!()
|
||||
}));
|
||||
}
|
||||
CastError::CastToBool => {
|
||||
span_err!(fcx.tcx().sess, self.span, E0054,
|
||||
"cannot cast as `bool`, compare with zero instead");
|
||||
span_err!(fcx.tcx().sess, self.span, E0054, "cannot cast as `bool`");
|
||||
fcx.ccx.tcx.sess.fileline_help(self.span, "compare with zero instead");
|
||||
}
|
||||
CastError::CastToChar => {
|
||||
fcx.type_error_message(self.span, |actual| {
|
||||
@ -151,17 +152,18 @@ impl<'tcx> CastCheck<'tcx> {
|
||||
}
|
||||
CastError::IllegalCast => {
|
||||
fcx.type_error_message(self.span, |actual| {
|
||||
format!("illegal cast: `{}` as `{}`",
|
||||
format!("casting `{}` as `{}` is invalid",
|
||||
actual,
|
||||
fcx.infcx().ty_to_string(self.cast_ty))
|
||||
}, self.expr_ty, None);
|
||||
}
|
||||
CastError::DifferingKinds => {
|
||||
fcx.type_error_message(self.span, |actual| {
|
||||
format!("illegal cast: `{}` as `{}`; vtable kinds may not match",
|
||||
format!("casting `{}` as `{}` is invalid",
|
||||
actual,
|
||||
fcx.infcx().ty_to_string(self.cast_ty))
|
||||
}, self.expr_ty, None);
|
||||
fcx.ccx.tcx.sess.fileline_note(self.span, "vtable kinds may not match");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -285,7 +287,7 @@ impl<'tcx> CastCheck<'tcx> {
|
||||
return Ok(CastKind::PtrPtrCast);
|
||||
}
|
||||
|
||||
// sized -> unsized? report illegal cast (don't complain about vtable kinds)
|
||||
// sized -> unsized? report invalid cast (don't complain about vtable kinds)
|
||||
if fcx.type_is_known_to_be_sized(m_expr.ty, self.span) {
|
||||
return Err(CastError::IllegalCast);
|
||||
}
|
||||
|
@ -8,5 +8,8 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern: cannot cast as `bool`, compare with zero instead
|
||||
fn main() { let u = (5 as bool); }
|
||||
fn main() {
|
||||
let u = (5 as bool);
|
||||
//~^ ERROR cannot cast as `bool`
|
||||
//~^^ HELP compare with zero instead
|
||||
}
|
||||
|
@ -10,12 +10,16 @@
|
||||
|
||||
fn illegal_cast<U:?Sized,V:?Sized>(u: *const U) -> *const V
|
||||
{
|
||||
u as *const V //~ ERROR vtable kinds
|
||||
u as *const V
|
||||
//~^ ERROR casting
|
||||
//~^^ NOTE vtable kinds
|
||||
}
|
||||
|
||||
fn illegal_cast_2<U:?Sized>(u: *const U) -> *const str
|
||||
{
|
||||
u as *const str //~ ERROR vtable kinds
|
||||
u as *const str
|
||||
//~^ ERROR casting
|
||||
//~^^ NOTE vtable kinds
|
||||
}
|
||||
|
||||
trait Foo { fn foo(&self) {} }
|
||||
@ -41,32 +45,58 @@ fn main()
|
||||
let _ = v as (u32,); //~ ERROR non-scalar
|
||||
let _ = Some(&v) as *const u8; //~ ERROR non-scalar
|
||||
|
||||
let _ = v as f32; //~ ERROR through a usize first
|
||||
let _ = main as f64; //~ ERROR through a usize first
|
||||
let _ = &v as usize; //~ ERROR through a raw pointer first
|
||||
let _ = f as *const u8; //~ ERROR through a usize first
|
||||
let _ = 3 as bool; //~ ERROR compare with zero
|
||||
let _ = E::A as bool; //~ ERROR compare with zero
|
||||
let _ = v as f32;
|
||||
//~^ ERROR casting
|
||||
//~^^ HELP through a usize first
|
||||
let _ = main as f64;
|
||||
//~^ ERROR casting
|
||||
//~^^ HELP through a usize first
|
||||
let _ = &v as usize;
|
||||
//~^ ERROR casting
|
||||
//~^^ HELP through a raw pointer first
|
||||
let _ = f as *const u8;
|
||||
//~^ ERROR casting
|
||||
//~^^ HELP through a usize first
|
||||
let _ = 3 as bool;
|
||||
//~^ ERROR cannot cast as `bool`
|
||||
//~^^ HELP compare with zero
|
||||
let _ = E::A as bool;
|
||||
//~^ ERROR cannot cast as `bool`
|
||||
//~^^ HELP compare with zero
|
||||
let _ = 0x61u32 as char; //~ ERROR only `u8` can be cast
|
||||
|
||||
let _ = false as f32; //~ ERROR through an integer first
|
||||
let _ = E::A as f32; //~ ERROR through an integer first
|
||||
let _ = 'a' as f32; //~ ERROR through an integer first
|
||||
let _ = false as f32;
|
||||
//~^ ERROR casting
|
||||
//~^^ HELP through an integer first
|
||||
let _ = E::A as f32;
|
||||
//~^ ERROR casting
|
||||
//~^^ HELP through an integer first
|
||||
let _ = 'a' as f32;
|
||||
//~^ ERROR casting
|
||||
//~^^ HELP through an integer first
|
||||
|
||||
let _ = false as *const u8; //~ ERROR through a usize first
|
||||
let _ = E::A as *const u8; //~ ERROR through a usize first
|
||||
let _ = 'a' as *const u8; //~ ERROR through a usize first
|
||||
let _ = false as *const u8;
|
||||
//~^ ERROR casting
|
||||
//~^^ HELP through a usize first
|
||||
let _ = E::A as *const u8;
|
||||
//~^ ERROR casting
|
||||
//~^^ HELP through a usize first
|
||||
let _ = 'a' as *const u8;
|
||||
//~^ ERROR casting
|
||||
//~^^ HELP through a usize first
|
||||
|
||||
let _ = 42usize as *const [u8]; //~ ERROR illegal cast
|
||||
let _ = v as *const [u8]; //~ ERROR illegal cast
|
||||
let _ = 42usize as *const [u8]; //~ ERROR casting
|
||||
let _ = v as *const [u8]; //~ ERROR casting
|
||||
let _ = fat_v as *const Foo;
|
||||
//~^ ERROR `core::marker::Sized` is not implemented for the type `[u8]`
|
||||
let _ = foo as *const str; //~ ERROR illegal cast
|
||||
let _ = foo as *mut str; //~ ERROR illegal cast
|
||||
let _ = main as *mut str; //~ ERROR illegal cast
|
||||
let _ = &f as *mut f32; //~ ERROR illegal cast
|
||||
let _ = &f as *const f64; //~ ERROR illegal cast
|
||||
let _ = fat_v as usize; //~ ERROR through a raw pointer first
|
||||
let _ = foo as *const str; //~ ERROR casting
|
||||
let _ = foo as *mut str; //~ ERROR casting
|
||||
let _ = main as *mut str; //~ ERROR casting
|
||||
let _ = &f as *mut f32; //~ ERROR casting
|
||||
let _ = &f as *const f64; //~ ERROR casting
|
||||
let _ = fat_v as usize;
|
||||
//~^ ERROR casting
|
||||
//~^^ HELP through a raw pointer first
|
||||
|
||||
let a : *const str = "hello";
|
||||
let _ = a as *const Foo;
|
||||
@ -76,6 +106,10 @@ fn main()
|
||||
let _ = main.f as *const u32; //~ ERROR attempted access of field
|
||||
|
||||
let cf: *const Foo = &0;
|
||||
let _ = cf as *const [u8]; //~ ERROR vtable kinds
|
||||
let _ = cf as *const Bar; //~ ERROR vtable kinds
|
||||
let _ = cf as *const [u8];
|
||||
//~^ ERROR casting
|
||||
//~^^ NOTE vtable kinds
|
||||
let _ = cf as *const Bar;
|
||||
//~^ ERROR casting
|
||||
//~^^ NOTE vtable kinds
|
||||
}
|
||||
|
@ -9,8 +9,8 @@
|
||||
// except according to those terms.
|
||||
|
||||
static a: &'static str = "foo";
|
||||
static b: *const u8 = a as *const u8; //~ ERROR illegal cast
|
||||
static c: *const u8 = &a as *const u8; //~ ERROR illegal cast
|
||||
static b: *const u8 = a as *const u8; //~ ERROR casting
|
||||
static c: *const u8 = &a as *const u8; //~ ERROR casting
|
||||
|
||||
fn main() {
|
||||
}
|
||||
|
@ -21,8 +21,8 @@ enum F {
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let a = E::L0 as f32; //~ ERROR illegal cast
|
||||
let c = F::H1 as f32; //~ ERROR illegal cast
|
||||
let a = E::L0 as f32; //~ ERROR casting
|
||||
let c = F::H1 as f32; //~ ERROR casting
|
||||
assert_eq!(a, -1.0f32);
|
||||
assert_eq!(c, -1.0f32);
|
||||
}
|
||||
|
@ -20,8 +20,8 @@ enum F {
|
||||
H1 = 0xFFFFFFFFFFFFFFFF
|
||||
}
|
||||
|
||||
static C0: f32 = E::L0 as f32; //~ ERROR illegal cast
|
||||
static C1: f32 = F::H1 as f32; //~ ERROR illegal cast
|
||||
static C0: f32 = E::L0 as f32; //~ ERROR casting
|
||||
static C1: f32 = F::H1 as f32; //~ ERROR casting
|
||||
|
||||
pub fn main() {
|
||||
let b = C0;
|
||||
|
@ -17,14 +17,16 @@ fn main() {
|
||||
let p = a as *const [i32];
|
||||
let q = a.as_ptr();
|
||||
|
||||
a as usize; //~ ERROR illegal cast
|
||||
a as usize; //~ ERROR casting
|
||||
b as usize; //~ ERROR non-scalar cast
|
||||
p as usize; //~ ERROR illegal cast; cast through a raw pointer
|
||||
p as usize;
|
||||
//~^ ERROR casting
|
||||
//~^^ HELP cast through a raw pointer
|
||||
|
||||
// #22955
|
||||
q as *const [i32]; //~ ERROR illegal cast
|
||||
q as *const [i32]; //~ ERROR casting
|
||||
|
||||
// #21397
|
||||
let t: *mut (Trait + 'static) = 0 as *mut _; //~ ERROR illegal cast
|
||||
let mut fail: *const str = 0 as *const str; //~ ERROR illegal cast
|
||||
let t: *mut (Trait + 'static) = 0 as *mut _; //~ ERROR casting
|
||||
let mut fail: *const str = 0 as *const str; //~ ERROR casting
|
||||
}
|
||||
|
@ -15,8 +15,8 @@ struct X {
|
||||
|
||||
fn main() {
|
||||
let x = X { a: [0] };
|
||||
let _f = &x.a as *mut u8; //~ ERROR illegal cast
|
||||
let _f = &x.a as *mut u8; //~ ERROR casting
|
||||
|
||||
let local: [u8; 1] = [0];
|
||||
let _v = &local as *mut u8; //~ ERROR illegal cast
|
||||
let _v = &local as *mut u8; //~ ERROR casting
|
||||
}
|
||||
|
@ -14,5 +14,6 @@ enum Test {
|
||||
|
||||
fn main() {
|
||||
let _x = Test::Foo as *const isize;
|
||||
//~^ ERROR illegal cast; cast through a usize first: `Test` as `*const isize`
|
||||
//~^ ERROR casting `Test` as `*const isize` is invalid
|
||||
//~^^ HELP cast through a usize first
|
||||
}
|
||||
|
@ -11,5 +11,7 @@
|
||||
struct Inches(i32);
|
||||
|
||||
fn main() {
|
||||
Inches as f32; //~ ERROR illegal cast; cast through a usize first
|
||||
Inches as f32;
|
||||
//~^ ERROR casting
|
||||
//~^^ cast through a usize first
|
||||
}
|
||||
|
@ -11,5 +11,6 @@
|
||||
fn main() {
|
||||
let x : i16 = 22;
|
||||
((&x) as *const i16) as f32;
|
||||
//~^ ERROR illegal cast; cast through a usize first: `*const i16` as `f32`
|
||||
//~^ ERROR casting `*const i16` as `f32` is invalid
|
||||
//~^^ HELP cast through a usize first
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern:illegal cast
|
||||
// error-pattern:casting
|
||||
|
||||
#![feature(libc)]
|
||||
|
||||
|
@ -28,7 +28,7 @@ fn main() {
|
||||
let mut x1 = X { y: [0, 0] };
|
||||
|
||||
// This is still an error since we don't allow casts from &mut [T; n] to *mut T.
|
||||
let p1: *mut u8 = &mut x1.y as *mut _; //~ ERROR illegal cast
|
||||
let p1: *mut u8 = &mut x1.y as *mut _; //~ ERROR casting
|
||||
let t1: *mut [u8; 2] = &mut x1.y as *mut _;
|
||||
let h1: *mut [u8; 2] = &mut x1.y as *mut [u8; 2];
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user