- /// Schedule dropping of a not yet fully initialised box. This cleanup will (and should) only
- /// be translated into unwind branch. The extent should be for the `EXPR` inside `box EXPR`.
- pub fn schedule_box_free(&mut self,
- span: Span,
- extent: CodeExtent,
- lvalue: &Lvalue<'tcx>,
- item_ty: Ty<'tcx>) {
- for scope in self.scopes.iter_mut().rev() {
- // We must invalidate all the cached_blocks leading up to the scope we’re looking
- // for, because otherwise some/most of the blocks in the chain might become
- // incorrect (i.e. they still are pointing at old cached_block).
- scope.cached_block = None;
- if scope.extent == extent {
- scope.frees.push((span, lvalue.clone(), item_ty));
- return;
- }
- }
- self.hir.span_bug(span,
- &format!("extent {:?} not in scope to drop {:?}", extent, lvalue));
- }
-
- pub fn extent_of_innermost_scope(&self) -> CodeExtent {
- self.scopes.last().map(|scope| scope.extent).unwrap()
- }
-
- pub fn extent_of_outermost_scope(&self) -> CodeExtent {
- self.scopes.first().map(|scope| scope.extent).unwrap()
+ /// Utility function for *non*-scope code to build their own drops
+ pub fn build_drop(&mut self, block: BasicBlock, value: Lvalue<'tcx>) -> BlockAnd<()> {
+ let next_target = self.cfg.start_new_block();
+ let diverge_target = self.diverge_cleanup();
+ self.cfg.terminate(block, Terminator::Drop {
+ value: value,
+ target: next_target,
+ unwind: diverge_target,
+ });
+ next_target.unit()