summary refs log tree commit diff
path: root/src/test/ui/generator/yield-while-iterating.rs
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2017-07-15 06:52:49 -0400
committerJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2017-07-28 15:46:27 +0200
commit3fdc3fa1ec091d4bec006e0201d29ce54dcbf430 (patch)
treecf460785b62304b47839e132e5614caf3e2bac03 /src/test/ui/generator/yield-while-iterating.rs
parent188cdf499f5fd6fdce0382367944e0f2a56026f8 (diff)
downloadrust-3fdc3fa1ec091d4bec006e0201d29ce54dcbf430.tar.gz
rust-3fdc3fa1ec091d4bec006e0201d29ce54dcbf430.zip
change how we report `err_out_of_scope` borrowck errors
Also, remove the explicit code detecting borrows over a yield.  It
turns out not to be necessary -- any such borrow winds up with a
lifetime that is part of the generator type, and therefore which will
outlive the generator expression itself, which yields an
`err_out_of_scope`. So instead we intercept those errors and display
them in a nicer way.
Diffstat (limited to 'src/test/ui/generator/yield-while-iterating.rs')
-rw-r--r--src/test/ui/generator/yield-while-iterating.rs84
1 files changed, 84 insertions, 0 deletions
diff --git a/src/test/ui/generator/yield-while-iterating.rs b/src/test/ui/generator/yield-while-iterating.rs
new file mode 100644
index 00000000000..fd260339efb
--- /dev/null
+++ b/src/test/ui/generator/yield-while-iterating.rs
@@ -0,0 +1,84 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(generators, generator_trait)]
+
+use std::ops::{State, Generator};
+use std::cell::Cell;
+
+fn yield_during_iter_owned_data(x: Vec<i32>) {
+    // The generator owns `x`, so we error out when yielding with a
+    // reference to it.  This winds up becoming a rather confusing
+    // regionck error -- in particular, we would freeze with the
+    // reference in scope, and it doesn't live long enough.
+    let _b = move || {
+        for p in &x { //~ ERROR
+            yield();
+        }
+    };
+}
+
+fn yield_during_iter_borrowed_slice(x: &[i32]) {
+    let _b = move || {
+        for p in x {
+            yield();
+        }
+    };
+}
+
+fn yield_during_iter_borrowed_slice_2() {
+    let mut x = vec![22_i32];
+    let _b = || {
+        for p in &x {
+            yield();
+        }
+    };
+    println!("{:?}", x);
+}
+
+fn yield_during_iter_borrowed_slice_3() {
+    // OK to take a mutable ref to `x` and yield
+    // up pointers from it:
+    let mut x = vec![22_i32];
+    let mut b = || {
+        for p in &mut x {
+            yield p;
+        }
+    };
+    b.resume();
+}
+
+fn yield_during_iter_borrowed_slice_4() {
+    // ...but not OK to do that while reading
+    // from `x` too
+    let mut x = vec![22_i32];
+    let mut b = || {
+        for p in &mut x {
+            yield p;
+        }
+    };
+    println!("{}", x[0]); //~ ERROR
+    b.resume();
+}
+
+fn yield_during_range_iter() {
+    // Should be OK.
+    let mut b = || {
+        let v = vec![1,2,3];
+        let len = v.len();
+        for i in 0..len {
+            let x = v[i];
+            yield x;
+        }
+    };
+    b.resume();
+}
+
+fn main() { }