about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_passes/src/liveness.rs14
-rw-r--r--src/test/ui/liveness/liveness-upvars.rs36
-rw-r--r--src/test/ui/liveness/liveness-upvars.stderr80
3 files changed, 107 insertions, 23 deletions
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs
index 72889bc49d0..ab9bfea9694 100644
--- a/compiler/rustc_passes/src/liveness.rs
+++ b/compiler/rustc_passes/src/liveness.rs
@@ -428,7 +428,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);
             }
@@ -462,7 +465,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(..))
@@ -856,6 +858,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)
@@ -1015,7 +1024,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 98ea4d71ccf..d446d57d396 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<T: Copy + Default + std::fmt::Debug>() {
     };
 }
 
+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 14fed917864..d1723302513 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