diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 585e54342b773..44b86438f2a89 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1004,11 +1004,13 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is /// [`std::mem::size_of_val`](../../std/mem/fn.size_of_val.html). + #[rustc_const_unstable(feature = "const_size_of_val", issue = "46571")] pub fn size_of_val(_: *const T) -> usize; /// The required alignment of the referenced value. /// /// The stabilized version of this intrinsic is /// [`std::mem::align_of_val`](../../std/mem/fn.align_of_val.html). + #[rustc_const_unstable(feature = "const_align_of_val", issue = "46571")] pub fn min_align_of_val(_: *const T) -> usize; /// Gets a static string slice containing the name of a type. diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index c2bd5d16088fd..550e07f9d5710 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -88,6 +88,8 @@ #![feature(const_result)] #![feature(const_slice_from_raw_parts)] #![feature(const_slice_ptr_len)] +#![feature(const_size_of_val)] +#![feature(const_align_of_val)] #![feature(const_type_name)] #![feature(const_likely)] #![feature(const_unreachable_unchecked)] diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 6ff7baab70f61..4e58e118562ef 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -332,7 +332,8 @@ pub const fn size_of() -> usize { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] -pub fn size_of_val(val: &T) -> usize { +#[rustc_const_unstable(feature = "const_size_of_val", issue = "46571")] +pub const fn size_of_val(val: &T) -> usize { intrinsics::size_of_val(val) } @@ -466,9 +467,10 @@ pub const fn align_of() -> usize { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_unstable(feature = "const_align_of_val", issue = "46571")] #[allow(deprecated)] -pub fn align_of_val(val: &T) -> usize { - min_align_of_val(val) +pub const fn align_of_val(val: &T) -> usize { + intrinsics::min_align_of_val(val) } /// Returns the [ABI]-required minimum alignment of the type of the value that `val` points to. diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index 39ed3b607934b..d830879eff374 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -120,6 +120,21 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.write_scalar(location.ptr, dest)?; } + sym::min_align_of_val | sym::size_of_val => { + let place = self.deref_operand(args[0])?; + let (size, align) = self + .size_and_align_of(place.meta, place.layout)? + .ok_or_else(|| err_unsup_format!("`extern type` does not have known layout"))?; + + let result = match intrinsic_name { + sym::min_align_of_val => align.bytes(), + sym::size_of_val => size.bytes(), + _ => bug!(), + }; + + self.write_scalar(Scalar::from_machine_usize(result, self), dest)?; + } + sym::min_align_of | sym::pref_align_of | sym::needs_drop