about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2016-10-24 14:52:14 +0200
committerGuillaume Gomez <guillaume1.gomez@gmail.com>2016-11-16 22:40:55 +0100
commit37903bfcf6dc15f9647b1a7f08af4757198fa189 (patch)
tree3ea8a13fd9c625fb6bf1d5eeb60731506e09f004
parentc11e2bda394c786fff27df94bfbe292ba33294df (diff)
downloadrust-37903bfcf6dc15f9647b1a7f08af4757198fa189.tar.gz
rust-37903bfcf6dc15f9647b1a7f08af4757198fa189.zip
Improve reference cast help message
-rw-r--r--src/librustc_typeck/check/cast.rs59
-rw-r--r--src/test/compile-fail/cast-rfc0401.rs6
-rw-r--r--src/test/compile-fail/fat-ptr-cast.rs3
-rw-r--r--src/test/compile-fail/issue-17444.rs1
-rw-r--r--src/test/compile-fail/issue-21554.rs1
-rw-r--r--src/test/compile-fail/typeck-cast-pointer-to-float.rs1
6 files changed, 39 insertions, 32 deletions
diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs
index c456b9358b3..4edf0011cb3 100644
--- a/src/librustc_typeck/check/cast.rs
+++ b/src/librustc_typeck/check/cast.rs
@@ -105,7 +105,6 @@ enum CastError {
     NeedViaPtr,
     NeedViaThinPtr,
     NeedViaInt,
-    NeedViaUsize,
     NonScalar,
 }
 
