about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2017-07-14 19:02:07 -0400
committerJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2017-07-28 15:46:25 +0200
commit264c3f4952f1ff182502aa0885ca479c42cec17c (patch)
tree91b0e57d06ff70e11cb286d060b1764a97383b4e /src
parent8e82b19c6b293aca9ad8bbcb755346803d1eb61d (diff)
downloadrust-264c3f4952f1ff182502aa0885ca479c42cec17c.tar.gz
rust-264c3f4952f1ff182502aa0885ca479c42cec17c.zip
add some tests of yielding with outstanding borrows
No doubt there are more tests one might write, but it's a start.
Diffstat (limited to 'src')
-rw-r--r--src/test/compile-fail/generator/yield-during-borrow.rs144
1 files changed, 144 insertions, 0 deletions
diff --git a/src/test/compile-fail/generator/yield-during-borrow.rs b/src/test/compile-fail/generator/yield-during-borrow.rs
new file mode 100644
index 00000000000..46732ce6599
--- /dev/null
+++ b/src/test/compile-fail/generator/yield-during-borrow.rs
@@ -0,0 +1,144 @@
+// 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 borrow_local_inline() {
+    // Not OK to yield with a borrow of a temporary.
+    //
+    // (This error occurs because the region shows up in the type of
+    // `b` and gets extended by region inference.)
+    let mut b = move || {
+        let a = &3;
+        yield();
+        println!("{}", a);
+    }; //~ ERROR E0597
+    b.resume();
+}
+
+fn borrow_local_inline_done() {
+    // No error here -- `a` is not in scope at the point of `yield`.
+    let mut b = move || {
+        {
+            let a = &3;
+        }
+        yield();
+    };
+    b.resume();
+}
+
+fn borrow_local() {
+    // Not OK to yield with a borrow of a temporary.
+    //
+    // (This error occurs because the region shows up in the type of
+    // `b` and gets extended by region inference.)
+    let mut b = move || {
+        let a = 3;
+        {
+            let b = &a;
+            yield();
+            println!("{}", b);
+        }
+    }; //~ ERROR E0597
+    b.resume();
+}
+
+fn reborrow_shared_ref(x: &i32) {
+    // This is OK -- we have a borrow live over the yield, but it's of
+    // data that outlives the generator.
+    let mut b = move || {
+        let a = &*x;
+        yield();
+        println!("{}", a);
+    };
+    b.resume();
+}
+
+fn reborrow_mutable_ref(x: &mut i32) {
+    // This is OK -- we have a borrow live over the yield, but it's of
+    // data that outlives the generator.
+    let mut b = move || {
+        let a = &mut *x;
+        yield();
+        println!("{}", a);
+    };
+    b.resume();
+}
+
+fn reborrow_mutable_ref_2(x: &mut i32) {
+    // ...but not OK to go on using `x`.
+    let mut b = || {
+        let a = &mut *x;
+        yield();
+        println!("{}", a);
+    };
+    println!("{}", x); //~ ERROR E0501
+    b.resume();
+}
+
+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 {
+            yield();
+        }
+    }; //~ ERROR E0597
+}
+
+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 cannot borrow `x` as immutable
+    b.resume();
+}
+
+fn main() { }