Stabilize const_fn_transmute
This commit is contained in:
parent
fd853c00e2
commit
36f02f3523
@ -10,7 +10,7 @@
|
||||
)]
|
||||
#![feature(box_syntax)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(const_fn_transmute)]
|
||||
#![cfg_attr(bootstrap, feature(const_fn_transmute))]
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(iter_zip)]
|
||||
#![feature(label_break_value)]
|
||||
|
@ -290,6 +290,8 @@ macro_rules! declare_features {
|
||||
/// Allows bindings in the subpattern of a binding pattern.
|
||||
/// For example, you can write `x @ Some(y)`.
|
||||
(accepted, bindings_after_at, "1.54.0", Some(65490), None),
|
||||
/// Allows calling `transmute` in const fn
|
||||
(accepted, const_fn_transmute, "1.56.0", Some(53605), None),
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// feature-group-end: accepted features
|
||||
|
@ -565,9 +565,6 @@ pub fn set(&self, features: &mut Features, span: Span) {
|
||||
/// Lazily evaluate constants. This allows constants to depend on type parameters.
|
||||
(incomplete, lazy_normalization_consts, "1.46.0", Some(72219), None),
|
||||
|
||||
/// Allows calling `transmute` in const fn
|
||||
(active, const_fn_transmute, "1.46.0", Some(53605), None),
|
||||
|
||||
/// Allows `if let` guard in match arms.
|
||||
(incomplete, if_let_guard, "1.47.0", Some(51114), None),
|
||||
|
||||
|
@ -876,15 +876,6 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location
|
||||
|
||||
let is_intrinsic = tcx.fn_sig(callee).abi() == RustIntrinsic;
|
||||
|
||||
// HACK: This is to "unstabilize" the `transmute` intrinsic
|
||||
// within const fns. `transmute` is allowed in all other const contexts.
|
||||
// This won't really scale to more intrinsics or functions. Let's allow const
|
||||
// transmutes in const fn before we add more hacks to this.
|
||||
if is_intrinsic && tcx.item_name(callee) == sym::transmute {
|
||||
self.check_op(ops::Transmute);
|
||||
return;
|
||||
}
|
||||
|
||||
if !tcx.is_const_fn_raw(callee) {
|
||||
let mut permitted = false;
|
||||
|
||||
|
@ -501,29 +501,6 @@ fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Transmute;
|
||||
impl NonConstOp for Transmute {
|
||||
fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
|
||||
if ccx.const_kind() != hir::ConstContext::ConstFn {
|
||||
Status::Allowed
|
||||
} else {
|
||||
Status::Unstable(sym::const_fn_transmute)
|
||||
}
|
||||
}
|
||||
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
let mut err = feature_err(
|
||||
&ccx.tcx.sess.parse_sess,
|
||||
sym::const_fn_transmute,
|
||||
span,
|
||||
&format!("`transmute` is not allowed in {}s", ccx.const_kind()),
|
||||
);
|
||||
err.note("`transmute` is only allowed in constants and statics for now");
|
||||
err
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct UnionAccess;
|
||||
impl NonConstOp for UnionAccess {
|
||||
|
@ -911,6 +911,9 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
|
||||
/// cause [undefined behavior][ub] with this function. `transmute` should be
|
||||
/// the absolute last resort.
|
||||
///
|
||||
/// Transmuting pointers to integers in a `const` context is [undefined behavior][ub].
|
||||
/// Any attempt to use the resulting value for integer operations will abort const-evaluation.
|
||||
///
|
||||
/// The [nomicon](../../nomicon/transmutes.html) has additional
|
||||
/// documentation.
|
||||
///
|
||||
@ -1128,8 +1131,6 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
|
||||
/// }
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
// NOTE: While this makes the intrinsic const stable, we have some custom code in const fn
|
||||
// checks that prevent its use within `const fn`.
|
||||
#[rustc_const_stable(feature = "const_transmute", since = "1.46.0")]
|
||||
#[rustc_diagnostic_item = "transmute"]
|
||||
pub fn transmute<T, U>(e: T) -> U;
|
||||
|
@ -159,7 +159,7 @@
|
||||
#![feature(rtm_target_feature)]
|
||||
#![feature(f16c_target_feature)]
|
||||
#![feature(hexagon_target_feature)]
|
||||
#![feature(const_fn_transmute)]
|
||||
#![cfg_attr(bootstrap, feature(const_fn_transmute))]
|
||||
#![feature(abi_unadjusted)]
|
||||
#![feature(adx_target_feature)]
|
||||
#![feature(associated_type_bounds)]
|
||||
|
@ -2096,7 +2096,7 @@ pub const fn is_negative(self) -> bool { self < 0 }
|
||||
#[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
|
||||
// SAFETY: const sound because integers are plain old datatypes so we can always
|
||||
// transmute them to arrays of bytes
|
||||
#[rustc_allow_const_fn_unstable(const_fn_transmute)]
|
||||
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
|
||||
#[inline]
|
||||
pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
|
||||
// SAFETY: integers are plain old datatypes so we can always transmute them to
|
||||
@ -2202,7 +2202,7 @@ pub const fn is_negative(self) -> bool { self < 0 }
|
||||
#[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
|
||||
// SAFETY: const sound because integers are plain old datatypes so we can always
|
||||
// transmute to them
|
||||
#[rustc_allow_const_fn_unstable(const_fn_transmute)]
|
||||
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
|
||||
#[inline]
|
||||
pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
|
||||
// SAFETY: integers are plain old datatypes so we can always transmute to them
|
||||
|
@ -1926,7 +1926,7 @@ pub const fn wrapping_next_power_of_two(self) -> Self {
|
||||
#[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
|
||||
// SAFETY: const sound because integers are plain old datatypes so we can always
|
||||
// transmute them to arrays of bytes
|
||||
#[rustc_allow_const_fn_unstable(const_fn_transmute)]
|
||||
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
|
||||
#[inline]
|
||||
pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
|
||||
// SAFETY: integers are plain old datatypes so we can always transmute them to
|
||||
@ -2032,7 +2032,7 @@ pub const fn wrapping_next_power_of_two(self) -> Self {
|
||||
#[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
|
||||
// SAFETY: const sound because integers are plain old datatypes so we can always
|
||||
// transmute to them
|
||||
#[rustc_allow_const_fn_unstable(const_fn_transmute)]
|
||||
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
|
||||
#[inline]
|
||||
pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
|
||||
// SAFETY: integers are plain old datatypes so we can always transmute to them
|
||||
|
@ -157,7 +157,7 @@ pub fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_stable(feature = "const_str_from_utf8_unchecked", since = "1.55.0")]
|
||||
#[rustc_allow_const_fn_unstable(const_fn_transmute)]
|
||||
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
|
||||
pub const unsafe fn from_utf8_unchecked(v: &[u8]) -> &str {
|
||||
// SAFETY: the caller must guarantee that the bytes `v` are valid UTF-8.
|
||||
// Also relies on `&str` and `&[u8]` having the same layout.
|
||||
|
@ -231,7 +231,7 @@ pub fn is_char_boundary(&self, index: usize) -> bool {
|
||||
#[rustc_const_stable(feature = "str_as_bytes", since = "1.39.0")]
|
||||
#[inline(always)]
|
||||
#[allow(unused_attributes)]
|
||||
#[rustc_allow_const_fn_unstable(const_fn_transmute)]
|
||||
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
|
||||
pub const fn as_bytes(&self) -> &[u8] {
|
||||
// SAFETY: const sound because we transmute two types with the same layout
|
||||
unsafe { mem::transmute(self) }
|
||||
|
@ -1087,7 +1087,7 @@ impl Ipv6Addr {
|
||||
///
|
||||
/// let addr = Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff);
|
||||
/// ```
|
||||
#[rustc_allow_const_fn_unstable(const_fn_transmute)]
|
||||
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
|
||||
#[rustc_const_stable(feature = "const_ipv6", since = "1.32.0")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
@ -1149,7 +1149,7 @@ pub const fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16)
|
||||
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).segments(),
|
||||
/// [0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff]);
|
||||
/// ```
|
||||
#[rustc_allow_const_fn_unstable(const_fn_transmute)]
|
||||
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
|
||||
#[rustc_const_stable(feature = "const_ipv6", since = "1.50.0")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
|
Loading…
Reference in New Issue
Block a user