@@ -139,26 +138,39 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
 
     fn report_cast_error(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>, e: CastError) {
         match e {
-            CastError::NeedViaPtr |
             CastError::NeedViaThinPtr |
-            CastError::NeedViaInt |
-            CastError::NeedViaUsize => {
+            CastError::NeedViaPtr => {
+                let mut err = fcx.type_error_struct(self.span,
+                                                    |actual| {
+                                                        format!("casting `{}` as `{}` is invalid",
+                                                                actual,
+                                                                fcx.ty_to_string(self.cast_ty))
+                                                    },
+                                                    self.expr_ty);
+                if self.cast_ty.is_uint() {
+                    err.help(&format!("cast through {} first",
+                                      match e {
+                                          CastError::NeedViaPtr => "a raw pointer",
+                                          CastError::NeedViaThinPtr => "a thin pointer",
+                                          _ => bug!(),
+                                      }));
+                }
+                err.emit();
+            }
+            CastError::NeedViaInt => {
                 fcx.type_error_struct(self.span,
-                                       |actual| {
-                                           format!("casting `{}` as `{}` is invalid",
-                                                   actual,
-                                                   fcx.ty_to_string(self.cast_ty))
-                                       },
-                                       self.expr_ty)
-                    .help(&format!("cast through {} first",
-                                   match e {
-                                       CastError::NeedViaPtr => "a raw pointer",
-                                       CastError::NeedViaThinPtr => "a thin pointer",
-                                       CastError::NeedViaInt => "an integer",
-                                       CastError::NeedViaUsize => "a usize",
-                                       _ => bug!(),
-                                   }))
-                    .emit();
+                                      |actual| {
+                                          format!("casting `{}` as `{}` is invalid",
+                                                  actual,
+                                                  fcx.ty_to_string(self.cast_ty))
+                                      },
+                                      self.expr_ty)
+                   .help(&format!("cast through {} first",
+                                  match e {
+                                      CastError::NeedViaInt => "an integer",
+                                      _ => bug!(),
+                                  }))
+                   .emit();
             }
             CastError::CastToBool => {
                 struct_span_err!(fcx.tcx.sess, self.span, E0054, "cannot cast as `bool`")
@@ -366,21 +378,23 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
             (Int(Bool), Float) |
             (Int(CEnum), Float) |
             (Int(Char), Float) => Err(CastError::NeedViaInt),
+
             (Int(Bool), Ptr(_)) |
             (Int(CEnum), Ptr(_)) |
-            (Int(Char), Ptr(_)) => Err(CastError::NeedViaUsize),
+            (Int(Char), Ptr(_)) |
+            (Ptr(_), Float) |
+            (FnPtr, Float) |
+            (Float, Ptr(_)) => Err(CastError::IllegalCast),
 
             // ptr -> *
             (Ptr(m_e), Ptr(m_c)) => self.check_ptr_ptr_cast(fcx, m_e, m_c), // ptr-ptr-cast
             (Ptr(m_expr), Int(_)) => self.check_ptr_addr_cast(fcx, m_expr), // ptr-addr-cast
-            (Ptr(_), Float) | (FnPtr, Float) => Err(CastError::NeedViaUsize),
             (FnPtr, Int(_)) => Ok(CastKind::FnPtrAddrCast),
             (RPtr(_), Int(_)) |
             (RPtr(_), Float) => Err(CastError::NeedViaPtr),
             // * -> ptr
             (Int(_), Ptr(mt)) => self.check_addr_ptr_cast(fcx, mt), // addr-ptr-cast
             (FnPtr, Ptr(mt)) => self.check_fptr_ptr_cast(fcx, mt),
-            (Float, Ptr(_)) => Err(CastError::NeedViaUsize),
             (RPtr(rmt), Ptr(mt)) => self.check_ref_cast(fcx, rmt, mt), // array-ptr-cast
 
             // prim -> prim
@@ -391,7 +405,6 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
             (Int(_), Int(_)) | (Int(_), Float) | (Float, Int(_)) | (Float, Float) => {
                 Ok(CastKind::NumericCast)
             }
-
         }
     }
 
diff --git a/src/test/compile-fail/cast-rfc0401.rs b/src/test/compile-fail/cast-rfc0401.rs
index 0c373057c76..1dbad9e30e3 100644
--- a/src/test/compile-fail/cast-rfc0401.rs
+++ b/src/test/compile-fail/cast-rfc0401.rs
@@ -48,16 +48,13 @@ fn main()
 
     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_i32 as bool;
     //~^ ERROR cannot cast as `bool` [E0054]
     //~| unsupported cast
@@ -80,13 +77,10 @@ fn main()
 
     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 casting
     let _ = v as *const [u8]; //~ ERROR cannot cast
diff --git a/src/test/compile-fail/fat-ptr-cast.rs b/src/test/compile-fail/fat-ptr-cast.rs
index b2fd11d4b39..c62987a5b90 100644
--- a/src/test/compile-fail/fat-ptr-cast.rs
+++ b/src/test/compile-fail/fat-ptr-cast.rs
@@ -19,6 +19,9 @@ fn main() {
 
     a as usize; //~ ERROR casting
     //~^ HELP cast through a raw pointer first
+    a as isize; //~ ERROR casting
+    a as i16; //~ ERROR casting `&[i32]` as `i16` is invalid
+    a as u32; //~ ERROR casting `&[i32]` as `u32` is invalid
     b as usize; //~ ERROR non-scalar cast
     p as usize;
     //~^ ERROR casting
diff --git a/src/test/compile-fail/issue-17444.rs b/src/test/compile-fail/issue-17444.rs
index c1d5827eb90..dafcff23838 100644
--- a/src/test/compile-fail/issue-17444.rs
+++ b/src/test/compile-fail/issue-17444.rs
@@ -15,5 +15,4 @@ enum Test {
 fn main() {
     let _x = Test::Foo as *const isize;
     //~^ ERROR casting `Test` as `*const isize` is invalid
-    //~^^ HELP cast through a usize first
 }
diff --git a/src/test/compile-fail/issue-21554.rs b/src/test/compile-fail/issue-21554.rs
index 741707a47b6..1b87862a056 100644
--- a/src/test/compile-fail/issue-21554.rs
+++ b/src/test/compile-fail/issue-21554.rs
@@ -13,5 +13,4 @@ struct Inches(i32);
 fn main() {
     Inches as f32;
     //~^ ERROR casting
-    //~^^ cast through a usize first
 }
diff --git a/src/test/compile-fail/typeck-cast-pointer-to-float.rs b/src/test/compile-fail/typeck-cast-pointer-to-float.rs
index 2277b1bad77..3f8b8f49cb3 100644
--- a/src/test/compile-fail/typeck-cast-pointer-to-float.rs
+++ b/src/test/compile-fail/typeck-cast-pointer-to-float.rs
@@ -12,5 +12,4 @@ fn main() {
     let x : i16 = 22;
     ((&x) as *const i16) as f32;
     //~^ ERROR casting `*const i16` as `f32` is invalid
-    //~^^ HELP cast through a usize first
 }