]> git.lizzy.rs Git - rust.git/commitdiff
add span/scope-id to terminator
authorNiko Matsakis <niko@alum.mit.edu>
Fri, 18 Mar 2016 12:52:13 +0000 (08:52 -0400)
committerNiko Matsakis <niko@alum.mit.edu>
Wed, 23 Mar 2016 20:42:52 +0000 (16:42 -0400)
src/librustc/mir/repr.rs
src/librustc_mir/build/block.rs
src/librustc_mir/build/cfg.rs
src/librustc_mir/build/expr/as_lvalue.rs
src/librustc_mir/build/expr/into.rs
src/librustc_mir/build/matches/mod.rs
src/librustc_mir/build/matches/test.rs
src/librustc_mir/build/mod.rs
src/librustc_mir/build/scope.rs

index 62fea3c6aa831426905672c5d327f97ff3afda39..cc95d5946a80123d449a389eacc02a617df2402e 100644 (file)
@@ -230,6 +230,8 @@ pub struct BasicBlockData<'tcx> {
 
 #[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
 pub struct Terminator<'tcx> {
+    pub span: Span,
+    pub scope: ScopeId,
     pub kind: TerminatorKind<'tcx>
 }
 
index 7ada408361d0582ac81a319cc4cfffb724ca2c7e..ef48a408e79a79746cf7eb8be65a3a0e005cf3ab 100644 (file)
@@ -44,9 +44,10 @@ pub fn ast_block(&mut self,
                     StmtKind::Expr { scope, expr } => {
                         unpack!(block = this.in_scope(scope, block, |this, _| {
                             let expr = this.hir.mirror(expr);
+                            let expr_span = expr.span;
                             let temp = this.temp(expr.ty.clone());
                             unpack!(block = this.into(&temp, block, expr));
-                            unpack!(block = this.build_drop(block, temp));
+                            unpack!(block = this.build_drop(block, expr_span, temp));
                             block.unit()
                         }));
                     }
index ed99364a0f230c0af02c60d6ea1a7a8e275d294b..4859257f291c9767f694b9d4171ddcfeaabb0805 100644 (file)
@@ -83,11 +83,15 @@ pub fn push_assign_unit(&mut self,
 
     pub fn terminate(&mut self,
                      block: BasicBlock,
+                     scope: ScopeId,
+                     span: Span,
                      kind: TerminatorKind<'tcx>) {
         debug_assert!(self.block_data(block).terminator.is_none(),
                       "terminate: block {:?} already has a terminator set", block);
         self.block_data_mut(block).terminator = Some(Terminator {
-            kind: kind
+            span: span,
+            scope: scope,
+            kind: kind,
         });
     }
 }
index fa864625f7f32e1baf86f2d1e1f8a547f20c1272..0c9323f4af3781ccacb2965cb57ab8e561370760 100644 (file)
@@ -68,6 +68,8 @@ fn expr_as_lvalue(&mut self,
 
                 let (success, failure) = (this.cfg.start_new_block(), this.cfg.start_new_block());
                 this.cfg.terminate(block,
+                                   scope_id,
+                                   expr_span,
                                    TerminatorKind::If {
                                        cond: Operand::Consume(lt),
                                        targets: (success, failure),
index 0ce2494ee35efc8cde0815e49168eeb29047bcfe..9992e904dea16f542c2b846d47df98f5ba2143ef 100644 (file)
@@ -53,7 +53,7 @@ pub fn into_expr(&mut self,
 
                 let mut then_block = this.cfg.start_new_block();
                 let mut else_block = this.cfg.start_new_block();
-                this.cfg.terminate(block, TerminatorKind::If {
+                this.cfg.terminate(block, scope_id, expr_span, TerminatorKind::If {
                     cond: operand,
                     targets: (then_block, else_block)
                 });
@@ -70,8 +70,14 @@ pub fn into_expr(&mut self,
                 };
 
                 let join_block = this.cfg.start_new_block();
-                this.cfg.terminate(then_block, TerminatorKind::Goto { target: join_block });
-                this.cfg.terminate(else_block, TerminatorKind::Goto { target: join_block });
+                this.cfg.terminate(then_block,
+                                   scope_id,
+                                   expr_span,
+                                   TerminatorKind::Goto { target: join_block });
+                this.cfg.terminate(else_block,
+                                   scope_id,
+                                   expr_span,
+                                   TerminatorKind::Goto { target: join_block });
 
                 join_block.unit()
             }
@@ -97,10 +103,13 @@ pub fn into_expr(&mut self,
                     LogicalOp::And => (else_block, false_block),
                     LogicalOp::Or => (true_block, else_block),
                 };
-                this.cfg.terminate(block, TerminatorKind::If { cond: lhs, targets: blocks });
+                this.cfg.terminate(block,
+                                   scope_id,
+                                   expr_span,
+                                   TerminatorKind::If { cond: lhs, targets: blocks });
 
                 let rhs = unpack!(else_block = this.as_operand(else_block, rhs));
-                this.cfg.terminate(else_block, TerminatorKind::If {
+                this.cfg.terminate(else_block, scope_id, expr_span, TerminatorKind::If {
                     cond: rhs,
                     targets: (true_block, false_block)
                 });
@@ -121,8 +130,14 @@ pub fn into_expr(&mut self,
                         literal: this.hir.false_literal(),
                     });
 
-                this.cfg.terminate(true_block, TerminatorKind::Goto { target: join_block });
-                this.cfg.terminate(false_block, TerminatorKind::Goto { target: join_block });
+                this.cfg.terminate(true_block,
+                                   scope_id,
+                                   expr_span,
+                                   TerminatorKind::Goto { target: join_block });
+                this.cfg.terminate(false_block,
+                                   scope_id,
+                                   expr_span,
+                                   TerminatorKind::Goto { target: join_block });
 
                 join_block.unit()
             }
@@ -146,7 +161,10 @@ pub fn into_expr(&mut self,
                 let exit_block = this.cfg.start_new_block();
 
                 // start the loop
-                this.cfg.terminate(block, TerminatorKind::Goto { target: loop_block });
+                this.cfg.terminate(block,
+                                   scope_id,
+                                   expr_span,
+                                   TerminatorKind::Goto { target: loop_block });
 
                 let might_break = this.in_loop_scope(loop_block, exit_block, move |this| {
                     // conduct the test, if necessary
@@ -159,6 +177,8 @@ pub fn into_expr(&mut self,
                         let cond = unpack!(loop_block_end = this.as_operand(loop_block, cond_expr));
                         body_block = this.cfg.start_new_block();
                         this.cfg.terminate(loop_block_end,
+                                           scope_id,
+                                           expr_span,
                                            TerminatorKind::If {
                                                cond: cond,
                                                targets: (body_block, exit_block)
@@ -175,7 +195,10 @@ pub fn into_expr(&mut self,
                     let tmp = this.get_unit_temp();
                     // Execute the body, branching back to the test.
                     let body_block_end = unpack!(this.into(&tmp, body_block, body));
-                    this.cfg.terminate(body_block_end, TerminatorKind::Goto { target: loop_block });
+                    this.cfg.terminate(body_block_end,
+                                       scope_id,
+                                       expr_span,
+                                       TerminatorKind::Goto { target: loop_block });
                 });
                 // If the loop may reach its exit_block, we assign an empty tuple to the
                 // destination to keep the MIR well-formed.
@@ -188,9 +211,11 @@ pub fn into_expr(&mut self,
                 // Note: we evaluate assignments right-to-left. This
                 // is better for borrowck interaction with overloaded
                 // operators like x[j] = x[i].
+                let lhs = this.hir.mirror(lhs);
+                let lhs_span = lhs.span;
                 let rhs = unpack!(block = this.as_operand(block, rhs));
                 let lhs = unpack!(block = this.as_lvalue(block, lhs));
-                unpack!(block = this.build_drop(block, lhs.clone()));
+                unpack!(block = this.build_drop(block, lhs_span, lhs.clone()));
                 this.cfg.push_assign(block, scope_id, expr_span, &lhs, Rvalue::Use(rhs));
                 block.unit()
             }
@@ -254,7 +279,7 @@ pub fn into_expr(&mut self,
 
                 let success = this.cfg.start_new_block();
                 let cleanup = this.diverge_cleanup();
-                this.cfg.terminate(block, TerminatorKind::Call {
+                this.cfg.terminate(block, scope_id, expr_span, TerminatorKind::Call {
                     func: fun,
                     args: args,
                     cleanup: cleanup,
index 2018d7255f5edd007f8ce7f3ed7c043fbcf761f3..9414752fbd86468dc34e680cc40788c8fe1cb9e8 100644 (file)
@@ -71,6 +71,7 @@ pub fn match_expr(&mut self,
                 })
                 .map(|(arm_index, pattern, guard)| {
                     Candidate {
+                        span: pattern.span,
                         match_pairs: vec![MatchPair::new(discriminant_lvalue.clone(), pattern)],
                         bindings: vec![],
                         guard: guard,
@@ -87,7 +88,7 @@ pub fn match_expr(&mut self,
         // an empty vector to be returned here, but the algorithm is
         // not entirely precise
         if !otherwise.is_empty() {
-            let join_block = self.join_otherwise_blocks(otherwise);
+            let join_block = self.join_otherwise_blocks(span, otherwise);
             self.panic(join_block, "something about matches algorithm not being precise", span);
         }
 
@@ -97,7 +98,10 @@ pub fn match_expr(&mut self,
         for (arm_index, arm_body) in arm_bodies.into_iter().enumerate() {
             let mut arm_block = arm_blocks.blocks[arm_index];
             unpack!(arm_block = self.into(destination, arm_block, arm_body));
-            self.cfg.terminate(arm_block, TerminatorKind::Goto { target: end_block });
+            self.cfg.terminate(arm_block,
+                               var_scope_id,
+                               span,
+                               TerminatorKind::Goto { target: end_block });
         }
 
         end_block.unit()
@@ -146,6 +150,7 @@ pub fn lvalue_into_pattern(&mut self,
 
         // create a dummy candidate
         let mut candidate = Candidate {
+            span: irrefutable_pat.span,
             match_pairs: vec![MatchPair::new(initializer.clone(), &irrefutable_pat)],
             bindings: vec![],
             guard: None,
@@ -206,6 +211,9 @@ struct ArmBlocks {
 
 #[derive(Clone, Debug)]
 pub struct Candidate<'pat, 'tcx:'pat> {
+    // span of the original pattern that gave rise to this candidate
+    span: Span,
+
     // all of these must be satisfied...
     match_pairs: Vec<MatchPair<'pat, 'tcx>>,
 
@@ -370,20 +378,25 @@ fn match_candidates<'pat>(&mut self,
         }
 
         // Otherwise, let's process those remaining candidates.
-        let join_block = self.join_otherwise_blocks(otherwise);
+        let join_block = self.join_otherwise_blocks(span, otherwise);
         self.match_candidates(span, arm_blocks, untested_candidates, join_block)
     }
 
     fn join_otherwise_blocks(&mut self,
+                             span: Span,
                              otherwise: Vec<BasicBlock>)
                              -> BasicBlock
     {
+        let scope_id = self.innermost_scope_id();
         if otherwise.len() == 1 {
             otherwise[0]
         } else {
             let join_block = self.cfg.start_new_block();
             for block in otherwise {
-                self.cfg.terminate(block, TerminatorKind::Goto { target: join_block });
+                self.cfg.terminate(block,
+                                   scope_id,
+                                   span,
+                                   TerminatorKind::Goto { target: join_block });
             }
             join_block
         }
@@ -550,16 +563,25 @@ fn bind_and_guard_matched_candidate<'pat>(&mut self,
 
         let arm_block = arm_blocks.blocks[candidate.arm_index];
 
+        let scope_id = self.innermost_scope_id();
         if let Some(guard) = candidate.guard {
             // the block to branch to if the guard fails; if there is no
             // guard, this block is simply unreachable
+            let guard = self.hir.mirror(guard);
+            let guard_span = guard.span;
             let cond = unpack!(block = self.as_operand(block, guard));
             let otherwise = self.cfg.start_new_block();
-            self.cfg.terminate(block, TerminatorKind::If { cond: cond,
-                                                       targets: (arm_block, otherwise)});
+            self.cfg.terminate(block,
+                               scope_id,
+                               guard_span,
+                               TerminatorKind::If { cond: cond,
+                                                    targets: (arm_block, otherwise)});
             Some(otherwise)
         } else {
-            self.cfg.terminate(block, TerminatorKind::Goto { target: arm_block });
+            self.cfg.terminate(block,
+                               scope_id,
+                               candidate.span,
+                               TerminatorKind::Goto { target: arm_block });
             None
         }
     }
index 74402ccba348f2ab578d38806f9ad27e9d51af47..3e374c07b46b1a507cb821c18c243fcab3021a3e 100644 (file)
@@ -153,7 +153,7 @@ pub fn perform_test(&mut self,
                 let target_blocks: Vec<_> =
                     (0..num_enum_variants).map(|_| self.cfg.start_new_block())
                                           .collect();
-                self.cfg.terminate(block, TerminatorKind::Switch {
+                self.cfg.terminate(block, scope_id, test.span, TerminatorKind::Switch {
                     discr: lvalue.clone(),
                     adt_def: adt_def,
                     targets: target_blocks.clone()
@@ -168,12 +168,15 @@ pub fn perform_test(&mut self,
                            .map(|_| self.cfg.start_new_block())
                            .chain(Some(otherwise))
                            .collect();
-                self.cfg.terminate(block, TerminatorKind::SwitchInt {
-                    discr: lvalue.clone(),
-                    switch_ty: switch_ty,
-                    values: options.clone(),
-                    targets: targets.clone(),
-                });
+                self.cfg.terminate(block,
+                                   scope_id,
+                                   test.span,
+                                   TerminatorKind::SwitchInt {
+                                       discr: lvalue.clone(),
+                                       switch_ty: switch_ty,
+                                       values: options.clone(),
+                                       targets: targets.clone(),
+                                   });
                 targets
             }
 
@@ -226,7 +229,7 @@ pub fn perform_test(&mut self,
                     let eq_result = self.temp(bool_ty);
                     let eq_block = self.cfg.start_new_block();
                     let cleanup = self.diverge_cleanup();
-                    self.cfg.terminate(block, Terminator::Call {
+                    self.cfg.terminate(block, scope_id, test.span, TerminatorKind::Call {
                         func: Operand::Constant(Constant {
                             span: test.span,
                             ty: mty,
@@ -239,7 +242,7 @@ pub fn perform_test(&mut self,
 
                     // check the result
                     let block = self.cfg.start_new_block();
-                    self.cfg.terminate(eq_block, Terminator::If {
+                    self.cfg.terminate(eq_block, scope_id, test.span, TerminatorKind::If {
                         cond: Operand::Consume(eq_result),
                         targets: (block, fail),
                     });
@@ -286,7 +289,7 @@ pub fn perform_test(&mut self,
                 // branch based on result
                 let target_blocks: Vec<_> = vec![self.cfg.start_new_block(),
                                                  self.cfg.start_new_block()];
-                self.cfg.terminate(block, TerminatorKind::If {
+                self.cfg.terminate(block, scope_id, test.span, TerminatorKind::If {
                     cond: Operand::Consume(result),
                     targets: (target_blocks[0], target_blocks[1])
                 });
@@ -313,7 +316,7 @@ fn compare(&mut self,
 
         // branch based on result
         let target_block = self.cfg.start_new_block();
-        self.cfg.terminate(block, TerminatorKind::If {
+        self.cfg.terminate(block, scope_id, span, TerminatorKind::If {
             cond: Operand::Consume(result),
             targets: (target_block, fail_block)
         });
@@ -466,6 +469,7 @@ fn candidate_without_match_pair<'pat>(&mut self,
                                  .map(|(_, mp)| mp.clone())
                                  .collect();
         Candidate {
+            span: candidate.span,
             match_pairs: other_match_pairs,
             bindings: candidate.bindings.clone(),
             guard: candidate.guard.clone(),
@@ -507,6 +511,7 @@ fn candidate_after_variant_switch<'pat>(&mut self,
         let all_match_pairs = consequent_match_pairs.chain(other_match_pairs).collect();
 
         Candidate {
+            span: candidate.span,
             match_pairs: all_match_pairs,
             bindings: candidate.bindings.clone(),
             guard: candidate.guard.clone(),
index 44bbb2e3f193985010c12c72f80961600364aeba..416c078f4a95a15d744c5a8b93381cd98cf30089 100644 (file)
@@ -160,14 +160,17 @@ pub fn construct<'a,'tcx>(hir: Cx<'a,'tcx>,
     assert_eq!(builder.cfg.start_new_block(), END_BLOCK);
 
     let mut block = START_BLOCK;
-    let arg_decls = unpack!(block = builder.args_and_body(block,
-                                                          implicit_arguments,
-                                                          explicit_arguments,
-                                                          argument_extent,
-                                                          ast_block));
-
-    builder.cfg.terminate(block, TerminatorKind::Goto { target: END_BLOCK });
-    builder.cfg.terminate(END_BLOCK, TerminatorKind::Return);
+    let (arg_decls, arg_scope_id) =
+        unpack!(block = builder.args_and_body(block,
+                                              implicit_arguments,
+                                              explicit_arguments,
+                                              argument_extent,
+                                              ast_block));
+
+    builder.cfg.terminate(block, arg_scope_id, span,
+                          TerminatorKind::Goto { target: END_BLOCK });
+    builder.cfg.terminate(END_BLOCK, arg_scope_id, span,
+                          TerminatorKind::Return);
 
     MirPlusPlus {
         mir: Mir {
@@ -190,7 +193,7 @@ fn args_and_body(&mut self,
                      explicit_arguments: Vec<(Ty<'tcx>, &'tcx hir::Pat)>,
                      argument_extent: CodeExtent,
                      ast_block: &'tcx hir::Block)
-                     -> BlockAnd<Vec<ArgDecl<'tcx>>>
+                     -> BlockAnd<(Vec<ArgDecl<'tcx>>, ScopeId)>
     {
         self.in_scope(argument_extent, block, |this, argument_scope_id| {
             // to start, translate the argument patterns and collect the argument types.
@@ -219,7 +222,7 @@ fn args_and_body(&mut self,
             // start the first basic block and translate the body
             unpack!(block = this.ast_block(&Lvalue::ReturnPointer, block, ast_block));
 
-            block.and(arg_decls)
+            block.and((arg_decls, argument_scope_id))
         })
     }
 
index c6d24591d2ac3de6739435ad96f1d43407782b8e..e7066ff083e245ac03cf7a56146d5ee06025a84a 100644 (file)
@@ -116,6 +116,7 @@ pub struct Scope<'tcx> {
 }
 
 struct DropData<'tcx> {
+    span: Span,
     value: Lvalue<'tcx>,
     // NB: per-drop “cache” is necessary for the build_scope_drops function below.
     /// The cached block for the cleanups-on-diverge path. This block contains code to run the
@@ -288,14 +289,19 @@ pub fn exit_scope(&mut self,
             if let Some(ref free_data) = scope.free {
                 let next = self.cfg.start_new_block();
                 let free = build_free(self.hir.tcx(), tmp.clone(), free_data, next);
-                self.cfg.terminate(block, free);
+                self.cfg.terminate(block, scope.id, span, free);
                 block = next;
             }
             self.scope_auxiliary[scope.id.index()]
                 .postdoms
                 .push(self.cfg.current_location(block));
         }
-        self.cfg.terminate(block, TerminatorKind::Goto { target: target });
+
+        let scope_id = self.innermost_scope_id();
+        self.cfg.terminate(block,
+                           scope_id,
+                           span,
+                           TerminatorKind::Goto { target: target });
     }
 
     // Finding scopes
@@ -351,6 +357,7 @@ pub fn schedule_drop(&mut self,
                 // No need to invalidate any caches here. The just-scheduled drop will branch into
                 // the drop that comes before it in the vector.
                 scope.drops.push(DropData {
+                    span: span,
                     value: lvalue.clone(),
                     cached_block: None
                 });
@@ -429,14 +436,22 @@ pub fn diverge_cleanup(&mut self) -> Option<BasicBlock> {
     }
 
     /// Utility function for *non*-scope code to build their own drops
-    pub fn build_drop(&mut self, block: BasicBlock, value: Lvalue<'tcx>) -> BlockAnd<()> {
+    pub fn build_drop(&mut self,
+                      block: BasicBlock,
+                      span: Span,
+                      value: Lvalue<'tcx>)
+                      -> BlockAnd<()> {
+        let scope_id = self.innermost_scope_id();
         let next_target = self.cfg.start_new_block();
         let diverge_target = self.diverge_cleanup();
-        self.cfg.terminate(block, TerminatorKind::Drop {
-            value: value,
-            target: next_target,
-            unwind: diverge_target,
-        });
+        self.cfg.terminate(block,
+                           scope_id,
+                           span,
+                           TerminatorKind::Drop {
+                               value: value,
+                               target: next_target,
+                               unwind: diverge_target,
+                           });
         next_target.unit()
     }
 
@@ -445,10 +460,10 @@ pub fn build_drop(&mut self, block: BasicBlock, value: Lvalue<'tcx>) -> BlockAnd
     // =========
     // FIXME: should be moved into their own module
     pub fn panic_bounds_check(&mut self,
-                             block: BasicBlock,
-                             index: Operand<'tcx>,
-                             len: Operand<'tcx>,
-                             span: Span) {
+                              block: BasicBlock,
+                              index: Operand<'tcx>,
+                              len: Operand<'tcx>,
+                              span: Span) {
         // fn(&(filename: &'static str, line: u32), index: usize, length: usize) -> !
         let region = ty::ReStatic; // FIXME(mir-borrowck): use a better region?
         let func = self.lang_function(lang_items::PanicBoundsCheckFnLangItem);
@@ -474,7 +489,7 @@ pub fn panic_bounds_check(&mut self,
         self.cfg.push_assign(block, scope_id, span, &tuple_ref, // tuple_ref = &tuple;
                              Rvalue::Ref(region, BorrowKind::Shared, tuple));
         let cleanup = self.diverge_cleanup();
-        self.cfg.terminate(block, TerminatorKind::Call {
+        self.cfg.terminate(block, scope_id, span, TerminatorKind::Call {
             func: Operand::Constant(func),
             args: vec![Operand::Consume(tuple_ref), index, len],
             destination: None,
@@ -516,7 +531,7 @@ pub fn panic(&mut self, block: BasicBlock, msg: &'static str, span: Span) {
         self.cfg.push_assign(block, scope_id, span, &tuple_ref, // tuple_ref = &tuple;
                              Rvalue::Ref(region, BorrowKind::Shared, tuple));
         let cleanup = self.diverge_cleanup();
-        self.cfg.terminate(block, TerminatorKind::Call {
+        self.cfg.terminate(block, scope_id, span, TerminatorKind::Call {
             func: Operand::Constant(func),
             args: vec![Operand::Consume(tuple_ref)],
             cleanup: cleanup,
@@ -575,7 +590,7 @@ fn build_scope_drops<'tcx>(cfg: &mut CFG<'tcx>,
             earlier_scopes.iter().rev().flat_map(|s| s.cached_block()).next()
         });
         let next = cfg.start_new_block();
-        cfg.terminate(block, TerminatorKind::Drop {
+        cfg.terminate(block, scope.id, drop_data.span, TerminatorKind::Drop {
             value: drop_data.value.clone(),
             target: next,
             unwind: on_diverge
@@ -599,12 +614,15 @@ fn build_diverge_scope<'tcx>(tcx: &TyCtxt<'tcx>,
     let mut last_drop_block = None;
     for drop_data in scope.drops.iter_mut().rev() {
         if let Some(cached_block) = drop_data.cached_block {
-            if let Some((previous_block, previous_value)) = previous {
-                cfg.terminate(previous_block, TerminatorKind::Drop {
-                    value: previous_value,
-                    target: cached_block,
-                    unwind: None
-                });
+            if let Some((previous_block, previous_span, previous_value)) = previous {
+                cfg.terminate(previous_block,
+                              scope.id,
+                              previous_span,
+                              TerminatorKind::Drop {
+                                  value: previous_value,
+                                  target: cached_block,
+                                  unwind: None
+                              });
                 return last_drop_block.unwrap();
             } else {
                 return cached_block;
@@ -612,23 +630,26 @@ fn build_diverge_scope<'tcx>(tcx: &TyCtxt<'tcx>,
         } else {
             let block = cfg.start_new_cleanup_block();
             drop_data.cached_block = Some(block);
-            if let Some((previous_block, previous_value)) = previous {
-                cfg.terminate(previous_block, TerminatorKind::Drop {
-                    value: previous_value,
-                    target: block,
-                    unwind: None
-                });
+            if let Some((previous_block, previous_span, previous_value)) = previous {
+                cfg.terminate(previous_block,
+                              scope.id,
+                              previous_span,
+                              TerminatorKind::Drop {
+                                  value: previous_value,
+                                  target: block,
+                                  unwind: None
+                              });
             } else {
                 last_drop_block = Some(block);
             }
-            previous = Some((block, drop_data.value.clone()));
+            previous = Some((block, drop_data.span, drop_data.value.clone()));
         }
     }
 
     // Prepare the end target for this chain.
     let mut target = target.unwrap_or_else(||{
         let b = cfg.start_new_cleanup_block();
-        cfg.terminate(b, TerminatorKind::Resume);
+        cfg.terminate(b, scope.id, DUMMY_SP, TerminatorKind::Resume); // TODO
         b
     });
 
@@ -638,19 +659,25 @@ fn build_diverge_scope<'tcx>(tcx: &TyCtxt<'tcx>,
             cached_block
         } else {
             let into = cfg.start_new_cleanup_block();
-            cfg.terminate(into, build_free(tcx, unit_temp, free_data, target));
+            cfg.terminate(into,
+                          scope.id,
+                          free_data.span,
+                          build_free(tcx, unit_temp, free_data, target));
             free_data.cached_block = Some(into);
             into
         }
     };
 
-    if let Some((previous_block, previous_value)) = previous {
+    if let Some((previous_block, previous_span, previous_value)) = previous {
         // Finally, branch into that just-built `target` from the `previous_block`.
-        cfg.terminate(previous_block, TerminatorKind::Drop {
-            value: previous_value,
-            target: target,
-            unwind: None
-        });
+        cfg.terminate(previous_block,
+                      scope.id,
+                      previous_span,
+                      TerminatorKind::Drop {
+                          value: previous_value,
+                          target: target,
+                          unwind: None
+                      });
         last_drop_block.unwrap()
     } else {
         // If `previous.is_none()`, there were no drops in this scope – we return the