mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-02 07:22:42 +00:00
Fix incorrect double assignment in MIR for while loops
This commit is contained in:
parent
5f9c0448dd
commit
62bec71446
@ -184,15 +184,23 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
loop_block_end = this.as_local_operand(loop_block, cond_expr)
|
||||
);
|
||||
body_block = this.cfg.start_new_block();
|
||||
let term =
|
||||
TerminatorKind::if_(this.hir.tcx(), cond, body_block, exit_block);
|
||||
let false_block = this.cfg.start_new_block();
|
||||
let term = TerminatorKind::if_(
|
||||
this.hir.tcx(),
|
||||
cond,
|
||||
body_block,
|
||||
false_block,
|
||||
);
|
||||
this.cfg.terminate(loop_block_end, source_info, term);
|
||||
|
||||
// if the test is false, there's no `break` to assign `destination`, so
|
||||
// we have to do it; this overwrites any `break`-assigned value but it's
|
||||
// always `()` anyway
|
||||
this.cfg
|
||||
.push_assign_unit(exit_block, source_info, destination);
|
||||
// we have to do it
|
||||
this.cfg.push_assign_unit(false_block, source_info, destination);
|
||||
this.cfg.terminate(
|
||||
false_block,
|
||||
source_info,
|
||||
TerminatorKind::Goto { target: exit_block },
|
||||
);
|
||||
} else {
|
||||
body_block = this.cfg.start_new_block();
|
||||
let diverge_cleanup = this.diverge_cleanup();
|
||||
|
11
src/test/ui/nll/assign-while-to-immutable.rs
Normal file
11
src/test/ui/nll/assign-while-to-immutable.rs
Normal file
@ -0,0 +1,11 @@
|
||||
// We used to incorrectly assign to `x` twice when generating MIR for this
|
||||
// function, preventing this from compiling.
|
||||
|
||||
// check-pass
|
||||
|
||||
fn main() {
|
||||
let x = while false {
|
||||
break;
|
||||
};
|
||||
let y = 'l: while break 'l {};
|
||||
}
|
Loading…
Reference in New Issue
Block a user