about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJonas Schievink <jonas@schievink.net>2016-03-13 17:01:10 +0100
committerJonas Schievink <jonas@schievink.net>2016-03-13 17:03:31 +0100
commit298b51e982703cda78fc3af469442e853b9db5aa (patch)
tree0baad2e2345eab89c03913e8b122322212c15fea
parent06074ac004701bff42c625247c4764b2ae6fca6c (diff)
downloadrust-298b51e982703cda78fc3af469442e853b9db5aa.tar.gz
rust-298b51e982703cda78fc3af469442e853b9db5aa.zip
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/issue-31511.rs16
2 files changed, 26 insertions, 1 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/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() {}