From 298b51e982703cda78fc3af469442e853b9db5aa Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sun, 13 Mar 2016 17:01:10 +0100 Subject: [PATCH 1/2] Give a more accurate error on thin-to-fat ptr cast Fixes #31511 --- src/librustc_typeck/check/cast.rs | 11 ++++++++++- src/test/compile-fail/issue-31511.rs | 16 ++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 src/test/compile-fail/issue-31511.rs 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 or the MIT license +// , 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() {} From be2698cb58687ba4c301680ad8dc47c39cd0a3db Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sun, 13 Mar 2016 20:35:04 +0100 Subject: [PATCH 2/2] Fix test fallout --- src/test/compile-fail/cast-rfc0401.rs | 2 +- src/test/compile-fail/fat-ptr-cast.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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