about summary refs log tree commit diff
path: root/compiler/rustc_mir_transform/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-06-30 14:28:58 +0000
committerbors <bors@rust-lang.org>2025-06-30 14:28:58 +0000
commitc65dccabacdfd6c8a7f7439eba13422fdd89b91e (patch)
tree6ebe9f9850150cd48069e0bad639dc5d55660e99 /compiler/rustc_mir_transform/src
parentad3b7257615c28aaf8212a189ec032b8af75de51 (diff)
parentc2904f7476b4558633a301aec9bbfedb0af0b501 (diff)
downloadrust-c65dccabacdfd6c8a7f7439eba13422fdd89b91e.tar.gz
rust-c65dccabacdfd6c8a7f7439eba13422fdd89b91e.zip
Auto merge of #143233 - dianqk:rollup-lcx3278, r=dianqk
Rollup of 14 pull requests

Successful merges:

 - rust-lang/rust#142429 (`tests/ui`: A New Order [13/N])
 - rust-lang/rust#142514 (Miri: handling of SNaN inputs in `f*::pow` operations)
 - rust-lang/rust#143066 (Use let chains in the new solver)
 - rust-lang/rust#143090 (Workaround for memory unsafety in third party DLLs)
 - rust-lang/rust#143118 (`tests/ui`: A New Order [15/N])
 - rust-lang/rust#143159 (Do not freshen `ReError`)
 - rust-lang/rust#143168 (`tests/ui`: A New Order [16/N])
 - rust-lang/rust#143176 (fix typos and improve clarity in documentation)
 - rust-lang/rust#143187 (Add my work email to mailmap)
 - rust-lang/rust#143190 (Use the `new` method for `BasicBlockData` and `Statement`)
 - rust-lang/rust#143195 (`tests/ui`: A New Order [17/N])
 - rust-lang/rust#143196 (Port #[link_section] to the new attribute parsing infrastructure)
 - rust-lang/rust#143199 (Re-disable `tests/run-make/short-ice` on Windows MSVC again)
 - rust-lang/rust#143219 (Show auto trait and blanket impls for `!`)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_mir_transform/src')
-rw-r--r--compiler/rustc_mir_transform/src/add_call_guards.rs7
-rw-r--r--compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs8
-rw-r--r--compiler/rustc_mir_transform/src/add_retag.rs19
-rw-r--r--compiler/rustc_mir_transform/src/check_alignment.rs34
-rw-r--r--compiler/rustc_mir_transform/src/check_null.rs35
-rw-r--r--compiler/rustc_mir_transform/src/check_pointers.rs10
-rw-r--r--compiler/rustc_mir_transform/src/coroutine.rs111
-rw-r--r--compiler/rustc_mir_transform/src/coroutine/drop.rs60
-rw-r--r--compiler/rustc_mir_transform/src/coverage/mod.rs2
-rw-r--r--compiler/rustc_mir_transform/src/coverage/tests.rs9
-rw-r--r--compiler/rustc_mir_transform/src/ctfe_limit.rs8
-rw-r--r--compiler/rustc_mir_transform/src/elaborate_drop.rs125
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs56
-rw-r--r--compiler/rustc_mir_transform/src/instsimplify.rs8
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs8
-rw-r--r--compiler/rustc_mir_transform/src/lower_intrinsics.rs135
-rw-r--r--compiler/rustc_mir_transform/src/lower_slice_len.rs3
-rw-r--r--compiler/rustc_mir_transform/src/patch.rs38
-rw-r--r--compiler/rustc_mir_transform/src/promote_consts.rs25
-rw-r--r--compiler/rustc_mir_transform/src/shim.rs90
-rw-r--r--compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs70
-rw-r--r--compiler/rustc_mir_transform/src/simplify_comparison_integral.rs8
22 files changed, 399 insertions, 470 deletions
diff --git a/compiler/rustc_mir_transform/src/add_call_guards.rs b/compiler/rustc_mir_transform/src/add_call_guards.rs
index bacff287859..26839ebf61e 100644
--- a/compiler/rustc_mir_transform/src/add_call_guards.rs
+++ b/compiler/rustc_mir_transform/src/add_call_guards.rs
@@ -44,11 +44,10 @@ impl<'tcx> crate::MirPass<'tcx> for AddCallGuards {
 
         let cur_len = body.basic_blocks.len();
         let mut new_block = |source_info: SourceInfo, is_cleanup: bool, target: BasicBlock| {
-            let block = BasicBlockData {
-                statements: vec![],
+            let block = BasicBlockData::new(
+                Some(Terminator { source_info, kind: TerminatorKind::Goto { target } }),
                 is_cleanup,
-                terminator: Some(Terminator { source_info, kind: TerminatorKind::Goto { target } }),
-            };
+            );
             let idx = cur_len + new_blocks.len();
             new_blocks.push(block);
             BasicBlock::new(idx)
diff --git a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs
index a414d120e68..7ae2ebaf4ff 100644
--- a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs
+++ b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs
@@ -93,11 +93,11 @@ fn add_move_for_packed_drop<'tcx>(
     let ty = place.ty(body, tcx).ty;
     let temp = patch.new_temp(ty, source_info.span);
 
-    let storage_dead_block = patch.new_block(BasicBlockData {
-        statements: vec![Statement { source_info, kind: StatementKind::StorageDead(temp) }],
-        terminator: Some(Terminator { source_info, kind: TerminatorKind::Goto { target } }),
+    let storage_dead_block = patch.new_block(BasicBlockData::new_stmts(
+        vec![Statement::new(source_info, StatementKind::StorageDead(temp))],
+        Some(Terminator { source_info, kind: TerminatorKind::Goto { target } }),
         is_cleanup,
-    });
+    ));
 
     patch.add_statement(loc, StatementKind::StorageLive(temp));
     patch.add_assign(loc, Place::from(temp), Rvalue::Use(Operand::Move(*place)));
diff --git a/compiler/rustc_mir_transform/src/add_retag.rs b/compiler/rustc_mir_transform/src/add_retag.rs
index e5a28d1b66c..3c29d4624b7 100644
--- a/compiler/rustc_mir_transform/src/add_retag.rs
+++ b/compiler/rustc_mir_transform/src/add_retag.rs
@@ -81,9 +81,11 @@ impl<'tcx> crate::MirPass<'tcx> for AddRetag {
             // Emit their retags.
             basic_blocks[START_BLOCK].statements.splice(
                 0..0,
-                places.map(|(place, source_info)| Statement {
-                    source_info,
-                    kind: StatementKind::Retag(RetagKind::FnEntry, Box::new(place)),
+                places.map(|(place, source_info)| {
+                    Statement::new(
+                        source_info,
+                        StatementKind::Retag(RetagKind::FnEntry, Box::new(place)),
+                    )
                 }),
             );
         }
@@ -113,10 +115,10 @@ impl<'tcx> crate::MirPass<'tcx> for AddRetag {
         for (source_info, dest_place, dest_block) in returns {
             basic_blocks[dest_block].statements.insert(
                 0,
-                Statement {
+                Statement::new(
                     source_info,
-                    kind: StatementKind::Retag(RetagKind::Default, Box::new(dest_place)),
-                },
+                    StatementKind::Retag(RetagKind::Default, Box::new(dest_place)),
+                ),
             );
         }
 
@@ -174,10 +176,7 @@ impl<'tcx> crate::MirPass<'tcx> for AddRetag {
                 let source_info = block_data.statements[i].source_info;
                 block_data.statements.insert(
                     i + 1,
-                    Statement {
-                        source_info,
-                        kind: StatementKind::Retag(retag_kind, Box::new(place)),
-                    },
+                    Statement::new(source_info, StatementKind::Retag(retag_kind, Box::new(place))),
                 );
             }
         }
diff --git a/compiler/rustc_mir_transform/src/check_alignment.rs b/compiler/rustc_mir_transform/src/check_alignment.rs
index 8f88613b79f..989787504b7 100644
--- a/compiler/rustc_mir_transform/src/check_alignment.rs
+++ b/compiler/rustc_mir_transform/src/check_alignment.rs
@@ -51,22 +51,18 @@ fn insert_alignment_check<'tcx>(
     let const_raw_ptr = Ty::new_imm_ptr(tcx, tcx.types.unit);
     let rvalue = Rvalue::Cast(CastKind::PtrToPtr, Operand::Copy(pointer), const_raw_ptr);
     let thin_ptr = local_decls.push(LocalDecl::with_source_info(const_raw_ptr, source_info)).into();
-    stmts
-        .push(Statement { source_info, kind: StatementKind::Assign(Box::new((thin_ptr, rvalue))) });
+    stmts.push(Statement::new(source_info, StatementKind::Assign(Box::new((thin_ptr, rvalue)))));
 
     // Transmute the pointer to a usize (equivalent to `ptr.addr()`).
     let rvalue = Rvalue::Cast(CastKind::Transmute, Operand::Copy(thin_ptr), tcx.types.usize);
     let addr = local_decls.push(LocalDecl::with_source_info(tcx.types.usize, source_info)).into();
-    stmts.push(Statement { source_info, kind: StatementKind::Assign(Box::new((addr, rvalue))) });
+    stmts.push(Statement::new(source_info, StatementKind::Assign(Box::new((addr, rvalue)))));
 
     // Get the alignment of the pointee
     let alignment =
         local_decls.push(LocalDecl::with_source_info(tcx.types.usize, source_info)).into();
     let rvalue = Rvalue::NullaryOp(NullOp::AlignOf, pointee_ty);
-    stmts.push(Statement {
-        source_info,
-        kind: StatementKind::Assign(Box::new((alignment, rvalue))),
-    });
+    stmts.push(Statement::new(source_info, StatementKind::Assign(Box::new((alignment, rvalue)))));
 
     // Subtract 1 from the alignment to get the alignment mask
     let alignment_mask =
@@ -76,13 +72,13 @@ fn insert_alignment_check<'tcx>(
         user_ty: None,
         const_: Const::Val(ConstValue::Scalar(Scalar::from_target_usize(1, &tcx)), tcx.types.usize),
     }));
-    stmts.push(Statement {
+    stmts.push(Statement::new(
         source_info,
-        kind: StatementKind::Assign(Box::new((
+        StatementKind::Assign(Box::new((
             alignment_mask,
             Rvalue::BinaryOp(BinOp::Sub, Box::new((Operand::Copy(alignment), one))),
         ))),
-    });
+    ));
 
     // If this target does not have reliable alignment, further limit the mask by anding it with
     // the mask for the highest reliable alignment.
@@ -99,31 +95,31 @@ fn insert_alignment_check<'tcx>(
                 tcx.types.usize,
             ),
         }));
-        stmts.push(Statement {
+        stmts.push(Statement::new(
             source_info,
-            kind: StatementKind::Assign(Box::new((
+            StatementKind::Assign(Box::new((
                 alignment_mask,
                 Rvalue::BinaryOp(
                     BinOp::BitAnd,
                     Box::new((Operand::Copy(alignment_mask), max_mask)),
                 ),
             ))),
-        });
+        ));
     }
 
     // BitAnd the alignment mask with the pointer
     let alignment_bits =
         local_decls.push(LocalDecl::with_source_info(tcx.types.usize, source_info)).into();
-    stmts.push(Statement {
+    stmts.push(Statement::new(
         source_info,
-        kind: StatementKind::Assign(Box::new((
+        StatementKind::Assign(Box::new((
             alignment_bits,
             Rvalue::BinaryOp(
                 BinOp::BitAnd,
                 Box::new((Operand::Copy(addr), Operand::Copy(alignment_mask))),
             ),
         ))),
-    });
+    ));
 
     // Check if the alignment bits are all zero
     let is_ok = local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into();
@@ -132,13 +128,13 @@ fn insert_alignment_check<'tcx>(
         user_ty: None,
         const_: Const::Val(ConstValue::Scalar(Scalar::from_target_usize(0, &tcx)), tcx.types.usize),
     }));
-    stmts.push(Statement {
+    stmts.push(Statement::new(
         source_info,
-        kind: StatementKind::Assign(Box::new((
+        StatementKind::Assign(Box::new((
             is_ok,
             Rvalue::BinaryOp(BinOp::Eq, Box::new((Operand::Copy(alignment_bits), zero.clone()))),
         ))),
-    });
+    ));
 
     // Emit a check that asserts on the alignment and otherwise triggers a
     // AssertKind::MisalignedPointerDereference.
diff --git a/compiler/rustc_mir_transform/src/check_null.rs b/compiler/rustc_mir_transform/src/check_null.rs
index ad74e335bd9..e365d36580a 100644
--- a/compiler/rustc_mir_transform/src/check_null.rs
+++ b/compiler/rustc_mir_transform/src/check_null.rs
@@ -41,13 +41,12 @@ fn insert_null_check<'tcx>(
     let const_raw_ptr = Ty::new_imm_ptr(tcx, tcx.types.unit);
     let rvalue = Rvalue::Cast(CastKind::PtrToPtr, Operand::Copy(pointer), const_raw_ptr);
     let thin_ptr = local_decls.push(LocalDecl::with_source_info(const_raw_ptr, source_info)).into();
-    stmts
-        .push(Statement { source_info, kind: StatementKind::Assign(Box::new((thin_ptr, rvalue))) });
+    stmts.push(Statement::new(source_info, StatementKind::Assign(Box::new((thin_ptr, rvalue)))));
 
     // Transmute the pointer to a usize (equivalent to `ptr.addr()`).
     let rvalue = Rvalue::Cast(CastKind::Transmute, Operand::Copy(thin_ptr), tcx.types.usize);
     let addr = local_decls.push(LocalDecl::with_source_info(tcx.types.usize, source_info)).into();
-    stmts.push(Statement { source_info, kind: StatementKind::Assign(Box::new((addr, rvalue))) });
+    stmts.push(Statement::new(source_info, StatementKind::Assign(Box::new((addr, rvalue)))));
 
     let zero = Operand::Constant(Box::new(ConstOperand {
         span: source_info.span,
@@ -71,24 +70,24 @@ fn insert_null_check<'tcx>(
             let rvalue = Rvalue::NullaryOp(NullOp::SizeOf, pointee_ty);
             let sizeof_pointee =
                 local_decls.push(LocalDecl::with_source_info(tcx.types.usize, source_info)).into();
-            stmts.push(Statement {
+            stmts.push(Statement::new(
                 source_info,
-                kind: StatementKind::Assign(Box::new((sizeof_pointee, rvalue))),
-            });
+                StatementKind::Assign(Box::new((sizeof_pointee, rvalue))),
+            ));
 
             // Check that the pointee is not a ZST.
             let is_pointee_not_zst =
                 local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into();
-            stmts.push(Statement {
+            stmts.push(Statement::new(
                 source_info,
-                kind: StatementKind::Assign(Box::new((
+                StatementKind::Assign(Box::new((
                     is_pointee_not_zst,
                     Rvalue::BinaryOp(
                         BinOp::Ne,
                         Box::new((Operand::Copy(sizeof_pointee), zero.clone())),
                     ),
                 ))),
-            });
+            ));
 
             // Pointer needs to be checked only if pointee is not a ZST.
             Operand::Copy(is_pointee_not_zst)
@@ -97,38 +96,38 @@ fn insert_null_check<'tcx>(
 
     // Check whether the pointer is null.
     let is_null = local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into();
-    stmts.push(Statement {
+    stmts.push(Statement::new(
         source_info,
-        kind: StatementKind::Assign(Box::new((
+        StatementKind::Assign(Box::new((
             is_null,
             Rvalue::BinaryOp(BinOp::Eq, Box::new((Operand::Copy(addr), zero))),
         ))),
-    });
+    ));
 
     // We want to throw an exception if the pointer is null and the pointee is not unconditionally
     // allowed (which for all non-borrow place uses, is when the pointee is ZST).
     let should_throw_exception =
         local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into();
-    stmts.push(Statement {
+    stmts.push(Statement::new(
         source_info,
-        kind: StatementKind::Assign(Box::new((
+        StatementKind::Assign(Box::new((
             should_throw_exception,
             Rvalue::BinaryOp(
                 BinOp::BitAnd,
                 Box::new((Operand::Copy(is_null), pointee_should_be_checked)),
             ),
         ))),
-    });
+    ));
 
     // The final condition whether this pointer usage is ok or not.
     let is_ok = local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into();
-    stmts.push(Statement {
+    stmts.push(Statement::new(
         source_info,
-        kind: StatementKind::Assign(Box::new((
+        StatementKind::Assign(Box::new((
             is_ok,
             Rvalue::UnaryOp(UnOp::Not, Operand::Copy(should_throw_exception)),
         ))),
-    });
+    ));
 
     // Emit a PointerCheck that asserts on the condition and otherwise triggers
     // a AssertKind::NullPointerDereference.
diff --git a/compiler/rustc_mir_transform/src/check_pointers.rs b/compiler/rustc_mir_transform/src/check_pointers.rs
index bf94f1aad24..4f913c1fca0 100644
--- a/compiler/rustc_mir_transform/src/check_pointers.rs
+++ b/compiler/rustc_mir_transform/src/check_pointers.rs
@@ -235,11 +235,11 @@ fn split_block(
     let block_data = &mut basic_blocks[location.block];
 
     // Drain every statement after this one and move the current terminator to a new basic block.
-    let new_block = BasicBlockData {
-        statements: block_data.statements.split_off(location.statement_index),
-        terminator: block_data.terminator.take(),
-        is_cleanup: block_data.is_cleanup,
-    };
+    let new_block = BasicBlockData::new_stmts(
+        block_data.statements.split_off(location.statement_index),
+        block_data.terminator.take(),
+        block_data.is_cleanup,
+    );
 
     basic_blocks.push(new_block)
 }
diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs
index 06c6b46a9c2..761d5461a99 100644
--- a/compiler/rustc_mir_transform/src/coroutine.rs
+++ b/compiler/rustc_mir_transform/src/coroutine.rs
@@ -252,16 +252,16 @@ impl<'tcx> TransformVisitor<'tcx> {
             }
         };
 
-        let statements = vec![Statement {
-            kind: StatementKind::Assign(Box::new((Place::return_place(), none_value))),
+        let statements = vec![Statement::new(
             source_info,
-        }];
+            StatementKind::Assign(Box::new((Place::return_place(), none_value))),
+        )];
 
-        body.basic_blocks_mut().push(BasicBlockData {
+        body.basic_blocks_mut().push(BasicBlockData::new_stmts(
             statements,
-            terminator: Some(Terminator { source_info, kind: TerminatorKind::Return }),
-            is_cleanup: false,
-        });
+            Some(Terminator { source_info, kind: TerminatorKind::Return }),
+            false,
+        ));
 
         block
     }
@@ -342,10 +342,10 @@ impl<'tcx> TransformVisitor<'tcx> {
             }
         };
 
-        statements.push(Statement {
-            kind: StatementKind::Assign(Box::new((Place::return_place(), rvalue))),
+        statements.push(Statement::new(
             source_info,
-        });
+            StatementKind::Assign(Box::new((Place::return_place(), rvalue))),
+        ));
     }
 
     // Create a Place referencing a coroutine struct field
@@ -361,13 +361,13 @@ impl<'tcx> TransformVisitor<'tcx> {
     // Create a statement which changes the discriminant
     fn set_discr(&self, state_disc: VariantIdx, source_info: SourceInfo) -> Statement<'tcx> {
         let self_place = Place::from(SELF_ARG);
-        Statement {
+        Statement::new(
             source_info,
-            kind: StatementKind::SetDiscriminant {
+            StatementKind::SetDiscriminant {
                 place: Box::new(self_place),
                 variant_index: state_disc,
             },
-        }
+        )
     }
 
     // Create a statement which reads the discriminant into a temporary
@@ -377,10 +377,10 @@ impl<'tcx> TransformVisitor<'tcx> {
         let temp = Place::from(local_decls_len);
 
         let self_place = Place::from(SELF_ARG);
-        let assign = Statement {
-            source_info: SourceInfo::outermost(body.span),
-            kind: StatementKind::Assign(Box::new((temp, Rvalue::Discriminant(self_place)))),
-        };
+        let assign = Statement::new(
+            SourceInfo::outermost(body.span),
+            StatementKind::Assign(Box::new((temp, Rvalue::Discriminant(self_place)))),
+        );
         (assign, temp)
     }
 }
@@ -450,7 +450,7 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> {
                         && !self.always_live_locals.contains(l);
                     if needs_storage_dead {
                         data.statements
-                            .push(Statement { source_info, kind: StatementKind::StorageDead(l) });
+                            .push(Statement::new(source_info, StatementKind::StorageDead(l)));
                     }
                 }
 
@@ -596,10 +596,8 @@ fn eliminate_get_context_call<'tcx>(bb_data: &mut BasicBlockData<'tcx>) -> Local
     let local = arg.node.place().unwrap().local;
 
     let arg = Rvalue::Use(arg.node);
-    let assign = Statement {
-        source_info: terminator.source_info,
-        kind: StatementKind::Assign(Box::new((destination, arg))),
-    };
+    let assign =
+        Statement::new(terminator.source_info, StatementKind::Assign(Box::new((destination, arg))));
     bb_data.statements.push(assign);
     bb_data.terminator = Some(Terminator {
         source_info: terminator.source_info,
@@ -1075,11 +1073,11 @@ fn insert_switch<'tcx>(
     let source_info = SourceInfo::outermost(body.span);
     body.basic_blocks_mut().raw.insert(
         0,
-        BasicBlockData {
-            statements: vec![assign],
-            terminator: Some(Terminator { source_info, kind: switch }),
-            is_cleanup: false,
-        },
+        BasicBlockData::new_stmts(
+            vec![assign],
+            Some(Terminator { source_info, kind: switch }),
+            false,
+        ),
     );
 
     for b in body.basic_blocks_mut().iter_mut() {
@@ -1089,11 +1087,7 @@ fn insert_switch<'tcx>(
 
 fn insert_term_block<'tcx>(body: &mut Body<'tcx>, kind: TerminatorKind<'tcx>) -> BasicBlock {
     let source_info = SourceInfo::outermost(body.span);
-    body.basic_blocks_mut().push(BasicBlockData {
-        statements: Vec::new(),
-        terminator: Some(Terminator { source_info, kind }),
-        is_cleanup: false,
-    })
+    body.basic_blocks_mut().push(BasicBlockData::new(Some(Terminator { source_info, kind }), false))
 }
 
 fn return_poll_ready_assign<'tcx>(tcx: TyCtxt<'tcx>, source_info: SourceInfo) -> Statement<'tcx> {
@@ -1109,19 +1103,16 @@ fn return_poll_ready_assign<'tcx>(tcx: TyCtxt<'tcx>, source_info: SourceInfo) ->
         Box::new(AggregateKind::Adt(poll_def_id, VariantIdx::from_usize(0), args, None, None)),
         IndexVec::from_raw(vec![val]),
     );
-    Statement {
-        kind: StatementKind::Assign(Box::new((Place::return_place(), ready_val))),
-        source_info,
-    }
+    Statement::new(source_info, StatementKind::Assign(Box::new((Place::return_place(), ready_val))))
 }
 
 fn insert_poll_ready_block<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> BasicBlock {
     let source_info = SourceInfo::outermost(body.span);
-    body.basic_blocks_mut().push(BasicBlockData {
-        statements: [return_poll_ready_assign(tcx, source_info)].to_vec(),
-        terminator: Some(Terminator { source_info, kind: TerminatorKind::Return }),
-        is_cleanup: false,
-    })
+    body.basic_blocks_mut().push(BasicBlockData::new_stmts(
+        [return_poll_ready_assign(tcx, source_info)].to_vec(),
+        Some(Terminator { source_info, kind: TerminatorKind::Return }),
+        false,
+    ))
 }
 
 fn insert_panic_block<'tcx>(
@@ -1205,13 +1196,11 @@ fn generate_poison_block_and_redirect_unwinds_there<'tcx>(
     body: &mut Body<'tcx>,
 ) {
     let source_info = SourceInfo::outermost(body.span);
-    let poison_block = body.basic_blocks_mut().push(BasicBlockData {
-        statements: vec![
-            transform.set_discr(VariantIdx::new(CoroutineArgs::POISONED), source_info),
-        ],
-        terminator: Some(Terminator { source_info, kind: TerminatorKind::UnwindResume }),
-        is_cleanup: true,
-    });
+    let poison_block = body.basic_blocks_mut().push(BasicBlockData::new_stmts(
+        vec![transform.set_discr(VariantIdx::new(CoroutineArgs::POISONED), source_info)],
+        Some(Terminator { source_info, kind: TerminatorKind::UnwindResume }),
+        true,
+    ));
 
     for (idx, block) in body.basic_blocks_mut().iter_enumerated_mut() {
         let source_info = block.terminator().source_info;
@@ -1345,32 +1334,28 @@ fn create_cases<'tcx>(
                         && !transform.remap.contains(l)
                         && !transform.always_live_locals.contains(l);
                     if needs_storage_live {
-                        statements
-                            .push(Statement { source_info, kind: StatementKind::StorageLive(l) });
+                        statements.push(Statement::new(source_info, StatementKind::StorageLive(l)));
                     }
                 }
 
                 if operation == Operation::Resume {
                     // Move the resume argument to the destination place of the `Yield` terminator
                     let resume_arg = CTX_ARG;
-                    statements.push(Statement {
+                    statements.push(Statement::new(
                         source_info,
-                        kind: StatementKind::Assign(Box::new((
+                        StatementKind::Assign(Box::new((
                             point.resume_arg,
                             Rvalue::Use(Operand::Move(resume_arg.into())),
                         ))),
-                    });
+                    ));
                 }
 
                 // Then jump to the real target
-                let block = body.basic_blocks_mut().push(BasicBlockData {
+                let block = body.basic_blocks_mut().push(BasicBlockData::new_stmts(
                     statements,
-                    terminator: Some(Terminator {
-                        source_info,
-                        kind: TerminatorKind::Goto { target },
-                    }),
-                    is_cleanup: false,
-                });
+                    Some(Terminator { source_info, kind: TerminatorKind::Goto { target } }),
+                    false,
+                ));
 
                 (point.state, block)
             })
@@ -1540,13 +1525,13 @@ impl<'tcx> crate::MirPass<'tcx> for StateTransform {
         let stmts = &mut body.basic_blocks_mut()[START_BLOCK].statements;
         stmts.insert(
             0,
-            Statement {
+            Statement::new(
                 source_info,
-                kind: StatementKind::Assign(Box::new((
+                StatementKind::Assign(Box::new((
                     old_resume_local.into(),
                     Rvalue::Use(Operand::Move(resume_local.into())),
                 ))),
-            },
+            ),
         );
 
         let always_live_locals = always_storage_live_locals(body);
diff --git a/compiler/rustc_mir_transform/src/coroutine/drop.rs b/compiler/rustc_mir_transform/src/coroutine/drop.rs
index dc68629ec0d..406575c4f43 100644
--- a/compiler/rustc_mir_transform/src/coroutine/drop.rs
+++ b/compiler/rustc_mir_transform/src/coroutine/drop.rs
@@ -87,12 +87,11 @@ fn build_pin_fut<'tcx>(
         const_: Const::zero_sized(pin_fut_new_unchecked_fn),
     }));
 
-    let storage_live =
-        Statement { source_info, kind: StatementKind::StorageLive(fut_pin_place.local) };
+    let storage_live = Statement::new(source_info, StatementKind::StorageLive(fut_pin_place.local));
 
-    let fut_ref_assign = Statement {
+    let fut_ref_assign = Statement::new(
         source_info,
-        kind: StatementKind::Assign(Box::new((
+        StatementKind::Assign(Box::new((
             fut_ref_place,
             Rvalue::Ref(
                 tcx.lifetimes.re_erased,
@@ -100,12 +99,12 @@ fn build_pin_fut<'tcx>(
                 fut_place,
             ),
         ))),
-    };
+    );
 
     // call Pin<FutTy>::new_unchecked(&mut fut)
-    let pin_fut_bb = body.basic_blocks_mut().push(BasicBlockData {
-        statements: [storage_live, fut_ref_assign].to_vec(),
-        terminator: Some(Terminator {
+    let pin_fut_bb = body.basic_blocks_mut().push(BasicBlockData::new_stmts(
+        [storage_live, fut_ref_assign].to_vec(),
+        Some(Terminator {
             source_info,
             kind: TerminatorKind::Call {
                 func: pin_fut_new_unchecked_fn,
@@ -117,8 +116,8 @@ fn build_pin_fut<'tcx>(
                 fn_span: span,
             },
         }),
-        is_cleanup: false,
-    });
+        false,
+    ));
     (pin_fut_bb, fut_pin_place)
 }
 
@@ -156,19 +155,15 @@ fn build_poll_switch<'tcx>(
     let source_info = SourceInfo::outermost(body.span);
     let poll_discr_place =
         Place::from(body.local_decls.push(LocalDecl::new(poll_discr_ty, source_info.span)));
-    let discr_assign = Statement {
+    let discr_assign = Statement::new(
         source_info,
-        kind: StatementKind::Assign(Box::new((
-            poll_discr_place,
-            Rvalue::Discriminant(*poll_unit_place),
-        ))),
-    };
-    let storage_dead =
-        Statement { source_info, kind: StatementKind::StorageDead(fut_pin_place.local) };
+        StatementKind::Assign(Box::new((poll_discr_place, Rvalue::Discriminant(*poll_unit_place)))),
+    );
+    let storage_dead = Statement::new(source_info, StatementKind::StorageDead(fut_pin_place.local));
     let unreachable_block = insert_term_block(body, TerminatorKind::Unreachable);
-    body.basic_blocks_mut().push(BasicBlockData {
-        statements: [storage_dead, discr_assign].to_vec(),
-        terminator: Some(Terminator {
+    body.basic_blocks_mut().push(BasicBlockData::new_stmts(
+        [storage_dead, discr_assign].to_vec(),
+        Some(Terminator {
             source_info,
             kind: TerminatorKind::SwitchInt {
                 discr: Operand::Move(poll_discr_place),
@@ -179,8 +174,8 @@ fn build_poll_switch<'tcx>(
                 ),
             },
         }),
-        is_cleanup: false,
-    })
+        false,
+    ))
 }
 
 // Gather blocks, reachable through 'drop' targets of Yield and Drop terminators (chained)
@@ -330,10 +325,10 @@ pub(super) fn expand_async_drops<'tcx>(
         let context_ref_place =
             Place::from(body.local_decls.push(LocalDecl::new(context_mut_ref, source_info.span)));
         let arg = Rvalue::Use(Operand::Move(Place::from(CTX_ARG)));
-        body[bb].statements.push(Statement {
+        body[bb].statements.push(Statement::new(
             source_info,
-            kind: StatementKind::Assign(Box::new((context_ref_place, arg))),
-        });
+            StatementKind::Assign(Box::new((context_ref_place, arg))),
+        ));
         let yield_block = insert_term_block(body, TerminatorKind::Unreachable); // `kind` replaced later to yield
         let (pin_bb, fut_pin_place) =
             build_pin_fut(tcx, body, fut_place.clone(), UnwindAction::Continue);
@@ -551,11 +546,8 @@ pub(super) fn insert_clean_drop<'tcx>(
     };
 
     // Create a block to destroy an unresumed coroutines. This can only destroy upvars.
-    body.basic_blocks_mut().push(BasicBlockData {
-        statements: Vec::new(),
-        terminator: Some(Terminator { source_info, kind: term }),
-        is_cleanup: false,
-    })
+    body.basic_blocks_mut()
+        .push(BasicBlockData::new(Some(Terminator { source_info, kind: term }), false))
 }
 
 pub(super) fn create_coroutine_drop_shim<'tcx>(
@@ -734,11 +726,7 @@ pub(super) fn create_coroutine_drop_shim_proxy_async<'tcx>(
     body.local_decls[RETURN_PLACE] = LocalDecl::with_source_info(poll_enum, source_info);
 
     // call coroutine_drop()
-    let call_bb = body.basic_blocks_mut().push(BasicBlockData {
-        statements: Vec::new(),
-        terminator: None,
-        is_cleanup: false,
-    });
+    let call_bb = body.basic_blocks_mut().push(BasicBlockData::new(None, false));
 
     // return Poll::Ready()
     let ret_bb = insert_poll_ready_block(tcx, &mut body);
diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs
index 702c62eddc7..f253d1662ca 100644
--- a/compiler/rustc_mir_transform/src/coverage/mod.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mod.rs
@@ -259,7 +259,7 @@ fn inject_statement(mir_body: &mut mir::Body<'_>, counter_kind: CoverageKind, bb
     debug!("  injecting statement {counter_kind:?} for {bb:?}");
     let data = &mut mir_body[bb];
     let source_info = data.terminator().source_info;
-    let statement = Statement { source_info, kind: StatementKind::Coverage(counter_kind) };
+    let statement = Statement::new(source_info, StatementKind::Coverage(counter_kind));
     data.statements.insert(0, statement);
 }
 
diff --git a/compiler/rustc_mir_transform/src/coverage/tests.rs b/compiler/rustc_mir_transform/src/coverage/tests.rs
index 3c0053c610d..b0fc5e90f07 100644
--- a/compiler/rustc_mir_transform/src/coverage/tests.rs
+++ b/compiler/rustc_mir_transform/src/coverage/tests.rs
@@ -68,14 +68,13 @@ impl<'tcx> MockBlocks<'tcx> {
             BytePos(1)
         };
         let next_hi = next_lo + BytePos(1);
-        self.blocks.push(BasicBlockData {
-            statements: vec![],
-            terminator: Some(Terminator {
+        self.blocks.push(BasicBlockData::new(
+            Some(Terminator {
                 source_info: SourceInfo::outermost(Span::with_root_ctxt(next_lo, next_hi)),
                 kind,
             }),
-            is_cleanup: false,
-        })
+            false,
+        ))
     }
 
     fn link(&mut self, from_block: BasicBlock, to_block: BasicBlock) {
diff --git a/compiler/rustc_mir_transform/src/ctfe_limit.rs b/compiler/rustc_mir_transform/src/ctfe_limit.rs
index d0b313e149a..fb17cca30f4 100644
--- a/compiler/rustc_mir_transform/src/ctfe_limit.rs
+++ b/compiler/rustc_mir_transform/src/ctfe_limit.rs
@@ -55,8 +55,8 @@ fn has_back_edge(
 }
 
 fn insert_counter(basic_block_data: &mut BasicBlockData<'_>) {
-    basic_block_data.statements.push(Statement {
-        source_info: basic_block_data.terminator().source_info,
-        kind: StatementKind::ConstEvalCounter,
-    });
+    basic_block_data.statements.push(Statement::new(
+        basic_block_data.terminator().source_info,
+        StatementKind::ConstEvalCounter,
+    ));
 }
diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs
index c9bc52c6c7e..de96b1f255a 100644
--- a/compiler/rustc_mir_transform/src/elaborate_drop.rs
+++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs
@@ -222,15 +222,14 @@ where
         let span = self.source_info.span;
 
         let pin_obj_bb = bb.unwrap_or_else(|| {
-            self.elaborator.patch().new_block(BasicBlockData {
-                statements: vec![],
-                terminator: Some(Terminator {
+            self.elaborator.patch().new_block(BasicBlockData::new(
+                Some(Terminator {
                     // Temporary terminator, will be replaced by patch
                     source_info: self.source_info,
                     kind: TerminatorKind::Return,
                 }),
-                is_cleanup: false,
-            })
+                false,
+            ))
         });
 
         let (fut_ty, drop_fn_def_id, trait_args) = if call_destructor_only {
@@ -366,10 +365,8 @@ where
             call_statements.push(self.assign(obj_ptr_place, addr));
             obj_ptr_place
         };
-        call_statements.push(Statement {
-            source_info: self.source_info,
-            kind: StatementKind::StorageLive(fut.local),
-        });
+        call_statements
+            .push(Statement::new(self.source_info, StatementKind::StorageLive(fut.local)));
 
         let call_drop_bb = self.new_block_with_statements(
             unwind,
@@ -732,17 +729,17 @@ where
 
         let do_drop_bb = self.drop_subpath(interior, interior_path, succ, unwind, dropline);
 
-        let setup_bbd = BasicBlockData {
-            statements: vec![self.assign(
+        let setup_bbd = BasicBlockData::new_stmts(
+            vec![self.assign(
                 Place::from(ptr_local),
                 Rvalue::Cast(CastKind::Transmute, Operand::Copy(nonnull_place), ptr_ty),
             )],
-            terminator: Some(Terminator {
+            Some(Terminator {
                 kind: TerminatorKind::Goto { target: do_drop_bb },
                 source_info: self.source_info,
             }),
-            is_cleanup: unwind.is_cleanup(),
-        };
+            unwind.is_cleanup(),
+        );
         self.elaborator.patch().new_block(setup_bbd)
     }
 
@@ -753,14 +750,13 @@ where
         args: GenericArgsRef<'tcx>,
     ) -> BasicBlock {
         if adt.variants().is_empty() {
-            return self.elaborator.patch().new_block(BasicBlockData {
-                statements: vec![],
-                terminator: Some(Terminator {
+            return self.elaborator.patch().new_block(BasicBlockData::new(
+                Some(Terminator {
                     source_info: self.source_info,
                     kind: TerminatorKind::Unreachable,
                 }),
-                is_cleanup: self.unwind.is_cleanup(),
-            });
+                self.unwind.is_cleanup(),
+            ));
         }
 
         let skip_contents = adt.is_union() || adt.is_manually_drop();
@@ -927,9 +923,9 @@ where
         let discr_ty = adt.repr().discr_type().to_ty(self.tcx());
         let discr = Place::from(self.new_temp(discr_ty));
         let discr_rv = Rvalue::Discriminant(self.place);
-        let switch_block = BasicBlockData {
-            statements: vec![self.assign(discr, discr_rv)],
-            terminator: Some(Terminator {
+        let switch_block = BasicBlockData::new_stmts(
+            vec![self.assign(discr, discr_rv)],
+            Some(Terminator {
                 source_info: self.source_info,
                 kind: TerminatorKind::SwitchInt {
                     discr: Operand::Move(discr),
@@ -939,8 +935,8 @@ where
                     ),
                 },
             }),
-            is_cleanup: unwind.is_cleanup(),
-        };
+            unwind.is_cleanup(),
+        );
         let switch_block = self.elaborator.patch().new_block(switch_block);
         self.drop_flag_test_block(switch_block, succ, unwind)
     }
@@ -956,8 +952,8 @@ where
         let ref_place = self.new_temp(ref_ty);
         let unit_temp = Place::from(self.new_temp(tcx.types.unit));
 
-        let result = BasicBlockData {
-            statements: vec![self.assign(
+        let result = BasicBlockData::new_stmts(
+            vec![self.assign(
                 Place::from(ref_place),
                 Rvalue::Ref(
                     tcx.lifetimes.re_erased,
@@ -965,7 +961,7 @@ where
                     self.place,
                 ),
             )],
-            terminator: Some(Terminator {
+            Some(Terminator {
                 kind: TerminatorKind::Call {
                     func: Operand::function_handle(
                         tcx,
@@ -983,8 +979,8 @@ where
                 },
                 source_info: self.source_info,
             }),
-            is_cleanup: unwind.is_cleanup(),
-        };
+            unwind.is_cleanup(),
+        );
 
         let destructor_block = self.elaborator.patch().new_block(result);
 
@@ -1047,8 +1043,8 @@ where
         let can_go = Place::from(self.new_temp(tcx.types.bool));
         let one = self.constant_usize(1);
 
-        let drop_block = BasicBlockData {
-            statements: vec![
+        let drop_block = BasicBlockData::new_stmts(
+            vec![
                 self.assign(
                     ptr,
                     Rvalue::RawPtr(RawPtrKind::Mut, tcx.mk_place_index(self.place, cur)),
@@ -1058,26 +1054,26 @@ where
                     Rvalue::BinaryOp(BinOp::Add, Box::new((move_(cur.into()), one))),
                 ),
             ],
-            is_cleanup: unwind.is_cleanup(),
-            terminator: Some(Terminator {
+            Some(Terminator {
                 source_info: self.source_info,
                 // this gets overwritten by drop elaboration.
                 kind: TerminatorKind::Unreachable,
             }),
-        };
+            unwind.is_cleanup(),
+        );
         let drop_block = self.elaborator.patch().new_block(drop_block);
 
-        let loop_block = BasicBlockData {
-            statements: vec![self.assign(
+        let loop_block = BasicBlockData::new_stmts(
+            vec![self.assign(
                 can_go,
                 Rvalue::BinaryOp(BinOp::Eq, Box::new((copy(Place::from(cur)), copy(len.into())))),
             )],
-            is_cleanup: unwind.is_cleanup(),
-            terminator: Some(Terminator {
+            Some(Terminator {
                 source_info: self.source_info,
                 kind: TerminatorKind::if_(move_(can_go), succ, drop_block),
             }),
-        };
+            unwind.is_cleanup(),
+        );
         let loop_block = self.elaborator.patch().new_block(loop_block);
 
         let place = tcx.mk_place_deref(ptr);
@@ -1187,8 +1183,8 @@ where
         let slice_ptr_ty = Ty::new_mut_ptr(tcx, slice_ty);
         let slice_ptr = self.new_temp(slice_ptr_ty);
 
-        let mut delegate_block = BasicBlockData {
-            statements: vec![
+        let mut delegate_block = BasicBlockData::new_stmts(
+            vec![
                 self.assign(Place::from(array_ptr), Rvalue::RawPtr(RawPtrKind::Mut, self.place)),
                 self.assign(
                     Place::from(slice_ptr),
@@ -1202,9 +1198,9 @@ where
                     ),
                 ),
             ],
-            is_cleanup: self.unwind.is_cleanup(),
-            terminator: None,
-        };
+            None,
+            self.unwind.is_cleanup(),
+        );
 
         let array_place = mem::replace(
             &mut self.place,
@@ -1246,8 +1242,8 @@ where
         };
 
         let zero = self.constant_usize(0);
-        let block = BasicBlockData {
-            statements: vec![
+        let block = BasicBlockData::new_stmts(
+            vec![
                 self.assign(
                     len.into(),
                     Rvalue::UnaryOp(
@@ -1257,12 +1253,12 @@ where
                 ),
                 self.assign(cur.into(), Rvalue::Use(zero)),
             ],
-            is_cleanup: unwind.is_cleanup(),
-            terminator: Some(Terminator {
+            Some(Terminator {
                 source_info: self.source_info,
                 kind: TerminatorKind::Goto { target: loop_block },
             }),
-        };
+            unwind.is_cleanup(),
+        );
 
         let drop_block = self.elaborator.patch().new_block(block);
         // FIXME(#34708): handle partially-dropped array/slice elements.
@@ -1308,14 +1304,13 @@ where
                     self.source_info.span,
                     "open drop for unsafe binder shouldn't be encountered",
                 );
-                self.elaborator.patch().new_block(BasicBlockData {
-                    statements: vec![],
-                    terminator: Some(Terminator {
+                self.elaborator.patch().new_block(BasicBlockData::new(
+                    Some(Terminator {
                         source_info: self.source_info,
                         kind: TerminatorKind::Unreachable,
                     }),
-                    is_cleanup: self.unwind.is_cleanup(),
-                })
+                    self.unwind.is_cleanup(),
+                ))
             }
 
             _ => span_bug!(self.source_info.span, "open drop from non-ADT `{:?}`", ty),
@@ -1434,11 +1429,10 @@ where
     }
 
     fn new_block(&mut self, unwind: Unwind, k: TerminatorKind<'tcx>) -> BasicBlock {
-        self.elaborator.patch().new_block(BasicBlockData {
-            statements: vec![],
-            terminator: Some(Terminator { source_info: self.source_info, kind: k }),
-            is_cleanup: unwind.is_cleanup(),
-        })
+        self.elaborator.patch().new_block(BasicBlockData::new(
+            Some(Terminator { source_info: self.source_info, kind: k }),
+            unwind.is_cleanup(),
+        ))
     }
 
     fn new_block_with_statements(
@@ -1447,11 +1441,11 @@ where
         statements: Vec<Statement<'tcx>>,
         k: TerminatorKind<'tcx>,
     ) -> BasicBlock {
-        self.elaborator.patch().new_block(BasicBlockData {
+        self.elaborator.patch().new_block(BasicBlockData::new_stmts(
             statements,
-            terminator: Some(Terminator { source_info: self.source_info, kind: k }),
-            is_cleanup: unwind.is_cleanup(),
-        })
+            Some(Terminator { source_info: self.source_info, kind: k }),
+            unwind.is_cleanup(),
+        ))
     }
 
     fn new_temp(&mut self, ty: Ty<'tcx>) -> Local {
@@ -1467,9 +1461,6 @@ where
     }
 
     fn assign(&self, lhs: Place<'tcx>, rhs: Rvalue<'tcx>) -> Statement<'tcx> {
-        Statement {
-            source_info: self.source_info,
-            kind: StatementKind::Assign(Box::new((lhs, rhs))),
-        }
+        Statement::new(self.source_info, StatementKind::Assign(Box::new((lhs, rhs))))
     }
 }
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index c27087fea11..7852bb7ae2f 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -900,10 +900,10 @@ fn inline_call<'tcx, I: Inliner<'tcx>>(
         );
         let dest_ty = dest.ty(caller_body, tcx);
         let temp = Place::from(new_call_temp(caller_body, callsite, dest_ty, return_block));
-        caller_body[callsite.block].statements.push(Statement {
-            source_info: callsite.source_info,
-            kind: StatementKind::Assign(Box::new((temp, dest))),
-        });
+        caller_body[callsite.block].statements.push(Statement::new(
+            callsite.source_info,
+            StatementKind::Assign(Box::new((temp, dest))),
+        ));
         tcx.mk_place_deref(temp)
     } else {
         destination
@@ -947,10 +947,9 @@ fn inline_call<'tcx, I: Inliner<'tcx>>(
     for local in callee_body.vars_and_temps_iter() {
         if integrator.always_live_locals.contains(local) {
             let new_local = integrator.map_local(local);
-            caller_body[callsite.block].statements.push(Statement {
-                source_info: callsite.source_info,
-                kind: StatementKind::StorageLive(new_local),
-            });
+            caller_body[callsite.block]
+                .statements
+                .push(Statement::new(callsite.source_info, StatementKind::StorageLive(new_local)));
         }
     }
     if let Some(block) = return_block {
@@ -958,22 +957,22 @@ fn inline_call<'tcx, I: Inliner<'tcx>>(
         // the slice once.
         let mut n = 0;
         if remap_destination {
-            caller_body[block].statements.push(Statement {
-                source_info: callsite.source_info,
-                kind: StatementKind::Assign(Box::new((
+            caller_body[block].statements.push(Statement::new(
+                callsite.source_info,
+                StatementKind::Assign(Box::new((
                     dest,
                     Rvalue::Use(Operand::Move(destination_local.into())),
                 ))),
-            });
+            ));
             n += 1;
         }
         for local in callee_body.vars_and_temps_iter().rev() {
             if integrator.always_live_locals.contains(local) {
                 let new_local = integrator.map_local(local);
-                caller_body[block].statements.push(Statement {
-                    source_info: callsite.source_info,
-                    kind: StatementKind::StorageDead(new_local),
-                });
+                caller_body[block].statements.push(Statement::new(
+                    callsite.source_info,
+                    StatementKind::StorageDead(new_local),
+                ));
                 n += 1;
             }
         }
@@ -1126,10 +1125,10 @@ fn create_temp_if_necessary<'tcx, I: Inliner<'tcx>>(
     trace!("creating temp for argument {:?}", arg);
     let arg_ty = arg.ty(caller_body, inliner.tcx());
     let local = new_call_temp(caller_body, callsite, arg_ty, return_block);
-    caller_body[callsite.block].statements.push(Statement {
-        source_info: callsite.source_info,
-        kind: StatementKind::Assign(Box::new((Place::from(local), Rvalue::Use(arg)))),
-    });
+    caller_body[callsite.block].statements.push(Statement::new(
+        callsite.source_info,
+        StatementKind::Assign(Box::new((Place::from(local), Rvalue::Use(arg)))),
+    ));
     local
 }
 
@@ -1142,19 +1141,14 @@ fn new_call_temp<'tcx>(
 ) -> Local {
     let local = caller_body.local_decls.push(LocalDecl::new(ty, callsite.source_info.span));
 
-    caller_body[callsite.block].statements.push(Statement {
-        source_info: callsite.source_info,
-        kind: StatementKind::StorageLive(local),
-    });
+    caller_body[callsite.block]
+        .statements
+        .push(Statement::new(callsite.source_info, StatementKind::StorageLive(local)));
 
     if let Some(block) = return_block {
-        caller_body[block].statements.insert(
-            0,
-            Statement {
-                source_info: callsite.source_info,
-                kind: StatementKind::StorageDead(local),
-            },
-        );
+        caller_body[block]
+            .statements
+            .insert(0, Statement::new(callsite.source_info, StatementKind::StorageDead(local)));
     }
 
     local
diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs
index 5f0c55ddc09..dbcaed20953 100644
--- a/compiler/rustc_mir_transform/src/instsimplify.rs
+++ b/compiler/rustc_mir_transform/src/instsimplify.rs
@@ -240,15 +240,15 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> {
 
         let Some(arg_place) = arg.node.place() else { return };
 
-        statements.push(Statement {
-            source_info: terminator.source_info,
-            kind: StatementKind::Assign(Box::new((
+        statements.push(Statement::new(
+            terminator.source_info,
+            StatementKind::Assign(Box::new((
                 *destination,
                 Rvalue::Use(Operand::Copy(
                     arg_place.project_deeper(&[ProjectionElem::Deref], self.tcx),
                 )),
             ))),
-        });
+        ));
         terminator.kind = TerminatorKind::Goto { target: *destination_block };
     }
 
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index c4415294264..08f25276cec 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -259,13 +259,13 @@ fn remap_mir_for_const_eval_select<'tcx>(
                             // (const generic stuff) so we just create a temporary and deconstruct
                             // that.
                             let local = body.local_decls.push(LocalDecl::new(ty, fn_span));
-                            bb.statements.push(Statement {
-                                source_info: SourceInfo::outermost(fn_span),
-                                kind: StatementKind::Assign(Box::new((
+                            bb.statements.push(Statement::new(
+                                SourceInfo::outermost(fn_span),
+                                StatementKind::Assign(Box::new((
                                     local.into(),
                                     Rvalue::Use(tupled_args.node.clone()),
                                 ))),
-                            });
+                            ));
                             (Operand::Move, local.into())
                         }
                         Operand::Move(place) => (Operand::Move, place),
diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs
index fa29ab985b7..8dadce0d448 100644
--- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs
+++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs
@@ -25,31 +25,31 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
                     }
                     sym::ub_checks => {
                         let target = target.unwrap();
-                        block.statements.push(Statement {
-                            source_info: terminator.source_info,
-                            kind: StatementKind::Assign(Box::new((
+                        block.statements.push(Statement::new(
+                            terminator.source_info,
+                            StatementKind::Assign(Box::new((
                                 *destination,
                                 Rvalue::NullaryOp(NullOp::UbChecks, tcx.types.bool),
                             ))),
-                        });
+                        ));
                         terminator.kind = TerminatorKind::Goto { target };
                     }
                     sym::contract_checks => {
                         let target = target.unwrap();
-                        block.statements.push(Statement {
-                            source_info: terminator.source_info,
-                            kind: StatementKind::Assign(Box::new((
+                        block.statements.push(Statement::new(
+                            terminator.source_info,
+                            StatementKind::Assign(Box::new((
                                 *destination,
                                 Rvalue::NullaryOp(NullOp::ContractChecks, tcx.types.bool),
                             ))),
-                        });
+                        ));
                         terminator.kind = TerminatorKind::Goto { target };
                     }
                     sym::forget => {
                         let target = target.unwrap();
-                        block.statements.push(Statement {
-                            source_info: terminator.source_info,
-                            kind: StatementKind::Assign(Box::new((
+                        block.statements.push(Statement::new(
+                            terminator.source_info,
+                            StatementKind::Assign(Box::new((
                                 *destination,
                                 Rvalue::Use(Operand::Constant(Box::new(ConstOperand {
                                     span: terminator.source_info.span,
@@ -57,7 +57,7 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
                                     const_: Const::zero_sized(tcx.types.unit),
                                 }))),
                             ))),
-                        });
+                        ));
                         terminator.kind = TerminatorKind::Goto { target };
                     }
                     sym::copy_nonoverlapping => {
@@ -65,9 +65,9 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
                         let Ok([src, dst, count]) = take_array(args) else {
                             bug!("Wrong arguments for copy_non_overlapping intrinsic");
                         };
-                        block.statements.push(Statement {
-                            source_info: terminator.source_info,
-                            kind: StatementKind::Intrinsic(Box::new(
+                        block.statements.push(Statement::new(
+                            terminator.source_info,
+                            StatementKind::Intrinsic(Box::new(
                                 NonDivergingIntrinsic::CopyNonOverlapping(
                                     rustc_middle::mir::CopyNonOverlapping {
                                         src: src.node,
@@ -76,7 +76,7 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
                                     },
                                 ),
                             )),
-                        });
+                        ));
                         terminator.kind = TerminatorKind::Goto { target };
                     }
                     sym::assume => {
@@ -84,12 +84,12 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
                         let Ok([arg]) = take_array(args) else {
                             bug!("Wrong arguments for assume intrinsic");
                         };
-                        block.statements.push(Statement {
-                            source_info: terminator.source_info,
-                            kind: StatementKind::Intrinsic(Box::new(
-                                NonDivergingIntrinsic::Assume(arg.node),
-                            )),
-                        });
+                        block.statements.push(Statement::new(
+                            terminator.source_info,
+                            StatementKind::Intrinsic(Box::new(NonDivergingIntrinsic::Assume(
+                                arg.node,
+                            ))),
+                        ));
                         terminator.kind = TerminatorKind::Goto { target };
                     }
                     sym::wrapping_add
@@ -121,13 +121,13 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
                             sym::unchecked_shr => BinOp::ShrUnchecked,
                             _ => bug!("unexpected intrinsic"),
                         };
-                        block.statements.push(Statement {
-                            source_info: terminator.source_info,
-                            kind: StatementKind::Assign(Box::new((
+                        block.statements.push(Statement::new(
+                            terminator.source_info,
+                            StatementKind::Assign(Box::new((
                                 *destination,
                                 Rvalue::BinaryOp(bin_op, Box::new((lhs.node, rhs.node))),
                             ))),
-                        });
+                        ));
                         terminator.kind = TerminatorKind::Goto { target };
                     }
                     sym::add_with_overflow | sym::sub_with_overflow | sym::mul_with_overflow => {
@@ -141,13 +141,13 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
                             sym::mul_with_overflow => BinOp::MulWithOverflow,
                             _ => bug!("unexpected intrinsic"),
                         };
-                        block.statements.push(Statement {
-                            source_info: terminator.source_info,
-                            kind: StatementKind::Assign(Box::new((
+                        block.statements.push(Statement::new(
+                            terminator.source_info,
+                            StatementKind::Assign(Box::new((
                                 *destination,
                                 Rvalue::BinaryOp(bin_op, Box::new((lhs.node, rhs.node))),
                             ))),
-                        });
+                        ));
                         terminator.kind = TerminatorKind::Goto { target };
                     }
                     sym::size_of | sym::align_of => {
@@ -158,13 +158,13 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
                             sym::align_of => NullOp::AlignOf,
                             _ => bug!("unexpected intrinsic"),
                         };
-                        block.statements.push(Statement {
-                            source_info: terminator.source_info,
-                            kind: StatementKind::Assign(Box::new((
+                        block.statements.push(Statement::new(
+                            terminator.source_info,
+                            StatementKind::Assign(Box::new((
                                 *destination,
                                 Rvalue::NullaryOp(null_op, tp_ty),
                             ))),
-                        });
+                        ));
                         terminator.kind = TerminatorKind::Goto { target };
                     }
                     sym::read_via_copy => {
@@ -183,13 +183,13 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
                         };
                         // Add new statement at the end of the block that does the read, and patch
                         // up the terminator.
-                        block.statements.push(Statement {
-                            source_info: terminator.source_info,
-                            kind: StatementKind::Assign(Box::new((
+                        block.statements.push(Statement::new(
+                            terminator.source_info,
+                            StatementKind::Assign(Box::new((
                                 *destination,
                                 Rvalue::Use(Operand::Copy(derefed_place)),
                             ))),
-                        });
+                        ));
                         terminator.kind = match *target {
                             None => {
                                 // No target means this read something uninhabited,
@@ -217,13 +217,10 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
                                 "Only passing a local is supported"
                             );
                         };
-                        block.statements.push(Statement {
-                            source_info: terminator.source_info,
-                            kind: StatementKind::Assign(Box::new((
-                                derefed_place,
-                                Rvalue::Use(val.node),
-                            ))),
-                        });
+                        block.statements.push(Statement::new(
+                            terminator.source_info,
+                            StatementKind::Assign(Box::new((derefed_place, Rvalue::Use(val.node)))),
+                        ));
                         terminator.kind = TerminatorKind::Goto { target };
                     }
                     sym::discriminant_value => {
@@ -236,13 +233,13 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
                         };
                         let arg = arg.node.place().unwrap();
                         let arg = tcx.mk_place_deref(arg);
-                        block.statements.push(Statement {
-                            source_info: terminator.source_info,
-                            kind: StatementKind::Assign(Box::new((
+                        block.statements.push(Statement::new(
+                            terminator.source_info,
+                            StatementKind::Assign(Box::new((
                                 *destination,
                                 Rvalue::Discriminant(arg),
                             ))),
-                        });
+                        ));
                         terminator.kind = TerminatorKind::Goto { target };
                     }
                     sym::offset => {
@@ -253,13 +250,13 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
                                 "Wrong number of arguments for offset intrinsic",
                             );
                         };
-                        block.statements.push(Statement {
-                            source_info: terminator.source_info,
-                            kind: StatementKind::Assign(Box::new((
+                        block.statements.push(Statement::new(
+                            terminator.source_info,
+                            StatementKind::Assign(Box::new((
                                 *destination,
                                 Rvalue::BinaryOp(BinOp::Offset, Box::new((ptr.node, delta.node))),
                             ))),
-                        });
+                        ));
                         terminator.kind = TerminatorKind::Goto { target };
                     }
                     sym::slice_get_unchecked => {
@@ -302,10 +299,10 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
                             _ => bug!("Unknown return type {ret_ty:?}"),
                         };
 
-                        block.statements.push(Statement {
-                            source_info: terminator.source_info,
-                            kind: StatementKind::Assign(Box::new((*destination, rvalue))),
-                        });
+                        block.statements.push(Statement::new(
+                            terminator.source_info,
+                            StatementKind::Assign(Box::new((*destination, rvalue))),
+                        ));
                         terminator.kind = TerminatorKind::Goto { target };
                     }
                     sym::transmute | sym::transmute_unchecked => {
@@ -320,13 +317,13 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
                         // Always emit the cast, even if we transmute to an uninhabited type,
                         // because that lets CTFE and codegen generate better error messages
                         // when such a transmute actually ends up reachable.
-                        block.statements.push(Statement {
-                            source_info: terminator.source_info,
-                            kind: StatementKind::Assign(Box::new((
+                        block.statements.push(Statement::new(
+                            terminator.source_info,
+                            StatementKind::Assign(Box::new((
                                 *destination,
                                 Rvalue::Cast(CastKind::Transmute, arg.node, dst_ty),
                             ))),
-                        });
+                        ));
                         if let Some(target) = *target {
                             terminator.kind = TerminatorKind::Goto { target };
                         } else {
@@ -351,13 +348,13 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
                             );
                         };
                         let fields = [data.node, meta.node];
-                        block.statements.push(Statement {
-                            source_info: terminator.source_info,
-                            kind: StatementKind::Assign(Box::new((
+                        block.statements.push(Statement::new(
+                            terminator.source_info,
+                            StatementKind::Assign(Box::new((
                                 *destination,
                                 Rvalue::Aggregate(Box::new(kind), fields.into()),
                             ))),
-                        });
+                        ));
                         terminator.kind = TerminatorKind::Goto { target };
                     }
                     sym::ptr_metadata => {
@@ -368,13 +365,13 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
                             );
                         };
                         let target = target.unwrap();
-                        block.statements.push(Statement {
-                            source_info: terminator.source_info,
-                            kind: StatementKind::Assign(Box::new((
+                        block.statements.push(Statement::new(
+                            terminator.source_info,
+                            StatementKind::Assign(Box::new((
                                 *destination,
                                 Rvalue::UnaryOp(UnOp::PtrMetadata, ptr.node),
                             ))),
-                        });
+                        ));
                         terminator.kind = TerminatorKind::Goto { target };
                     }
                     _ => {}
diff --git a/compiler/rustc_mir_transform/src/lower_slice_len.rs b/compiler/rustc_mir_transform/src/lower_slice_len.rs
index aca80e36e33..79a9017de3e 100644
--- a/compiler/rustc_mir_transform/src/lower_slice_len.rs
+++ b/compiler/rustc_mir_transform/src/lower_slice_len.rs
@@ -56,8 +56,7 @@ fn lower_slice_len_call<'tcx>(block: &mut BasicBlockData<'tcx>, slice_len_fn_ite
         // make new RValue for Len
         let r_value = Rvalue::UnaryOp(UnOp::PtrMetadata, arg.node.clone());
         let len_statement_kind = StatementKind::Assign(Box::new((*destination, r_value)));
-        let add_statement =
-            Statement { kind: len_statement_kind, source_info: terminator.source_info };
+        let add_statement = Statement::new(terminator.source_info, len_statement_kind);
 
         // modify terminator into simple Goto
         let new_terminator_kind = TerminatorKind::Goto { target: *bb };
diff --git a/compiler/rustc_mir_transform/src/patch.rs b/compiler/rustc_mir_transform/src/patch.rs
index a872eae15f1..c781d1a5324 100644
--- a/compiler/rustc_mir_transform/src/patch.rs
+++ b/compiler/rustc_mir_transform/src/patch.rs
@@ -78,14 +78,13 @@ impl<'tcx> MirPatch<'tcx> {
             return bb;
         }
 
-        let bb = self.new_block(BasicBlockData {
-            statements: vec![],
-            terminator: Some(Terminator {
+        let bb = self.new_block(BasicBlockData::new(
+            Some(Terminator {
                 source_info: SourceInfo::outermost(self.body_span),
                 kind: TerminatorKind::UnwindResume,
             }),
-            is_cleanup: true,
-        });
+            true,
+        ));
         self.resume_block = Some(bb);
         bb
     }
@@ -95,14 +94,13 @@ impl<'tcx> MirPatch<'tcx> {
             return bb;
         }
 
-        let bb = self.new_block(BasicBlockData {
-            statements: vec![],
-            terminator: Some(Terminator {
+        let bb = self.new_block(BasicBlockData::new(
+            Some(Terminator {
                 source_info: SourceInfo::outermost(self.body_span),
                 kind: TerminatorKind::Unreachable,
             }),
-            is_cleanup: true,
-        });
+            true,
+        ));
         self.unreachable_cleanup_block = Some(bb);
         bb
     }
@@ -112,14 +110,13 @@ impl<'tcx> MirPatch<'tcx> {
             return bb;
         }
 
-        let bb = self.new_block(BasicBlockData {
-            statements: vec![],
-            terminator: Some(Terminator {
+        let bb = self.new_block(BasicBlockData::new(
+            Some(Terminator {
                 source_info: SourceInfo::outermost(self.body_span),
                 kind: TerminatorKind::Unreachable,
             }),
-            is_cleanup: false,
-        });
+            false,
+        ));
         self.unreachable_no_cleanup_block = Some(bb);
         bb
     }
@@ -131,14 +128,13 @@ impl<'tcx> MirPatch<'tcx> {
             return cached_bb;
         }
 
-        let bb = self.new_block(BasicBlockData {
-            statements: vec![],
-            terminator: Some(Terminator {
+        let bb = self.new_block(BasicBlockData::new(
+            Some(Terminator {
                 source_info: SourceInfo::outermost(self.body_span),
                 kind: TerminatorKind::UnwindTerminate(reason),
             }),
-            is_cleanup: true,
-        });
+            true,
+        ));
         self.terminate_block = Some((bb, reason));
         bb
     }
@@ -280,7 +276,7 @@ impl<'tcx> MirPatch<'tcx> {
             let source_info = Self::source_info_for_index(&body[loc.block], loc);
             body[loc.block]
                 .statements
-                .insert(loc.statement_index, Statement { source_info, kind: stmt });
+                .insert(loc.statement_index, Statement::new(source_info, stmt));
             delta += 1;
         }
     }
diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs
index 47d43830970..4e8f30e077b 100644
--- a/compiler/rustc_mir_transform/src/promote_consts.rs
+++ b/compiler/rustc_mir_transform/src/promote_consts.rs
@@ -731,23 +731,22 @@ struct Promoter<'a, 'tcx> {
 impl<'a, 'tcx> Promoter<'a, 'tcx> {
     fn new_block(&mut self) -> BasicBlock {
         let span = self.promoted.span;
-        self.promoted.basic_blocks_mut().push(BasicBlockData {
-            statements: vec![],
-            terminator: Some(Terminator {
+        self.promoted.basic_blocks_mut().push(BasicBlockData::new(
+            Some(Terminator {
                 source_info: SourceInfo::outermost(span),
                 kind: TerminatorKind::Return,
             }),
-            is_cleanup: false,
-        })
+            false,
+        ))
     }
 
     fn assign(&mut self, dest: Local, rvalue: Rvalue<'tcx>, span: Span) {
         let last = self.promoted.basic_blocks.last_index().unwrap();
         let data = &mut self.promoted[last];
-        data.statements.push(Statement {
-            source_info: SourceInfo::outermost(span),
-            kind: StatementKind::Assign(Box::new((Place::from(dest), rvalue))),
-        });
+        data.statements.push(Statement::new(
+            SourceInfo::outermost(span),
+            StatementKind::Assign(Box::new((Place::from(dest), rvalue))),
+        ));
     }
 
     fn is_temp_kind(&self, local: Local) -> bool {
@@ -914,13 +913,13 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
             assert_eq!(self.temps.push(TempState::Unpromotable), promoted_ref);
 
             let promoted_operand = promoted_operand(ref_ty, span);
-            let promoted_ref_statement = Statement {
-                source_info: statement.source_info,
-                kind: StatementKind::Assign(Box::new((
+            let promoted_ref_statement = Statement::new(
+                statement.source_info,
+                StatementKind::Assign(Box::new((
                     Place::from(promoted_ref),
                     Rvalue::Use(Operand::Constant(Box::new(promoted_operand))),
                 ))),
-            };
+            );
             self.extra_statements.push((loc, promoted_ref_statement));
 
             (
diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs
index 6d45bbc6e16..4083038cbb6 100644
--- a/compiler/rustc_mir_transform/src/shim.rs
+++ b/compiler/rustc_mir_transform/src/shim.rs
@@ -323,9 +323,7 @@ fn dropee_emit_retag<'tcx>(
             StatementKind::Retag(RetagKind::FnEntry, Box::new(dropee_ptr)),
         ];
         for s in new_statements {
-            body.basic_blocks_mut()[START_BLOCK]
-                .statements
-                .push(Statement { source_info, kind: s });
+            body.basic_blocks_mut()[START_BLOCK].statements.push(Statement::new(source_info, s));
         }
     }
     dropee_ptr
@@ -350,11 +348,7 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option<Ty<'tcx>>)
     let return_block = BasicBlock::new(1);
     let mut blocks = IndexVec::with_capacity(2);
     let block = |blocks: &mut IndexVec<_, _>, kind| {
-        blocks.push(BasicBlockData {
-            statements: vec![],
-            terminator: Some(Terminator { source_info, kind }),
-            is_cleanup: false,
-        })
+        blocks.push(BasicBlockData::new(Some(Terminator { source_info, kind }), false))
     };
     block(&mut blocks, TerminatorKind::Goto { target: return_block });
     block(&mut blocks, TerminatorKind::Return);
@@ -515,17 +509,17 @@ fn build_thread_local_shim<'tcx>(
     let span = tcx.def_span(def_id);
     let source_info = SourceInfo::outermost(span);
 
-    let blocks = IndexVec::from_raw(vec![BasicBlockData {
-        statements: vec![Statement {
+    let blocks = IndexVec::from_raw(vec![BasicBlockData::new_stmts(
+        vec![Statement::new(
             source_info,
-            kind: StatementKind::Assign(Box::new((
+            StatementKind::Assign(Box::new((
                 Place::return_place(),
                 Rvalue::ThreadLocalRef(def_id),
             ))),
-        }],
-        terminator: Some(Terminator { source_info, kind: TerminatorKind::Return }),
-        is_cleanup: false,
-    }]);
+        )],
+        Some(Terminator { source_info, kind: TerminatorKind::Return }),
+        false,
+    )]);
 
     new_body(
         MirSource::from_instance(instance),
@@ -609,11 +603,11 @@ impl<'tcx> CloneShimBuilder<'tcx> {
         is_cleanup: bool,
     ) -> BasicBlock {
         let source_info = self.source_info();
-        self.blocks.push(BasicBlockData {
+        self.blocks.push(BasicBlockData::new_stmts(
             statements,
-            terminator: Some(Terminator { source_info, kind }),
+            Some(Terminator { source_info, kind }),
             is_cleanup,
-        })
+        ))
     }
 
     /// Gives the index of an upcoming BasicBlock, with an offset.
@@ -625,7 +619,7 @@ impl<'tcx> CloneShimBuilder<'tcx> {
     }
 
     fn make_statement(&self, kind: StatementKind<'tcx>) -> Statement<'tcx> {
-        Statement { source_info: self.source_info(), kind }
+        Statement::new(self.source_info(), kind)
     }
 
     fn copy_shim(&mut self) {
@@ -901,13 +895,13 @@ fn build_call_shim<'tcx>(
                 .immutable(),
             );
             let borrow_kind = BorrowKind::Mut { kind: MutBorrowKind::Default };
-            statements.push(Statement {
+            statements.push(Statement::new(
                 source_info,
-                kind: StatementKind::Assign(Box::new((
+                StatementKind::Assign(Box::new((
                     Place::from(ref_rcvr),
                     Rvalue::Ref(tcx.lifetimes.re_erased, borrow_kind, rcvr_place()),
                 ))),
-            });
+            ));
             Operand::Move(Place::from(ref_rcvr))
         }
     });
@@ -956,11 +950,11 @@ fn build_call_shim<'tcx>(
     let n_blocks = if let Some(Adjustment::RefMut) = rcvr_adjustment { 5 } else { 2 };
     let mut blocks = IndexVec::with_capacity(n_blocks);
     let block = |blocks: &mut IndexVec<_, _>, statements, kind, is_cleanup| {
-        blocks.push(BasicBlockData {
+        blocks.push(BasicBlockData::new_stmts(
             statements,
-            terminator: Some(Terminator { source_info, kind }),
+            Some(Terminator { source_info, kind }),
             is_cleanup,
-        })
+        ))
     };
 
     // BB #0
@@ -1071,8 +1065,9 @@ pub(super) fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> {
 
     let kind = AggregateKind::Adt(adt_def.did(), variant_index, args, None, None);
     let variant = adt_def.variant(variant_index);
-    let statement = Statement {
-        kind: StatementKind::Assign(Box::new((
+    let statement = Statement::new(
+        source_info,
+        StatementKind::Assign(Box::new((
             Place::return_place(),
             Rvalue::Aggregate(
                 Box::new(kind),
@@ -1081,14 +1076,13 @@ pub(super) fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> {
                     .collect(),
             ),
         ))),
-        source_info,
-    };
+    );
 
-    let start_block = BasicBlockData {
-        statements: vec![statement],
-        terminator: Some(Terminator { source_info, kind: TerminatorKind::Return }),
-        is_cleanup: false,
-    };
+    let start_block = BasicBlockData::new_stmts(
+        vec![statement],
+        Some(Terminator { source_info, kind: TerminatorKind::Return }),
+        false,
+    );
 
     let source = MirSource::item(ctor_id);
     let mut body = new_body(
@@ -1130,16 +1124,16 @@ fn build_fn_ptr_addr_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'t
         Operand::Move(Place::from(Local::new(1))),
         Ty::new_imm_ptr(tcx, tcx.types.unit),
     );
-    let stmt = Statement {
+    let stmt = Statement::new(
         source_info,
-        kind: StatementKind::Assign(Box::new((Place::return_place(), rvalue))),
-    };
+        StatementKind::Assign(Box::new((Place::return_place(), rvalue))),
+    );
     let statements = vec![stmt];
-    let start_block = BasicBlockData {
+    let start_block = BasicBlockData::new_stmts(
         statements,
-        terminator: Some(Terminator { source_info, kind: TerminatorKind::Return }),
-        is_cleanup: false,
-    };
+        Some(Terminator { source_info, kind: TerminatorKind::Return }),
+        false,
+    );
     let source = MirSource::from_instance(ty::InstanceKind::FnPtrAddrShim(def_id, self_ty));
     new_body(source, IndexVec::from_elem_n(start_block, 1), locals, sig.inputs().len(), span)
 }
@@ -1230,16 +1224,16 @@ fn build_construct_coroutine_by_move_shim<'tcx>(
         Box::new(AggregateKind::Coroutine(coroutine_def_id, coroutine_args)),
         IndexVec::from_raw(fields),
     );
-    let stmt = Statement {
+    let stmt = Statement::new(
         source_info,
-        kind: StatementKind::Assign(Box::new((Place::return_place(), rvalue))),
-    };
+        StatementKind::Assign(Box::new((Place::return_place(), rvalue))),
+    );
     let statements = vec![stmt];
-    let start_block = BasicBlockData {
+    let start_block = BasicBlockData::new_stmts(
         statements,
-        terminator: Some(Terminator { source_info, kind: TerminatorKind::Return }),
-        is_cleanup: false,
-    };
+        Some(Terminator { source_info, kind: TerminatorKind::Return }),
+        false,
+    );
 
     let source = MirSource::from_instance(ty::InstanceKind::ConstructCoroutineInClosureShim {
         coroutine_closure_def_id,
diff --git a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs
index fd7b7362cd9..18d09473c19 100644
--- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs
+++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs
@@ -88,11 +88,7 @@ pub(super) fn build_async_drop_shim<'tcx>(
     let return_block = BasicBlock::new(1);
     let mut blocks = IndexVec::with_capacity(2);
     let block = |blocks: &mut IndexVec<_, _>, kind| {
-        blocks.push(BasicBlockData {
-            statements: vec![],
-            terminator: Some(Terminator { source_info, kind }),
-            is_cleanup: false,
-        })
+        blocks.push(BasicBlockData::new(Some(Terminator { source_info, kind }), false))
     };
     block(
         &mut blocks,
@@ -133,7 +129,7 @@ pub(super) fn build_async_drop_shim<'tcx>(
         dropee_ptr,
         Rvalue::Use(Operand::Move(coroutine_layout_dropee)),
     )));
-    body.basic_blocks_mut()[START_BLOCK].statements.push(Statement { source_info, kind: st_kind });
+    body.basic_blocks_mut()[START_BLOCK].statements.push(Statement::new(source_info, st_kind));
     dropee_ptr = dropee_emit_retag(tcx, &mut body, dropee_ptr, span);
 
     let dropline = body.basic_blocks.last_index();
@@ -240,13 +236,13 @@ fn build_adrop_for_coroutine_shim<'tcx>(
             .project_deeper(&[PlaceElem::Field(FieldIdx::ZERO, proxy_ref)], tcx);
         body.basic_blocks_mut()[START_BLOCK].statements.insert(
             idx,
-            Statement {
+            Statement::new(
                 source_info,
-                kind: StatementKind::Assign(Box::new((
+                StatementKind::Assign(Box::new((
                     Place::from(proxy_ref_local),
                     Rvalue::CopyForDeref(proxy_ref_place),
                 ))),
-            },
+            ),
         );
         idx += 1;
         let mut cor_ptr_local = proxy_ref_local;
@@ -261,13 +257,13 @@ fn build_adrop_for_coroutine_shim<'tcx>(
                 // _cor_ptr = _proxy.0.0 (... .0)
                 body.basic_blocks_mut()[START_BLOCK].statements.insert(
                     idx,
-                    Statement {
+                    Statement::new(
                         source_info,
-                        kind: StatementKind::Assign(Box::new((
+                        StatementKind::Assign(Box::new((
                             Place::from(cor_ptr_local),
                             Rvalue::CopyForDeref(impl_ptr_place),
                         ))),
-                    },
+                    ),
                 );
                 idx += 1;
             }
@@ -281,10 +277,10 @@ fn build_adrop_for_coroutine_shim<'tcx>(
         );
         body.basic_blocks_mut()[START_BLOCK].statements.insert(
             idx,
-            Statement {
+            Statement::new(
                 source_info,
-                kind: StatementKind::Assign(Box::new((Place::from(cor_ref_local), reborrow))),
-            },
+                StatementKind::Assign(Box::new((Place::from(cor_ref_local), reborrow))),
+            ),
         );
     }
     body
@@ -334,13 +330,13 @@ fn build_adrop_for_adrop_shim<'tcx>(
 
     let mut statements = Vec::new();
 
-    statements.push(Statement {
+    statements.push(Statement::new(
         source_info,
-        kind: StatementKind::Assign(Box::new((
+        StatementKind::Assign(Box::new((
             Place::from(proxy_ref_local),
             Rvalue::CopyForDeref(proxy_ref_place),
         ))),
-    });
+    ));
 
     let mut cor_ptr_local = proxy_ref_local;
     proxy_ty.find_async_drop_impl_coroutine(tcx, |ty| {
@@ -350,13 +346,13 @@ fn build_adrop_for_adrop_shim<'tcx>(
                 .project_deeper(&[PlaceElem::Deref, PlaceElem::Field(FieldIdx::ZERO, ty_ptr)], tcx);
             cor_ptr_local = locals.push(LocalDecl::new(ty_ptr, span));
             // _cor_ptr = _proxy.0.0 (... .0)
-            statements.push(Statement {
+            statements.push(Statement::new(
                 source_info,
-                kind: StatementKind::Assign(Box::new((
+                StatementKind::Assign(Box::new((
                     Place::from(cor_ptr_local),
                     Rvalue::CopyForDeref(impl_ptr_place),
                 ))),
-            });
+            ));
         }
     });
 
@@ -367,10 +363,10 @@ fn build_adrop_for_adrop_shim<'tcx>(
         tcx.mk_place_deref(Place::from(cor_ptr_local)),
     );
     let cor_ref_place = Place::from(locals.push(LocalDecl::new(cor_ref, span)));
-    statements.push(Statement {
+    statements.push(Statement::new(
         source_info,
-        kind: StatementKind::Assign(Box::new((cor_ref_place, reborrow))),
-    });
+        StatementKind::Assign(Box::new((cor_ref_place, reborrow))),
+    ));
 
     // cor_pin_ty = `Pin<&mut cor_ref>`
     let cor_pin_ty = Ty::new_adt(tcx, pin_adt_ref, tcx.mk_args(&[cor_ref.into()]));
@@ -378,9 +374,9 @@ fn build_adrop_for_adrop_shim<'tcx>(
 
     let pin_fn = tcx.require_lang_item(LangItem::PinNewUnchecked, span);
     // call Pin<FutTy>::new_unchecked(&mut impl_cor)
-    blocks.push(BasicBlockData {
+    blocks.push(BasicBlockData::new_stmts(
         statements,
-        terminator: Some(Terminator {
+        Some(Terminator {
             source_info,
             kind: TerminatorKind::Call {
                 func: Operand::function_handle(tcx, pin_fn, [cor_ref.into()], span),
@@ -392,15 +388,14 @@ fn build_adrop_for_adrop_shim<'tcx>(
                 fn_span: span,
             },
         }),
-        is_cleanup: false,
-    });
+        false,
+    ));
     // When dropping async drop coroutine, we continue its execution:
     // we call impl::poll (impl_layout, ctx)
     let poll_fn = tcx.require_lang_item(LangItem::FuturePoll, span);
     let resume_ctx = Place::from(Local::new(2));
-    blocks.push(BasicBlockData {
-        statements: vec![],
-        terminator: Some(Terminator {
+    blocks.push(BasicBlockData::new(
+        Some(Terminator {
             source_info,
             kind: TerminatorKind::Call {
                 func: Operand::function_handle(tcx, poll_fn, [impl_ty.into()], span),
@@ -416,13 +411,12 @@ fn build_adrop_for_adrop_shim<'tcx>(
                 fn_span: span,
             },
         }),
-        is_cleanup: false,
-    });
-    blocks.push(BasicBlockData {
-        statements: vec![],
-        terminator: Some(Terminator { source_info, kind: TerminatorKind::Return }),
-        is_cleanup: false,
-    });
+        false,
+    ));
+    blocks.push(BasicBlockData::new(
+        Some(Terminator { source_info, kind: TerminatorKind::Return }),
+        false,
+    ));
 
     let source = MirSource::from_instance(instance);
     let mut body = new_body(source, blocks, locals, sig.inputs().len(), span);
diff --git a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs
index bd008230731..c60eb566521 100644
--- a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs
+++ b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs
@@ -115,10 +115,10 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyComparisonIntegral {
                 for bb_idx in new_targets.all_targets() {
                     storage_deads_to_insert.push((
                         *bb_idx,
-                        Statement {
-                            source_info: terminator.source_info,
-                            kind: StatementKind::StorageDead(opt.to_switch_on.local),
-                        },
+                        Statement::new(
+                            terminator.source_info,
+                            StatementKind::StorageDead(opt.to_switch_on.local),
+                        ),
                     ));
                 }
             }