diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index b7aebff9ac096..045b88e2357cd 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 f9bf3eaf3ddf6..cab6f76d0271b 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 0000000000000..839ebbd279a99 --- /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 or the MIT license +// , 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 +}