diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-01-18 22:56:39 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-01-18 22:56:39 +0100 |
| commit | 0dd4bfa35616d43bb6b24f209baade9270afdb59 (patch) | |
| tree | d33f6cbf0189accd484e103303b9d88c1fe1e42d | |
| parent | bb683b9f3aacffd5db61c015a519349dbe4ed969 (diff) | |
| parent | 069b0c410808c1d1d33b495e048b1186e9f8d57f (diff) | |
| download | rust-0dd4bfa35616d43bb6b24f209baade9270afdb59.tar.gz rust-0dd4bfa35616d43bb6b24f209baade9270afdb59.zip | |
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`). https://github.com/rust-lang/rust/blob/069b0c410808c1d1d33b495e048b1186e9f8d57f/src/librustc/middle/liveness.rs#L1358-L1370
| -rw-r--r-- | src/librustc/middle/liveness.rs | 29 | ||||
| -rw-r--r-- | src/test/ui/liveness/liveness-dead.rs | 9 |
2 files changed, 15 insertions, 23 deletions
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index a78cf1a471b..2ca823929fd 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -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: diff --git a/src/test/ui/liveness/liveness-dead.rs b/src/test/ui/liveness/liveness-dead.rs index 7d420afde4b..004663c85ee 100644 --- a/src/test/ui/liveness/liveness-dead.rs +++ b/src/test/ui/liveness/liveness-dead.rs @@ -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() {} |
