Skip to content

Commit 36f02f3

Browse files
committed
Stabilize const_fn_transmute
1 parent fd853c0 commit 36f02f3

File tree

12 files changed

+15
-47
lines changed

12 files changed

+15
-47
lines changed

compiler/rustc_ast/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
)]
1111
#![feature(box_syntax)]
1212
#![feature(box_patterns)]
13-
#![feature(const_fn_transmute)]
13+
#![cfg_attr(bootstrap, feature(const_fn_transmute))]
1414
#![feature(crate_visibility_modifier)]
1515
#![feature(iter_zip)]
1616
#![feature(label_break_value)]

compiler/rustc_feature/src/accepted.rs

+2
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,8 @@ declare_features! (
290290
/// Allows bindings in the subpattern of a binding pattern.
291291
/// For example, you can write `x @ Some(y)`.
292292
(accepted, bindings_after_at, "1.54.0", Some(65490), None),
293+
/// Allows calling `transmute` in const fn
294+
(accepted, const_fn_transmute, "1.56.0", Some(53605), None),
293295

294296
// -------------------------------------------------------------------------
295297
// feature-group-end: accepted features

compiler/rustc_feature/src/active.rs

-3
Original file line numberDiff line numberDiff line change
@@ -565,9 +565,6 @@ declare_features! (
565565
/// Lazily evaluate constants. This allows constants to depend on type parameters.
566566
(incomplete, lazy_normalization_consts, "1.46.0", Some(72219), None),
567567

568-
/// Allows calling `transmute` in const fn
569-
(active, const_fn_transmute, "1.46.0", Some(53605), None),
570-
571568
/// Allows `if let` guard in match arms.
572569
(incomplete, if_let_guard, "1.47.0", Some(51114), None),
573570

compiler/rustc_mir/src/transform/check_consts/check.rs

-9
Original file line numberDiff line numberDiff line change
@@ -876,15 +876,6 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
876876

877877
let is_intrinsic = tcx.fn_sig(callee).abi() == RustIntrinsic;
878878

879-
// HACK: This is to "unstabilize" the `transmute` intrinsic
880-
// within const fns. `transmute` is allowed in all other const contexts.
881-
// This won't really scale to more intrinsics or functions. Let's allow const
882-
// transmutes in const fn before we add more hacks to this.
883-
if is_intrinsic && tcx.item_name(callee) == sym::transmute {
884-
self.check_op(ops::Transmute);
885-
return;
886-
}
887-
888879
if !tcx.is_const_fn_raw(callee) {
889880
let mut permitted = false;
890881

compiler/rustc_mir/src/transform/check_consts/ops.rs

-23
Original file line numberDiff line numberDiff line change
@@ -501,29 +501,6 @@ impl NonConstOp for ThreadLocalAccess {
501501
}
502502
}
503503

504-
#[derive(Debug)]
505-
pub struct Transmute;
506-
impl NonConstOp for Transmute {
507-
fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
508-
if ccx.const_kind() != hir::ConstContext::ConstFn {
509-
Status::Allowed
510-
} else {
511-
Status::Unstable(sym::const_fn_transmute)
512-
}
513-
}
514-
515-
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
516-
let mut err = feature_err(
517-
&ccx.tcx.sess.parse_sess,
518-
sym::const_fn_transmute,
519-
span,
520-
&format!("`transmute` is not allowed in {}s", ccx.const_kind()),
521-
);
522-
err.note("`transmute` is only allowed in constants and statics for now");
523-
err
524-
}
525-
}
526-
527504
#[derive(Debug)]
528505
pub struct UnionAccess;
529506
impl NonConstOp for UnionAccess {

library/core/src/intrinsics.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -911,6 +911,9 @@ extern "rust-intrinsic" {
911911
/// cause [undefined behavior][ub] with this function. `transmute` should be
912912
/// the absolute last resort.
913913
///
914+
/// Transmuting pointers to integers in a `const` context is [undefined behavior][ub].
915+
/// Any attempt to use the resulting value for integer operations will abort const-evaluation.
916+
///
914917
/// The [nomicon](../../nomicon/transmutes.html) has additional
915918
/// documentation.
916919
///
@@ -1128,8 +1131,6 @@ extern "rust-intrinsic" {
11281131
/// }
11291132
/// ```
11301133
#[stable(feature = "rust1", since = "1.0.0")]
1131-
// NOTE: While this makes the intrinsic const stable, we have some custom code in const fn
1132-
// checks that prevent its use within `const fn`.
11331134
#[rustc_const_stable(feature = "const_transmute", since = "1.46.0")]
11341135
#[rustc_diagnostic_item = "transmute"]
11351136
pub fn transmute<T, U>(e: T) -> U;

library/core/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@
159159
#![feature(rtm_target_feature)]
160160
#![feature(f16c_target_feature)]
161161
#![feature(hexagon_target_feature)]
162-
#![feature(const_fn_transmute)]
162+
#![cfg_attr(bootstrap, feature(const_fn_transmute))]
163163
#![feature(abi_unadjusted)]
164164
#![feature(adx_target_feature)]
165165
#![feature(associated_type_bounds)]

library/core/src/num/int_macros.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2096,7 +2096,7 @@ macro_rules! int_impl {
20962096
#[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
20972097
// SAFETY: const sound because integers are plain old datatypes so we can always
20982098
// transmute them to arrays of bytes
2099-
#[rustc_allow_const_fn_unstable(const_fn_transmute)]
2099+
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
21002100
#[inline]
21012101
pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
21022102
// SAFETY: integers are plain old datatypes so we can always transmute them to
@@ -2202,7 +2202,7 @@ macro_rules! int_impl {
22022202
#[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
22032203
// SAFETY: const sound because integers are plain old datatypes so we can always
22042204
// transmute to them
2205-
#[rustc_allow_const_fn_unstable(const_fn_transmute)]
2205+
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
22062206
#[inline]
22072207
pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
22082208
// SAFETY: integers are plain old datatypes so we can always transmute to them

library/core/src/num/uint_macros.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1926,7 +1926,7 @@ macro_rules! uint_impl {
19261926
#[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
19271927
// SAFETY: const sound because integers are plain old datatypes so we can always
19281928
// transmute them to arrays of bytes
1929-
#[rustc_allow_const_fn_unstable(const_fn_transmute)]
1929+
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
19301930
#[inline]
19311931
pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
19321932
// SAFETY: integers are plain old datatypes so we can always transmute them to
@@ -2032,7 +2032,7 @@ macro_rules! uint_impl {
20322032
#[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
20332033
// SAFETY: const sound because integers are plain old datatypes so we can always
20342034
// transmute to them
2035-
#[rustc_allow_const_fn_unstable(const_fn_transmute)]
2035+
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
20362036
#[inline]
20372037
pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
20382038
// SAFETY: integers are plain old datatypes so we can always transmute to them

library/core/src/str/converts.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ pub fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
157157
#[inline]
158158
#[stable(feature = "rust1", since = "1.0.0")]
159159
#[rustc_const_stable(feature = "const_str_from_utf8_unchecked", since = "1.55.0")]
160-
#[rustc_allow_const_fn_unstable(const_fn_transmute)]
160+
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
161161
pub const unsafe fn from_utf8_unchecked(v: &[u8]) -> &str {
162162
// SAFETY: the caller must guarantee that the bytes `v` are valid UTF-8.
163163
// Also relies on `&str` and `&[u8]` having the same layout.

library/core/src/str/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ impl str {
231231
#[rustc_const_stable(feature = "str_as_bytes", since = "1.39.0")]
232232
#[inline(always)]
233233
#[allow(unused_attributes)]
234-
#[rustc_allow_const_fn_unstable(const_fn_transmute)]
234+
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
235235
pub const fn as_bytes(&self) -> &[u8] {
236236
// SAFETY: const sound because we transmute two types with the same layout
237237
unsafe { mem::transmute(self) }

library/std/src/net/ip.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1087,7 +1087,7 @@ impl Ipv6Addr {
10871087
///
10881088
/// let addr = Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff);
10891089
/// ```
1090-
#[rustc_allow_const_fn_unstable(const_fn_transmute)]
1090+
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
10911091
#[rustc_const_stable(feature = "const_ipv6", since = "1.32.0")]
10921092
#[stable(feature = "rust1", since = "1.0.0")]
10931093
#[inline]
@@ -1149,7 +1149,7 @@ impl Ipv6Addr {
11491149
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).segments(),
11501150
/// [0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff]);
11511151
/// ```
1152-
#[rustc_allow_const_fn_unstable(const_fn_transmute)]
1152+
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
11531153
#[rustc_const_stable(feature = "const_ipv6", since = "1.50.0")]
11541154
#[stable(feature = "rust1", since = "1.0.0")]
11551155
#[inline]

0 commit comments

Comments
 (0)