about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSeo Sanghyeon <sanxiyn@gmail.com>2015-04-08 00:45:57 +0900
committerSeo Sanghyeon <sanxiyn@gmail.com>2015-04-08 00:45:57 +0900
commitd18b405faf09514febc4163d96e85e57e137df81 (patch)
treea81b1eb65722e34ef2201cd3542c3928028617d1
parentf4c2228be05887aeaee741c37715f6a1f2b51a5d (diff)
downloadrust-d18b405faf09514febc4163d96e85e57e137df81.tar.gz
rust-d18b405faf09514febc4163d96e85e57e137df81.zip
Check casts from fat pointer
-rw-r--r--src/librustc_typeck/check/cast.rs5
-rw-r--r--src/librustc_typeck/check/mod.rs10
-rw-r--r--src/test/compile-fail/fat-ptr-cast.rs14
3 files changed, 29 insertions, 0 deletions
diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs
index b7aebff9ac0..045b88e2357 100644
--- a/src/librustc_typeck/check/cast.rs
+++ b/src/librustc_typeck/check/cast.rs
@@ -170,6 +170,11 @@ pub fn check_cast<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, cast: &CastCheck<'tcx>) {
                 demand::coerce(fcx, e.span, t_1, &e);
             }
         }
+    } else if fcx.type_is_fat_ptr(t_e, span) && !fcx.type_is_fat_ptr(t_1, span) {
+        fcx.type_error_message(span, |actual| {
+            format!("illegal cast; cast from fat pointer: `{}` as `{}`",
+                    actual, fcx.infcx().ty_to_string(t_1))
+        }, t_e, None);
     } else if !(t_e_is_scalar && t_1_is_trivial) {
         /*
         If more type combinations should be supported than are
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index f9bf3eaf3dd..cab6f76d027 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1559,6 +1559,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                                  span)
     }
 
+    pub fn type_is_fat_ptr(&self, ty: Ty<'tcx>, span: Span) -> bool {
+        match ty.sty {
+            ty::ty_ptr(ty::mt { ty: t, .. }) |
+            ty::ty_rptr(_, ty::mt { ty: t, .. }) => {
+                !self.type_is_known_to_be_sized(t, span)
+            }
+            _ => false
+        }
+    }
+
     pub fn register_builtin_bound(&self,
                                   ty: Ty<'tcx>,
                                   builtin_bound: ty::BuiltinBound,
diff --git a/src/test/compile-fail/fat-ptr-cast.rs b/src/test/compile-fail/fat-ptr-cast.rs
new file mode 100644
index 00000000000..839ebbd279a
--- /dev/null
+++ b/src/test/compile-fail/fat-ptr-cast.rs
@@ -0,0 +1,14 @@
+// Copyright 2015 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 main() {
+    let a: &[i32] = &[1, 2, 3];
+    a as *const [i32] as usize; //~ ERROR cast from fat pointer
+}