From fff905bc698c0b6ee8b407273e7151d7b9a7a89a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 27 Dec 2018 09:40:33 +0100 Subject: panic when calling MaybeUninhabited::into_inner on uninhabited type --- src/libcore/intrinsics.rs | 5 +++++ src/libcore/mem.rs | 6 ++++++ 2 files changed, 11 insertions(+) (limited to 'src/libcore') diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 7508257f780..4f5310f5285 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -690,6 +690,11 @@ extern "rust-intrinsic" { /// crate it is invoked in. pub fn type_id() -> u64; + /// A guard for unsafe functions that cannot ever be executed if `T` is uninhabited: + /// This will statically either panic, or do nothing. + #[cfg(not(stage0))] + pub fn panic_if_uninhabited(); + /// Creates a value initialized to zero. /// /// `init` is unsafe because it returns a zeroed-out datum, diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index c024868714c..8fcbb73d9ce 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -492,6 +492,8 @@ pub const fn needs_drop() -> bool { #[rustc_deprecated(since = "2.0.0", reason = "use `mem::MaybeUninit::zeroed` instead")] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn zeroed() -> T { + #[cfg(not(stage0))] + intrinsics::panic_if_uninhabited::(); intrinsics::init() } @@ -624,6 +626,8 @@ pub unsafe fn zeroed() -> T { #[rustc_deprecated(since = "2.0.0", reason = "use `mem::MaybeUninit::uninitialized` instead")] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn uninitialized() -> T { + #[cfg(not(stage0))] + intrinsics::panic_if_uninhabited::(); intrinsics::uninit() } @@ -1128,6 +1132,8 @@ impl MaybeUninit { #[unstable(feature = "maybe_uninit", issue = "53491")] #[inline(always)] pub unsafe fn into_inner(self) -> T { + #[cfg(not(stage0))] + intrinsics::panic_if_uninhabited::(); ManuallyDrop::into_inner(self.value) } -- cgit 1.4.1-3-g733a5