/// Elaborate a MIR `replace` terminator. This instruction
/// is not directly handled by translation, and therefore
/// must be desugared.
///
/// The desugaring drops the location if needed, and then writes
/// the value (including setting the drop flag) over it in *both* arms.
///
/// The `replace` terminator can also be called on lvalues that
/// are not tracked by elaboration (for example,
/// `replace x[i] <- tmp0`). The borrow checker requires that
/// these locations are initialized before the assignment,
/// so we just generate an unconditional drop.
Elaborate a MIR `replace` terminator. This instruction
is not directly handled by translation, and therefore
must be desugared.

The desugaring drops the location if needed, and then writes
the value (including setting the drop flag) over it in *both* arms.

The `replace` terminator can also be called on lvalues that
are not tracked by elaboration (for example,
`replace x[i] <- tmp0`). The borrow checker requires that
these locations are initialized before the assignment,
so we just generate an unconditional drop.
Elaborate a MIR ` replace ` terminator . This instruction is not directly handled by translation and therefore must be desugared . The desugaring drops the location if needed and then writes the value ( including setting the drop flag ) over it in * both * arms . The ` replace ` terminator can also be called on lvalues that are not tracked by elaboration ( for example ` replace x [ i ] < - tmp0 ` ) . The borrow checker requires that these locations are initialized before the assignment so we just generate an unconditional drop .
fn elaborate_replace(
        &mut self,
        loc: Location,
        location: &Lvalue<'tcx>,
        value: &Operand<'tcx>,
        target: BasicBlock,
        unwind: Option<BasicBlock>)
    {
        let bb = loc.block;
        let data = &self.mir[bb];
        let terminator = data.terminator();
        let assign = Statement {
            kind: StatementKind::Assign(location.clone(), Rvalue::Use(value.clone())),
            source_info: terminator.source_info
        };
        let unwind = unwind.unwrap_or(self.patch.resume_block());
        let unwind = self.patch.new_block(BasicBlockData {
            statements: vec![assign.clone()],
            terminator: Some(Terminator {
                kind: TerminatorKind::Goto { target: unwind },
                ..*terminator
            }),
            is_cleanup: true
        });
        let target = self.patch.new_block(BasicBlockData {
            statements: vec![assign],
            terminator: Some(Terminator {
                kind: TerminatorKind::Goto { target: target },
                ..*terminator
            }),
            is_cleanup: data.is_cleanup,
        });
        if !self.lvalue_is_tracked(location) {
            // drop and replace behind a pointer/array/whatever. The location
            // must be initialized.
            debug!("elaborate_drop_and_replace({:?}) - untracked", terminator);
            self.patch.patch_terminator(bb, TerminatorKind::Drop {
                location: location.clone(),
                target: target,
                unwind: Some(unwind)
            });
        } else {
            debug!("elaborate_drop_and_replace({:?}) - tracked", terminator);
            let init_data = self.initialization_data_at(loc);
            let path = self.move_data().rev_lookup.find(location);
            self.elaborate_drop(&DropCtxt {
                source_info: terminator.source_info,
                is_cleanup: data.is_cleanup,
                init_data: &init_data,
                lvalue: location,
                path: path,
                succ: target,
                unwind: Some(unwind)
            }, bb);
            on_all_children_bits(self.tcx, self.mir, self.move_data(), path, |child| {
                self.set_drop_flag(Location { block: target, index: 0 },
                                   child, DropFlagState::Present);
                self.set_drop_flag(Location { block: unwind, index: 0 },
                                   child, DropFlagState::Present);
            });
        }
    }
fn elaborate_replace ( & mut self , loc : Location , location : & Lvalue < ' tcx > , value : & Operand < ' tcx > , target : BasicBlock , unwind : Option < BasicBlock > ) { let bb = loc . block ; let data = & self . mir [ bb ] ; let terminator = data . terminator ( ) ; let assign = Statement { kind : StatementKind :: Assign ( location . clone ( ) , Rvalue :: Use ( value . clone ( ) ) ) , source_info : terminator . source_info } ; let unwind = unwind . unwrap_or ( self . patch . resume_block ( ) ) ; let unwind = self . patch . new_block ( BasicBlockData { statements : vec ! [ assign clone ( ) ] , terminator : Some ( Terminator { kind : TerminatorKind :: Goto { target : unwind } , .. * terminator } ) , is_cleanup : true } ) ; let target = self . patch . new_block ( BasicBlockData { statements : vec ! [ assign ] , terminator : Some ( Terminator { kind : TerminatorKind :: Goto { target : target } , .. * terminator } ) , is_cleanup : data . is_cleanup , } ) ; if ! self . lvalue_is_tracked ( location ) { // drop and replace behind a pointer/array/whatever. The location // must be initialized. debug ! ( " " terminator ) ; self . patch . patch_terminator ( bb , TerminatorKind :: Drop { location : location . clone ( ) , target : target , unwind : Some ( unwind ) } ) ; } else { debug ! ( " " terminator ) ; let init_data = self . initialization_data_at ( loc ) ; let path = self . move_data ( ) . rev_lookup . find ( location ) ; self . elaborate_drop ( & DropCtxt { source_info : terminator . source_info , is_cleanup : data . is_cleanup , init_data : & init_data , lvalue : location , path : path , succ : target , unwind : Some ( unwind ) } , bb ) ; on_all_children_bits ( self . tcx , self . mir , self . move_data ( ) , path , | child | { self . set_drop_flag ( Location { block : target , index : 0 } , child , DropFlagState :: Present ) ; self . set_drop_flag ( Location { block : unwind , index : 0 } , child , DropFlagState :: Present ) ; } ) ; } }
Elaborate a MIR `replace` terminator.
Elaborate a MIR ` replace ` terminator .
&mut self
loc
Location
location
&Lvalue<'tcx>
value
&Operand<'tcx>
target
BasicBlock
unwind
Option<BasicBlock>