@@ -92,7 +92,6 @@ use rustc_middle::mir::*;
92
92
use rustc_middle:: thir:: { ExprId , LintLevel } ;
93
93
use rustc_middle:: { bug, span_bug} ;
94
94
use rustc_session:: lint:: Level ;
95
- use rustc_span:: source_map:: Spanned ;
96
95
use rustc_span:: { Span , DUMMY_SP } ;
97
96
use tracing:: { debug, instrument} ;
98
97
@@ -128,8 +127,6 @@ struct Scope {
128
127
/// end of the vector (top of the stack) first.
129
128
drops : Vec < DropData > ,
130
129
131
- moved_locals : Vec < Local > ,
132
-
133
130
/// The drop index that will drop everything in and below this scope on an
134
131
/// unwind path.
135
132
cached_unwind_block : Option < DropIdx > ,
@@ -445,7 +442,6 @@ impl<'tcx> Scopes<'tcx> {
445
442
source_scope : vis_scope,
446
443
region_scope : region_scope. 0 ,
447
444
drops : vec ! [ ] ,
448
- moved_locals : vec ! [ ] ,
449
445
cached_unwind_block : None ,
450
446
cached_coroutine_drop_block : None ,
451
447
} ) ;
@@ -752,13 +748,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
752
748
pub ( crate ) fn break_for_tail_call (
753
749
& mut self ,
754
750
mut block : BasicBlock ,
755
- args : & [ Spanned < Operand < ' tcx > > ] ,
751
+ args : & [ Operand < ' tcx > ] ,
756
752
source_info : SourceInfo ,
757
753
) -> BlockAnd < ( ) > {
758
754
let arg_drops: Vec < _ > = args
759
755
. iter ( )
760
756
. rev ( )
761
- . filter_map ( |arg| match & arg. node {
757
+ . filter_map ( |arg| match arg {
762
758
Operand :: Copy ( _) => bug ! ( "copy op in tail call args" ) ,
763
759
Operand :: Move ( place) => {
764
760
let local =
@@ -1102,14 +1098,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1102
1098
span_bug ! ( span, "region scope {:?} not in scope to drop {:?}" , region_scope, local) ;
1103
1099
}
1104
1100
1105
- /// Indicates that the "local operand " stored in `local` is
1101
+ /// Indicates that the "local operands " stored in `local` are
1106
1102
/// *moved* at some point during execution (see `local_scope` for
1107
1103
/// more information about what a "local operand" is -- in short,
1108
1104
/// it's an intermediate operand created as part of preparing some
1109
1105
/// MIR instruction). We use this information to suppress
1110
- /// redundant drops on the non-unwind paths. This results in less
1111
- /// MIR, but also avoids spurious borrow check errors
1112
- /// (c.f. #64391).
1106
+ /// redundant drops. This results in less MIR, but also avoids spurious
1107
+ /// borrow check errors (c.f. #64391).
1113
1108
///
1114
1109
/// Example: when compiling the call to `foo` here:
1115
1110
///
@@ -1138,27 +1133,23 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1138
1133
/// spurious borrow-check errors -- the problem, ironically, is
1139
1134
/// not the `DROP(_X)` itself, but the (spurious) unwind pathways
1140
1135
/// that it creates. See #64391 for an example.
1141
- pub ( crate ) fn record_operands_moved ( & mut self , operands : & [ Spanned < Operand < ' tcx > > ] ) {
1136
+ pub ( crate ) fn record_operands_moved ( & mut self , operands : & [ Operand < ' tcx > ] ) {
1142
1137
let local_scope = self . local_scope ( ) ;
1143
1138
let scope = self . scopes . scopes . last_mut ( ) . unwrap ( ) ;
1144
1139
1145
1140
assert_eq ! ( scope. region_scope, local_scope, "local scope is not the topmost scope!" , ) ;
1146
1141
1147
1142
// look for moves of a local variable, like `MOVE(_X)`
1148
- let locals_moved = operands. iter ( ) . flat_map ( |operand| match operand. node {
1143
+ let locals_moved = operands. iter ( ) . flat_map ( |operand| match operand {
1149
1144
Operand :: Copy ( _) | Operand :: Constant ( _) => None ,
1150
1145
Operand :: Move ( place) => place. as_local ( ) ,
1151
1146
} ) ;
1152
1147
1153
1148
for local in locals_moved {
1154
- // check if we have a Drop for this operand and -- if so
1155
- // -- add it to the list of moved operands. Note that this
1156
- // local might not have been an operand created for this
1157
- // call, it could come from other places too.
1158
- if scope. drops . iter ( ) . any ( |drop| drop. local == local && drop. kind == DropKind :: Value ) {
1159
- scope. moved_locals . push ( local) ;
1160
- }
1149
+ // Unschedule drops from the scope.
1150
+ scope. drops . retain ( |drop| drop. local != local || drop. kind != DropKind :: Value ) ;
1161
1151
}
1152
+ scope. invalidate_cache ( ) ;
1162
1153
}
1163
1154
1164
1155
// Other
@@ -1382,14 +1373,6 @@ fn build_scope_drops<'tcx>(
1382
1373
debug_assert_eq ! ( unwind_drops. drops[ unwind_to] . data. kind, drop_data. kind) ;
1383
1374
unwind_to = unwind_drops. drops [ unwind_to] . next ;
1384
1375
1385
- // If the operand has been moved, and we are not on an unwind
1386
- // path, then don't generate the drop. (We only take this into
1387
- // account for non-unwind paths so as not to disturb the
1388
- // caching mechanism.)
1389
- if scope. moved_locals . iter ( ) . any ( |& o| o == local) {
1390
- continue ;
1391
- }
1392
-
1393
1376
unwind_drops. add_entry_point ( block, unwind_to) ;
1394
1377
1395
1378
let next = cfg. start_new_block ( ) ;
0 commit comments