diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 36d1a6c104421..edc0ff62bd5ec 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -435,7 +435,10 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> { } // live nodes required for interesting control flow: - hir::ExprKind::If(..) | hir::ExprKind::Match(..) | hir::ExprKind::Loop(..) => { + hir::ExprKind::If(..) + | hir::ExprKind::Match(..) + | hir::ExprKind::Loop(..) + | hir::ExprKind::Yield(..) => { self.add_live_node_for_node(expr.hir_id, ExprNode(expr.span, expr.hir_id)); intravisit::walk_expr(self, expr); } @@ -469,7 +472,6 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> { | hir::ExprKind::InlineAsm(..) | hir::ExprKind::LlvmInlineAsm(..) | hir::ExprKind::Box(..) - | hir::ExprKind::Yield(..) | hir::ExprKind::Type(..) | hir::ExprKind::Err | hir::ExprKind::Path(hir::QPath::TypeRelative(..)) @@ -866,6 +868,13 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { // at the label ident hir::ExprKind::Loop(ref blk, ..) => self.propagate_through_loop(expr, &blk, succ), + hir::ExprKind::Yield(ref e, ..) => { + let yield_ln = self.live_node(expr.hir_id, expr.span); + self.init_from_succ(yield_ln, succ); + self.merge_from_succ(yield_ln, self.exit_ln); + self.propagate_through_expr(e, yield_ln) + } + hir::ExprKind::If(ref cond, ref then, ref else_opt) => { // // (cond) @@ -1025,7 +1034,6 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { | hir::ExprKind::Type(ref e, _) | hir::ExprKind::DropTemps(ref e) | hir::ExprKind::Unary(_, ref e) - | hir::ExprKind::Yield(ref e, _) | hir::ExprKind::Repeat(ref e, _) => self.propagate_through_expr(&e, succ), hir::ExprKind::InlineAsm(ref asm) => { diff --git a/src/test/ui/liveness/liveness-upvars.rs b/src/test/ui/liveness/liveness-upvars.rs index 98ea4d71ccf4f..d446d57d39647 100644 --- a/src/test/ui/liveness/liveness-upvars.rs +++ b/src/test/ui/liveness/liveness-upvars.rs @@ -1,5 +1,6 @@ // edition:2018 // check-pass +#![feature(generators)] #![warn(unused)] #![allow(unreachable_code)] @@ -105,4 +106,39 @@ pub fn h() { }; } +async fn yield_now() { + todo!(); +} + +pub fn async_generator() { + let mut state: u32 = 0; + + let _ = async { + state = 1; + yield_now().await; + state = 2; + yield_now().await; + state = 3; + }; + + let _ = async move { + state = 4; //~ WARN value assigned to `state` is never read + //~| WARN unused variable: `state` + yield_now().await; + state = 5; //~ WARN value assigned to `state` is never read + }; +} + +pub fn generator() { + let mut s: u32 = 0; + let _ = |_| { + s = 0; + yield (); + s = 1; //~ WARN value assigned to `s` is never read + yield (s = 2); + s = yield (); //~ WARN value assigned to `s` is never read + s = 3; + }; +} + fn main() {} diff --git a/src/test/ui/liveness/liveness-upvars.stderr b/src/test/ui/liveness/liveness-upvars.stderr index 14fed91786436..d172330251365 100644 --- a/src/test/ui/liveness/liveness-upvars.stderr +++ b/src/test/ui/liveness/liveness-upvars.stderr @@ -1,11 +1,11 @@ warning: value assigned to `last` is never read - --> $DIR/liveness-upvars.rs:9:9 + --> $DIR/liveness-upvars.rs:10:9 | LL | last = Some(s); | ^^^^ | note: the lint level is defined here - --> $DIR/liveness-upvars.rs:3:9 + --> $DIR/liveness-upvars.rs:4:9 | LL | #![warn(unused)] | ^^^^^^ @@ -13,13 +13,13 @@ LL | #![warn(unused)] = help: maybe it is overwritten before being read? warning: unused variable: `last` - --> $DIR/liveness-upvars.rs:9:9 + --> $DIR/liveness-upvars.rs:10:9 | LL | last = Some(s); | ^^^^ | note: the lint level is defined here - --> $DIR/liveness-upvars.rs:3:9 + --> $DIR/liveness-upvars.rs:4:9 | LL | #![warn(unused)] | ^^^^^^ @@ -27,7 +27,7 @@ LL | #![warn(unused)] = help: did you mean to capture by reference instead? warning: unused variable: `sum` - --> $DIR/liveness-upvars.rs:21:9 + --> $DIR/liveness-upvars.rs:22:9 | LL | sum += x; | ^^^ @@ -35,7 +35,7 @@ LL | sum += x; = help: did you mean to capture by reference instead? warning: value captured by `c` is never read - --> $DIR/liveness-upvars.rs:31:9 + --> $DIR/liveness-upvars.rs:32:9 | LL | c = 1; | ^ @@ -43,7 +43,7 @@ LL | c = 1; = help: did you mean to capture by reference instead? warning: value captured by `c` is never read - --> $DIR/liveness-upvars.rs:35:9 + --> $DIR/liveness-upvars.rs:36:9 | LL | c = 1; | ^ @@ -51,7 +51,7 @@ LL | c = 1; = help: did you mean to capture by reference instead? warning: unused variable: `c` - --> $DIR/liveness-upvars.rs:41:9 + --> $DIR/liveness-upvars.rs:42:9 | LL | c += 1; | ^ @@ -59,7 +59,7 @@ LL | c += 1; = help: did you mean to capture by reference instead? warning: value assigned to `c` is never read - --> $DIR/liveness-upvars.rs:44:9 + --> $DIR/liveness-upvars.rs:45:9 | LL | c += 1; | ^ @@ -67,7 +67,7 @@ LL | c += 1; = help: maybe it is overwritten before being read? warning: unused variable: `c` - --> $DIR/liveness-upvars.rs:44:9 + --> $DIR/liveness-upvars.rs:45:9 | LL | c += 1; | ^ @@ -75,7 +75,7 @@ LL | c += 1; = help: did you mean to capture by reference instead? warning: value assigned to `c` is never read - --> $DIR/liveness-upvars.rs:57:9 + --> $DIR/liveness-upvars.rs:58:9 | LL | c += 1; | ^ @@ -83,7 +83,7 @@ LL | c += 1; = help: maybe it is overwritten before being read? warning: value assigned to `c` is never read - --> $DIR/liveness-upvars.rs:63:9 + --> $DIR/liveness-upvars.rs:64:9 | LL | c += 1; | ^ @@ -91,7 +91,7 @@ LL | c += 1; = help: maybe it is overwritten before being read? warning: value assigned to `d` is never read - --> $DIR/liveness-upvars.rs:72:13 + --> $DIR/liveness-upvars.rs:73:13 | LL | d = Some("d1"); | ^ @@ -99,7 +99,7 @@ LL | d = Some("d1"); = help: maybe it is overwritten before being read? warning: value assigned to `e` is never read - --> $DIR/liveness-upvars.rs:76:13 + --> $DIR/liveness-upvars.rs:77:13 | LL | e = Some("e1"); | ^ @@ -107,7 +107,7 @@ LL | e = Some("e1"); = help: maybe it is overwritten before being read? warning: value assigned to `e` is never read - --> $DIR/liveness-upvars.rs:78:13 + --> $DIR/liveness-upvars.rs:79:13 | LL | e = Some("e2"); | ^ @@ -115,7 +115,7 @@ LL | e = Some("e2"); = help: maybe it is overwritten before being read? warning: unused variable: `e` - --> $DIR/liveness-upvars.rs:76:13 + --> $DIR/liveness-upvars.rs:77:13 | LL | e = Some("e1"); | ^ @@ -123,7 +123,7 @@ LL | e = Some("e1"); = help: did you mean to capture by reference instead? warning: value assigned to `v` is never read - --> $DIR/liveness-upvars.rs:86:13 + --> $DIR/liveness-upvars.rs:87:13 | LL | v = T::default(); | ^ @@ -131,7 +131,7 @@ LL | v = T::default(); = help: maybe it is overwritten before being read? warning: value assigned to `z` is never read - --> $DIR/liveness-upvars.rs:98:17 + --> $DIR/liveness-upvars.rs:99:17 | LL | z = T::default(); | ^ @@ -139,12 +139,52 @@ LL | z = T::default(); = help: maybe it is overwritten before being read? warning: unused variable: `z` - --> $DIR/liveness-upvars.rs:98:17 + --> $DIR/liveness-upvars.rs:99:17 | LL | z = T::default(); | ^ | = help: did you mean to capture by reference instead? -warning: 17 warnings emitted +warning: value assigned to `state` is never read + --> $DIR/liveness-upvars.rs:125:9 + | +LL | state = 4; + | ^^^^^ + | + = help: maybe it is overwritten before being read? + +warning: value assigned to `state` is never read + --> $DIR/liveness-upvars.rs:128:9 + | +LL | state = 5; + | ^^^^^ + | + = help: maybe it is overwritten before being read? + +warning: unused variable: `state` + --> $DIR/liveness-upvars.rs:125:9 + | +LL | state = 4; + | ^^^^^ + | + = help: did you mean to capture by reference instead? + +warning: value assigned to `s` is never read + --> $DIR/liveness-upvars.rs:137:9 + | +LL | s = 1; + | ^ + | + = help: maybe it is overwritten before being read? + +warning: value assigned to `s` is never read + --> $DIR/liveness-upvars.rs:139:9 + | +LL | s = yield (); + | ^ + | + = help: maybe it is overwritten before being read? + +warning: 22 warnings emitted