about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-03-14 05:44:24 -0700
committerbors <bors@rust-lang.org>2016-03-14 05:44:24 -0700
commitaf8f85cc397e10cc63b7c1c2ece7423d438afc67 (patch)
treef67c67f011de82c081cbb55e29dbff5d65eada5e
parent170f4708bb48234a2f1a089342b31a424ac94fa9 (diff)
parentbe2698cb58687ba4c301680ad8dc47c39cd0a3db (diff)
downloadrust-af8f85cc397e10cc63b7c1c2ece7423d438afc67.tar.gz
rust-af8f85cc397e10cc63b7c1c2ece7423d438afc67.zip
Auto merge of #32232 - jonas-schievink:issue31511, r=eddyb
Give a more accurate error on thin-to-fat ptr cast

Fixes #31511
-rw-r--r--src/librustc_typeck/check/cast.rs11
-rw-r--r--src/test/compile-fail/cast-rfc0401.rs2
-rw-r--r--src/test/compile-fail/fat-ptr-cast.rs2
-rw-r--r--src/test/compile-fail/issue-31511.rs16
4 files changed, 28 insertions, 3 deletions
diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs
index b5cd5d7f8e5..31c0fea5c2d 100644
--- a/src/librustc_typeck/check/cast.rs
+++ b/src/librustc_typeck/check/cast.rs
@@ -100,6 +100,8 @@ enum CastError {
     CastToBool,
     CastToChar,
     DifferingKinds,
+    /// Cast of thin to fat raw ptr (eg. `*const () as *const [u8]`)
+    SizedUnsizedCast,
     IllegalCast,
     NeedViaPtr,
     NeedViaThinPtr,
@@ -165,6 +167,13 @@ impl<'tcx> CastCheck<'tcx> {
                             fcx.infcx().ty_to_string(self.cast_ty))
                 }, self.expr_ty, None);
             }
+            CastError::SizedUnsizedCast => {
+                fcx.type_error_message(self.span, |actual| {
+                    format!("cannot cast thin pointer `{}` to fat pointer `{}`",
+                            actual,
+                            fcx.infcx().ty_to_string(self.cast_ty))
+                }, self.expr_ty, None)
+            }
             CastError::DifferingKinds => {
                 fcx.type_error_struct(self.span, |actual| {
                     format!("casting `{}` as `{}` is invalid",
@@ -312,7 +321,7 @@ impl<'tcx> CastCheck<'tcx> {
 
         // 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);
+            return Err(CastError::SizedUnsizedCast);
         }
 
         // vtable kinds must match
diff --git a/src/test/compile-fail/cast-rfc0401.rs b/src/test/compile-fail/cast-rfc0401.rs
index d14b0fa9e66..8e129722722 100644
--- a/src/test/compile-fail/cast-rfc0401.rs
+++ b/src/test/compile-fail/cast-rfc0401.rs
@@ -87,7 +87,7 @@ fn main()
     //~^^ HELP through a usize first
 
     let _ = 42usize as *const [u8]; //~ ERROR casting
-    let _ = v as *const [u8]; //~ ERROR casting
+    let _ = v as *const [u8]; //~ ERROR cannot cast
     let _ = fat_v as *const Foo;
     //~^ ERROR `core::marker::Sized` is not implemented for the type `[u8]`
     let _ = foo as *const str; //~ ERROR casting
diff --git a/src/test/compile-fail/fat-ptr-cast.rs b/src/test/compile-fail/fat-ptr-cast.rs
index 1c462779b43..c920b6c171e 100644
--- a/src/test/compile-fail/fat-ptr-cast.rs
+++ b/src/test/compile-fail/fat-ptr-cast.rs
@@ -24,7 +24,7 @@ fn main() {
     //~^^ HELP cast through a thin pointer
 
     // #22955
-    q as *const [i32]; //~ ERROR casting
+    q as *const [i32]; //~ ERROR cannot cast
 
     // #21397
     let t: *mut (Trait + 'static) = 0 as *mut _; //~ ERROR casting
diff --git a/src/test/compile-fail/issue-31511.rs b/src/test/compile-fail/issue-31511.rs
new file mode 100644
index 00000000000..dd1af2f4448
--- /dev/null
+++ b/src/test/compile-fail/issue-31511.rs
@@ -0,0 +1,16 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn cast_thin_to_fat(x: *const ()) {
+    x as *const [u8];
+    //~^ ERROR: cannot cast thin pointer `*const ()` to fat pointer `*const [u8]`
+}
+
+fn main() {}