1
Fork 0

Auto merge of #111568 - scottmcm:undo-opt, r=WaffleLapkin

Stop turning transmutes into discriminant reads in mir-opt

Partially reverts #109612, as after #109993 these aren't actually equivalent any more, and I'm no longer confident this was ever an improvement in the first place.

Having this "simplification" meant that similar-looking code actually did somewhat different things.  For example,
```rust
pub unsafe fn demo1(x: std::cmp::Ordering) -> u8 {
    std::mem::transmute(x)
}
pub unsafe fn demo2(x: std::cmp::Ordering) -> i8 {
    std::mem::transmute(x)
}
```
in nightly today is generating <https://rust.godbolt.org/z/dPK58zW18>
```llvm
define noundef i8 `@_ZN7example5demo117h341ef313673d2ee6E(i8` noundef %x) unnamed_addr #0 {
  %0 = icmp uge i8 %x, -1
  %1 = icmp ule i8 %x, 1
  %2 = or i1 %0, %1
  call void `@llvm.assume(i1` %2)
  ret i8 %x
}

define noundef i8 `@_ZN7example5demo217h5ad29f361a3f5700E(i8` noundef %0) unnamed_addr #0 {
  %x = alloca i8, align 1
  store i8 %0, ptr %x, align 1
  %1 = load i8, ptr %x, align 1, !range !2, !noundef !3
  ret i8 %1
}
```

Which feels too different when the original code is essentially identical.

---

Aside: that example is different *after* optimizations too:
```llvm
define noundef i8 `@_ZN7example5demo117h341ef313673d2ee6E(i8` noundef returned %x) unnamed_addr #0 {
  %0 = add i8 %x, 1
  %1 = icmp ult i8 %0, 3
  tail call void `@llvm.assume(i1` %1)
  ret i8 %x
}

define noundef i8 `@_ZN7example5demo217h5ad29f361a3f5700E(i8` noundef returned %0) unnamed_addr #1 {
  ret i8 %0
}
```
so turning the `Transmute` into a `Discriminant` was arguably just making things worse, so leaving it alone instead -- and thus having less code in rustc -- seems clearly better.
This commit is contained in:
bors 2023-05-17 18:53:26 +00:00
commit e9e1bbc7a8
3 changed files with 49 additions and 152 deletions

View file

@ -5,7 +5,6 @@ use crate::MirPass;
use rustc_hir::Mutability; use rustc_hir::Mutability;
use rustc_middle::mir::*; use rustc_middle::mir::*;
use rustc_middle::ty::layout::ValidityRequirement; use rustc_middle::ty::layout::ValidityRequirement;
use rustc_middle::ty::util::IntTypeExt;
use rustc_middle::ty::{self, ParamEnv, SubstsRef, Ty, TyCtxt}; use rustc_middle::ty::{self, ParamEnv, SubstsRef, Ty, TyCtxt};
use rustc_span::symbol::Symbol; use rustc_span::symbol::Symbol;
use rustc_target::abi::FieldIdx; use rustc_target::abi::FieldIdx;
@ -163,18 +162,6 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
return; return;
} }
// Transmuting a fieldless enum to its repr is a discriminant read
if let ty::Adt(adt_def, ..) = operand_ty.kind()
&& adt_def.is_enum()
&& adt_def.is_payloadfree()
&& let Some(place) = operand.place()
&& let Some(repr_int) = adt_def.repr().int
&& repr_int.to_ty(self.tcx) == *cast_ty
{
*rvalue = Rvalue::Discriminant(place);
return;
}
// Transmuting a transparent struct/union to a field's type is a projection // Transmuting a transparent struct/union to a field's type is a projection
if let ty::Adt(adt_def, substs) = operand_ty.kind() if let ty::Adt(adt_def, substs) = operand_ty.kind()
&& adt_def.repr().transparent() && adt_def.repr().transparent()

View file

@ -4,59 +4,29 @@
fn adt_transmutes() -> () { fn adt_transmutes() -> () {
let mut _0: (); // return place in scope 0 at $DIR/combine_transmutes.rs:+0:32: +0:32 let mut _0: (); // return place in scope 0 at $DIR/combine_transmutes.rs:+0:32: +0:32
let _1: u8; // in scope 0 at $DIR/combine_transmutes.rs:+1:9: +1:11 let _1: u8; // in scope 0 at $DIR/combine_transmutes.rs:+1:9: +1:11
let mut _2: EnumNoRepr; // in scope 0 at $DIR/combine_transmutes.rs:+1:28: +1:41 let mut _2: std::option::Option<std::num::NonZeroU8>; // in scope 0 at $DIR/combine_transmutes.rs:+1:28: +1:58
let mut _4: EnumNoRepr; // in scope 0 at $DIR/combine_transmutes.rs:+2:28: +2:41 let mut _4: std::num::Wrapping<i16>; // in scope 0 at $DIR/combine_transmutes.rs:+2:29: +2:54
let mut _6: EnumReprIsize; // in scope 0 at $DIR/combine_transmutes.rs:+3:31: +3:47 let mut _6: std::num::Wrapping<i16>; // in scope 0 at $DIR/combine_transmutes.rs:+3:29: +3:54
let mut _8: EnumReprIsize; // in scope 0 at $DIR/combine_transmutes.rs:+4:31: +4:47 let mut _8: Union32; // in scope 0 at $DIR/combine_transmutes.rs:+4:29: +4:47
let mut _10: std::cmp::Ordering; // in scope 0 at $DIR/combine_transmutes.rs:+5:28: +5:52 let mut _10: Union32; // in scope 0 at $DIR/combine_transmutes.rs:+5:29: +5:47
let mut _12: std::cmp::Ordering; // in scope 0 at $DIR/combine_transmutes.rs:+6:28: +6:52 let mut _12: std::mem::MaybeUninit<std::string::String>; // in scope 0 at $DIR/combine_transmutes.rs:+6:46: +6:77
let mut _14: std::option::Option<std::num::NonZeroU8>; // in scope 0 at $DIR/combine_transmutes.rs:+7:28: +7:58
let mut _16: std::num::Wrapping<i16>; // in scope 0 at $DIR/combine_transmutes.rs:+8:29: +8:54
let mut _18: std::num::Wrapping<i16>; // in scope 0 at $DIR/combine_transmutes.rs:+9:29: +9:54
let mut _20: Union32; // in scope 0 at $DIR/combine_transmutes.rs:+10:29: +10:47
let mut _22: Union32; // in scope 0 at $DIR/combine_transmutes.rs:+11:29: +11:47
let mut _24: std::mem::MaybeUninit<std::string::String>; // in scope 0 at $DIR/combine_transmutes.rs:+12:46: +12:77
scope 1 { scope 1 {
debug _a => _1; // in scope 1 at $DIR/combine_transmutes.rs:+1:9: +1:11 debug _a => _1; // in scope 1 at $DIR/combine_transmutes.rs:+1:9: +1:11
let _3: i8; // in scope 1 at $DIR/combine_transmutes.rs:+2:9: +2:11 let _3: i16; // in scope 1 at $DIR/combine_transmutes.rs:+2:9: +2:11
scope 2 { scope 2 {
debug _a => _3; // in scope 2 at $DIR/combine_transmutes.rs:+2:9: +2:11 debug _a => _3; // in scope 2 at $DIR/combine_transmutes.rs:+2:9: +2:11
let _5: usize; // in scope 2 at $DIR/combine_transmutes.rs:+3:9: +3:11 let _5: u16; // in scope 2 at $DIR/combine_transmutes.rs:+3:9: +3:11
scope 3 { scope 3 {
debug _a => _5; // in scope 3 at $DIR/combine_transmutes.rs:+3:9: +3:11 debug _a => _5; // in scope 3 at $DIR/combine_transmutes.rs:+3:9: +3:11
let _7: isize; // in scope 3 at $DIR/combine_transmutes.rs:+4:9: +4:11 let _7: u32; // in scope 3 at $DIR/combine_transmutes.rs:+4:9: +4:11
scope 4 { scope 4 {
debug _a => _7; // in scope 4 at $DIR/combine_transmutes.rs:+4:9: +4:11 debug _a => _7; // in scope 4 at $DIR/combine_transmutes.rs:+4:9: +4:11
let _9: u8; // in scope 4 at $DIR/combine_transmutes.rs:+5:9: +5:11 let _9: i32; // in scope 4 at $DIR/combine_transmutes.rs:+5:9: +5:11
scope 5 { scope 5 {
debug _a => _9; // in scope 5 at $DIR/combine_transmutes.rs:+5:9: +5:11 debug _a => _9; // in scope 5 at $DIR/combine_transmutes.rs:+5:9: +5:11
let _11: i8; // in scope 5 at $DIR/combine_transmutes.rs:+6:9: +6:11 let _11: std::mem::ManuallyDrop<std::string::String>; // in scope 5 at $DIR/combine_transmutes.rs:+6:9: +6:11
scope 6 { scope 6 {
debug _a => _11; // in scope 6 at $DIR/combine_transmutes.rs:+6:9: +6:11 debug _a => _11; // in scope 6 at $DIR/combine_transmutes.rs:+6:9: +6:11
let _13: u8; // in scope 6 at $DIR/combine_transmutes.rs:+7:9: +7:11
scope 7 {
debug _a => _13; // in scope 7 at $DIR/combine_transmutes.rs:+7:9: +7:11
let _15: i16; // in scope 7 at $DIR/combine_transmutes.rs:+8:9: +8:11
scope 8 {
debug _a => _15; // in scope 8 at $DIR/combine_transmutes.rs:+8:9: +8:11
let _17: u16; // in scope 8 at $DIR/combine_transmutes.rs:+9:9: +9:11
scope 9 {
debug _a => _17; // in scope 9 at $DIR/combine_transmutes.rs:+9:9: +9:11
let _19: u32; // in scope 9 at $DIR/combine_transmutes.rs:+10:9: +10:11
scope 10 {
debug _a => _19; // in scope 10 at $DIR/combine_transmutes.rs:+10:9: +10:11
let _21: i32; // in scope 10 at $DIR/combine_transmutes.rs:+11:9: +11:11
scope 11 {
debug _a => _21; // in scope 11 at $DIR/combine_transmutes.rs:+11:9: +11:11
let _23: std::mem::ManuallyDrop<std::string::String>; // in scope 11 at $DIR/combine_transmutes.rs:+12:9: +12:11
scope 12 {
debug _a => _23; // in scope 12 at $DIR/combine_transmutes.rs:+12:9: +12:11
}
}
}
}
}
}
} }
} }
} }
@ -66,93 +36,55 @@
bb0: { bb0: {
StorageLive(_1); // scope 0 at $DIR/combine_transmutes.rs:+1:9: +1:11 StorageLive(_1); // scope 0 at $DIR/combine_transmutes.rs:+1:9: +1:11
StorageLive(_2); // scope 0 at $DIR/combine_transmutes.rs:+1:28: +1:41 StorageLive(_2); // scope 0 at $DIR/combine_transmutes.rs:+1:28: +1:58
_2 = EnumNoRepr::A; // scope 0 at $DIR/combine_transmutes.rs:+1:28: +1:41 _2 = Option::<NonZeroU8>::Some(const _); // scope 0 at $DIR/combine_transmutes.rs:+1:28: +1:58
_1 = move _2 as u8 (Transmute); // scope 0 at $DIR/combine_transmutes.rs:+1:18: +1:42 // mir::Constant
StorageDead(_2); // scope 0 at $DIR/combine_transmutes.rs:+1:41: +1:42 // + span: $DIR/combine_transmutes.rs:35:33: 35:57
// + literal: Const { ty: NonZeroU8, val: Unevaluated(NonZeroU8::MAX, [], None) }
_1 = move _2 as u8 (Transmute); // scope 0 at $DIR/combine_transmutes.rs:+1:18: +1:59
StorageDead(_2); // scope 0 at $DIR/combine_transmutes.rs:+1:58: +1:59
StorageLive(_3); // scope 1 at $DIR/combine_transmutes.rs:+2:9: +2:11 StorageLive(_3); // scope 1 at $DIR/combine_transmutes.rs:+2:9: +2:11
StorageLive(_4); // scope 1 at $DIR/combine_transmutes.rs:+2:28: +2:41 StorageLive(_4); // scope 1 at $DIR/combine_transmutes.rs:+2:29: +2:54
_4 = EnumNoRepr::B; // scope 1 at $DIR/combine_transmutes.rs:+2:28: +2:41 _4 = Wrapping::<i16>(const 0_i16); // scope 1 at $DIR/combine_transmutes.rs:+2:29: +2:54
_3 = move _4 as i8 (Transmute); // scope 1 at $DIR/combine_transmutes.rs:+2:18: +2:42 - _3 = move _4 as i16 (Transmute); // scope 1 at $DIR/combine_transmutes.rs:+2:19: +2:55
StorageDead(_4); // scope 1 at $DIR/combine_transmutes.rs:+2:41: +2:42 + _3 = move (_4.0: i16); // scope 1 at $DIR/combine_transmutes.rs:+2:19: +2:55
StorageDead(_4); // scope 1 at $DIR/combine_transmutes.rs:+2:54: +2:55
StorageLive(_5); // scope 2 at $DIR/combine_transmutes.rs:+3:9: +3:11 StorageLive(_5); // scope 2 at $DIR/combine_transmutes.rs:+3:9: +3:11
StorageLive(_6); // scope 2 at $DIR/combine_transmutes.rs:+3:31: +3:47 StorageLive(_6); // scope 2 at $DIR/combine_transmutes.rs:+3:29: +3:54
_6 = EnumReprIsize::A; // scope 2 at $DIR/combine_transmutes.rs:+3:31: +3:47 _6 = Wrapping::<i16>(const 0_i16); // scope 2 at $DIR/combine_transmutes.rs:+3:29: +3:54
_5 = move _6 as usize (Transmute); // scope 2 at $DIR/combine_transmutes.rs:+3:21: +3:48 _5 = move _6 as u16 (Transmute); // scope 2 at $DIR/combine_transmutes.rs:+3:19: +3:55
StorageDead(_6); // scope 2 at $DIR/combine_transmutes.rs:+3:47: +3:48 StorageDead(_6); // scope 2 at $DIR/combine_transmutes.rs:+3:54: +3:55
StorageLive(_7); // scope 3 at $DIR/combine_transmutes.rs:+4:9: +4:11 StorageLive(_7); // scope 3 at $DIR/combine_transmutes.rs:+4:9: +4:11
StorageLive(_8); // scope 3 at $DIR/combine_transmutes.rs:+4:31: +4:47 StorageLive(_8); // scope 3 at $DIR/combine_transmutes.rs:+4:29: +4:47
_8 = EnumReprIsize::B; // scope 3 at $DIR/combine_transmutes.rs:+4:31: +4:47 _8 = Union32 { u32: const 0_i32 }; // scope 3 at $DIR/combine_transmutes.rs:+4:29: +4:47
- _7 = move _8 as isize (Transmute); // scope 3 at $DIR/combine_transmutes.rs:+4:21: +4:48 _7 = move _8 as u32 (Transmute); // scope 3 at $DIR/combine_transmutes.rs:+4:19: +4:48
+ _7 = discriminant(_8); // scope 3 at $DIR/combine_transmutes.rs:+4:21: +4:48
StorageDead(_8); // scope 3 at $DIR/combine_transmutes.rs:+4:47: +4:48 StorageDead(_8); // scope 3 at $DIR/combine_transmutes.rs:+4:47: +4:48
StorageLive(_9); // scope 4 at $DIR/combine_transmutes.rs:+5:9: +5:11 StorageLive(_9); // scope 4 at $DIR/combine_transmutes.rs:+5:9: +5:11
StorageLive(_10); // scope 4 at $DIR/combine_transmutes.rs:+5:28: +5:52 StorageLive(_10); // scope 4 at $DIR/combine_transmutes.rs:+5:29: +5:47
_10 = Less; // scope 4 at $DIR/combine_transmutes.rs:+5:28: +5:52 _10 = Union32 { u32: const 0_u32 }; // scope 4 at $DIR/combine_transmutes.rs:+5:29: +5:47
_9 = move _10 as u8 (Transmute); // scope 4 at $DIR/combine_transmutes.rs:+5:18: +5:53 _9 = move _10 as i32 (Transmute); // scope 4 at $DIR/combine_transmutes.rs:+5:19: +5:48
StorageDead(_10); // scope 4 at $DIR/combine_transmutes.rs:+5:52: +5:53 StorageDead(_10); // scope 4 at $DIR/combine_transmutes.rs:+5:47: +5:48
StorageLive(_11); // scope 5 at $DIR/combine_transmutes.rs:+6:9: +6:11 StorageLive(_11); // scope 5 at $DIR/combine_transmutes.rs:+6:9: +6:11
StorageLive(_12); // scope 5 at $DIR/combine_transmutes.rs:+6:28: +6:52 StorageLive(_12); // scope 5 at $DIR/combine_transmutes.rs:+6:46: +6:77
_12 = Less; // scope 5 at $DIR/combine_transmutes.rs:+6:28: +6:52 _12 = MaybeUninit::<String>::uninit() -> [return: bb1, unwind unreachable]; // scope 5 at $DIR/combine_transmutes.rs:+6:46: +6:77
- _11 = move _12 as i8 (Transmute); // scope 5 at $DIR/combine_transmutes.rs:+6:18: +6:53
+ _11 = discriminant(_12); // scope 5 at $DIR/combine_transmutes.rs:+6:18: +6:53
StorageDead(_12); // scope 5 at $DIR/combine_transmutes.rs:+6:52: +6:53
StorageLive(_13); // scope 6 at $DIR/combine_transmutes.rs:+7:9: +7:11
StorageLive(_14); // scope 6 at $DIR/combine_transmutes.rs:+7:28: +7:58
_14 = Option::<NonZeroU8>::Some(const _); // scope 6 at $DIR/combine_transmutes.rs:+7:28: +7:58
// mir::Constant // mir::Constant
// + span: $DIR/combine_transmutes.rs:41:33: 41:57 // + span: $DIR/combine_transmutes.rs:40:46: 40:75
// + literal: Const { ty: NonZeroU8, val: Unevaluated(NonZeroU8::MAX, [], None) } // + user_ty: UserType(11)
_13 = move _14 as u8 (Transmute); // scope 6 at $DIR/combine_transmutes.rs:+7:18: +7:59
StorageDead(_14); // scope 6 at $DIR/combine_transmutes.rs:+7:58: +7:59
StorageLive(_15); // scope 7 at $DIR/combine_transmutes.rs:+8:9: +8:11
StorageLive(_16); // scope 7 at $DIR/combine_transmutes.rs:+8:29: +8:54
_16 = Wrapping::<i16>(const 0_i16); // scope 7 at $DIR/combine_transmutes.rs:+8:29: +8:54
- _15 = move _16 as i16 (Transmute); // scope 7 at $DIR/combine_transmutes.rs:+8:19: +8:55
+ _15 = move (_16.0: i16); // scope 7 at $DIR/combine_transmutes.rs:+8:19: +8:55
StorageDead(_16); // scope 7 at $DIR/combine_transmutes.rs:+8:54: +8:55
StorageLive(_17); // scope 8 at $DIR/combine_transmutes.rs:+9:9: +9:11
StorageLive(_18); // scope 8 at $DIR/combine_transmutes.rs:+9:29: +9:54
_18 = Wrapping::<i16>(const 0_i16); // scope 8 at $DIR/combine_transmutes.rs:+9:29: +9:54
_17 = move _18 as u16 (Transmute); // scope 8 at $DIR/combine_transmutes.rs:+9:19: +9:55
StorageDead(_18); // scope 8 at $DIR/combine_transmutes.rs:+9:54: +9:55
StorageLive(_19); // scope 9 at $DIR/combine_transmutes.rs:+10:9: +10:11
StorageLive(_20); // scope 9 at $DIR/combine_transmutes.rs:+10:29: +10:47
_20 = Union32 { u32: const 0_i32 }; // scope 9 at $DIR/combine_transmutes.rs:+10:29: +10:47
_19 = move _20 as u32 (Transmute); // scope 9 at $DIR/combine_transmutes.rs:+10:19: +10:48
StorageDead(_20); // scope 9 at $DIR/combine_transmutes.rs:+10:47: +10:48
StorageLive(_21); // scope 10 at $DIR/combine_transmutes.rs:+11:9: +11:11
StorageLive(_22); // scope 10 at $DIR/combine_transmutes.rs:+11:29: +11:47
_22 = Union32 { u32: const 0_u32 }; // scope 10 at $DIR/combine_transmutes.rs:+11:29: +11:47
_21 = move _22 as i32 (Transmute); // scope 10 at $DIR/combine_transmutes.rs:+11:19: +11:48
StorageDead(_22); // scope 10 at $DIR/combine_transmutes.rs:+11:47: +11:48
StorageLive(_23); // scope 11 at $DIR/combine_transmutes.rs:+12:9: +12:11
StorageLive(_24); // scope 11 at $DIR/combine_transmutes.rs:+12:46: +12:77
_24 = MaybeUninit::<String>::uninit() -> [return: bb1, unwind unreachable]; // scope 11 at $DIR/combine_transmutes.rs:+12:46: +12:77
// mir::Constant
// + span: $DIR/combine_transmutes.rs:46:46: 46:75
// + user_ty: UserType(23)
// + literal: Const { ty: fn() -> MaybeUninit<String> {MaybeUninit::<String>::uninit}, val: Value(<ZST>) } // + literal: Const { ty: fn() -> MaybeUninit<String> {MaybeUninit::<String>::uninit}, val: Value(<ZST>) }
} }
bb1: { bb1: {
- _23 = move _24 as std::mem::ManuallyDrop<std::string::String> (Transmute); // scope 11 at $DIR/combine_transmutes.rs:+12:36: +12:78 - _11 = move _12 as std::mem::ManuallyDrop<std::string::String> (Transmute); // scope 5 at $DIR/combine_transmutes.rs:+6:36: +6:78
+ _23 = move (_24.1: std::mem::ManuallyDrop<std::string::String>); // scope 11 at $DIR/combine_transmutes.rs:+12:36: +12:78 + _11 = move (_12.1: std::mem::ManuallyDrop<std::string::String>); // scope 5 at $DIR/combine_transmutes.rs:+6:36: +6:78
StorageDead(_24); // scope 11 at $DIR/combine_transmutes.rs:+12:77: +12:78 StorageDead(_12); // scope 5 at $DIR/combine_transmutes.rs:+6:77: +6:78
_0 = const (); // scope 0 at $DIR/combine_transmutes.rs:+0:32: +13:2 _0 = const (); // scope 0 at $DIR/combine_transmutes.rs:+0:32: +7:2
StorageDead(_23); // scope 11 at $DIR/combine_transmutes.rs:+13:1: +13:2 StorageDead(_11); // scope 5 at $DIR/combine_transmutes.rs:+7:1: +7:2
StorageDead(_21); // scope 10 at $DIR/combine_transmutes.rs:+13:1: +13:2 StorageDead(_9); // scope 4 at $DIR/combine_transmutes.rs:+7:1: +7:2
StorageDead(_19); // scope 9 at $DIR/combine_transmutes.rs:+13:1: +13:2 StorageDead(_7); // scope 3 at $DIR/combine_transmutes.rs:+7:1: +7:2
StorageDead(_17); // scope 8 at $DIR/combine_transmutes.rs:+13:1: +13:2 StorageDead(_5); // scope 2 at $DIR/combine_transmutes.rs:+7:1: +7:2
StorageDead(_15); // scope 7 at $DIR/combine_transmutes.rs:+13:1: +13:2 StorageDead(_3); // scope 1 at $DIR/combine_transmutes.rs:+7:1: +7:2
StorageDead(_13); // scope 6 at $DIR/combine_transmutes.rs:+13:1: +13:2 StorageDead(_1); // scope 0 at $DIR/combine_transmutes.rs:+7:1: +7:2
StorageDead(_11); // scope 5 at $DIR/combine_transmutes.rs:+13:1: +13:2 return; // scope 0 at $DIR/combine_transmutes.rs:+7:2: +7:2
StorageDead(_9); // scope 4 at $DIR/combine_transmutes.rs:+13:1: +13:2
StorageDead(_7); // scope 3 at $DIR/combine_transmutes.rs:+13:1: +13:2
StorageDead(_5); // scope 2 at $DIR/combine_transmutes.rs:+13:1: +13:2
StorageDead(_3); // scope 1 at $DIR/combine_transmutes.rs:+13:1: +13:2
StorageDead(_1); // scope 0 at $DIR/combine_transmutes.rs:+13:1: +13:2
return; // scope 0 at $DIR/combine_transmutes.rs:+13:2: +13:2
} }
} }

View file

@ -32,12 +32,6 @@ pub unsafe fn integer_transmutes() {
// EMIT_MIR combine_transmutes.adt_transmutes.InstSimplify.diff // EMIT_MIR combine_transmutes.adt_transmutes.InstSimplify.diff
pub unsafe fn adt_transmutes() { pub unsafe fn adt_transmutes() {
let _a: u8 = transmute(EnumNoRepr::A);
let _a: i8 = transmute(EnumNoRepr::B);
let _a: usize = transmute(EnumReprIsize::A);
let _a: isize = transmute(EnumReprIsize::B);
let _a: u8 = transmute(std::cmp::Ordering::Less);
let _a: i8 = transmute(std::cmp::Ordering::Less);
let _a: u8 = transmute(Some(std::num::NonZeroU8::MAX)); let _a: u8 = transmute(Some(std::num::NonZeroU8::MAX));
let _a: i16 = transmute(std::num::Wrapping(0_i16)); let _a: i16 = transmute(std::num::Wrapping(0_i16));
let _a: u16 = transmute(std::num::Wrapping(0_i16)); let _a: u16 = transmute(std::num::Wrapping(0_i16));
@ -46,20 +40,4 @@ pub unsafe fn adt_transmutes() {
let _a: ManuallyDrop<String> = transmute(MaybeUninit::<String>::uninit()); let _a: ManuallyDrop<String> = transmute(MaybeUninit::<String>::uninit());
} }
#[inline(always)]
#[custom_mir(dialect = "runtime", phase = "initial")]
const unsafe fn mir_transmute<T, U>(x: T) -> U {
mir!{
{
RET = CastTransmute(x);
Return()
}
}
}
pub enum EnumNoRepr { A, B, C }
#[repr(isize)]
pub enum EnumReprIsize { A, B, C }
pub union Union32 { u32: u32, i32: i32 } pub union Union32 { u32: u32, i32: i32 }