Rollup merge of #57302 - sinkuu:unused_assignments_fp, r=estebank
Fix unused_assignments false positive
Fixes #22630.
In liveness analysis, make `continue` jump to the loop condition's `LiveNode` (`cond` as in comment) instead of the loop's one (`expr`).
069b0c4108/src/librustc/middle/liveness.rs (L1358-L1370)
This commit is contained in:
commit
0dd4bfa356
2 changed files with 15 additions and 23 deletions
|
|
@ -911,17 +911,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
}
|
||||
|
||||
fn compute(&mut self, body: &hir::Expr) -> LiveNode {
|
||||
// if there is a `break` or `again` at the top level, then it's
|
||||
// effectively a return---this only occurs in `for` loops,
|
||||
// where the body is really a closure.
|
||||
|
||||
debug!("compute: using id for body, {}", self.ir.tcx.hir().node_to_pretty_string(body.id));
|
||||
|
||||
let exit_ln = self.s.exit_ln;
|
||||
|
||||
self.break_ln.insert(body.id, exit_ln);
|
||||
self.cont_ln.insert(body.id, exit_ln);
|
||||
|
||||
// the fallthrough exit is only for those cases where we do not
|
||||
// explicitly return:
|
||||
let s = self.s;
|
||||
|
|
@ -1024,19 +1015,10 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
self.propagate_through_expr(&e, succ)
|
||||
}
|
||||
|
||||
hir::ExprKind::Closure(.., blk_id, _, _) => {
|
||||
hir::ExprKind::Closure(..) => {
|
||||
debug!("{} is an ExprKind::Closure",
|
||||
self.ir.tcx.hir().node_to_pretty_string(expr.id));
|
||||
|
||||
// The next-node for a break is the successor of the entire
|
||||
// loop. The next-node for a continue is the top of this loop.
|
||||
let node = self.live_node(expr.hir_id, expr.span);
|
||||
|
||||
let break_ln = succ;
|
||||
let cont_ln = node;
|
||||
self.break_ln.insert(blk_id.node_id, break_ln);
|
||||
self.cont_ln.insert(blk_id.node_id, cont_ln);
|
||||
|
||||
// the construction of a closure itself is not important,
|
||||
// but we have to consider the closed over variables.
|
||||
let caps = self.ir.capture_info_map.get(&expr.id).cloned().unwrap_or_else(||
|
||||
|
|
@ -1407,15 +1389,16 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
debug!("propagate_through_loop: using id for loop body {} {}",
|
||||
expr.id, self.ir.tcx.hir().node_to_pretty_string(body.id));
|
||||
|
||||
let break_ln = succ;
|
||||
let cont_ln = ln;
|
||||
self.break_ln.insert(expr.id, break_ln);
|
||||
self.cont_ln.insert(expr.id, cont_ln);
|
||||
|
||||
self.break_ln.insert(expr.id, succ);
|
||||
|
||||
let cond_ln = match kind {
|
||||
LoopLoop => ln,
|
||||
WhileLoop(ref cond) => self.propagate_through_expr(&cond, ln),
|
||||
};
|
||||
|
||||
self.cont_ln.insert(expr.id, cond_ln);
|
||||
|
||||
let body_ln = self.propagate_through_block(body, cond_ln);
|
||||
|
||||
// repeat until fixed point is reached:
|
||||
|
|
|
|||
|
|
@ -27,4 +27,13 @@ fn f5(mut x: i32) {
|
|||
x = 4; //~ ERROR: value assigned to `x` is never read
|
||||
}
|
||||
|
||||
// #22630
|
||||
fn f6() {
|
||||
let mut done = false;
|
||||
while !done {
|
||||
done = true; // no error
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue