Skip to content

Commit 1f4e578

Browse files
authored
Rollup merge of rust-lang#72920 - oli-obk:const_transmute, r=RalfJung
Stabilize `transmute` in constants and statics but not const fn cc rust-lang#53605 (leaving issue open so we can add `transmute` to `const fn` later) Previous attempt: rust-lang#64011 r? @RalfJung cc @rust-lang/wg-const-eval
2 parents 346aec9 + dd872be commit 1f4e578

39 files changed

+238
-106
lines changed

src/libcore/intrinsics.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1285,7 +1285,9 @@ extern "rust-intrinsic" {
12851285
/// }
12861286
/// ```
12871287
#[stable(feature = "rust1", since = "1.0.0")]
1288-
#[rustc_const_unstable(feature = "const_transmute", issue = "53605")]
1288+
// NOTE: While this makes the intrinsic const stable, we have some custom code in const fn
1289+
// checks that prevent its use within `const fn`.
1290+
#[rustc_const_stable(feature = "const_transmute", since = "1.46.0")]
12891291
pub fn transmute<T, U>(e: T) -> U;
12901292

12911293
/// Returns `true` if the actual type given as `T` requires drop

src/libcore/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@
140140
#![feature(rtm_target_feature)]
141141
#![feature(f16c_target_feature)]
142142
#![feature(hexagon_target_feature)]
143-
#![feature(const_transmute)]
143+
#![cfg_attr(not(bootstrap), feature(const_fn_transmute))]
144144
#![feature(abi_unadjusted)]
145145
#![feature(adx_target_feature)]
146146
#![feature(maybe_uninit_slice)]

src/librustc_ast/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#![cfg_attr(bootstrap, feature(const_if_match))]
1111
#![feature(const_fn)] // For the `transmute` in `P::new`
1212
#![feature(const_panic)]
13-
#![feature(const_transmute)]
13+
#![cfg_attr(not(bootstrap), feature(const_fn_transmute))]
1414
#![feature(crate_visibility_modifier)]
1515
#![feature(label_break_value)]
1616
#![feature(nll)]

src/librustc_feature/active.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,9 @@ declare_features! (
573573
/// Lazily evaluate constants. This allows constants to depend on type parameters.
574574
(active, lazy_normalization_consts, "1.46.0", Some(72219), None),
575575

576+
/// Alloc calling `transmute` in const fn
577+
(active, const_fn_transmute, "1.46.0", Some(53605), None),
578+
576579
// -------------------------------------------------------------------------
577580
// feature-group-end: actual feature gates
578581
// -------------------------------------------------------------------------

src/librustc_middle/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
#![cfg_attr(bootstrap, feature(const_if_match))]
3131
#![feature(const_fn)]
3232
#![feature(const_panic)]
33-
#![feature(const_transmute)]
33+
#![cfg_attr(not(bootstrap), feature(const_fn_transmute))]
3434
#![feature(core_intrinsics)]
3535
#![feature(discriminant_kind)]
3636
#![feature(drain_filter)]

src/librustc_mir/transform/qualify_min_const_fn.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use rustc_middle::ty::subst::GenericArgKind;
66
use rustc_middle::ty::{self, adjustment::PointerCast, Ty, TyCtxt};
77
use rustc_span::symbol::{sym, Symbol};
88
use rustc_span::Span;
9+
use rustc_target::spec::abi::Abi::RustIntrinsic;
910
use std::borrow::Cow;
1011

1112
type McfResult = Result<(), (Span, Cow<'static, str>)>;
@@ -418,6 +419,20 @@ fn check_terminator(
418419
));
419420
}
420421

422+
// HACK: This is to "unstabilize" the `transmute` intrinsic
423+
// within const fns. `transmute` is allowed in all other const contexts.
424+
// This won't really scale to more intrinsics or functions. Let's allow const
425+
// transmutes in const fn before we add more hacks to this.
426+
if tcx.fn_sig(fn_def_id).abi() == RustIntrinsic
427+
&& tcx.item_name(fn_def_id) == sym::transmute
428+
&& !feature_allowed(tcx, def_id, sym::const_fn_transmute)
429+
{
430+
return Err((
431+
span,
432+
"can only call `transmute` from const items, not `const fn`".into(),
433+
));
434+
}
435+
421436
check_operand(tcx, func, span, fn_def_id, body)?;
422437

423438
for arg in args {

src/librustc_span/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -848,6 +848,7 @@ symbols! {
848848
track_caller,
849849
trait_alias,
850850
transmute,
851+
const_fn_transmute,
851852
transparent,
852853
transparent_enums,
853854
transparent_unions,

src/test/ui/consts/const-eval/dangling.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![feature(const_transmute, const_raw_ptr_deref)]
1+
#![feature(const_raw_ptr_deref)]
22

33
use std::{mem, usize};
44

src/test/ui/consts/const-eval/double_check.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,6 @@ static FOO: (&Foo, &Bar) = unsafe {(
2020
Union { u8: &BAR }.bar,
2121
)};
2222

23+
static FOO2: (&Foo, &Bar) = unsafe {(std::mem::transmute(&BAR), std::mem::transmute(&BAR))};
24+
2325
fn main() {}

src/test/ui/consts/const-eval/double_check2.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,7 @@ static FOO: (&Foo, &Bar) = unsafe {( //~ undefined behavior
1717
Union { u8: &BAR }.foo,
1818
Union { u8: &BAR }.bar,
1919
)};
20+
static FOO2: (&Foo, &Bar) = unsafe {(std::mem::transmute(&BAR), std::mem::transmute(&BAR))};
21+
//~^ undefined behavior
2022

2123
fn main() {}

0 commit comments

Comments
 (0)