@@ -91,7 +91,7 @@ use rustc_middle::middle::region;
9191use rustc_middle:: mir:: * ;
9292use rustc_middle:: thir:: { Expr , LintLevel } ;
9393
94- use rustc_span:: { Span , DUMMY_SP } ;
94+ use rustc_span:: { DesugaringKind , Span , DUMMY_SP } ;
9595
9696#[ derive( Debug ) ]
9797pub struct Scopes < ' tcx > {
@@ -1118,24 +1118,35 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
11181118 }
11191119
11201120 /// Utility function for *non*-scope code to build their own drops
1121+ /// Force a drop at this point in the MIR by creating a new block.
11211122 pub ( crate ) fn build_drop_and_replace (
11221123 & mut self ,
11231124 block : BasicBlock ,
11241125 span : Span ,
11251126 place : Place < ' tcx > ,
1126- value : Operand < ' tcx > ,
1127+ value : Rvalue < ' tcx > ,
11271128 ) -> BlockAnd < ( ) > {
1129+ let span = self . tcx . with_stable_hashing_context ( |hcx| {
1130+ span. mark_with_reason ( None , DesugaringKind :: Replace , self . tcx . sess . edition ( ) , hcx)
1131+ } ) ;
11281132 let source_info = self . source_info ( span) ;
1129- let next_target = self . cfg . start_new_block ( ) ;
1133+
1134+ // create the new block for the assignment
1135+ let assign = self . cfg . start_new_block ( ) ;
1136+ self . cfg . push_assign ( assign, source_info, place, value. clone ( ) ) ;
1137+
1138+ // create the new block for the assignment in the case of unwinding
1139+ let assign_unwind = self . cfg . start_new_cleanup_block ( ) ;
1140+ self . cfg . push_assign ( assign_unwind, source_info, place, value. clone ( ) ) ;
11301141
11311142 self . cfg . terminate (
11321143 block,
11331144 source_info,
1134- TerminatorKind :: DropAndReplace { place, value , target : next_target , unwind : None } ,
1145+ TerminatorKind :: Drop { place, target : assign , unwind : Some ( assign_unwind ) } ,
11351146 ) ;
11361147 self . diverge_from ( block) ;
11371148
1138- next_target . unit ( )
1149+ assign . unit ( )
11391150 }
11401151
11411152 /// Creates an `Assert` terminator and return the success block.
@@ -1413,8 +1424,15 @@ impl<'tcx> DropTreeBuilder<'tcx> for Unwind {
14131424 fn add_entry ( cfg : & mut CFG < ' tcx > , from : BasicBlock , to : BasicBlock ) {
14141425 let term = & mut cfg. block_data_mut ( from) . terminator_mut ( ) ;
14151426 match & mut term. kind {
1416- TerminatorKind :: Drop { unwind, .. }
1417- | TerminatorKind :: DropAndReplace { unwind, .. }
1427+ TerminatorKind :: Drop { unwind, .. } => {
1428+ if let Some ( unwind) = * unwind {
1429+ let source_info = term. source_info ;
1430+ cfg. terminate ( unwind, source_info, TerminatorKind :: Goto { target : to } ) ;
1431+ } else {
1432+ * unwind = Some ( to) ;
1433+ }
1434+ }
1435+ TerminatorKind :: DropAndReplace { unwind, .. }
14181436 | TerminatorKind :: FalseUnwind { unwind, .. }
14191437 | TerminatorKind :: Call { cleanup : unwind, .. }
14201438 | TerminatorKind :: Assert { cleanup : unwind, .. }
0 commit comments