Skip to content

Commit 37903bf

Browse files
Improve reference cast help message
1 parent c11e2bd commit 37903bf

File tree

6 files changed

+39
-32
lines changed

6 files changed

+39
-32
lines changed

Diff for: src/librustc_typeck/check/cast.rs

+36-23
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@ enum CastError {
105105
NeedViaPtr,
106106
NeedViaThinPtr,
107107
NeedViaInt,
108-
NeedViaUsize,
109108
NonScalar,
110109
}
111110

@@ -139,26 +138,39 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
139138

140139
fn report_cast_error(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>, e: CastError) {
141140
match e {
142-
CastError::NeedViaPtr |
143141
CastError::NeedViaThinPtr |
144-
CastError::NeedViaInt |
145-
CastError::NeedViaUsize => {
142+
CastError::NeedViaPtr => {
143+
let mut err = fcx.type_error_struct(self.span,
144+
|actual| {
145+
format!("casting `{}` as `{}` is invalid",
146+
actual,
147+
fcx.ty_to_string(self.cast_ty))
148+
},
149+
self.expr_ty);
150+
if self.cast_ty.is_uint() {
151+
err.help(&format!("cast through {} first",
152+
match e {
153+
CastError::NeedViaPtr => "a raw pointer",
154+
CastError::NeedViaThinPtr => "a thin pointer",
155+
_ => bug!(),
156+
}));
157+
}
158+
err.emit();
159+
}
160+
CastError::NeedViaInt => {
146161
fcx.type_error_struct(self.span,
147-
|actual| {
148-
format!("casting `{}` as `{}` is invalid",
149-
actual,
150-
fcx.ty_to_string(self.cast_ty))
151-
},
152-
self.expr_ty)
153-
.help(&format!("cast through {} first",
154-
match e {
155-
CastError::NeedViaPtr => "a raw pointer",
156-
CastError::NeedViaThinPtr => "a thin pointer",
157-
CastError::NeedViaInt => "an integer",
158-
CastError::NeedViaUsize => "a usize",
159-
_ => bug!(),
160-
}))
161-
.emit();
162+
|actual| {
163+
format!("casting `{}` as `{}` is invalid",
164+
actual,
165+
fcx.ty_to_string(self.cast_ty))
166+
},
167+
self.expr_ty)
168+
.help(&format!("cast through {} first",
169+
match e {
170+
CastError::NeedViaInt => "an integer",
171+
_ => bug!(),
172+
}))
173+
.emit();
162174
}
163175
CastError::CastToBool => {
164176
struct_span_err!(fcx.tcx.sess, self.span, E0054, "cannot cast as `bool`")
@@ -366,21 +378,23 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
366378
(Int(Bool), Float) |
367379
(Int(CEnum), Float) |
368380
(Int(Char), Float) => Err(CastError::NeedViaInt),
381+
369382
(Int(Bool), Ptr(_)) |
370383
(Int(CEnum), Ptr(_)) |
371-
(Int(Char), Ptr(_)) => Err(CastError::NeedViaUsize),
384+
(Int(Char), Ptr(_)) |
385+
(Ptr(_), Float) |
386+
(FnPtr, Float) |
387+
(Float, Ptr(_)) => Err(CastError::IllegalCast),
372388

373389
// ptr -> *
374390
(Ptr(m_e), Ptr(m_c)) => self.check_ptr_ptr_cast(fcx, m_e, m_c), // ptr-ptr-cast
375391
(Ptr(m_expr), Int(_)) => self.check_ptr_addr_cast(fcx, m_expr), // ptr-addr-cast
376-
(Ptr(_), Float) | (FnPtr, Float) => Err(CastError::NeedViaUsize),
377392
(FnPtr, Int(_)) => Ok(CastKind::FnPtrAddrCast),
378393
(RPtr(_), Int(_)) |
379394
(RPtr(_), Float) => Err(CastError::NeedViaPtr),
380395
// * -> ptr
381396
(Int(_), Ptr(mt)) => self.check_addr_ptr_cast(fcx, mt), // addr-ptr-cast
382397
(FnPtr, Ptr(mt)) => self.check_fptr_ptr_cast(fcx, mt),
383-
(Float, Ptr(_)) => Err(CastError::NeedViaUsize),
384398
(RPtr(rmt), Ptr(mt)) => self.check_ref_cast(fcx, rmt, mt), // array-ptr-cast
385399

386400
// prim -> prim
@@ -391,7 +405,6 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
391405
(Int(_), Int(_)) | (Int(_), Float) | (Float, Int(_)) | (Float, Float) => {
392406
Ok(CastKind::NumericCast)
393407
}
394-
395408
}
396409
}
397410

Diff for: src/test/compile-fail/cast-rfc0401.rs

-6
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,13 @@ fn main()
4848

4949
let _ = v as f32;
5050
//~^ ERROR casting
51-
//~^^ HELP through a usize first
5251
let _ = main as f64;
5352
//~^ ERROR casting
54-
//~^^ HELP through a usize first
5553
let _ = &v as usize;
5654
//~^ ERROR casting
5755
//~^^ HELP through a raw pointer first
5856
let _ = f as *const u8;
5957
//~^ ERROR casting
60-
//~^^ HELP through a usize first
6158
let _ = 3_i32 as bool;
6259
//~^ ERROR cannot cast as `bool` [E0054]
6360
//~| unsupported cast
@@ -80,13 +77,10 @@ fn main()
8077

8178
let _ = false as *const u8;
8279
//~^ ERROR casting
83-
//~^^ HELP through a usize first
8480
let _ = E::A as *const u8;
8581
//~^ ERROR casting
86-
//~^^ HELP through a usize first
8782
let _ = 'a' as *const u8;
8883
//~^ ERROR casting
89-
//~^^ HELP through a usize first
9084

9185
let _ = 42usize as *const [u8]; //~ ERROR casting
9286
let _ = v as *const [u8]; //~ ERROR cannot cast

Diff for: src/test/compile-fail/fat-ptr-cast.rs

+3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ fn main() {
1919

2020
a as usize; //~ ERROR casting
2121
//~^ HELP cast through a raw pointer first
22+
a as isize; //~ ERROR casting
23+
a as i16; //~ ERROR casting `&[i32]` as `i16` is invalid
24+
a as u32; //~ ERROR casting `&[i32]` as `u32` is invalid
2225
b as usize; //~ ERROR non-scalar cast
2326
p as usize;
2427
//~^ ERROR casting

Diff for: src/test/compile-fail/issue-17444.rs

-1
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,4 @@ enum Test {
1515
fn main() {
1616
let _x = Test::Foo as *const isize;
1717
//~^ ERROR casting `Test` as `*const isize` is invalid
18-
//~^^ HELP cast through a usize first
1918
}

Diff for: src/test/compile-fail/issue-21554.rs

-1
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,4 @@ struct Inches(i32);
1313
fn main() {
1414
Inches as f32;
1515
//~^ ERROR casting
16-
//~^^ cast through a usize first
1716
}

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

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

0 commit comments

Comments
 (0)