Auto merge of #148190 - RalfJung:box_new, r=RalfJung
replace box_new with lower-level intrinsics The `box_new` intrinsic is super special: during THIR construction it turns into an `ExprKind::Box` (formerly known as the `box` keyword), which then during MIR building turns into a special instruction sequence that invokes the exchange_malloc lang item (which has a name from a different time) and a special MIR statement to represent a shallowly-initialized `Box` (which raises [interesting opsem questions](https://github.com/rust-lang/rust/issues/97270)). This PR is the n-th attempt to get rid of `box_new`. That's non-trivial because it usually causes a perf regression: replacing `box_new` by naive unsafe code will incur extra copies in debug builds, making the resulting binaries a lot slower, and will generate a lot more MIR, making compilation measurably slower. Furthermore, `vec!` is a macro, so the exact code it expands to is highly relevant for borrow checking, type inference, and temporary scopes. To avoid those problems, this PR does its best to make the MIR almost exactly the same as what it was before. `box_new` is used in two places, `Box::new` and `vec!`: - For `Box::new` that is fairly easy: the `move_by_value` intrinsic is basically all we need. However, to avoid the extra copy that would usually be generated for the argument of a function call, we need to special-case this intrinsic during MIR building. That's what the first commit does. - `vec!` is a lot more tricky. As a macro, its details leak to stable code, so almost every variant I tried broke either type inference or the lifetimes of temporaries in some ui test or ended up accepting unsound code due to the borrow checker not enforcing all the constraints I hoped it would enforce. I ended up with a variant that involves a new intrinsic, `fn write_box_via_move<T>(b: Box<MaybeUninit<T>>, x: T) -> Box<MaybeUninit<T>>`, that writes a value into a `Box<MaybeUninit<T>>` and returns that box again. In exchange we can get rid of somewhat similar code in the lowering for `ExprKind::Box`, and the `exchange_malloc` lang item. (We can also get rid of `Rvalue::ShallowInitBox`; I didn't include that in this PR -- I think @cjgillot has a commit for this somewhere [around here](https://github.com/rust-lang/rust/pull/147862/commits).) See [here](https://github.com/rust-lang/rust/pull/148190#issuecomment-3457454814) for the latest perf numbers. Most of the regressions are in deep-vector which consists entirely of an invocation of `vec!`, so any change to that macro affects this benchmark disproportionally. This is my first time even looking at MIR building code, so I am very low confidence in that part of the patch, in particular when it comes to scopes and drops and things like that. I also had do nerf some clippy tests because clippy gets confused by the new expansion of `vec!` so it makes fewer suggestions when `vec!` is involved. ### `vec!` FAQ - Why does `write_box_via_move` return the `Box` again? Because we need to expand `vec!` to a bunch of method invocations without any blocks or let-statements, or else the temporary scopes (and type inference) don't work out. - Why is `box_assume_init_into_vec_unsafe` (unsoundly!) a safe function? Because we can't use an unsafe block in `vec!` as that would necessarily also include the `$x` (due to it all being one big method invocation) and therefore interpret the user's code as being inside `unsafe`, which would be bad (and 10 years later, we still don't have safe blocks for macros like this). - Why does `write_box_via_move` use `Box` as input/output type, and not, say, raw pointers? Because that is the only way to get the correct behavior when `$x` panics or has control effects: we need the `Box` to be dropped in that case. (As a nice side-effect this also makes the intrinsic safe, which is imported as explained in the previous bullet.) - Can't we make it safe by having `write_box_via_move` return `Box<T>`? Yes we could, but there's no easy way for the intrinsic to convert its `Box<MaybeUninit<T>>` to a `Box<T>`. Transmuting would be unsound as the borrow checker would no longer properly enforce that lifetimes involved in a `vec!` invocation behave correctly. - Is this macro truly cursed? Yes, yes it is.
This commit is contained in:
commit
3c9faa0d03
100 changed files with 1256 additions and 1508 deletions
|
|
@ -42,7 +42,6 @@ pub fn foo2() -> Box<dyn TestTrait2> {
|
|||
}
|
||||
|
||||
//~ MONO_ITEM fn <TestStruct2 as TestTrait2>::test_func2
|
||||
//~ MONO_ITEM fn alloc::alloc::exchange_malloc
|
||||
//~ MONO_ITEM fn foo2
|
||||
//~ MONO_ITEM fn std::alloc::Global::alloc_impl_runtime
|
||||
//~ MONO_ITEM fn std::boxed::Box::<TestStruct2>::new
|
||||
|
|
|
|||
|
|
@ -1,89 +0,0 @@
|
|||
- // MIR for `main` before ElaborateDrops
|
||||
+ // MIR for `main` after ElaborateDrops
|
||||
|
||||
fn main() -> () {
|
||||
let mut _0: ();
|
||||
let _1: std::boxed::Box<S>;
|
||||
let mut _2: *mut u8;
|
||||
let mut _3: std::boxed::Box<S>;
|
||||
let _4: ();
|
||||
let mut _5: std::boxed::Box<S>;
|
||||
+ let mut _6: &mut std::boxed::Box<S>;
|
||||
+ let mut _7: ();
|
||||
+ let mut _8: *const S;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
_2 = alloc::alloc::exchange_malloc(const <S as std::mem::SizedTypeProperties>::SIZE, const <S as std::mem::SizedTypeProperties>::ALIGN) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageLive(_3);
|
||||
_3 = ShallowInitBox(move _2, S);
|
||||
(*_3) = S::new() -> [return: bb2, unwind: bb8];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
_1 = move _3;
|
||||
- drop(_3) -> [return: bb3, unwind continue];
|
||||
+ goto -> bb3;
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageDead(_3);
|
||||
StorageLive(_4);
|
||||
StorageLive(_5);
|
||||
_5 = move _1;
|
||||
_4 = std::mem::drop::<Box<S>>(move _5) -> [return: bb4, unwind: bb6];
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageDead(_5);
|
||||
StorageDead(_4);
|
||||
_0 = const ();
|
||||
- drop(_1) -> [return: bb5, unwind continue];
|
||||
+ goto -> bb5;
|
||||
}
|
||||
|
||||
bb5: {
|
||||
StorageDead(_1);
|
||||
return;
|
||||
}
|
||||
|
||||
bb6 (cleanup): {
|
||||
- drop(_5) -> [return: bb7, unwind terminate(cleanup)];
|
||||
+ goto -> bb7;
|
||||
}
|
||||
|
||||
bb7 (cleanup): {
|
||||
- drop(_1) -> [return: bb9, unwind terminate(cleanup)];
|
||||
+ goto -> bb9;
|
||||
}
|
||||
|
||||
bb8 (cleanup): {
|
||||
- drop(_3) -> [return: bb9, unwind terminate(cleanup)];
|
||||
+ goto -> bb12;
|
||||
}
|
||||
|
||||
bb9 (cleanup): {
|
||||
resume;
|
||||
+ }
|
||||
+
|
||||
+ bb10 (cleanup): {
|
||||
+ _6 = &mut _3;
|
||||
+ _7 = <Box<S> as Drop>::drop(move _6) -> [return: bb9, unwind terminate(cleanup)];
|
||||
+ }
|
||||
+
|
||||
+ bb11 (cleanup): {
|
||||
+ goto -> bb10;
|
||||
+ }
|
||||
+
|
||||
+ bb12 (cleanup): {
|
||||
+ _8 = copy ((_3.0: std::ptr::Unique<S>).0: std::ptr::NonNull<S>) as *const S (Transmute);
|
||||
+ goto -> bb11;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
//@ test-mir-pass: ElaborateDrops
|
||||
//@ needs-unwind
|
||||
|
||||
#![feature(rustc_attrs, liballoc_internals)]
|
||||
|
||||
// EMIT_MIR box_expr.main.ElaborateDrops.diff
|
||||
fn main() {
|
||||
// CHECK-LABEL: fn main(
|
||||
// CHECK: [[ptr:_.*]] = move {{_.*}} as *const S (Transmute);
|
||||
// CHECK: [[nonnull:_.*]] = NonNull::<S> { pointer: move [[ptr]] };
|
||||
// CHECK: [[unique:_.*]] = std::ptr::Unique::<S> { pointer: move [[nonnull]], _marker: const PhantomData::<S> };
|
||||
// CHECK: [[box:_.*]] = Box::<S>(move [[unique]], const std::alloc::Global);
|
||||
// CHECK: [[ptr:_.*]] = copy (([[box]].0: std::ptr::Unique<S>).0: std::ptr::NonNull<S>) as *const S (Transmute);
|
||||
// CHECK: (*[[ptr]]) = S::new() -> [return: [[ret:bb.*]], unwind: [[unwind:bb.*]]];
|
||||
// CHECK: [[ret]]: {
|
||||
// CHECK: [[box2:_.*]] = move [[box]];
|
||||
// CHECK: [[box3:_.*]] = move [[box2]];
|
||||
// CHECK: std::mem::drop::<Box<S>>(move [[box3]])
|
||||
// CHECK: [[unwind]] (cleanup): {
|
||||
// CHECK: [[boxref:_.*]] = &mut [[box]];
|
||||
// CHECK: <Box<S> as Drop>::drop(move [[boxref]])
|
||||
|
||||
let x = std::boxed::box_new(S::new());
|
||||
drop(x);
|
||||
}
|
||||
|
||||
struct S;
|
||||
|
||||
impl S {
|
||||
fn new() -> Self {
|
||||
S
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for S {
|
||||
fn drop(&mut self) {
|
||||
println!("splat!");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
// MIR for `move_out_by_subslice` after CleanupPostBorrowck
|
||||
|
||||
fn move_out_by_subslice() -> () {
|
||||
let mut _0: ();
|
||||
let _1: [std::boxed::Box<i32>; 2];
|
||||
let mut _2: std::boxed::Box<i32>;
|
||||
let mut _3: std::boxed::Box<i32>;
|
||||
scope 1 {
|
||||
debug a => _1;
|
||||
let _4: [std::boxed::Box<i32>; 2];
|
||||
scope 2 {
|
||||
debug _y => _4;
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
StorageLive(_2);
|
||||
_2 = Box::<i32>::new(const 1_i32) -> [return: bb1, unwind: bb9];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageLive(_3);
|
||||
_3 = Box::<i32>::new(const 2_i32) -> [return: bb2, unwind: bb8];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
_1 = [move _2, move _3];
|
||||
drop(_3) -> [return: bb3, unwind: bb8];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageDead(_3);
|
||||
drop(_2) -> [return: bb4, unwind: bb9];
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageDead(_2);
|
||||
nop;
|
||||
PlaceMention(_1);
|
||||
StorageLive(_4);
|
||||
_4 = move _1[0..2];
|
||||
_0 = const ();
|
||||
drop(_4) -> [return: bb5, unwind: bb7];
|
||||
}
|
||||
|
||||
bb5: {
|
||||
StorageDead(_4);
|
||||
drop(_1) -> [return: bb6, unwind: bb9];
|
||||
}
|
||||
|
||||
bb6: {
|
||||
StorageDead(_1);
|
||||
return;
|
||||
}
|
||||
|
||||
bb7 (cleanup): {
|
||||
drop(_1) -> [return: bb9, unwind terminate(cleanup)];
|
||||
}
|
||||
|
||||
bb8 (cleanup): {
|
||||
drop(_2) -> [return: bb9, unwind terminate(cleanup)];
|
||||
}
|
||||
|
||||
bb9 (cleanup): {
|
||||
resume;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
// MIR for `move_out_by_subslice` after built
|
||||
|
||||
fn move_out_by_subslice() -> () {
|
||||
let mut _0: ();
|
||||
let _1: [std::boxed::Box<i32>; 2];
|
||||
let mut _2: std::boxed::Box<i32>;
|
||||
let mut _3: *mut u8;
|
||||
let mut _4: std::boxed::Box<i32>;
|
||||
let mut _5: std::boxed::Box<i32>;
|
||||
let mut _6: *mut u8;
|
||||
let mut _7: std::boxed::Box<i32>;
|
||||
scope 1 {
|
||||
debug a => _1;
|
||||
let _8: [std::boxed::Box<i32>; 2];
|
||||
scope 2 {
|
||||
debug _y => _8;
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
StorageLive(_2);
|
||||
_3 = alloc::alloc::exchange_malloc(const <i32 as std::mem::SizedTypeProperties>::SIZE, const <i32 as std::mem::SizedTypeProperties>::ALIGN) -> [return: bb1, unwind: bb13];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageLive(_4);
|
||||
_4 = ShallowInitBox(move _3, i32);
|
||||
(*_4) = const 1_i32;
|
||||
_2 = move _4;
|
||||
drop(_4) -> [return: bb2, unwind: bb12];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageDead(_4);
|
||||
StorageLive(_5);
|
||||
_6 = alloc::alloc::exchange_malloc(const <i32 as std::mem::SizedTypeProperties>::SIZE, const <i32 as std::mem::SizedTypeProperties>::ALIGN) -> [return: bb3, unwind: bb12];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageLive(_7);
|
||||
_7 = ShallowInitBox(move _6, i32);
|
||||
(*_7) = const 2_i32;
|
||||
_5 = move _7;
|
||||
drop(_7) -> [return: bb4, unwind: bb11];
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageDead(_7);
|
||||
_1 = [move _2, move _5];
|
||||
drop(_5) -> [return: bb5, unwind: bb12];
|
||||
}
|
||||
|
||||
bb5: {
|
||||
StorageDead(_5);
|
||||
drop(_2) -> [return: bb6, unwind: bb13];
|
||||
}
|
||||
|
||||
bb6: {
|
||||
StorageDead(_2);
|
||||
FakeRead(ForLet(None), _1);
|
||||
PlaceMention(_1);
|
||||
StorageLive(_8);
|
||||
_8 = move _1[0..2];
|
||||
_0 = const ();
|
||||
drop(_8) -> [return: bb8, unwind: bb10];
|
||||
}
|
||||
|
||||
bb7: {
|
||||
FakeRead(ForMatchedPlace(None), _1);
|
||||
unreachable;
|
||||
}
|
||||
|
||||
bb8: {
|
||||
StorageDead(_8);
|
||||
drop(_1) -> [return: bb9, unwind: bb13];
|
||||
}
|
||||
|
||||
bb9: {
|
||||
StorageDead(_1);
|
||||
return;
|
||||
}
|
||||
|
||||
bb10 (cleanup): {
|
||||
drop(_1) -> [return: bb13, unwind terminate(cleanup)];
|
||||
}
|
||||
|
||||
bb11 (cleanup): {
|
||||
drop(_5) -> [return: bb12, unwind terminate(cleanup)];
|
||||
}
|
||||
|
||||
bb12 (cleanup): {
|
||||
drop(_2) -> [return: bb13, unwind terminate(cleanup)];
|
||||
}
|
||||
|
||||
bb13 (cleanup): {
|
||||
resume;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
// MIR for `move_out_from_end` after CleanupPostBorrowck
|
||||
|
||||
fn move_out_from_end() -> () {
|
||||
let mut _0: ();
|
||||
let _1: [std::boxed::Box<i32>; 2];
|
||||
let mut _2: std::boxed::Box<i32>;
|
||||
let mut _3: std::boxed::Box<i32>;
|
||||
scope 1 {
|
||||
debug a => _1;
|
||||
let _4: std::boxed::Box<i32>;
|
||||
scope 2 {
|
||||
debug _y => _4;
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
StorageLive(_2);
|
||||
_2 = Box::<i32>::new(const 1_i32) -> [return: bb1, unwind: bb9];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageLive(_3);
|
||||
_3 = Box::<i32>::new(const 2_i32) -> [return: bb2, unwind: bb8];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
_1 = [move _2, move _3];
|
||||
drop(_3) -> [return: bb3, unwind: bb8];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageDead(_3);
|
||||
drop(_2) -> [return: bb4, unwind: bb9];
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageDead(_2);
|
||||
nop;
|
||||
PlaceMention(_1);
|
||||
StorageLive(_4);
|
||||
_4 = move _1[1 of 2];
|
||||
_0 = const ();
|
||||
drop(_4) -> [return: bb5, unwind: bb7];
|
||||
}
|
||||
|
||||
bb5: {
|
||||
StorageDead(_4);
|
||||
drop(_1) -> [return: bb6, unwind: bb9];
|
||||
}
|
||||
|
||||
bb6: {
|
||||
StorageDead(_1);
|
||||
return;
|
||||
}
|
||||
|
||||
bb7 (cleanup): {
|
||||
drop(_1) -> [return: bb9, unwind terminate(cleanup)];
|
||||
}
|
||||
|
||||
bb8 (cleanup): {
|
||||
drop(_2) -> [return: bb9, unwind terminate(cleanup)];
|
||||
}
|
||||
|
||||
bb9 (cleanup): {
|
||||
resume;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
// MIR for `move_out_from_end` after built
|
||||
|
||||
fn move_out_from_end() -> () {
|
||||
let mut _0: ();
|
||||
let _1: [std::boxed::Box<i32>; 2];
|
||||
let mut _2: std::boxed::Box<i32>;
|
||||
let mut _3: *mut u8;
|
||||
let mut _4: std::boxed::Box<i32>;
|
||||
let mut _5: std::boxed::Box<i32>;
|
||||
let mut _6: *mut u8;
|
||||
let mut _7: std::boxed::Box<i32>;
|
||||
scope 1 {
|
||||
debug a => _1;
|
||||
let _8: std::boxed::Box<i32>;
|
||||
scope 2 {
|
||||
debug _y => _8;
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
StorageLive(_2);
|
||||
_3 = alloc::alloc::exchange_malloc(const <i32 as std::mem::SizedTypeProperties>::SIZE, const <i32 as std::mem::SizedTypeProperties>::ALIGN) -> [return: bb1, unwind: bb13];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageLive(_4);
|
||||
_4 = ShallowInitBox(move _3, i32);
|
||||
(*_4) = const 1_i32;
|
||||
_2 = move _4;
|
||||
drop(_4) -> [return: bb2, unwind: bb12];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageDead(_4);
|
||||
StorageLive(_5);
|
||||
_6 = alloc::alloc::exchange_malloc(const <i32 as std::mem::SizedTypeProperties>::SIZE, const <i32 as std::mem::SizedTypeProperties>::ALIGN) -> [return: bb3, unwind: bb12];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageLive(_7);
|
||||
_7 = ShallowInitBox(move _6, i32);
|
||||
(*_7) = const 2_i32;
|
||||
_5 = move _7;
|
||||
drop(_7) -> [return: bb4, unwind: bb11];
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageDead(_7);
|
||||
_1 = [move _2, move _5];
|
||||
drop(_5) -> [return: bb5, unwind: bb12];
|
||||
}
|
||||
|
||||
bb5: {
|
||||
StorageDead(_5);
|
||||
drop(_2) -> [return: bb6, unwind: bb13];
|
||||
}
|
||||
|
||||
bb6: {
|
||||
StorageDead(_2);
|
||||
FakeRead(ForLet(None), _1);
|
||||
PlaceMention(_1);
|
||||
StorageLive(_8);
|
||||
_8 = move _1[1 of 2];
|
||||
_0 = const ();
|
||||
drop(_8) -> [return: bb8, unwind: bb10];
|
||||
}
|
||||
|
||||
bb7: {
|
||||
FakeRead(ForMatchedPlace(None), _1);
|
||||
unreachable;
|
||||
}
|
||||
|
||||
bb8: {
|
||||
StorageDead(_8);
|
||||
drop(_1) -> [return: bb9, unwind: bb13];
|
||||
}
|
||||
|
||||
bb9: {
|
||||
StorageDead(_1);
|
||||
return;
|
||||
}
|
||||
|
||||
bb10 (cleanup): {
|
||||
drop(_1) -> [return: bb13, unwind terminate(cleanup)];
|
||||
}
|
||||
|
||||
bb11 (cleanup): {
|
||||
drop(_5) -> [return: bb12, unwind terminate(cleanup)];
|
||||
}
|
||||
|
||||
bb12 (cleanup): {
|
||||
drop(_2) -> [return: bb13, unwind terminate(cleanup)];
|
||||
}
|
||||
|
||||
bb13 (cleanup): {
|
||||
resume;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +1,17 @@
|
|||
//@ compile-flags: -Zmir-opt-level=0
|
||||
// skip-filecheck
|
||||
#![feature(liballoc_internals, rustc_attrs)]
|
||||
|
||||
// EMIT_MIR uniform_array_move_out.move_out_from_end.built.after.mir
|
||||
// Can't emit `built.after` here as that contains user type annotations which contain DefId that
|
||||
// change all the time.
|
||||
// EMIT_MIR uniform_array_move_out.move_out_from_end.CleanupPostBorrowck.after.mir
|
||||
fn move_out_from_end() {
|
||||
let a = [std::boxed::box_new(1), std::boxed::box_new(2)];
|
||||
let a = [Box::new(1), Box::new(2)];
|
||||
let [.., _y] = a;
|
||||
}
|
||||
|
||||
// EMIT_MIR uniform_array_move_out.move_out_by_subslice.built.after.mir
|
||||
// EMIT_MIR uniform_array_move_out.move_out_by_subslice.CleanupPostBorrowck.after.mir
|
||||
fn move_out_by_subslice() {
|
||||
let a = [std::boxed::box_new(1), std::boxed::box_new(2)];
|
||||
let a = [Box::new(1), Box::new(2)];
|
||||
let [_y @ ..] = a;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
// MIR for `box_new` after CleanupPostBorrowck
|
||||
|
||||
fn box_new(_1: T) -> Box<[T; 1024]> {
|
||||
debug x => _1;
|
||||
let mut _0: std::boxed::Box<[T; 1024]>;
|
||||
let mut _2: std::boxed::Box<std::mem::MaybeUninit<[T; 1024]>>;
|
||||
let mut _3: std::boxed::Box<std::mem::MaybeUninit<[T; 1024]>>;
|
||||
let mut _4: std::boxed::Box<std::mem::MaybeUninit<[T; 1024]>>;
|
||||
let mut _5: T;
|
||||
scope 1 {
|
||||
debug b => _2;
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2);
|
||||
_2 = Box::<[T; 1024]>::new_uninit() -> [return: bb1, unwind: bb7];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
nop;
|
||||
StorageLive(_3);
|
||||
StorageLive(_4);
|
||||
_4 = move _2;
|
||||
StorageLive(_5);
|
||||
_5 = copy _1;
|
||||
((((*_4).1: std::mem::ManuallyDrop<[T; 1024]>).0: std::mem::MaybeDangling<[T; 1024]>).0: [T; 1024]) = [move _5; 1024];
|
||||
StorageDead(_5);
|
||||
_3 = move _4;
|
||||
drop(_4) -> [return: bb2, unwind: bb5];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageDead(_4);
|
||||
_0 = Box::<MaybeUninit<[T; 1024]>>::assume_init(move _3) -> [return: bb3, unwind: bb5];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageDead(_3);
|
||||
drop(_2) -> [return: bb4, unwind: bb7];
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageDead(_2);
|
||||
return;
|
||||
}
|
||||
|
||||
bb5 (cleanup): {
|
||||
drop(_3) -> [return: bb6, unwind terminate(cleanup)];
|
||||
}
|
||||
|
||||
bb6 (cleanup): {
|
||||
drop(_2) -> [return: bb7, unwind terminate(cleanup)];
|
||||
}
|
||||
|
||||
bb7 (cleanup): {
|
||||
resume;
|
||||
}
|
||||
}
|
||||
29
tests/mir-opt/building/write_box_via_move.rs
Normal file
29
tests/mir-opt/building/write_box_via_move.rs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
//! Ensure we don't generate unnecessary copys for `write_via_move`.
|
||||
//@ compile-flags: -Zmir-opt-level=0
|
||||
#![feature(liballoc_internals)]
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
// Can't emit `built.after` here as that contains user type annotations which contain DefId that
|
||||
// change all the time.
|
||||
// EMIT_MIR write_box_via_move.box_new.CleanupPostBorrowck.after.mir
|
||||
// CHECK-LABEL: fn box_new
|
||||
#[inline(never)]
|
||||
fn box_new<T: Copy>(x: T) -> Box<[T; 1024]> {
|
||||
let mut b = Box::new_uninit();
|
||||
// Ensure the array gets constructed directly into the deref'd pointer.
|
||||
// CHECK: (*[[TEMP1:_.+]]) = [{{(move|copy) _.+}}; 1024];
|
||||
unsafe { alloc::intrinsics::write_box_via_move(b, [x; 1024]).assume_init() }
|
||||
}
|
||||
|
||||
// EMIT_MIR write_box_via_move.vec_macro.CleanupPostBorrowck.after.mir
|
||||
// CHECK-LABEL: fn vec_macro
|
||||
fn vec_macro() -> Vec<i32> {
|
||||
// CHECK: (*[[TEMP1:_.+]]) = [const 0_i32, const 1_i32,
|
||||
vec![0, 1, 2, 3, 4, 5, 6, 7]
|
||||
}
|
||||
|
||||
fn main() {
|
||||
box_new(0);
|
||||
vec_macro();
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
// MIR for `vec_macro` after CleanupPostBorrowck
|
||||
|
||||
fn vec_macro() -> Vec<i32> {
|
||||
let mut _0: std::vec::Vec<i32>;
|
||||
let mut _1: std::boxed::Box<std::mem::MaybeUninit<[i32; 8]>>;
|
||||
let mut _2: std::boxed::Box<std::mem::MaybeUninit<[i32; 8]>>;
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
StorageLive(_2);
|
||||
_2 = Box::<[i32; 8]>::new_uninit() -> [return: bb1, unwind: bb5];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
((((*_2).1: std::mem::ManuallyDrop<[i32; 8]>).0: std::mem::MaybeDangling<[i32; 8]>).0: [i32; 8]) = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32, const 6_i32, const 7_i32];
|
||||
_1 = move _2;
|
||||
drop(_2) -> [return: bb2, unwind: bb4];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageDead(_2);
|
||||
_0 = std::boxed::box_assume_init_into_vec_unsafe::<i32, 8>(move _1) -> [return: bb3, unwind: bb4];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageDead(_1);
|
||||
return;
|
||||
}
|
||||
|
||||
bb4 (cleanup): {
|
||||
drop(_1) -> [return: bb5, unwind terminate(cleanup)];
|
||||
}
|
||||
|
||||
bb5 (cleanup): {
|
||||
resume;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
// MIR for `box_new` after CleanupPostBorrowck
|
||||
|
||||
fn box_new(_1: T) -> Box<[T; 1024]> {
|
||||
debug x => _1;
|
||||
let mut _0: std::boxed::Box<[T; 1024]>;
|
||||
let mut _2: std::boxed::Box<std::mem::MaybeUninit<[T; 1024]>>;
|
||||
let mut _4: &mut std::mem::MaybeUninit<[T; 1024]>;
|
||||
let mut _5: &mut std::mem::MaybeUninit<[T; 1024]>;
|
||||
let _6: ();
|
||||
let mut _7: *mut [T; 1024];
|
||||
let mut _8: T;
|
||||
let mut _9: std::boxed::Box<std::mem::MaybeUninit<[T; 1024]>>;
|
||||
scope 1 {
|
||||
debug b => _2;
|
||||
let _3: *mut [T; 1024];
|
||||
scope 2 {
|
||||
debug ptr => _3;
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2);
|
||||
_2 = Box::<[T; 1024]>::new_uninit() -> [return: bb1, unwind: bb7];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
nop;
|
||||
StorageLive(_3);
|
||||
StorageLive(_4);
|
||||
StorageLive(_5);
|
||||
_5 = &mut (*_2);
|
||||
_4 = &mut (*_5);
|
||||
_3 = MaybeUninit::<[T; 1024]>::as_mut_ptr(move _4) -> [return: bb2, unwind: bb6];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageDead(_4);
|
||||
nop;
|
||||
StorageDead(_5);
|
||||
StorageLive(_6);
|
||||
StorageLive(_7);
|
||||
_7 = copy _3;
|
||||
StorageLive(_8);
|
||||
_8 = copy _1;
|
||||
(*_7) = [move _8; 1024];
|
||||
StorageDead(_8);
|
||||
StorageDead(_7);
|
||||
StorageDead(_6);
|
||||
StorageLive(_9);
|
||||
_9 = move _2;
|
||||
_0 = Box::<MaybeUninit<[T; 1024]>>::assume_init(move _9) -> [return: bb3, unwind: bb5];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageDead(_9);
|
||||
StorageDead(_3);
|
||||
drop(_2) -> [return: bb4, unwind: bb7];
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageDead(_2);
|
||||
return;
|
||||
}
|
||||
|
||||
bb5 (cleanup): {
|
||||
drop(_9) -> [return: bb6, unwind terminate(cleanup)];
|
||||
}
|
||||
|
||||
bb6 (cleanup): {
|
||||
drop(_2) -> [return: bb7, unwind terminate(cleanup)];
|
||||
}
|
||||
|
||||
bb7 (cleanup): {
|
||||
resume;
|
||||
}
|
||||
}
|
||||
23
tests/mir-opt/building/write_via_move.rs
Normal file
23
tests/mir-opt/building/write_via_move.rs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
//! Ensure we don't generate unnecessary copys for `write_via_move`.
|
||||
//@ compile-flags: -Zmir-opt-level=0
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
use std::mem;
|
||||
|
||||
// Can't emit `built.after` here as that contains user type annotations which contain DefId that
|
||||
// change all the time.
|
||||
// EMIT_MIR write_via_move.box_new.CleanupPostBorrowck.after.mir
|
||||
// CHECK-LABEL: fn box_new
|
||||
#[inline(never)]
|
||||
fn box_new<T: Copy>(x: T) -> Box<[T; 1024]> {
|
||||
let mut b = Box::new_uninit();
|
||||
let ptr = mem::MaybeUninit::as_mut_ptr(&mut *b);
|
||||
// Ensure the array gets constructed directly into the deref'd pointer.
|
||||
// CHECK: (*[[TEMP1:_.+]]) = [{{(move|copy) _.+}}; 1024];
|
||||
unsafe { std::intrinsics::write_via_move(ptr, [x; 1024]) };
|
||||
unsafe { b.assume_init() }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
box_new(0);
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
- // MIR for `main` before GVN
|
||||
+ // MIR for `main` after GVN
|
||||
|
||||
fn main() -> () {
|
||||
let mut _0: ();
|
||||
let _1: i32;
|
||||
let mut _2: i32;
|
||||
let mut _3: std::boxed::Box<i32>;
|
||||
let mut _4: *mut u8;
|
||||
let mut _5: std::boxed::Box<i32>;
|
||||
let mut _6: *const i32;
|
||||
let mut _7: std::ptr::NonNull<i32>;
|
||||
let mut _8: std::ptr::Unique<i32>;
|
||||
let mut _9: *const i32;
|
||||
let mut _10: *const i32;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
- StorageLive(_2);
|
||||
+ nop;
|
||||
StorageLive(_3);
|
||||
_4 = alloc::alloc::exchange_malloc(const <i32 as std::mem::SizedTypeProperties>::SIZE, const <i32 as std::mem::SizedTypeProperties>::ALIGN) -> [return: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageLive(_5);
|
||||
- _6 = move _4 as *const i32 (Transmute);
|
||||
- _7 = NonNull::<i32> { pointer: move _6 };
|
||||
- _8 = std::ptr::Unique::<i32> { pointer: move _7, _marker: const PhantomData::<i32> };
|
||||
+ _6 = copy _4 as *const i32 (PtrToPtr);
|
||||
+ _7 = NonNull::<i32> { pointer: copy _6 };
|
||||
+ _8 = std::ptr::Unique::<i32> { pointer: copy _7, _marker: const PhantomData::<i32> };
|
||||
_5 = Box::<i32>(move _8, const std::alloc::Global);
|
||||
- _9 = copy ((_5.0: std::ptr::Unique<i32>).0: std::ptr::NonNull<i32>) as *const i32 (Transmute);
|
||||
- (*_9) = const 42_i32;
|
||||
+ _9 = copy _6;
|
||||
+ (*_6) = const 42_i32;
|
||||
_3 = move _5;
|
||||
StorageDead(_5);
|
||||
_10 = copy ((_3.0: std::ptr::Unique<i32>).0: std::ptr::NonNull<i32>) as *const i32 (Transmute);
|
||||
_2 = copy (*_10);
|
||||
- _1 = Add(move _2, const 0_i32);
|
||||
- StorageDead(_2);
|
||||
+ _1 = copy _2;
|
||||
+ nop;
|
||||
drop(_3) -> [return: bb2, unwind unreachable];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageDead(_3);
|
||||
_0 = const ();
|
||||
StorageDead(_1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
- // MIR for `main` before GVN
|
||||
+ // MIR for `main` after GVN
|
||||
|
||||
fn main() -> () {
|
||||
let mut _0: ();
|
||||
let _1: i32;
|
||||
let mut _2: i32;
|
||||
let mut _3: std::boxed::Box<i32>;
|
||||
let mut _4: *mut u8;
|
||||
let mut _5: std::boxed::Box<i32>;
|
||||
let mut _6: *const i32;
|
||||
let mut _7: std::ptr::NonNull<i32>;
|
||||
let mut _8: std::ptr::Unique<i32>;
|
||||
let mut _9: *const i32;
|
||||
let mut _10: *const i32;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
- StorageLive(_2);
|
||||
+ nop;
|
||||
StorageLive(_3);
|
||||
_4 = alloc::alloc::exchange_malloc(const <i32 as std::mem::SizedTypeProperties>::SIZE, const <i32 as std::mem::SizedTypeProperties>::ALIGN) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageLive(_5);
|
||||
- _6 = move _4 as *const i32 (Transmute);
|
||||
- _7 = NonNull::<i32> { pointer: move _6 };
|
||||
- _8 = std::ptr::Unique::<i32> { pointer: move _7, _marker: const PhantomData::<i32> };
|
||||
+ _6 = copy _4 as *const i32 (PtrToPtr);
|
||||
+ _7 = NonNull::<i32> { pointer: copy _6 };
|
||||
+ _8 = std::ptr::Unique::<i32> { pointer: copy _7, _marker: const PhantomData::<i32> };
|
||||
_5 = Box::<i32>(move _8, const std::alloc::Global);
|
||||
- _9 = copy ((_5.0: std::ptr::Unique<i32>).0: std::ptr::NonNull<i32>) as *const i32 (Transmute);
|
||||
- (*_9) = const 42_i32;
|
||||
+ _9 = copy _6;
|
||||
+ (*_6) = const 42_i32;
|
||||
_3 = move _5;
|
||||
StorageDead(_5);
|
||||
_10 = copy ((_3.0: std::ptr::Unique<i32>).0: std::ptr::NonNull<i32>) as *const i32 (Transmute);
|
||||
_2 = copy (*_10);
|
||||
- _1 = Add(move _2, const 0_i32);
|
||||
- StorageDead(_2);
|
||||
+ _1 = copy _2;
|
||||
+ nop;
|
||||
drop(_3) -> [return: bb2, unwind: bb3];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageDead(_3);
|
||||
_0 = const ();
|
||||
StorageDead(_1);
|
||||
return;
|
||||
}
|
||||
|
||||
bb3 (cleanup): {
|
||||
resume;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
//@ test-mir-pass: GVN
|
||||
//@ compile-flags: -O
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
|
||||
#![feature(rustc_attrs, liballoc_internals)]
|
||||
|
||||
// Note: this test verifies that we, in fact, do not const prop `#[rustc_box]`
|
||||
|
||||
// EMIT_MIR boxes.main.GVN.diff
|
||||
fn main() {
|
||||
// CHECK-LABEL: fn main(
|
||||
// CHECK: debug x => [[x:_.*]];
|
||||
// CHECK: (*{{_.*}}) = const 42_i32;
|
||||
// CHECK: [[tmp:_.*]] = copy (*{{_.*}});
|
||||
// CHECK: [[x]] = copy [[tmp]];
|
||||
let x = *(std::boxed::box_new(42)) + 0;
|
||||
}
|
||||
|
|
@ -11,9 +11,9 @@
|
|||
let mut _9: *const [()];
|
||||
let mut _10: std::boxed::Box<()>;
|
||||
let mut _11: *const ();
|
||||
let mut _16: usize;
|
||||
let mut _17: usize;
|
||||
let mut _26: usize;
|
||||
let mut _14: usize;
|
||||
let mut _15: usize;
|
||||
let mut _24: usize;
|
||||
scope 1 {
|
||||
debug vp_ctx => _1;
|
||||
let _5: *const ();
|
||||
|
|
@ -26,49 +26,49 @@
|
|||
scope 4 {
|
||||
debug _x => _8;
|
||||
}
|
||||
scope 19 (inlined foo) {
|
||||
let mut _27: *const [()];
|
||||
scope 20 (inlined foo) {
|
||||
let mut _25: *const [()];
|
||||
}
|
||||
}
|
||||
scope 17 (inlined slice_from_raw_parts::<()>) {
|
||||
scope 18 (inlined std::ptr::from_raw_parts::<[()], ()>) {
|
||||
scope 18 (inlined slice_from_raw_parts::<()>) {
|
||||
scope 19 (inlined std::ptr::from_raw_parts::<[()], ()>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
scope 5 (inlined Box::<()>::new) {
|
||||
let mut _12: *mut u8;
|
||||
let mut _13: *const ();
|
||||
let mut _14: std::ptr::NonNull<()>;
|
||||
let mut _15: std::ptr::Unique<()>;
|
||||
scope 6 (inlined alloc::alloc::exchange_malloc) {
|
||||
let _18: std::alloc::Layout;
|
||||
let mut _19: std::result::Result<std::ptr::NonNull<[u8]>, std::alloc::AllocError>;
|
||||
let mut _20: isize;
|
||||
let mut _22: !;
|
||||
scope 7 {
|
||||
let _21: std::ptr::NonNull<[u8]>;
|
||||
scope 8 {
|
||||
scope 12 (inlined NonNull::<[u8]>::as_mut_ptr) {
|
||||
scope 13 (inlined NonNull::<[u8]>::as_non_null_ptr) {
|
||||
scope 14 (inlined NonNull::<[u8]>::cast::<u8>) {
|
||||
let mut _25: *mut [u8];
|
||||
scope 15 (inlined NonNull::<[u8]>::as_ptr) {
|
||||
let mut _12: *mut ();
|
||||
let mut _13: *mut u8;
|
||||
scope 6 {
|
||||
}
|
||||
scope 7 (inlined boxed::box_new_uninit) {
|
||||
let _16: std::alloc::Layout;
|
||||
let mut _17: std::result::Result<std::ptr::NonNull<[u8]>, std::alloc::AllocError>;
|
||||
let mut _18: isize;
|
||||
let mut _20: !;
|
||||
scope 8 {
|
||||
let _19: std::ptr::NonNull<[u8]>;
|
||||
scope 9 {
|
||||
scope 13 (inlined NonNull::<[u8]>::as_mut_ptr) {
|
||||
scope 14 (inlined NonNull::<[u8]>::as_non_null_ptr) {
|
||||
scope 15 (inlined NonNull::<[u8]>::cast::<u8>) {
|
||||
let mut _23: *mut [u8];
|
||||
scope 16 (inlined NonNull::<[u8]>::as_ptr) {
|
||||
}
|
||||
}
|
||||
}
|
||||
scope 16 (inlined NonNull::<u8>::as_ptr) {
|
||||
scope 17 (inlined NonNull::<u8>::as_ptr) {
|
||||
}
|
||||
}
|
||||
}
|
||||
scope 10 (inlined <std::alloc::Global as Allocator>::allocate) {
|
||||
scope 11 (inlined std::alloc::Global::alloc_impl) {
|
||||
scope 11 (inlined <std::alloc::Global as Allocator>::allocate) {
|
||||
scope 12 (inlined std::alloc::Global::alloc_impl) {
|
||||
}
|
||||
}
|
||||
}
|
||||
scope 9 (inlined #[track_caller] Layout::from_size_align_unchecked) {
|
||||
let _23: ();
|
||||
let mut _24: std::ptr::Alignment;
|
||||
scope 10 (inlined #[track_caller] Layout::from_size_align_unchecked) {
|
||||
let _21: ();
|
||||
let mut _22: std::ptr::Alignment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -83,18 +83,16 @@
|
|||
StorageLive(_12);
|
||||
StorageLive(_13);
|
||||
StorageLive(_14);
|
||||
- _14 = const <() as std::mem::SizedTypeProperties>::SIZE;
|
||||
+ _14 = const 0_usize;
|
||||
StorageLive(_15);
|
||||
- _15 = const <() as std::mem::SizedTypeProperties>::ALIGN;
|
||||
+ _15 = const 1_usize;
|
||||
StorageLive(_16);
|
||||
- _16 = const <() as std::mem::SizedTypeProperties>::SIZE;
|
||||
+ _16 = const 0_usize;
|
||||
StorageLive(_17);
|
||||
- _17 = const <() as std::mem::SizedTypeProperties>::ALIGN;
|
||||
+ _17 = const 1_usize;
|
||||
StorageLive(_18);
|
||||
StorageLive(_19);
|
||||
StorageLive(_20);
|
||||
StorageLive(_21);
|
||||
StorageLive(_22);
|
||||
StorageLive(_23);
|
||||
switchInt(UbChecks) -> [0: bb6, otherwise: bb5];
|
||||
}
|
||||
|
||||
|
|
@ -109,35 +107,31 @@
|
|||
}
|
||||
|
||||
bb3: {
|
||||
- _22 = handle_alloc_error(move _18) -> unwind unreachable;
|
||||
+ _22 = handle_alloc_error(const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }}) -> unwind unreachable;
|
||||
- _20 = handle_alloc_error(move _16) -> unwind unreachable;
|
||||
+ _20 = handle_alloc_error(const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }}) -> unwind unreachable;
|
||||
}
|
||||
|
||||
bb4: {
|
||||
_21 = copy ((_19 as Ok).0: std::ptr::NonNull<[u8]>);
|
||||
- StorageLive(_25);
|
||||
_19 = copy ((_17 as Ok).0: std::ptr::NonNull<[u8]>);
|
||||
- StorageLive(_23);
|
||||
+ nop;
|
||||
_25 = copy _21 as *mut [u8] (Transmute);
|
||||
_12 = copy _25 as *mut u8 (PtrToPtr);
|
||||
- StorageDead(_25);
|
||||
_23 = copy _19 as *mut [u8] (Transmute);
|
||||
_13 = copy _23 as *mut u8 (PtrToPtr);
|
||||
- StorageDead(_23);
|
||||
+ nop;
|
||||
StorageDead(_19);
|
||||
StorageDead(_23);
|
||||
StorageDead(_22);
|
||||
StorageDead(_17);
|
||||
StorageDead(_21);
|
||||
StorageDead(_20);
|
||||
StorageDead(_19);
|
||||
StorageDead(_18);
|
||||
StorageDead(_17);
|
||||
StorageDead(_16);
|
||||
- _13 = copy _12 as *const () (PtrToPtr);
|
||||
+ _13 = copy _25 as *const () (PtrToPtr);
|
||||
_14 = NonNull::<()> { pointer: copy _13 };
|
||||
_15 = std::ptr::Unique::<()> { pointer: copy _14, _marker: const PhantomData::<()> };
|
||||
_3 = Box::<()>(move _15, const std::alloc::Global);
|
||||
- (*_13) = move _4;
|
||||
+ (*_13) = const ();
|
||||
StorageDead(_15);
|
||||
StorageDead(_14);
|
||||
- _12 = copy _13 as *mut () (PtrToPtr);
|
||||
- (*_12) = move _4;
|
||||
+ _12 = copy _23 as *mut () (PtrToPtr);
|
||||
+ (*_12) = const ();
|
||||
_3 = copy _13 as std::boxed::Box<()> (Transmute);
|
||||
StorageDead(_13);
|
||||
StorageDead(_12);
|
||||
StorageDead(_4);
|
||||
|
|
@ -153,21 +147,21 @@
|
|||
+ nop;
|
||||
StorageLive(_7);
|
||||
_7 = copy _5;
|
||||
StorageLive(_26);
|
||||
_26 = const 1_usize;
|
||||
- _6 = *const [()] from (copy _7, copy _26);
|
||||
StorageLive(_24);
|
||||
_24 = const 1_usize;
|
||||
- _6 = *const [()] from (copy _7, copy _24);
|
||||
+ _6 = *const [()] from (copy _5, const 1_usize);
|
||||
StorageDead(_26);
|
||||
StorageDead(_24);
|
||||
StorageDead(_7);
|
||||
StorageLive(_8);
|
||||
StorageLive(_9);
|
||||
_9 = copy _6;
|
||||
StorageLive(_27);
|
||||
- _27 = copy _9;
|
||||
StorageLive(_25);
|
||||
- _25 = copy _9;
|
||||
- _8 = copy _9 as *mut () (PtrToPtr);
|
||||
+ _27 = copy _6;
|
||||
+ _25 = copy _6;
|
||||
+ _8 = copy _5 as *mut () (PtrToPtr);
|
||||
StorageDead(_27);
|
||||
StorageDead(_25);
|
||||
StorageDead(_9);
|
||||
_0 = const ();
|
||||
StorageDead(_8);
|
||||
|
|
@ -179,25 +173,25 @@
|
|||
}
|
||||
|
||||
bb5: {
|
||||
- _23 = Layout::from_size_align_unchecked::precondition_check(copy _16, copy _17) -> [return: bb6, unwind unreachable];
|
||||
+ _23 = Layout::from_size_align_unchecked::precondition_check(const 0_usize, const 1_usize) -> [return: bb6, unwind unreachable];
|
||||
- _21 = Layout::from_size_align_unchecked::precondition_check(copy _14, copy _15) -> [return: bb6, unwind unreachable];
|
||||
+ _21 = Layout::from_size_align_unchecked::precondition_check(const 0_usize, const 1_usize) -> [return: bb6, unwind unreachable];
|
||||
}
|
||||
|
||||
bb6: {
|
||||
StorageLive(_24);
|
||||
- _24 = copy _17 as std::ptr::Alignment (Transmute);
|
||||
- _18 = Layout { size: copy _16, align: move _24 };
|
||||
+ _24 = const std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }};
|
||||
+ _18 = const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }};
|
||||
StorageDead(_24);
|
||||
StorageLive(_19);
|
||||
- _19 = std::alloc::Global::alloc_impl_runtime(copy _18, const false) -> [return: bb7, unwind unreachable];
|
||||
+ _19 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }}, const false) -> [return: bb7, unwind unreachable];
|
||||
StorageLive(_22);
|
||||
- _22 = copy _15 as std::ptr::Alignment (Transmute);
|
||||
- _16 = Layout { size: copy _14, align: move _22 };
|
||||
+ _22 = const std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }};
|
||||
+ _16 = const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }};
|
||||
StorageDead(_22);
|
||||
StorageLive(_17);
|
||||
- _17 = std::alloc::Global::alloc_impl_runtime(copy _16, const false) -> [return: bb7, unwind unreachable];
|
||||
+ _17 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }}, const false) -> [return: bb7, unwind unreachable];
|
||||
}
|
||||
|
||||
bb7: {
|
||||
_20 = discriminant(_19);
|
||||
switchInt(move _20) -> [0: bb4, 1: bb3, otherwise: bb2];
|
||||
_18 = discriminant(_17);
|
||||
switchInt(move _18) -> [0: bb4, 1: bb3, otherwise: bb2];
|
||||
}
|
||||
+ }
|
||||
+
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@
|
|||
let mut _9: *const [()];
|
||||
let mut _10: std::boxed::Box<()>;
|
||||
let mut _11: *const ();
|
||||
let mut _16: usize;
|
||||
let mut _17: usize;
|
||||
let mut _26: usize;
|
||||
let mut _14: usize;
|
||||
let mut _15: usize;
|
||||
let mut _24: usize;
|
||||
scope 1 {
|
||||
debug vp_ctx => _1;
|
||||
let _5: *const ();
|
||||
|
|
@ -26,49 +26,49 @@
|
|||
scope 4 {
|
||||
debug _x => _8;
|
||||
}
|
||||
scope 19 (inlined foo) {
|
||||
let mut _27: *const [()];
|
||||
scope 20 (inlined foo) {
|
||||
let mut _25: *const [()];
|
||||
}
|
||||
}
|
||||
scope 17 (inlined slice_from_raw_parts::<()>) {
|
||||
scope 18 (inlined std::ptr::from_raw_parts::<[()], ()>) {
|
||||
scope 18 (inlined slice_from_raw_parts::<()>) {
|
||||
scope 19 (inlined std::ptr::from_raw_parts::<[()], ()>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
scope 5 (inlined Box::<()>::new) {
|
||||
let mut _12: *mut u8;
|
||||
let mut _13: *const ();
|
||||
let mut _14: std::ptr::NonNull<()>;
|
||||
let mut _15: std::ptr::Unique<()>;
|
||||
scope 6 (inlined alloc::alloc::exchange_malloc) {
|
||||
let _18: std::alloc::Layout;
|
||||
let mut _19: std::result::Result<std::ptr::NonNull<[u8]>, std::alloc::AllocError>;
|
||||
let mut _20: isize;
|
||||
let mut _22: !;
|
||||
scope 7 {
|
||||
let _21: std::ptr::NonNull<[u8]>;
|
||||
scope 8 {
|
||||
scope 12 (inlined NonNull::<[u8]>::as_mut_ptr) {
|
||||
scope 13 (inlined NonNull::<[u8]>::as_non_null_ptr) {
|
||||
scope 14 (inlined NonNull::<[u8]>::cast::<u8>) {
|
||||
let mut _25: *mut [u8];
|
||||
scope 15 (inlined NonNull::<[u8]>::as_ptr) {
|
||||
let mut _12: *mut ();
|
||||
let mut _13: *mut u8;
|
||||
scope 6 {
|
||||
}
|
||||
scope 7 (inlined boxed::box_new_uninit) {
|
||||
let _16: std::alloc::Layout;
|
||||
let mut _17: std::result::Result<std::ptr::NonNull<[u8]>, std::alloc::AllocError>;
|
||||
let mut _18: isize;
|
||||
let mut _20: !;
|
||||
scope 8 {
|
||||
let _19: std::ptr::NonNull<[u8]>;
|
||||
scope 9 {
|
||||
scope 13 (inlined NonNull::<[u8]>::as_mut_ptr) {
|
||||
scope 14 (inlined NonNull::<[u8]>::as_non_null_ptr) {
|
||||
scope 15 (inlined NonNull::<[u8]>::cast::<u8>) {
|
||||
let mut _23: *mut [u8];
|
||||
scope 16 (inlined NonNull::<[u8]>::as_ptr) {
|
||||
}
|
||||
}
|
||||
}
|
||||
scope 16 (inlined NonNull::<u8>::as_ptr) {
|
||||
scope 17 (inlined NonNull::<u8>::as_ptr) {
|
||||
}
|
||||
}
|
||||
}
|
||||
scope 10 (inlined <std::alloc::Global as Allocator>::allocate) {
|
||||
scope 11 (inlined std::alloc::Global::alloc_impl) {
|
||||
scope 11 (inlined <std::alloc::Global as Allocator>::allocate) {
|
||||
scope 12 (inlined std::alloc::Global::alloc_impl) {
|
||||
}
|
||||
}
|
||||
}
|
||||
scope 9 (inlined #[track_caller] Layout::from_size_align_unchecked) {
|
||||
let _23: ();
|
||||
let mut _24: std::ptr::Alignment;
|
||||
scope 10 (inlined #[track_caller] Layout::from_size_align_unchecked) {
|
||||
let _21: ();
|
||||
let mut _22: std::ptr::Alignment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -83,18 +83,16 @@
|
|||
StorageLive(_12);
|
||||
StorageLive(_13);
|
||||
StorageLive(_14);
|
||||
- _14 = const <() as std::mem::SizedTypeProperties>::SIZE;
|
||||
+ _14 = const 0_usize;
|
||||
StorageLive(_15);
|
||||
- _15 = const <() as std::mem::SizedTypeProperties>::ALIGN;
|
||||
+ _15 = const 1_usize;
|
||||
StorageLive(_16);
|
||||
- _16 = const <() as std::mem::SizedTypeProperties>::SIZE;
|
||||
+ _16 = const 0_usize;
|
||||
StorageLive(_17);
|
||||
- _17 = const <() as std::mem::SizedTypeProperties>::ALIGN;
|
||||
+ _17 = const 1_usize;
|
||||
StorageLive(_18);
|
||||
StorageLive(_19);
|
||||
StorageLive(_20);
|
||||
StorageLive(_21);
|
||||
StorageLive(_22);
|
||||
StorageLive(_23);
|
||||
switchInt(UbChecks) -> [0: bb6, otherwise: bb5];
|
||||
}
|
||||
|
||||
|
|
@ -109,35 +107,31 @@
|
|||
}
|
||||
|
||||
bb3: {
|
||||
- _22 = handle_alloc_error(move _18) -> unwind unreachable;
|
||||
+ _22 = handle_alloc_error(const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }}) -> unwind unreachable;
|
||||
- _20 = handle_alloc_error(move _16) -> unwind unreachable;
|
||||
+ _20 = handle_alloc_error(const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }}) -> unwind unreachable;
|
||||
}
|
||||
|
||||
bb4: {
|
||||
_21 = copy ((_19 as Ok).0: std::ptr::NonNull<[u8]>);
|
||||
- StorageLive(_25);
|
||||
_19 = copy ((_17 as Ok).0: std::ptr::NonNull<[u8]>);
|
||||
- StorageLive(_23);
|
||||
+ nop;
|
||||
_25 = copy _21 as *mut [u8] (Transmute);
|
||||
_12 = copy _25 as *mut u8 (PtrToPtr);
|
||||
- StorageDead(_25);
|
||||
_23 = copy _19 as *mut [u8] (Transmute);
|
||||
_13 = copy _23 as *mut u8 (PtrToPtr);
|
||||
- StorageDead(_23);
|
||||
+ nop;
|
||||
StorageDead(_19);
|
||||
StorageDead(_23);
|
||||
StorageDead(_22);
|
||||
StorageDead(_17);
|
||||
StorageDead(_21);
|
||||
StorageDead(_20);
|
||||
StorageDead(_19);
|
||||
StorageDead(_18);
|
||||
StorageDead(_17);
|
||||
StorageDead(_16);
|
||||
- _13 = copy _12 as *const () (PtrToPtr);
|
||||
+ _13 = copy _25 as *const () (PtrToPtr);
|
||||
_14 = NonNull::<()> { pointer: copy _13 };
|
||||
_15 = std::ptr::Unique::<()> { pointer: copy _14, _marker: const PhantomData::<()> };
|
||||
_3 = Box::<()>(move _15, const std::alloc::Global);
|
||||
- (*_13) = move _4;
|
||||
+ (*_13) = const ();
|
||||
StorageDead(_15);
|
||||
StorageDead(_14);
|
||||
- _12 = copy _13 as *mut () (PtrToPtr);
|
||||
- (*_12) = move _4;
|
||||
+ _12 = copy _23 as *mut () (PtrToPtr);
|
||||
+ (*_12) = const ();
|
||||
_3 = copy _13 as std::boxed::Box<()> (Transmute);
|
||||
StorageDead(_13);
|
||||
StorageDead(_12);
|
||||
StorageDead(_4);
|
||||
|
|
@ -153,21 +147,21 @@
|
|||
+ nop;
|
||||
StorageLive(_7);
|
||||
_7 = copy _5;
|
||||
StorageLive(_26);
|
||||
_26 = const 1_usize;
|
||||
- _6 = *const [()] from (copy _7, copy _26);
|
||||
StorageLive(_24);
|
||||
_24 = const 1_usize;
|
||||
- _6 = *const [()] from (copy _7, copy _24);
|
||||
+ _6 = *const [()] from (copy _5, const 1_usize);
|
||||
StorageDead(_26);
|
||||
StorageDead(_24);
|
||||
StorageDead(_7);
|
||||
StorageLive(_8);
|
||||
StorageLive(_9);
|
||||
_9 = copy _6;
|
||||
StorageLive(_27);
|
||||
- _27 = copy _9;
|
||||
StorageLive(_25);
|
||||
- _25 = copy _9;
|
||||
- _8 = copy _9 as *mut () (PtrToPtr);
|
||||
+ _27 = copy _6;
|
||||
+ _25 = copy _6;
|
||||
+ _8 = copy _5 as *mut () (PtrToPtr);
|
||||
StorageDead(_27);
|
||||
StorageDead(_25);
|
||||
StorageDead(_9);
|
||||
_0 = const ();
|
||||
StorageDead(_8);
|
||||
|
|
@ -179,25 +173,25 @@
|
|||
}
|
||||
|
||||
bb5: {
|
||||
- _23 = Layout::from_size_align_unchecked::precondition_check(copy _16, copy _17) -> [return: bb6, unwind unreachable];
|
||||
+ _23 = Layout::from_size_align_unchecked::precondition_check(const 0_usize, const 1_usize) -> [return: bb6, unwind unreachable];
|
||||
- _21 = Layout::from_size_align_unchecked::precondition_check(copy _14, copy _15) -> [return: bb6, unwind unreachable];
|
||||
+ _21 = Layout::from_size_align_unchecked::precondition_check(const 0_usize, const 1_usize) -> [return: bb6, unwind unreachable];
|
||||
}
|
||||
|
||||
bb6: {
|
||||
StorageLive(_24);
|
||||
- _24 = copy _17 as std::ptr::Alignment (Transmute);
|
||||
- _18 = Layout { size: copy _16, align: move _24 };
|
||||
+ _24 = const std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }};
|
||||
+ _18 = const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }};
|
||||
StorageDead(_24);
|
||||
StorageLive(_19);
|
||||
- _19 = std::alloc::Global::alloc_impl_runtime(copy _18, const false) -> [return: bb7, unwind unreachable];
|
||||
+ _19 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }}, const false) -> [return: bb7, unwind unreachable];
|
||||
StorageLive(_22);
|
||||
- _22 = copy _15 as std::ptr::Alignment (Transmute);
|
||||
- _16 = Layout { size: copy _14, align: move _22 };
|
||||
+ _22 = const std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }};
|
||||
+ _16 = const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }};
|
||||
StorageDead(_22);
|
||||
StorageLive(_17);
|
||||
- _17 = std::alloc::Global::alloc_impl_runtime(copy _16, const false) -> [return: bb7, unwind unreachable];
|
||||
+ _17 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }}, const false) -> [return: bb7, unwind unreachable];
|
||||
}
|
||||
|
||||
bb7: {
|
||||
_20 = discriminant(_19);
|
||||
switchInt(move _20) -> [0: bb4, 1: bb3, otherwise: bb2];
|
||||
_18 = discriminant(_17);
|
||||
switchInt(move _18) -> [0: bb4, 1: bb3, otherwise: bb2];
|
||||
}
|
||||
+ }
|
||||
+
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@
|
|||
+ StorageLive(_42);
|
||||
+ _42 = Option::<()>::None;
|
||||
+ _35 = copy ((*_37).0: std::option::Option<()>);
|
||||
+ ((*_37).0: std::option::Option<()>) = copy _42;
|
||||
+ ((*_37).0: std::option::Option<()>) = move _42;
|
||||
+ StorageDead(_42);
|
||||
+ StorageLive(_43);
|
||||
+ _43 = discriminant(_35);
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@
|
|||
+ StorageLive(_42);
|
||||
+ _42 = Option::<()>::None;
|
||||
+ _35 = copy ((*_37).0: std::option::Option<()>);
|
||||
+ ((*_37).0: std::option::Option<()>) = copy _42;
|
||||
+ ((*_37).0: std::option::Option<()>) = move _42;
|
||||
+ StorageDead(_42);
|
||||
+ StorageLive(_43);
|
||||
+ _43 = discriminant(_35);
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
|
||||
#![feature(rustc_attrs, liballoc_internals)]
|
||||
|
||||
// EMIT_MIR issue_62289.test.ElaborateDrops.before.mir
|
||||
fn test() -> Option<Box<u32>> {
|
||||
Some(std::boxed::box_new(None?))
|
||||
// EMIT_MIR issue_62289.test.ElaborateDrops.after.mir
|
||||
fn test() -> Option<Vec<u32>> {
|
||||
Some(vec![None?])
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,119 @@
|
|||
// MIR for `test` after ElaborateDrops
|
||||
|
||||
fn test() -> Option<Vec<u32>> {
|
||||
let mut _0: std::option::Option<std::vec::Vec<u32>>;
|
||||
let mut _1: std::vec::Vec<u32>;
|
||||
let mut _2: std::boxed::Box<std::mem::MaybeUninit<[u32; 1]>>;
|
||||
let mut _3: std::boxed::Box<std::mem::MaybeUninit<[u32; 1]>>;
|
||||
let mut _4: u32;
|
||||
let mut _5: std::ops::ControlFlow<std::option::Option<std::convert::Infallible>, u32>;
|
||||
let mut _6: std::option::Option<u32>;
|
||||
let mut _7: isize;
|
||||
let _8: std::option::Option<std::convert::Infallible>;
|
||||
let mut _9: !;
|
||||
let mut _10: std::option::Option<std::convert::Infallible>;
|
||||
let _11: u32;
|
||||
scope 1 {
|
||||
debug residual => _8;
|
||||
scope 2 {
|
||||
}
|
||||
}
|
||||
scope 3 {
|
||||
debug val => _11;
|
||||
scope 4 {
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
_3 = Box::<[u32; 1]>::new_uninit() -> [return: bb1, unwind: bb14];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageLive(_4);
|
||||
StorageLive(_5);
|
||||
StorageLive(_6);
|
||||
_6 = Option::<u32>::None;
|
||||
_5 = <Option<u32> as Try>::branch(move _6) -> [return: bb2, unwind: bb13];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageDead(_6);
|
||||
PlaceMention(_5);
|
||||
_7 = discriminant(_5);
|
||||
switchInt(move _7) -> [0: bb4, 1: bb5, otherwise: bb3];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
unreachable;
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageLive(_11);
|
||||
_11 = copy ((_5 as Continue).0: u32);
|
||||
_4 = copy _11;
|
||||
StorageDead(_11);
|
||||
((((*_3).1: std::mem::ManuallyDrop<[u32; 1]>).0: std::mem::MaybeDangling<[u32; 1]>).0: [u32; 1]) = [move _4];
|
||||
StorageDead(_4);
|
||||
_2 = move _3;
|
||||
goto -> bb7;
|
||||
}
|
||||
|
||||
bb5: {
|
||||
StorageLive(_8);
|
||||
_8 = copy ((_5 as Break).0: std::option::Option<std::convert::Infallible>);
|
||||
StorageLive(_10);
|
||||
_10 = copy _8;
|
||||
_0 = <Option<Vec<u32>> as FromResidual<Option<Infallible>>>::from_residual(move _10) -> [return: bb6, unwind: bb13];
|
||||
}
|
||||
|
||||
bb6: {
|
||||
StorageDead(_10);
|
||||
StorageDead(_8);
|
||||
StorageDead(_4);
|
||||
drop(_3) -> [return: bb10, unwind: bb14];
|
||||
}
|
||||
|
||||
bb7: {
|
||||
StorageDead(_3);
|
||||
_1 = std::boxed::box_assume_init_into_vec_unsafe::<u32, 1>(move _2) -> [return: bb8, unwind: bb12];
|
||||
}
|
||||
|
||||
bb8: {
|
||||
StorageDead(_2);
|
||||
_0 = Option::<Vec<u32>>::Some(move _1);
|
||||
goto -> bb9;
|
||||
}
|
||||
|
||||
bb9: {
|
||||
StorageDead(_1);
|
||||
StorageDead(_5);
|
||||
goto -> bb11;
|
||||
}
|
||||
|
||||
bb10: {
|
||||
StorageDead(_3);
|
||||
StorageDead(_2);
|
||||
StorageDead(_1);
|
||||
StorageDead(_5);
|
||||
goto -> bb11;
|
||||
}
|
||||
|
||||
bb11: {
|
||||
return;
|
||||
}
|
||||
|
||||
bb12 (cleanup): {
|
||||
goto -> bb14;
|
||||
}
|
||||
|
||||
bb13 (cleanup): {
|
||||
drop(_3) -> [return: bb14, unwind terminate(cleanup)];
|
||||
}
|
||||
|
||||
bb14 (cleanup): {
|
||||
resume;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
// MIR for `test` after ElaborateDrops
|
||||
|
||||
fn test() -> Option<Vec<u32>> {
|
||||
let mut _0: std::option::Option<std::vec::Vec<u32>>;
|
||||
let mut _1: std::vec::Vec<u32>;
|
||||
let mut _2: std::boxed::Box<std::mem::MaybeUninit<[u32; 1]>>;
|
||||
let mut _3: std::boxed::Box<std::mem::MaybeUninit<[u32; 1]>>;
|
||||
let mut _4: u32;
|
||||
let mut _5: std::ops::ControlFlow<std::option::Option<std::convert::Infallible>, u32>;
|
||||
let mut _6: std::option::Option<u32>;
|
||||
let mut _7: isize;
|
||||
let _8: std::option::Option<std::convert::Infallible>;
|
||||
let mut _9: !;
|
||||
let mut _10: std::option::Option<std::convert::Infallible>;
|
||||
let _11: u32;
|
||||
scope 1 {
|
||||
debug residual => _8;
|
||||
scope 2 {
|
||||
}
|
||||
}
|
||||
scope 3 {
|
||||
debug val => _11;
|
||||
scope 4 {
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
_3 = Box::<[u32; 1]>::new_uninit() -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageLive(_4);
|
||||
StorageLive(_5);
|
||||
StorageLive(_6);
|
||||
_6 = Option::<u32>::None;
|
||||
_5 = <Option<u32> as Try>::branch(move _6) -> [return: bb2, unwind: bb13];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageDead(_6);
|
||||
PlaceMention(_5);
|
||||
_7 = discriminant(_5);
|
||||
switchInt(move _7) -> [0: bb4, 1: bb5, otherwise: bb3];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
unreachable;
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageLive(_11);
|
||||
_11 = copy ((_5 as Continue).0: u32);
|
||||
_4 = copy _11;
|
||||
StorageDead(_11);
|
||||
((((*_3).1: std::mem::ManuallyDrop<[u32; 1]>).0: std::mem::MaybeDangling<[u32; 1]>).0: [u32; 1]) = [move _4];
|
||||
StorageDead(_4);
|
||||
_2 = move _3;
|
||||
goto -> bb7;
|
||||
}
|
||||
|
||||
bb5: {
|
||||
StorageLive(_8);
|
||||
_8 = copy ((_5 as Break).0: std::option::Option<std::convert::Infallible>);
|
||||
StorageLive(_10);
|
||||
_10 = copy _8;
|
||||
_0 = <Option<Vec<u32>> as FromResidual<Option<Infallible>>>::from_residual(move _10) -> [return: bb6, unwind: bb13];
|
||||
}
|
||||
|
||||
bb6: {
|
||||
StorageDead(_10);
|
||||
StorageDead(_8);
|
||||
StorageDead(_4);
|
||||
drop(_3) -> [return: bb10, unwind: bb14];
|
||||
}
|
||||
|
||||
bb7: {
|
||||
StorageDead(_3);
|
||||
_1 = std::boxed::box_assume_init_into_vec_unsafe::<u32, 1>(move _2) -> [return: bb8, unwind: bb12];
|
||||
}
|
||||
|
||||
bb8: {
|
||||
StorageDead(_2);
|
||||
_0 = Option::<Vec<u32>>::Some(move _1);
|
||||
goto -> bb9;
|
||||
}
|
||||
|
||||
bb9: {
|
||||
StorageDead(_1);
|
||||
StorageDead(_5);
|
||||
goto -> bb11;
|
||||
}
|
||||
|
||||
bb10: {
|
||||
StorageDead(_3);
|
||||
StorageDead(_2);
|
||||
StorageDead(_1);
|
||||
StorageDead(_5);
|
||||
goto -> bb11;
|
||||
}
|
||||
|
||||
bb11: {
|
||||
return;
|
||||
}
|
||||
|
||||
bb12 (cleanup): {
|
||||
goto -> bb14;
|
||||
}
|
||||
|
||||
bb13 (cleanup): {
|
||||
drop(_3) -> [return: bb14, unwind terminate(cleanup)];
|
||||
}
|
||||
|
||||
bb14 (cleanup): {
|
||||
resume;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
// MIR for `test` before ElaborateDrops
|
||||
|
||||
fn test() -> Option<Box<u32>> {
|
||||
let mut _0: std::option::Option<std::boxed::Box<u32>>;
|
||||
let mut _1: std::boxed::Box<u32>;
|
||||
let mut _2: *mut u8;
|
||||
let mut _3: std::boxed::Box<u32>;
|
||||
let mut _4: std::ops::ControlFlow<std::option::Option<std::convert::Infallible>, u32>;
|
||||
let mut _5: std::option::Option<u32>;
|
||||
let mut _6: isize;
|
||||
let _7: std::option::Option<std::convert::Infallible>;
|
||||
let mut _8: !;
|
||||
let mut _9: std::option::Option<std::convert::Infallible>;
|
||||
let _10: u32;
|
||||
scope 1 {
|
||||
debug residual => _7;
|
||||
scope 2 {
|
||||
}
|
||||
}
|
||||
scope 3 {
|
||||
debug val => _10;
|
||||
scope 4 {
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
_2 = alloc::alloc::exchange_malloc(const <u32 as std::mem::SizedTypeProperties>::SIZE, const <u32 as std::mem::SizedTypeProperties>::ALIGN) -> [return: bb1, unwind: bb13];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageLive(_3);
|
||||
_3 = ShallowInitBox(move _2, u32);
|
||||
StorageLive(_4);
|
||||
StorageLive(_5);
|
||||
_5 = Option::<u32>::None;
|
||||
_4 = <Option<u32> as Try>::branch(move _5) -> [return: bb2, unwind: bb12];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageDead(_5);
|
||||
PlaceMention(_4);
|
||||
_6 = discriminant(_4);
|
||||
switchInt(move _6) -> [0: bb4, 1: bb5, otherwise: bb3];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
unreachable;
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageLive(_10);
|
||||
_10 = copy ((_4 as Continue).0: u32);
|
||||
(*_3) = copy _10;
|
||||
StorageDead(_10);
|
||||
_1 = move _3;
|
||||
drop(_3) -> [return: bb7, unwind: bb11];
|
||||
}
|
||||
|
||||
bb5: {
|
||||
StorageLive(_7);
|
||||
_7 = copy ((_4 as Break).0: std::option::Option<std::convert::Infallible>);
|
||||
StorageLive(_9);
|
||||
_9 = copy _7;
|
||||
_0 = <Option<Box<u32>> as FromResidual<Option<Infallible>>>::from_residual(move _9) -> [return: bb6, unwind: bb12];
|
||||
}
|
||||
|
||||
bb6: {
|
||||
StorageDead(_9);
|
||||
StorageDead(_7);
|
||||
drop(_3) -> [return: bb9, unwind: bb13];
|
||||
}
|
||||
|
||||
bb7: {
|
||||
StorageDead(_3);
|
||||
_0 = Option::<Box<u32>>::Some(move _1);
|
||||
drop(_1) -> [return: bb8, unwind: bb13];
|
||||
}
|
||||
|
||||
bb8: {
|
||||
StorageDead(_1);
|
||||
StorageDead(_4);
|
||||
goto -> bb10;
|
||||
}
|
||||
|
||||
bb9: {
|
||||
StorageDead(_3);
|
||||
StorageDead(_1);
|
||||
StorageDead(_4);
|
||||
goto -> bb10;
|
||||
}
|
||||
|
||||
bb10: {
|
||||
return;
|
||||
}
|
||||
|
||||
bb11 (cleanup): {
|
||||
drop(_1) -> [return: bb13, unwind terminate(cleanup)];
|
||||
}
|
||||
|
||||
bb12 (cleanup): {
|
||||
drop(_3) -> [return: bb13, unwind terminate(cleanup)];
|
||||
}
|
||||
|
||||
bb13 (cleanup): {
|
||||
resume;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
// MIR for `test` before ElaborateDrops
|
||||
|
||||
fn test() -> Option<Box<u32>> {
|
||||
let mut _0: std::option::Option<std::boxed::Box<u32>>;
|
||||
let mut _1: std::boxed::Box<u32>;
|
||||
let mut _2: *mut u8;
|
||||
let mut _3: std::boxed::Box<u32>;
|
||||
let mut _4: std::ops::ControlFlow<std::option::Option<std::convert::Infallible>, u32>;
|
||||
let mut _5: std::option::Option<u32>;
|
||||
let mut _6: isize;
|
||||
let _7: std::option::Option<std::convert::Infallible>;
|
||||
let mut _8: !;
|
||||
let mut _9: std::option::Option<std::convert::Infallible>;
|
||||
let _10: u32;
|
||||
scope 1 {
|
||||
debug residual => _7;
|
||||
scope 2 {
|
||||
}
|
||||
}
|
||||
scope 3 {
|
||||
debug val => _10;
|
||||
scope 4 {
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
_2 = alloc::alloc::exchange_malloc(const <u32 as std::mem::SizedTypeProperties>::SIZE, const <u32 as std::mem::SizedTypeProperties>::ALIGN) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageLive(_3);
|
||||
_3 = ShallowInitBox(move _2, u32);
|
||||
StorageLive(_4);
|
||||
StorageLive(_5);
|
||||
_5 = Option::<u32>::None;
|
||||
_4 = <Option<u32> as Try>::branch(move _5) -> [return: bb2, unwind: bb12];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageDead(_5);
|
||||
PlaceMention(_4);
|
||||
_6 = discriminant(_4);
|
||||
switchInt(move _6) -> [0: bb4, 1: bb5, otherwise: bb3];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
unreachable;
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageLive(_10);
|
||||
_10 = copy ((_4 as Continue).0: u32);
|
||||
(*_3) = copy _10;
|
||||
StorageDead(_10);
|
||||
_1 = move _3;
|
||||
drop(_3) -> [return: bb7, unwind: bb11];
|
||||
}
|
||||
|
||||
bb5: {
|
||||
StorageLive(_7);
|
||||
_7 = copy ((_4 as Break).0: std::option::Option<std::convert::Infallible>);
|
||||
StorageLive(_9);
|
||||
_9 = copy _7;
|
||||
_0 = <Option<Box<u32>> as FromResidual<Option<Infallible>>>::from_residual(move _9) -> [return: bb6, unwind: bb12];
|
||||
}
|
||||
|
||||
bb6: {
|
||||
StorageDead(_9);
|
||||
StorageDead(_7);
|
||||
drop(_3) -> [return: bb9, unwind continue];
|
||||
}
|
||||
|
||||
bb7: {
|
||||
StorageDead(_3);
|
||||
_0 = Option::<Box<u32>>::Some(move _1);
|
||||
drop(_1) -> [return: bb8, unwind continue];
|
||||
}
|
||||
|
||||
bb8: {
|
||||
StorageDead(_1);
|
||||
StorageDead(_4);
|
||||
goto -> bb10;
|
||||
}
|
||||
|
||||
bb9: {
|
||||
StorageDead(_3);
|
||||
StorageDead(_1);
|
||||
StorageDead(_4);
|
||||
goto -> bb10;
|
||||
}
|
||||
|
||||
bb10: {
|
||||
return;
|
||||
}
|
||||
|
||||
bb11 (cleanup): {
|
||||
drop(_1) -> [return: bb13, unwind terminate(cleanup)];
|
||||
}
|
||||
|
||||
bb12 (cleanup): {
|
||||
drop(_3) -> [return: bb13, unwind terminate(cleanup)];
|
||||
}
|
||||
|
||||
bb13 (cleanup): {
|
||||
resume;
|
||||
}
|
||||
}
|
||||
|
|
@ -197,17 +197,6 @@ pub fn read_via_copy_uninhabited(r: &Never) -> Never {
|
|||
unsafe { core::intrinsics::read_via_copy(r) }
|
||||
}
|
||||
|
||||
// EMIT_MIR lower_intrinsics.write_via_move_string.LowerIntrinsics.diff
|
||||
pub fn write_via_move_string(r: &mut String, v: String) {
|
||||
// CHECK-LABEL: fn write_via_move_string(
|
||||
// CHECK: [[ptr:_.*]] = &raw mut (*_1);
|
||||
// CHECK: [[tmp:_.*]] = move _2;
|
||||
// CHECK: (*[[ptr]]) = move [[tmp]];
|
||||
// CHECK: return;
|
||||
|
||||
unsafe { core::intrinsics::write_via_move(r, v) }
|
||||
}
|
||||
|
||||
pub enum Never {}
|
||||
|
||||
// EMIT_MIR lower_intrinsics.ptr_offset.LowerIntrinsics.diff
|
||||
|
|
|
|||
|
|
@ -1,31 +0,0 @@
|
|||
- // MIR for `write_via_move_string` before LowerIntrinsics
|
||||
+ // MIR for `write_via_move_string` after LowerIntrinsics
|
||||
|
||||
fn write_via_move_string(_1: &mut String, _2: String) -> () {
|
||||
debug r => _1;
|
||||
debug v => _2;
|
||||
let mut _0: ();
|
||||
let mut _3: *mut std::string::String;
|
||||
let mut _4: std::string::String;
|
||||
|
||||
bb0: {
|
||||
StorageLive(_3);
|
||||
_3 = &raw mut (*_1);
|
||||
StorageLive(_4);
|
||||
_4 = move _2;
|
||||
- _0 = write_via_move::<String>(move _3, move _4) -> [return: bb1, unwind unreachable];
|
||||
+ (*_3) = move _4;
|
||||
+ goto -> bb1;
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageDead(_4);
|
||||
StorageDead(_3);
|
||||
goto -> bb2;
|
||||
}
|
||||
|
||||
bb2: {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
- // MIR for `write_via_move_string` before LowerIntrinsics
|
||||
+ // MIR for `write_via_move_string` after LowerIntrinsics
|
||||
|
||||
fn write_via_move_string(_1: &mut String, _2: String) -> () {
|
||||
debug r => _1;
|
||||
debug v => _2;
|
||||
let mut _0: ();
|
||||
let mut _3: *mut std::string::String;
|
||||
let mut _4: std::string::String;
|
||||
|
||||
bb0: {
|
||||
StorageLive(_3);
|
||||
_3 = &raw mut (*_1);
|
||||
StorageLive(_4);
|
||||
_4 = move _2;
|
||||
- _0 = write_via_move::<String>(move _3, move _4) -> [return: bb1, unwind unreachable];
|
||||
+ (*_3) = move _4;
|
||||
+ goto -> bb1;
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageDead(_4);
|
||||
StorageDead(_3);
|
||||
goto -> bb2;
|
||||
}
|
||||
|
||||
bb2: {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5,33 +5,36 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
|
|||
debug f => _2;
|
||||
let mut _0: ();
|
||||
let mut _10: usize;
|
||||
let mut _28: std::option::Option<(usize, &T)>;
|
||||
let mut _31: &impl Fn(usize, &T);
|
||||
let mut _32: (usize, &T);
|
||||
let _33: ();
|
||||
let mut _31: std::option::Option<(usize, &T)>;
|
||||
let mut _34: &impl Fn(usize, &T);
|
||||
let mut _35: (usize, &T);
|
||||
let _36: ();
|
||||
scope 1 {
|
||||
debug (((iter: Enumerate<std::slice::Iter<'_, T>>).0: std::slice::Iter<'_, T>).0: std::ptr::NonNull<T>) => _6;
|
||||
debug (((iter: Enumerate<std::slice::Iter<'_, T>>).0: std::slice::Iter<'_, T>).1: *const T) => _9;
|
||||
debug (((iter: Enumerate<std::slice::Iter<'_, T>>).0: std::slice::Iter<'_, T>).2: std::marker::PhantomData<&T>) => const ZeroSized: PhantomData<&T>;
|
||||
debug ((iter: Enumerate<std::slice::Iter<'_, T>>).1: usize) => _10;
|
||||
let _29: usize;
|
||||
let _30: &T;
|
||||
let _32: usize;
|
||||
let _33: &T;
|
||||
scope 2 {
|
||||
debug i => _29;
|
||||
debug x => _30;
|
||||
debug i => _32;
|
||||
debug x => _33;
|
||||
}
|
||||
scope 18 (inlined <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next) {
|
||||
let mut _23: std::option::Option<&T>;
|
||||
let mut _26: (usize, bool);
|
||||
let mut _27: (usize, &T);
|
||||
let mut _21: std::option::Option<std::convert::Infallible>;
|
||||
let mut _26: std::option::Option<&T>;
|
||||
let mut _29: (usize, bool);
|
||||
let mut _30: (usize, &T);
|
||||
scope 19 {
|
||||
let _25: usize;
|
||||
let _28: usize;
|
||||
scope 24 {
|
||||
}
|
||||
}
|
||||
scope 20 {
|
||||
scope 21 {
|
||||
scope 27 (inlined <Option<(usize, &T)> as FromResidual<Option<Infallible>>>::from_residual) {
|
||||
let mut _20: isize;
|
||||
let mut _22: bool;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -40,7 +43,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
|
|||
}
|
||||
}
|
||||
scope 25 (inlined <Option<&T> as Try>::branch) {
|
||||
let _24: &T;
|
||||
let _27: &T;
|
||||
scope 26 {
|
||||
}
|
||||
}
|
||||
|
|
@ -49,8 +52,8 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
|
|||
let _11: std::ptr::NonNull<T>;
|
||||
let _13: std::ptr::NonNull<T>;
|
||||
let mut _16: bool;
|
||||
let mut _20: usize;
|
||||
let _22: &T;
|
||||
let mut _23: usize;
|
||||
let _25: &T;
|
||||
scope 29 {
|
||||
let _12: *const T;
|
||||
scope 30 {
|
||||
|
|
@ -84,7 +87,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
|
|||
}
|
||||
}
|
||||
scope 43 (inlined NonNull::<T>::as_ref::<'_>) {
|
||||
let _21: *const T;
|
||||
let _24: *const T;
|
||||
scope 44 (inlined NonNull::<T>::as_ptr) {
|
||||
}
|
||||
scope 45 (inlined std::ptr::mut_ptr::<impl *mut T>::cast_const) {
|
||||
|
|
@ -169,16 +172,16 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
|
|||
}
|
||||
|
||||
bb4: {
|
||||
StorageLive(_31);
|
||||
StorageLive(_28);
|
||||
StorageLive(_25);
|
||||
StorageLive(_29);
|
||||
StorageLive(_26);
|
||||
StorageLive(_23);
|
||||
StorageLive(_11);
|
||||
StorageLive(_12);
|
||||
StorageLive(_19);
|
||||
StorageLive(_20);
|
||||
StorageLive(_23);
|
||||
StorageLive(_13);
|
||||
StorageLive(_22);
|
||||
StorageLive(_25);
|
||||
_11 = copy _6;
|
||||
_12 = copy _9;
|
||||
switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb5, otherwise: bb8];
|
||||
|
|
@ -224,16 +227,23 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
|
|||
}
|
||||
|
||||
bb10: {
|
||||
StorageDead(_22);
|
||||
StorageDead(_25);
|
||||
StorageDead(_13);
|
||||
StorageDead(_20);
|
||||
StorageDead(_23);
|
||||
StorageDead(_19);
|
||||
StorageDead(_12);
|
||||
StorageDead(_11);
|
||||
StorageDead(_23);
|
||||
StorageDead(_26);
|
||||
StorageDead(_25);
|
||||
StorageLive(_20);
|
||||
StorageLive(_22);
|
||||
_20 = discriminant(_21);
|
||||
_22 = Eq(copy _20, const 0_isize);
|
||||
assume(move _22);
|
||||
StorageDead(_22);
|
||||
StorageDead(_20);
|
||||
StorageDead(_29);
|
||||
StorageDead(_28);
|
||||
StorageDead(_31);
|
||||
StorageDead(_10);
|
||||
drop(_2) -> [return: bb11, unwind unreachable];
|
||||
}
|
||||
|
|
@ -243,51 +253,51 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
|
|||
}
|
||||
|
||||
bb12: {
|
||||
_20 = SubUnchecked(copy _19, const 1_usize);
|
||||
_9 = copy _20 as *const T (Transmute);
|
||||
_23 = SubUnchecked(copy _19, const 1_usize);
|
||||
_9 = copy _23 as *const T (Transmute);
|
||||
goto -> bb13;
|
||||
}
|
||||
|
||||
bb13: {
|
||||
StorageLive(_21);
|
||||
_21 = copy _11 as *const T (Transmute);
|
||||
_22 = &(*_21);
|
||||
StorageDead(_21);
|
||||
_23 = Option::<&T>::Some(copy _22);
|
||||
StorageDead(_22);
|
||||
StorageLive(_24);
|
||||
_24 = copy _11 as *const T (Transmute);
|
||||
_25 = &(*_24);
|
||||
StorageDead(_24);
|
||||
_26 = Option::<&T>::Some(copy _25);
|
||||
StorageDead(_25);
|
||||
StorageDead(_13);
|
||||
StorageDead(_20);
|
||||
StorageDead(_23);
|
||||
StorageDead(_19);
|
||||
StorageDead(_12);
|
||||
StorageDead(_11);
|
||||
_24 = copy ((_23 as Some).0: &T);
|
||||
StorageDead(_23);
|
||||
_25 = copy _10;
|
||||
_26 = AddWithOverflow(copy _10, const 1_usize);
|
||||
assert(!move (_26.1: bool), "attempt to compute `{} + {}`, which would overflow", copy _10, const 1_usize) -> [success: bb14, unwind unreachable];
|
||||
_27 = copy ((_26 as Some).0: &T);
|
||||
StorageDead(_26);
|
||||
_28 = copy _10;
|
||||
_29 = AddWithOverflow(copy _10, const 1_usize);
|
||||
assert(!move (_29.1: bool), "attempt to compute `{} + {}`, which would overflow", copy _10, const 1_usize) -> [success: bb14, unwind unreachable];
|
||||
}
|
||||
|
||||
bb14: {
|
||||
_10 = move (_26.0: usize);
|
||||
StorageLive(_27);
|
||||
_27 = (copy _25, copy _24);
|
||||
_28 = Option::<(usize, &T)>::Some(move _27);
|
||||
StorageDead(_27);
|
||||
StorageDead(_26);
|
||||
StorageDead(_25);
|
||||
_29 = copy (((_28 as Some).0: (usize, &T)).0: usize);
|
||||
_30 = copy (((_28 as Some).0: (usize, &T)).1: &T);
|
||||
StorageLive(_31);
|
||||
_31 = &_2;
|
||||
StorageLive(_32);
|
||||
_32 = (copy _29, copy _30);
|
||||
_33 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _31, move _32) -> [return: bb15, unwind unreachable];
|
||||
_10 = move (_29.0: usize);
|
||||
StorageLive(_30);
|
||||
_30 = (copy _28, copy _27);
|
||||
_31 = Option::<(usize, &T)>::Some(move _30);
|
||||
StorageDead(_30);
|
||||
StorageDead(_29);
|
||||
StorageDead(_28);
|
||||
_32 = copy (((_31 as Some).0: (usize, &T)).0: usize);
|
||||
_33 = copy (((_31 as Some).0: (usize, &T)).1: &T);
|
||||
StorageLive(_34);
|
||||
_34 = &_2;
|
||||
StorageLive(_35);
|
||||
_35 = (copy _32, copy _33);
|
||||
_36 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _34, move _35) -> [return: bb15, unwind unreachable];
|
||||
}
|
||||
|
||||
bb15: {
|
||||
StorageDead(_32);
|
||||
StorageDead(_35);
|
||||
StorageDead(_34);
|
||||
StorageDead(_31);
|
||||
StorageDead(_28);
|
||||
goto -> bb4;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
12
tests/ui/coercion/vec-macro-coercions.rs
Normal file
12
tests/ui/coercion/vec-macro-coercions.rs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
//@ check-pass
|
||||
|
||||
fn main() {
|
||||
let functions = &vec![
|
||||
|x: i32| -> i32 { x + 3 },
|
||||
|x: i32| -> i32 { x + 3 },
|
||||
];
|
||||
|
||||
let string = String::new();
|
||||
let a = vec![&string, "abc"];
|
||||
let b = vec!["abc", &string];
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
const fn foo(a: i32) -> Vec<i32> {
|
||||
vec![1, 2, 3]
|
||||
//~^ ERROR allocations are not allowed
|
||||
//~| ERROR cannot call non-const method
|
||||
//~^ ERROR cannot call non-const
|
||||
//~| ERROR cannot call non-const
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,4 @@
|
|||
error[E0010]: allocations are not allowed in constant functions
|
||||
--> $DIR/bad_const_fn_body_ice.rs:2:5
|
||||
|
|
||||
LL | vec![1, 2, 3]
|
||||
| ^^^^^^^^^^^^^ allocation not allowed in constant functions
|
||||
|
||||
error[E0015]: cannot call non-const method `slice::<impl [i32]>::into_vec::<std::alloc::Global>` in constant functions
|
||||
error[E0015]: cannot call non-const associated function `Box::<[i32; 3]>::new_uninit` in constant functions
|
||||
--> $DIR/bad_const_fn_body_ice.rs:2:5
|
||||
|
|
||||
LL | vec![1, 2, 3]
|
||||
|
|
@ -12,7 +6,16 @@ LL | vec![1, 2, 3]
|
|||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::<i32, 3>` in constant functions
|
||||
--> $DIR/bad_const_fn_body_ice.rs:2:5
|
||||
|
|
||||
LL | vec![1, 2, 3]
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
note: function `box_assume_init_into_vec_unsafe` is not const
|
||||
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0010, E0015.
|
||||
For more information about an error, try `rustc --explain E0010`.
|
||||
For more information about this error, try `rustc --explain E0015`.
|
||||
|
|
|
|||
|
|
@ -15,11 +15,11 @@ fn main() {
|
|||
let mut g = #[coroutine]
|
||||
|| {
|
||||
// This is desuraged as 4 stages:
|
||||
// - allocate a `*mut u8` with `exchange_malloc`;
|
||||
// - create a Box that is ignored for trait computations;
|
||||
// - `vec!` macro
|
||||
// - `write_via_move`
|
||||
// - compute fields (and yields);
|
||||
// - assign to `t`.
|
||||
let t = std::boxed::box_new((5, yield));
|
||||
let t = vec![(5, yield)];
|
||||
drop(t);
|
||||
};
|
||||
|
||||
|
|
@ -30,7 +30,7 @@ fn main() {
|
|||
// As it is not taken into account for trait computation,
|
||||
// the coroutine is `Copy`.
|
||||
let mut h = copy(g);
|
||||
//~^ ERROR the trait bound `Box<(i32, ())>: Copy` is not satisfied in
|
||||
//~^ ERROR the trait bound `Box<MaybeUninit<[(i32, ()); 1]>>: Copy` is not satisfied in
|
||||
|
||||
// We now have 2 boxes with the same backing allocation:
|
||||
// one inside `g` and one inside `h`.
|
||||
|
|
|
|||
|
|
@ -1,20 +1,20 @@
|
|||
error[E0277]: the trait bound `Box<(i32, ())>: Copy` is not satisfied in `{coroutine@$DIR/issue-105084.rs:16:5: 16:7}`
|
||||
error[E0277]: the trait bound `Box<MaybeUninit<[(i32, ()); 1]>>: Copy` is not satisfied in `{coroutine@$DIR/issue-105084.rs:16:5: 16:7}`
|
||||
--> $DIR/issue-105084.rs:32:17
|
||||
|
|
||||
LL | || {
|
||||
| -- within this `{coroutine@$DIR/issue-105084.rs:16:5: 16:7}`
|
||||
...
|
||||
LL | let mut h = copy(g);
|
||||
| ^^^^^^^ within `{coroutine@$DIR/issue-105084.rs:16:5: 16:7}`, the trait `Copy` is not implemented for `Box<(i32, ())>`
|
||||
| ^^^^^^^ within `{coroutine@$DIR/issue-105084.rs:16:5: 16:7}`, the trait `Copy` is not implemented for `Box<MaybeUninit<[(i32, ()); 1]>>`
|
||||
|
|
||||
note: coroutine does not implement `Copy` as this value is used across a yield
|
||||
--> $DIR/issue-105084.rs:22:41
|
||||
--> $DIR/issue-105084.rs:22:26
|
||||
|
|
||||
LL | let t = std::boxed::box_new((5, yield));
|
||||
| ------------------------^^^^^--
|
||||
| | |
|
||||
| | yield occurs here, with `std::boxed::box_new((5, yield))` maybe used later
|
||||
| has type `Box<(i32, ())>` which does not implement `Copy`
|
||||
LL | let t = vec![(5, yield)];
|
||||
| ---------^^^^^--
|
||||
| | |
|
||||
| | yield occurs here, with the value maybe used later
|
||||
| has type `Box<MaybeUninit<[(i32, ()); 1]>>` which does not implement `Copy`
|
||||
note: required by a bound in `copy`
|
||||
--> $DIR/issue-105084.rs:10:12
|
||||
|
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
//@ compile-flags: -Z teach
|
||||
|
||||
#![allow(warnings)]
|
||||
|
||||
const CON: Vec<i32> = vec![1, 2, 3]; //~ ERROR E0010
|
||||
//~| ERROR cannot call non-const method
|
||||
fn main() {}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
error[E0010]: allocations are not allowed in constants
|
||||
--> $DIR/E0010-teach.rs:5:23
|
||||
|
|
||||
LL | const CON: Vec<i32> = vec![1, 2, 3];
|
||||
| ^^^^^^^^^^^^^ allocation not allowed in constants
|
||||
|
|
||||
= note: the runtime heap is not yet available at compile-time, so no runtime heap allocations can be created
|
||||
|
||||
error[E0015]: cannot call non-const method `slice::<impl [i32]>::into_vec::<std::alloc::Global>` in constants
|
||||
--> $DIR/E0010-teach.rs:5:23
|
||||
|
|
||||
LL | const CON: Vec<i32> = vec![1, 2, 3];
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0010, E0015.
|
||||
For more information about an error, try `rustc --explain E0010`.
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
#![allow(warnings)]
|
||||
|
||||
const CON: Vec<i32> = vec![1, 2, 3]; //~ ERROR E0010
|
||||
//~| ERROR cannot call non-const method
|
||||
fn main() {}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
error[E0010]: allocations are not allowed in constants
|
||||
--> $DIR/E0010.rs:3:23
|
||||
|
|
||||
LL | const CON: Vec<i32> = vec![1, 2, 3];
|
||||
| ^^^^^^^^^^^^^ allocation not allowed in constants
|
||||
|
||||
error[E0015]: cannot call non-const method `slice::<impl [i32]>::into_vec::<std::alloc::Global>` in constants
|
||||
--> $DIR/E0010.rs:3:23
|
||||
|
|
||||
LL | const CON: Vec<i32> = vec![1, 2, 3];
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0010, E0015.
|
||||
For more information about an error, try `rustc --explain E0010`.
|
||||
|
|
@ -390,14 +390,6 @@ LL | fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { pani
|
|||
- impl<F, Args> Fn<Args> for Exclusive<F>
|
||||
where F: Sync, F: Fn<Args>, Args: std::marker::Tuple;
|
||||
|
||||
error[E0118]: no nominal type found for inherent implementation
|
||||
--> $DIR/where-allowed.rs:241:1
|
||||
|
|
||||
LL | impl<T = impl Debug> T {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type
|
||||
|
|
||||
= note: either implement a trait on it or create a newtype to wrap it instead
|
||||
|
||||
error: unconstrained opaque type
|
||||
--> $DIR/where-allowed.rs:122:16
|
||||
|
|
||||
|
|
@ -414,6 +406,14 @@ LL | type InTypeAlias<R> = impl Debug;
|
|||
|
|
||||
= note: `InTypeAlias` must be used in combination with a concrete type within the same crate
|
||||
|
||||
error[E0118]: no nominal type found for inherent implementation
|
||||
--> $DIR/where-allowed.rs:241:1
|
||||
|
|
||||
LL | impl<T = impl Debug> T {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type
|
||||
|
|
||||
= note: either implement a trait on it or create a newtype to wrap it instead
|
||||
|
||||
error: aborting due to 48 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0053, E0118, E0283, E0562, E0658, E0666.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ fn main() {
|
|||
match Some(vec![42]) {
|
||||
Some(vec![43]) => {} //~ ERROR expected a pattern, found a function call
|
||||
//~| ERROR found associated function
|
||||
//~| ERROR usage of qualified paths in this context is experimental
|
||||
//~| ERROR expected a pattern, found a function call
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,17 +6,15 @@ LL | Some(vec![43]) => {}
|
|||
|
|
||||
= note: function calls are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
|
||||
|
||||
error[E0658]: usage of qualified paths in this context is experimental
|
||||
error[E0532]: expected a pattern, found a function call
|
||||
--> $DIR/vec-macro-in-pattern.rs:7:14
|
||||
|
|
||||
LL | Some(vec![43]) => {}
|
||||
| ^^^^^^^^
|
||||
| ^^^^^^^^ not a tuple struct or tuple variant
|
||||
|
|
||||
= note: see issue #86935 <https://github.com/rust-lang/rust/issues/86935> for more information
|
||||
= help: add `#![feature(more_qualified_paths)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
= note: function calls are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
|
||||
|
||||
error[E0164]: expected tuple struct or tuple variant, found associated function `<[_]>::into_vec`
|
||||
error[E0164]: expected tuple struct or tuple variant, found associated function `::alloc::boxed::Box::new_uninit`
|
||||
--> $DIR/vec-macro-in-pattern.rs:7:14
|
||||
|
|
||||
LL | Some(vec![43]) => {}
|
||||
|
|
@ -26,5 +24,5 @@ LL | Some(vec![43]) => {}
|
|||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0164, E0532, E0658.
|
||||
Some errors have detailed explanations: E0164, E0532.
|
||||
For more information about an error, try `rustc --explain E0164`.
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
//! regression test for issue <https://github.com/rust-lang/rust/issues/47184>
|
||||
fn main() {
|
||||
let _vec: Vec<&'static String> = vec![&String::new()];
|
||||
//~^ ERROR temporary value dropped while borrowed [E0716]
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/borrowck-annotate-static-lifetime.rs:3:44
|
||||
|
|
||||
LL | let _vec: Vec<&'static String> = vec![&String::new()];
|
||||
| -------------------- ^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
|
||||
| | |
|
||||
| | creates a temporary value which is freed while still in use
|
||||
| type annotation requires that borrow lasts for `'static`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0716`.
|
||||
|
|
@ -70,6 +70,11 @@ fn underscore_with_initializer() {
|
|||
//~^ ERROR temporary value dropped while borrowed [E0716]
|
||||
}
|
||||
|
||||
fn issue_47184() {
|
||||
let _vec: Vec<&'static String> = vec![&String::new()];
|
||||
//~^ ERROR temporary value dropped while borrowed [E0716]
|
||||
}
|
||||
|
||||
fn pair_underscores_with_initializer() {
|
||||
let x = 22;
|
||||
let (_, _): (&'static u32, u32) = (&x, 44); //~ ERROR
|
||||
|
|
|
|||
|
|
@ -111,8 +111,17 @@ LL | let (_a, b): (Vec<&'static String>, _) = (vec![&String::new()], 44);
|
|||
| | creates a temporary value which is freed while still in use
|
||||
| type annotation requires that borrow lasts for `'static`
|
||||
|
||||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/patterns.rs:74:44
|
||||
|
|
||||
LL | let _vec: Vec<&'static String> = vec![&String::new()];
|
||||
| -------------------- ^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
|
||||
| | |
|
||||
| | creates a temporary value which is freed while still in use
|
||||
| type annotation requires that borrow lasts for `'static`
|
||||
|
||||
error[E0597]: `x` does not live long enough
|
||||
--> $DIR/patterns.rs:75:40
|
||||
--> $DIR/patterns.rs:80:40
|
||||
|
|
||||
LL | let x = 22;
|
||||
| - binding `x` declared here
|
||||
|
|
@ -124,7 +133,7 @@ LL | }
|
|||
| - `x` dropped here while still borrowed
|
||||
|
||||
error[E0597]: `x` does not live long enough
|
||||
--> $DIR/patterns.rs:80:40
|
||||
--> $DIR/patterns.rs:85:40
|
||||
|
|
||||
LL | let x = 22;
|
||||
| - binding `x` declared here
|
||||
|
|
@ -136,7 +145,7 @@ LL | }
|
|||
| - `x` dropped here while still borrowed
|
||||
|
||||
error[E0597]: `x` does not live long enough
|
||||
--> $DIR/patterns.rs:85:69
|
||||
--> $DIR/patterns.rs:90:69
|
||||
|
|
||||
LL | let x = 22;
|
||||
| - binding `x` declared here
|
||||
|
|
@ -148,7 +157,7 @@ LL | }
|
|||
| - `x` dropped here while still borrowed
|
||||
|
||||
error[E0597]: `x` does not live long enough
|
||||
--> $DIR/patterns.rs:90:69
|
||||
--> $DIR/patterns.rs:95:69
|
||||
|
|
||||
LL | let x = 22;
|
||||
| - binding `x` declared here
|
||||
|
|
@ -160,7 +169,7 @@ LL | }
|
|||
| - `x` dropped here while still borrowed
|
||||
|
||||
error[E0597]: `x` does not live long enough
|
||||
--> $DIR/patterns.rs:98:17
|
||||
--> $DIR/patterns.rs:103:17
|
||||
|
|
||||
LL | let x = 22;
|
||||
| - binding `x` declared here
|
||||
|
|
@ -173,7 +182,7 @@ LL | }
|
|||
| - `x` dropped here while still borrowed
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/patterns.rs:111:5
|
||||
--> $DIR/patterns.rs:116:5
|
||||
|
|
||||
LL | fn static_to_a_to_static_through_variable<'a>(x: &'a u32) -> &'static u32 {
|
||||
| -- lifetime `'a` defined here
|
||||
|
|
@ -182,7 +191,7 @@ LL | y
|
|||
| ^ returning this value requires that `'a` must outlive `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/patterns.rs:123:5
|
||||
--> $DIR/patterns.rs:128:5
|
||||
|
|
||||
LL | fn static_to_a_to_static_through_tuple<'a>(x: &'a u32) -> &'static u32 {
|
||||
| -- lifetime `'a` defined here
|
||||
|
|
@ -191,7 +200,7 @@ LL | y
|
|||
| ^ returning this value requires that `'a` must outlive `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/patterns.rs:128:5
|
||||
--> $DIR/patterns.rs:133:5
|
||||
|
|
||||
LL | fn static_to_a_to_static_through_struct<'a>(_x: &'a u32) -> &'static u32 {
|
||||
| -- lifetime `'a` defined here
|
||||
|
|
@ -200,14 +209,14 @@ LL | y
|
|||
| ^ returning this value requires that `'a` must outlive `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/patterns.rs:132:18
|
||||
--> $DIR/patterns.rs:137:18
|
||||
|
|
||||
LL | fn a_to_static_then_static<'a>(x: &'a u32) -> &'static u32 {
|
||||
| -- lifetime `'a` defined here
|
||||
LL | let (y, _z): (&'static u32, u32) = (x, 44);
|
||||
| ^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
||||
|
||||
error: aborting due to 19 previous errors
|
||||
error: aborting due to 20 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0597, E0716.
|
||||
For more information about an error, try `rustc --explain E0597`.
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
fn main() {
|
||||
let vec![const { vec![] }]: Vec<usize> = vec![];
|
||||
//~^ ERROR expected a pattern, found a function call
|
||||
//~| ERROR usage of qualified paths in this context is experimental
|
||||
//~| ERROR expected a pattern, found a function call
|
||||
//~| ERROR expected tuple struct or tuple variant
|
||||
//~| ERROR arbitrary expressions aren't allowed in patterns
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,15 +6,13 @@ LL | let vec![const { vec![] }]: Vec<usize> = vec![];
|
|||
|
|
||||
= note: function calls are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
|
||||
|
||||
error[E0658]: usage of qualified paths in this context is experimental
|
||||
error[E0532]: expected a pattern, found a function call
|
||||
--> $DIR/ice-adjust-mode-unimplemented-for-constblock.rs:5:9
|
||||
|
|
||||
LL | let vec![const { vec![] }]: Vec<usize> = vec![];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ not a tuple struct or tuple variant
|
||||
|
|
||||
= note: see issue #86935 <https://github.com/rust-lang/rust/issues/86935> for more information
|
||||
= help: add `#![feature(more_qualified_paths)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
= note: function calls are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
|
||||
|
||||
error: arbitrary expressions aren't allowed in patterns
|
||||
--> $DIR/ice-adjust-mode-unimplemented-for-constblock.rs:5:14
|
||||
|
|
@ -24,7 +22,7 @@ LL | let vec![const { vec![] }]: Vec<usize> = vec![];
|
|||
|
|
||||
= help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead
|
||||
|
||||
error[E0164]: expected tuple struct or tuple variant, found associated function `<[_]>::into_vec`
|
||||
error[E0164]: expected tuple struct or tuple variant, found associated function `::alloc::boxed::Box::new_uninit`
|
||||
--> $DIR/ice-adjust-mode-unimplemented-for-constblock.rs:5:9
|
||||
|
|
||||
LL | let vec![const { vec![] }]: Vec<usize> = vec![];
|
||||
|
|
@ -34,5 +32,5 @@ LL | let vec![const { vec![] }]: Vec<usize> = vec![];
|
|||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0164, E0532, E0658.
|
||||
Some errors have detailed explanations: E0164, E0532.
|
||||
For more information about an error, try `rustc --explain E0164`.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/issue-15480.rs:6:10
|
||||
--> $DIR/vec-macro-outlives-issue-15480.rs:6:10
|
||||
|
|
||||
LL | &id(3)
|
||||
| ^^^^^ creates a temporary value which is freed while still in use
|
||||
|
|
@ -79,8 +79,8 @@ static STATIC10: UnsafeStruct = UnsafeStruct;
|
|||
struct MyOwned;
|
||||
|
||||
static STATIC11: Vec<MyOwned> = vec![MyOwned];
|
||||
//~^ ERROR allocations are not allowed in statics
|
||||
//~^^ ERROR cannot call non-const
|
||||
//~^ ERROR cannot call non-const function
|
||||
//~| ERROR cannot call non-const
|
||||
|
||||
static mut STATIC12: UnsafeStruct = UnsafeStruct;
|
||||
|
||||
|
|
@ -93,29 +93,29 @@ static mut STATIC14: SafeStruct = SafeStruct {
|
|||
};
|
||||
|
||||
static STATIC15: &'static [Vec<MyOwned>] = &[
|
||||
vec![MyOwned], //~ ERROR allocations are not allowed in statics
|
||||
//~^ ERROR cannot call non-const
|
||||
vec![MyOwned], //~ ERROR allocations are not allowed in statics
|
||||
//~^ ERROR cannot call non-const
|
||||
vec![MyOwned], //~ ERROR cannot call non-const function
|
||||
//~| ERROR cannot call non-const
|
||||
vec![MyOwned], //~ ERROR cannot call non-const function
|
||||
//~| ERROR cannot call non-const
|
||||
];
|
||||
|
||||
static STATIC16: (&'static Vec<MyOwned>, &'static Vec<MyOwned>) = (
|
||||
&vec![MyOwned], //~ ERROR allocations are not allowed in statics
|
||||
//~^ ERROR cannot call non-const
|
||||
&vec![MyOwned], //~ ERROR allocations are not allowed in statics
|
||||
//~^ ERROR cannot call non-const
|
||||
&vec![MyOwned], //~ ERROR cannot call non-const function
|
||||
//~| ERROR cannot call non-const
|
||||
&vec![MyOwned], //~ ERROR cannot call non-const function
|
||||
//~| ERROR cannot call non-const
|
||||
);
|
||||
|
||||
static mut STATIC17: SafeEnum = SafeEnum::Variant1;
|
||||
|
||||
static STATIC19: Vec<isize> = vec![3];
|
||||
//~^ ERROR allocations are not allowed in statics
|
||||
//~^^ ERROR cannot call non-const
|
||||
//~^ ERROR cannot call non-const function
|
||||
//~| ERROR cannot call non-const
|
||||
|
||||
pub fn main() {
|
||||
let y = {
|
||||
static x: Vec<isize> = vec![3]; //~ ERROR allocations are not allowed in statics
|
||||
//~^ ERROR cannot call non-const
|
||||
static x: Vec<isize> = vec![3]; //~ ERROR cannot call non-const function
|
||||
//~| ERROR cannot call non-const
|
||||
x
|
||||
//~^ ERROR cannot move out of static
|
||||
};
|
||||
|
|
|
|||
|
|
@ -11,13 +11,7 @@ LL | | }
|
|||
LL | };
|
||||
| - value is dropped here
|
||||
|
||||
error[E0010]: allocations are not allowed in statics
|
||||
--> $DIR/check-values-constraints.rs:81:33
|
||||
|
|
||||
LL | static STATIC11: Vec<MyOwned> = vec![MyOwned];
|
||||
| ^^^^^^^^^^^^^ allocation not allowed in statics
|
||||
|
||||
error[E0015]: cannot call non-const method `slice::<impl [MyOwned]>::into_vec::<std::alloc::Global>` in statics
|
||||
error[E0015]: cannot call non-const associated function `Box::<[MyOwned; 1]>::new_uninit` in statics
|
||||
--> $DIR/check-values-constraints.rs:81:33
|
||||
|
|
||||
LL | static STATIC11: Vec<MyOwned> = vec![MyOwned];
|
||||
|
|
@ -26,6 +20,17 @@ LL | static STATIC11: Vec<MyOwned> = vec![MyOwned];
|
|||
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
||||
|
||||
error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::<MyOwned, 1>` in statics
|
||||
--> $DIR/check-values-constraints.rs:81:33
|
||||
|
|
||||
LL | static STATIC11: Vec<MyOwned> = vec![MyOwned];
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
note: function `box_assume_init_into_vec_unsafe` is not const
|
||||
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
||||
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
||||
|
||||
error[E0015]: cannot call non-const method `<str as ToString>::to_string` in statics
|
||||
--> $DIR/check-values-constraints.rs:92:38
|
||||
|
|
||||
|
|
@ -42,13 +47,7 @@ note: method `to_string` is not const because trait `ToString` is not const
|
|||
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
||||
|
||||
error[E0010]: allocations are not allowed in statics
|
||||
--> $DIR/check-values-constraints.rs:96:5
|
||||
|
|
||||
LL | vec![MyOwned],
|
||||
| ^^^^^^^^^^^^^ allocation not allowed in statics
|
||||
|
||||
error[E0015]: cannot call non-const method `slice::<impl [MyOwned]>::into_vec::<std::alloc::Global>` in statics
|
||||
error[E0015]: cannot call non-const associated function `Box::<[MyOwned; 1]>::new_uninit` in statics
|
||||
--> $DIR/check-values-constraints.rs:96:5
|
||||
|
|
||||
LL | vec![MyOwned],
|
||||
|
|
@ -57,13 +56,18 @@ LL | vec![MyOwned],
|
|||
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
||||
|
||||
error[E0010]: allocations are not allowed in statics
|
||||
--> $DIR/check-values-constraints.rs:98:5
|
||||
error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::<MyOwned, 1>` in statics
|
||||
--> $DIR/check-values-constraints.rs:96:5
|
||||
|
|
||||
LL | vec![MyOwned],
|
||||
| ^^^^^^^^^^^^^ allocation not allowed in statics
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
note: function `box_assume_init_into_vec_unsafe` is not const
|
||||
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
||||
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
||||
|
||||
error[E0015]: cannot call non-const method `slice::<impl [MyOwned]>::into_vec::<std::alloc::Global>` in statics
|
||||
error[E0015]: cannot call non-const associated function `Box::<[MyOwned; 1]>::new_uninit` in statics
|
||||
--> $DIR/check-values-constraints.rs:98:5
|
||||
|
|
||||
LL | vec![MyOwned],
|
||||
|
|
@ -72,13 +76,18 @@ LL | vec![MyOwned],
|
|||
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
||||
|
||||
error[E0010]: allocations are not allowed in statics
|
||||
--> $DIR/check-values-constraints.rs:103:6
|
||||
error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::<MyOwned, 1>` in statics
|
||||
--> $DIR/check-values-constraints.rs:98:5
|
||||
|
|
||||
LL | &vec![MyOwned],
|
||||
| ^^^^^^^^^^^^^ allocation not allowed in statics
|
||||
LL | vec![MyOwned],
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
note: function `box_assume_init_into_vec_unsafe` is not const
|
||||
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
||||
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
||||
|
||||
error[E0015]: cannot call non-const method `slice::<impl [MyOwned]>::into_vec::<std::alloc::Global>` in statics
|
||||
error[E0015]: cannot call non-const associated function `Box::<[MyOwned; 1]>::new_uninit` in statics
|
||||
--> $DIR/check-values-constraints.rs:103:6
|
||||
|
|
||||
LL | &vec![MyOwned],
|
||||
|
|
@ -87,13 +96,18 @@ LL | &vec![MyOwned],
|
|||
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
||||
|
||||
error[E0010]: allocations are not allowed in statics
|
||||
--> $DIR/check-values-constraints.rs:105:6
|
||||
error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::<MyOwned, 1>` in statics
|
||||
--> $DIR/check-values-constraints.rs:103:6
|
||||
|
|
||||
LL | &vec![MyOwned],
|
||||
| ^^^^^^^^^^^^^ allocation not allowed in statics
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
note: function `box_assume_init_into_vec_unsafe` is not const
|
||||
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
||||
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
||||
|
||||
error[E0015]: cannot call non-const method `slice::<impl [MyOwned]>::into_vec::<std::alloc::Global>` in statics
|
||||
error[E0015]: cannot call non-const associated function `Box::<[MyOwned; 1]>::new_uninit` in statics
|
||||
--> $DIR/check-values-constraints.rs:105:6
|
||||
|
|
||||
LL | &vec![MyOwned],
|
||||
|
|
@ -102,13 +116,18 @@ LL | &vec![MyOwned],
|
|||
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
||||
|
||||
error[E0010]: allocations are not allowed in statics
|
||||
--> $DIR/check-values-constraints.rs:111:31
|
||||
error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::<MyOwned, 1>` in statics
|
||||
--> $DIR/check-values-constraints.rs:105:6
|
||||
|
|
||||
LL | static STATIC19: Vec<isize> = vec![3];
|
||||
| ^^^^^^^ allocation not allowed in statics
|
||||
LL | &vec![MyOwned],
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
note: function `box_assume_init_into_vec_unsafe` is not const
|
||||
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
||||
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
||||
|
||||
error[E0015]: cannot call non-const method `slice::<impl [isize]>::into_vec::<std::alloc::Global>` in statics
|
||||
error[E0015]: cannot call non-const associated function `Box::<[isize; 1]>::new_uninit` in statics
|
||||
--> $DIR/check-values-constraints.rs:111:31
|
||||
|
|
||||
LL | static STATIC19: Vec<isize> = vec![3];
|
||||
|
|
@ -117,13 +136,18 @@ LL | static STATIC19: Vec<isize> = vec![3];
|
|||
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
||||
|
||||
error[E0010]: allocations are not allowed in statics
|
||||
--> $DIR/check-values-constraints.rs:117:32
|
||||
error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::<isize, 1>` in statics
|
||||
--> $DIR/check-values-constraints.rs:111:31
|
||||
|
|
||||
LL | static x: Vec<isize> = vec![3];
|
||||
| ^^^^^^^ allocation not allowed in statics
|
||||
LL | static STATIC19: Vec<isize> = vec![3];
|
||||
| ^^^^^^^
|
||||
|
|
||||
note: function `box_assume_init_into_vec_unsafe` is not const
|
||||
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
||||
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
||||
|
||||
error[E0015]: cannot call non-const method `slice::<impl [isize]>::into_vec::<std::alloc::Global>` in statics
|
||||
error[E0015]: cannot call non-const associated function `Box::<[isize; 1]>::new_uninit` in statics
|
||||
--> $DIR/check-values-constraints.rs:117:32
|
||||
|
|
||||
LL | static x: Vec<isize> = vec![3];
|
||||
|
|
@ -132,6 +156,17 @@ LL | static x: Vec<isize> = vec![3];
|
|||
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
||||
|
||||
error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::<isize, 1>` in statics
|
||||
--> $DIR/check-values-constraints.rs:117:32
|
||||
|
|
||||
LL | static x: Vec<isize> = vec![3];
|
||||
| ^^^^^^^
|
||||
|
|
||||
note: function `box_assume_init_into_vec_unsafe` is not const
|
||||
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
||||
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
||||
|
||||
error[E0507]: cannot move out of static item `x`
|
||||
--> $DIR/check-values-constraints.rs:119:9
|
||||
|
|
||||
|
|
@ -149,5 +184,5 @@ LL | x.clone()
|
|||
|
||||
error: aborting due to 17 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0010, E0015, E0493, E0507.
|
||||
For more information about an error, try `rustc --explain E0010`.
|
||||
Some errors have detailed explanations: E0015, E0493, E0507.
|
||||
For more information about an error, try `rustc --explain E0015`.
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
//@ compile-flags: -Zunpretty=thir-tree
|
||||
//@ check-pass
|
||||
|
||||
#![feature(liballoc_internals)]
|
||||
|
||||
fn main() {
|
||||
let _ = std::boxed::box_new(1);
|
||||
}
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
DefId(0:3 ~ box[efb9]::main):
|
||||
params: [
|
||||
]
|
||||
body:
|
||||
Expr {
|
||||
ty: ()
|
||||
temp_scope_id: 11
|
||||
span: $DIR/box.rs:6:11: 8:2 (#0)
|
||||
kind:
|
||||
Scope {
|
||||
region_scope: Node(11)
|
||||
hir_id: HirId(DefId(0:3 ~ box[efb9]::main).11)
|
||||
value:
|
||||
Expr {
|
||||
ty: ()
|
||||
temp_scope_id: 11
|
||||
span: $DIR/box.rs:6:11: 8:2 (#0)
|
||||
kind:
|
||||
Block {
|
||||
targeted_by_break: false
|
||||
span: $DIR/box.rs:6:11: 8:2 (#0)
|
||||
region_scope: Node(1)
|
||||
safety_mode: Safe
|
||||
stmts: [
|
||||
Stmt {
|
||||
kind: Let {
|
||||
remainder_scope: Remainder { block: 1, first_statement_index: 0}
|
||||
init_scope: Node(2)
|
||||
pattern:
|
||||
Pat {
|
||||
ty: std::boxed::Box<i32, std::alloc::Global>
|
||||
span: $DIR/box.rs:7:9: 7:10 (#0)
|
||||
kind: PatKind {
|
||||
Wild
|
||||
}
|
||||
}
|
||||
,
|
||||
initializer: Some(
|
||||
Expr {
|
||||
ty: std::boxed::Box<i32, std::alloc::Global>
|
||||
temp_scope_id: 3
|
||||
span: $DIR/box.rs:7:13: 7:35 (#0)
|
||||
kind:
|
||||
Scope {
|
||||
region_scope: Node(3)
|
||||
hir_id: HirId(DefId(0:3 ~ box[efb9]::main).3)
|
||||
value:
|
||||
Expr {
|
||||
ty: std::boxed::Box<i32, std::alloc::Global>
|
||||
temp_scope_id: 3
|
||||
span: $DIR/box.rs:7:13: 7:35 (#0)
|
||||
kind:
|
||||
Box {
|
||||
Expr {
|
||||
ty: i32
|
||||
temp_scope_id: 8
|
||||
span: $DIR/box.rs:7:33: 7:34 (#0)
|
||||
kind:
|
||||
Scope {
|
||||
region_scope: Node(8)
|
||||
hir_id: HirId(DefId(0:3 ~ box[efb9]::main).8)
|
||||
value:
|
||||
Expr {
|
||||
ty: i32
|
||||
temp_scope_id: 8
|
||||
span: $DIR/box.rs:7:33: 7:34 (#0)
|
||||
kind:
|
||||
Literal( lit: Spanned { node: Int(Pu128(1), Unsuffixed), span: $DIR/box.rs:7:33: 7:34 (#0) }, neg: false)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
else_block: None
|
||||
hir_id: HirId(DefId(0:3 ~ box[efb9]::main).9)
|
||||
span: $DIR/box.rs:7:5: 7:35 (#0)
|
||||
}
|
||||
}
|
||||
]
|
||||
expr: []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue