@@ -333,7 +333,7 @@ pub fn simplify_locals<'tcx>(body: &mut Body<'tcx>, tcx: TyCtxt<'tcx>) {
333
333
// count. For example, if we removed `_2 = discriminant(_1)`, then we'll subtract one from
334
334
// `use_counts[_1]`. That in turn might make `_1` unused, so we loop until we hit a
335
335
// fixedpoint where there are no more unused locals.
336
- remove_unused_definitions ( & mut used_locals, body) ;
336
+ remove_unused_definitions ( & mut used_locals, body, tcx ) ;
337
337
338
338
// Finally, we'll actually do the work of shrinking `body.local_decls` and remapping the `Local`s.
339
339
let map = make_local_map ( & mut body. local_decls , & used_locals) ;
@@ -462,12 +462,22 @@ impl Visitor<'_> for UsedLocals {
462
462
}
463
463
464
464
/// Removes unused definitions. Updates the used locals to reflect the changes made.
465
- fn remove_unused_definitions < ' a , ' tcx > ( used_locals : & ' a mut UsedLocals , body : & mut Body < ' tcx > ) {
465
+ fn remove_unused_definitions < ' a , ' tcx > (
466
+ used_locals : & ' a mut UsedLocals ,
467
+ body : & mut Body < ' tcx > ,
468
+ tcx : TyCtxt < ' tcx > ,
469
+ ) {
466
470
// The use counts are updated as we remove the statements. A local might become unused
467
471
// during the retain operation, leading to a temporary inconsistency (storage statements or
468
472
// definitions referencing the local might remain). For correctness it is crucial that this
469
473
// computation reaches a fixed point.
470
474
475
+ let def_id = body. source . def_id ( ) ;
476
+ let is_static = tcx. is_static ( def_id) ;
477
+ let param_env = tcx. param_env ( def_id) ;
478
+
479
+ let local_decls = body. local_decls . clone ( ) ;
480
+
471
481
let mut modified = true ;
472
482
while modified {
473
483
modified = false ;
@@ -479,7 +489,21 @@ fn remove_unused_definitions<'a, 'tcx>(used_locals: &'a mut UsedLocals, body: &m
479
489
StatementKind :: StorageLive ( local) | StatementKind :: StorageDead ( local) => {
480
490
used_locals. is_used ( * local)
481
491
}
482
- StatementKind :: Assign ( box ( place, _) ) => used_locals. is_used ( place. local ) ,
492
+ StatementKind :: Assign ( box ( place, _) ) => {
493
+ let used = used_locals. is_used ( place. local ) ;
494
+ let mut is_zst = false ;
495
+
496
+ // ZST locals can be removed
497
+ if used && !is_static {
498
+ let ty = local_decls[ place. local ] . ty ;
499
+ let param_env_and = param_env. and ( ty) ;
500
+ if let Ok ( layout) = tcx. layout_of ( param_env_and) {
501
+ is_zst = layout. is_zst ( ) ;
502
+ }
503
+ }
504
+
505
+ used && !is_zst
506
+ }
483
507
484
508
StatementKind :: SetDiscriminant { ref place, .. } => {
485
509
used_locals. is_used ( place. local )
0 commit comments