Skip to content

Commit ffcdf08

Browse files
committed
Improve typeck diagnostic messages
Mostly by splitting error messages into proper pairs of errors and helps
1 parent 77e9228 commit ffcdf08

13 files changed

+102
-57
lines changed

src/librustc_typeck/check/cast.rs

+15-13
Original file line numberDiff line numberDiff line change
@@ -122,20 +122,21 @@ impl<'tcx> CastCheck<'tcx> {
122122
CastError::NeedViaInt |
123123
CastError::NeedViaUsize => {
124124
fcx.type_error_message(self.span, |actual| {
125-
format!("illegal cast; cast through {} first: `{}` as `{}`",
126-
match e {
127-
CastError::NeedViaPtr => "a raw pointer",
128-
CastError::NeedViaInt => "an integer",
129-
CastError::NeedViaUsize => "a usize",
130-
_ => unreachable!()
131-
},
125+
format!("casting `{}` as `{}` is invalid",
132126
actual,
133127
fcx.infcx().ty_to_string(self.cast_ty))
134-
}, self.expr_ty, None)
128+
}, self.expr_ty, None);
129+
fcx.ccx.tcx.sess.fileline_help(self.span,
130+
&format!("cast through {} first", match e {
131+
CastError::NeedViaPtr => "a raw pointer",
132+
CastError::NeedViaInt => "an integer",
133+
CastError::NeedViaUsize => "a usize",
134+
_ => unreachable!()
135+
}));
135136
}
136137
CastError::CastToBool => {
137-
span_err!(fcx.tcx().sess, self.span, E0054,
138-
"cannot cast as `bool`, compare with zero instead");
138+
span_err!(fcx.tcx().sess, self.span, E0054, "cannot cast as `bool`");
139+
fcx.ccx.tcx.sess.fileline_help(self.span, "compare with zero instead");
139140
}
140141
CastError::CastToChar => {
141142
fcx.type_error_message(self.span, |actual| {
@@ -151,17 +152,18 @@ impl<'tcx> CastCheck<'tcx> {
151152
}
152153
CastError::IllegalCast => {
153154
fcx.type_error_message(self.span, |actual| {
154-
format!("illegal cast: `{}` as `{}`",
155+
format!("casting `{}` as `{}` is invalid",
155156
actual,
156157
fcx.infcx().ty_to_string(self.cast_ty))
157158
}, self.expr_ty, None);
158159
}
159160
CastError::DifferingKinds => {
160161
fcx.type_error_message(self.span, |actual| {
161-
format!("illegal cast: `{}` as `{}`; vtable kinds may not match",
162+
format!("casting `{}` as `{}` is invalid",
162163
actual,
163164
fcx.infcx().ty_to_string(self.cast_ty))
164165
}, self.expr_ty, None);
166+
fcx.ccx.tcx.sess.fileline_note(self.span, "vtable kinds may not match");
165167
}
166168
}
167169
}
@@ -285,7 +287,7 @@ impl<'tcx> CastCheck<'tcx> {
285287
return Ok(CastKind::PtrPtrCast);
286288
}
287289

288-
// sized -> unsized? report illegal cast (don't complain about vtable kinds)
290+
// sized -> unsized? report invalid cast (don't complain about vtable kinds)
289291
if fcx.type_is_known_to_be_sized(m_expr.ty, self.span) {
290292
return Err(CastError::IllegalCast);
291293
}

src/test/compile-fail/cast-as-bool.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,8 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// error-pattern: cannot cast as `bool`, compare with zero instead
12-
fn main() { let u = (5 as bool); }
11+
fn main() {
12+
let u = (5 as bool);
13+
//~^ ERROR cannot cast as `bool`
14+
//~^^ HELP compare with zero instead
15+
}

src/test/compile-fail/cast-rfc0401.rs

+58-24
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,16 @@
1010

1111
fn illegal_cast<U:?Sized,V:?Sized>(u: *const U) -> *const V
1212
{
13-
u as *const V //~ ERROR vtable kinds
13+
u as *const V
14+
//~^ ERROR casting
15+
//~^^ NOTE vtable kinds
1416
}
1517

1618
fn illegal_cast_2<U:?Sized>(u: *const U) -> *const str
1719
{
18-
u as *const str //~ ERROR vtable kinds
20+
u as *const str
21+
//~^ ERROR casting
22+
//~^^ NOTE vtable kinds
1923
}
2024

2125
trait Foo { fn foo(&self) {} }
@@ -41,32 +45,58 @@ fn main()
4145
let _ = v as (u32,); //~ ERROR non-scalar
4246
let _ = Some(&v) as *const u8; //~ ERROR non-scalar
4347

44-
let _ = v as f32; //~ ERROR through a usize first
45-
let _ = main as f64; //~ ERROR through a usize first
46-
let _ = &v as usize; //~ ERROR through a raw pointer first
47-
let _ = f as *const u8; //~ ERROR through a usize first
48-
let _ = 3 as bool; //~ ERROR compare with zero
49-
let _ = E::A as bool; //~ ERROR compare with zero
48+
let _ = v as f32;
49+
//~^ ERROR casting
50+
//~^^ HELP through a usize first
51+
let _ = main as f64;
52+
//~^ ERROR casting
53+
//~^^ HELP through a usize first
54+
let _ = &v as usize;
55+
//~^ ERROR casting
56+
//~^^ HELP through a raw pointer first
57+
let _ = f as *const u8;
58+
//~^ ERROR casting
59+
//~^^ HELP through a usize first
60+
let _ = 3 as bool;
61+
//~^ ERROR cannot cast as `bool`
62+
//~^^ HELP compare with zero
63+
let _ = E::A as bool;
64+
//~^ ERROR cannot cast as `bool`
65+
//~^^ HELP compare with zero
5066
let _ = 0x61u32 as char; //~ ERROR only `u8` can be cast
5167

52-
let _ = false as f32; //~ ERROR through an integer first
53-
let _ = E::A as f32; //~ ERROR through an integer first
54-
let _ = 'a' as f32; //~ ERROR through an integer first
68+
let _ = false as f32;
69+
//~^ ERROR casting
70+
//~^^ HELP through an integer first
71+
let _ = E::A as f32;
72+
//~^ ERROR casting
73+
//~^^ HELP through an integer first
74+
let _ = 'a' as f32;
75+
//~^ ERROR casting
76+
//~^^ HELP through an integer first
5577

56-
let _ = false as *const u8; //~ ERROR through a usize first
57-
let _ = E::A as *const u8; //~ ERROR through a usize first
58-
let _ = 'a' as *const u8; //~ ERROR through a usize first
78+
let _ = false as *const u8;
79+
//~^ ERROR casting
80+
//~^^ HELP through a usize first
81+
let _ = E::A as *const u8;
82+
//~^ ERROR casting
83+
//~^^ HELP through a usize first
84+
let _ = 'a' as *const u8;
85+
//~^ ERROR casting
86+
//~^^ HELP through a usize first
5987

60-
let _ = 42usize as *const [u8]; //~ ERROR illegal cast
61-
let _ = v as *const [u8]; //~ ERROR illegal cast
88+
let _ = 42usize as *const [u8]; //~ ERROR casting
89+
let _ = v as *const [u8]; //~ ERROR casting
6290
let _ = fat_v as *const Foo;
6391
//~^ ERROR `core::marker::Sized` is not implemented for the type `[u8]`
64-
let _ = foo as *const str; //~ ERROR illegal cast
65-
let _ = foo as *mut str; //~ ERROR illegal cast
66-
let _ = main as *mut str; //~ ERROR illegal cast
67-
let _ = &f as *mut f32; //~ ERROR illegal cast
68-
let _ = &f as *const f64; //~ ERROR illegal cast
69-
let _ = fat_v as usize; //~ ERROR through a raw pointer first
92+
let _ = foo as *const str; //~ ERROR casting
93+
let _ = foo as *mut str; //~ ERROR casting
94+
let _ = main as *mut str; //~ ERROR casting
95+
let _ = &f as *mut f32; //~ ERROR casting
96+
let _ = &f as *const f64; //~ ERROR casting
97+
let _ = fat_v as usize;
98+
//~^ ERROR casting
99+
//~^^ HELP through a raw pointer first
70100

71101
let a : *const str = "hello";
72102
let _ = a as *const Foo;
@@ -76,6 +106,10 @@ fn main()
76106
let _ = main.f as *const u32; //~ ERROR attempted access of field
77107

78108
let cf: *const Foo = &0;
79-
let _ = cf as *const [u8]; //~ ERROR vtable kinds
80-
let _ = cf as *const Bar; //~ ERROR vtable kinds
109+
let _ = cf as *const [u8];
110+
//~^ ERROR casting
111+
//~^^ NOTE vtable kinds
112+
let _ = cf as *const Bar;
113+
//~^ ERROR casting
114+
//~^^ NOTE vtable kinds
81115
}

src/test/compile-fail/const-cast-different-types.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
// except according to those terms.
1010

1111
static a: &'static str = "foo";
12-
static b: *const u8 = a as *const u8; //~ ERROR illegal cast
13-
static c: *const u8 = &a as *const u8; //~ ERROR illegal cast
12+
static b: *const u8 = a as *const u8; //~ ERROR casting
13+
static c: *const u8 = &a as *const u8; //~ ERROR casting
1414

1515
fn main() {
1616
}

src/test/compile-fail/enum-to-float-cast-2.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ enum F {
2121
}
2222

2323
pub fn main() {
24-
let a = E::L0 as f32; //~ ERROR illegal cast
25-
let c = F::H1 as f32; //~ ERROR illegal cast
24+
let a = E::L0 as f32; //~ ERROR casting
25+
let c = F::H1 as f32; //~ ERROR casting
2626
assert_eq!(a, -1.0f32);
2727
assert_eq!(c, -1.0f32);
2828
}

src/test/compile-fail/enum-to-float-cast.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ enum F {
2020
H1 = 0xFFFFFFFFFFFFFFFF
2121
}
2222

23-
static C0: f32 = E::L0 as f32; //~ ERROR illegal cast
24-
static C1: f32 = F::H1 as f32; //~ ERROR illegal cast
23+
static C0: f32 = E::L0 as f32; //~ ERROR casting
24+
static C1: f32 = F::H1 as f32; //~ ERROR casting
2525

2626
pub fn main() {
2727
let b = C0;

src/test/compile-fail/fat-ptr-cast.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,16 @@ fn main() {
1717
let p = a as *const [i32];
1818
let q = a.as_ptr();
1919

20-
a as usize; //~ ERROR illegal cast
20+
a as usize; //~ ERROR casting
2121
b as usize; //~ ERROR non-scalar cast
22-
p as usize; //~ ERROR illegal cast; cast through a raw pointer
22+
p as usize;
23+
//~^ ERROR casting
24+
//~^^ HELP cast through a raw pointer
2325

2426
// #22955
25-
q as *const [i32]; //~ ERROR illegal cast
27+
q as *const [i32]; //~ ERROR casting
2628

2729
// #21397
28-
let t: *mut (Trait + 'static) = 0 as *mut _; //~ ERROR illegal cast
29-
let mut fail: *const str = 0 as *const str; //~ ERROR illegal cast
30+
let t: *mut (Trait + 'static) = 0 as *mut _; //~ ERROR casting
31+
let mut fail: *const str = 0 as *const str; //~ ERROR casting
3032
}

src/test/compile-fail/issue-14845.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ struct X {
1515

1616
fn main() {
1717
let x = X { a: [0] };
18-
let _f = &x.a as *mut u8; //~ ERROR illegal cast
18+
let _f = &x.a as *mut u8; //~ ERROR casting
1919

2020
let local: [u8; 1] = [0];
21-
let _v = &local as *mut u8; //~ ERROR illegal cast
21+
let _v = &local as *mut u8; //~ ERROR casting
2222
}

src/test/compile-fail/issue-17444.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@ enum Test {
1414

1515
fn main() {
1616
let _x = Test::Foo as *const isize;
17-
//~^ ERROR illegal cast; cast through a usize first: `Test` as `*const isize`
17+
//~^ ERROR casting `Test` as `*const isize` is invalid
18+
//~^^ HELP cast through a usize first
1819
}

src/test/compile-fail/issue-21554.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,7 @@
1111
struct Inches(i32);
1212

1313
fn main() {
14-
Inches as f32; //~ ERROR illegal cast; cast through a usize first
14+
Inches as f32;
15+
//~^ ERROR casting
16+
//~^^ cast through a usize first
1517
}

src/test/compile-fail/typeck-cast-pointer-to-float.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@
1111
fn main() {
1212
let x : i16 = 22;
1313
((&x) as *const i16) as f32;
14-
//~^ ERROR illegal cast; cast through a usize first: `*const i16` as `f32`
14+
//~^ ERROR casting `*const i16` as `f32` is invalid
15+
//~^^ HELP cast through a usize first
1516
}

src/test/compile-fail/unsupported-cast.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// error-pattern:illegal cast
11+
// error-pattern:casting
1212

1313
#![feature(libc)]
1414

src/test/compile-fail/vector-cast-weirdness.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ fn main() {
2828
let mut x1 = X { y: [0, 0] };
2929

3030
// This is still an error since we don't allow casts from &mut [T; n] to *mut T.
31-
let p1: *mut u8 = &mut x1.y as *mut _; //~ ERROR illegal cast
31+
let p1: *mut u8 = &mut x1.y as *mut _; //~ ERROR casting
3232
let t1: *mut [u8; 2] = &mut x1.y as *mut _;
3333
let h1: *mut [u8; 2] = &mut x1.y as *mut [u8; 2];
3434
}

0 commit comments

Comments
 (0)