about summary refs log tree commit diff
path: root/src/test
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
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')
-rw-r--r--src/test/ui/generator/ref-escapes-but-not-over-yield.rs28
-rw-r--r--src/test/ui/generator/ref-escapes-but-not-over-yield.stderr12
-rw-r--r--src/test/ui/generator/yield-in-args-rev.rs (renamed from src/test/compile-fail/generator/yield-in-args-rev.rs)8
-rw-r--r--src/test/ui/generator/yield-in-args-rev.stderr10
-rw-r--r--src/test/ui/generator/yield-in-args.rs (renamed from src/test/compile-fail/generator/yield-in-args.rs)8
-rw-r--r--src/test/ui/generator/yield-in-args.stderr8
-rw-r--r--src/test/ui/generator/yield-while-iterating.rs (renamed from src/test/compile-fail/generator/yield-during-borrow.rs)92
-rw-r--r--src/test/ui/generator/yield-while-iterating.stderr24
-rw-r--r--src/test/ui/generator/yield-while-local-borrowed.rs56
-rw-r--r--src/test/ui/generator/yield-while-local-borrowed.stderr18
-rw-r--r--src/test/ui/generator/yield-while-ref-reborrowed.rs49
-rw-r--r--src/test/ui/generator/yield-while-ref-reborrowed.stderr16
12 files changed, 245 insertions, 84 deletions
diff --git a/src/test/ui/generator/ref-escapes-but-not-over-yield.rs b/src/test/ui/generator/ref-escapes-but-not-over-yield.rs
new file mode 100644
index 00000000000..8d77eb92a63
--- /dev/null
+++ b/src/test/ui/generator/ref-escapes-but-not-over-yield.rs
@@ -0,0 +1,28 @@
+// 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 foo(x: &i32) {
+    // In this case, a reference to `b` escapes the generator, but not
+    // because of a yield. We see that there is no yield in the scope of
+    // `b` and give the more generic error message.
+    let mut a = &3;
+    let mut b = move || {
+        yield();
+        let b = 5;
+        a = &b; //~ ERROR
+    };
+}
+
+fn main() { }
diff --git a/src/test/ui/generator/ref-escapes-but-not-over-yield.stderr b/src/test/ui/generator/ref-escapes-but-not-over-yield.stderr
new file mode 100644
index 00000000000..e30d28c2db8
--- /dev/null
+++ b/src/test/ui/generator/ref-escapes-but-not-over-yield.stderr
@@ -0,0 +1,12 @@
+error[E0597]: `b` does not live long enough
+  --> $DIR/ref-escapes-but-not-over-yield.rs:25:5
+   |
+24 |         a = &b; //~ ERROR
+   |              - borrow occurs here
+25 |     };
+   |     ^ `b` dropped here while still borrowed
+26 | }
+   | - borrowed value needs to live until here
+
+error: aborting due to previous error
+
diff --git a/src/test/compile-fail/generator/yield-in-args-rev.rs b/src/test/ui/generator/yield-in-args-rev.rs
index 6d220abe2b5..0d2e9a85de1 100644
--- a/src/test/compile-fail/generator/yield-in-args-rev.rs
+++ b/src/test/ui/generator/yield-in-args-rev.rs
@@ -15,10 +15,10 @@ fn foo(_a: (), _b: &bool) {}
 // Some examples that probably *could* be accepted, but which we reject for now.
 
 fn bar() {
-    || {
-        let b = true;
-        foo(yield, &b);
-    }; //~ ERROR `b` does not live long enough
+	|| {
+		let b = true;
+		foo(yield, &b); //~ ERROR
+	};
 }
 
 fn main() { }
diff --git a/src/test/ui/generator/yield-in-args-rev.stderr b/src/test/ui/generator/yield-in-args-rev.stderr
new file mode 100644
index 00000000000..8f30089fc71
--- /dev/null
+++ b/src/test/ui/generator/yield-in-args-rev.stderr
@@ -0,0 +1,10 @@
+error[E0624]: borrow may still be in use when generator yields
+  --> $DIR/yield-in-args-rev.rs:20:15
+   |
+20 | \t\tfoo(yield, &b); //~ ERROR
+   | \t\t    -----   ^
+   | \t\t    |
+   | \t\t    possible yield occurs here
+
+error: aborting due to previous error
+
diff --git a/src/test/compile-fail/generator/yield-in-args.rs b/src/test/ui/generator/yield-in-args.rs
index 5c8d65067d6..c2fcfa5cdc2 100644
--- a/src/test/compile-fail/generator/yield-in-args.rs
+++ b/src/test/ui/generator/yield-in-args.rs
@@ -13,8 +13,8 @@
 fn foo(_b: &bool, _a: ()) {}
 
 fn main() {
-    || {
-        let b = true;
-        foo(&b, yield);
-    }; //~ ERROR `b` does not live long enough
+	|| {
+		let b = true;
+		foo(&b, yield); //~ ERROR
+	};
 }
diff --git a/src/test/ui/generator/yield-in-args.stderr b/src/test/ui/generator/yield-in-args.stderr
new file mode 100644
index 00000000000..e4c31ef36c9
--- /dev/null
+++ b/src/test/ui/generator/yield-in-args.stderr
@@ -0,0 +1,8 @@
+error[E0624]: borrow may still be in use when generator yields
+  --> $DIR/yield-in-args.rs:18:8
+   |
+18 | \t\tfoo(&b, yield); //~ ERROR
+   | \t\t     ^  ----- possible yield occurs here
+
+error: aborting due to previous error
+
diff --git a/src/test/compile-fail/generator/yield-during-borrow.rs b/src/test/ui/generator/yield-while-iterating.rs
index 46732ce6599..fd260339efb 100644
--- a/src/test/compile-fail/generator/yield-during-borrow.rs
+++ b/src/test/ui/generator/yield-while-iterating.rs
@@ -13,89 +13,16 @@
 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 {
+        for p in &x { //~ ERROR
             yield();
         }
-    }; //~ ERROR E0597
+    };
 }
 
 fn yield_during_iter_borrowed_slice(x: &[i32]) {
@@ -137,7 +64,20 @@ fn yield_during_iter_borrowed_slice_4() {
             yield p;
         }
     };
-    println!("{}", x[0]); //~ ERROR cannot borrow `x` as immutable
+    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();
 }
 
diff --git a/src/test/ui/generator/yield-while-iterating.stderr b/src/test/ui/generator/yield-while-iterating.stderr
new file mode 100644
index 00000000000..775c36a3df4
--- /dev/null
+++ b/src/test/ui/generator/yield-while-iterating.stderr
@@ -0,0 +1,24 @@
+error[E0624]: borrow may still be in use when generator yields
+  --> $DIR/yield-while-iterating.rs:22:19
+   |
+22 |         for p in &x { //~ ERROR
+   |                   ^
+23 |             yield();
+   |             ------- possible yield occurs here
+
+error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable
+  --> $DIR/yield-while-iterating.rs:67:20
+   |
+62 |     let mut b = || {
+   |                 -- mutable borrow occurs here
+63 |         for p in &mut x {
+   |                       - previous borrow occurs due to use of `x` in closure
+...
+67 |     println!("{}", x[0]); //~ ERROR
+   |                    ^ immutable borrow occurs here
+68 |     b.resume();
+69 | }
+   | - mutable borrow ends here
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/generator/yield-while-local-borrowed.rs b/src/test/ui/generator/yield-while-local-borrowed.rs
new file mode 100644
index 00000000000..b3e6dedf291
--- /dev/null
+++ b/src/test/ui/generator/yield-while-local-borrowed.rs
@@ -0,0 +1,56 @@
+// 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; //~ ERROR
+        yield();
+        println!("{}", a);
+    };
+    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; //~ ERROR
+            yield();
+            println!("{}", b);
+        }
+    };
+    b.resume();
+}
+
+fn main() { }
diff --git a/src/test/ui/generator/yield-while-local-borrowed.stderr b/src/test/ui/generator/yield-while-local-borrowed.stderr
new file mode 100644
index 00000000000..1e333a33db6
--- /dev/null
+++ b/src/test/ui/generator/yield-while-local-borrowed.stderr
@@ -0,0 +1,18 @@
+error[E0624]: borrow may still be in use when generator yields
+  --> $DIR/yield-while-local-borrowed.rs:22:18
+   |
+22 |         let a = &3; //~ ERROR
+   |                  ^
+23 |         yield();
+   |         ------- possible yield occurs here
+
+error[E0624]: borrow may still be in use when generator yields
+  --> $DIR/yield-while-local-borrowed.rs:48:22
+   |
+48 |             let b = &a; //~ ERROR
+   |                      ^
+49 |             yield();
+   |             ------- possible yield occurs here
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/generator/yield-while-ref-reborrowed.rs b/src/test/ui/generator/yield-while-ref-reborrowed.rs
new file mode 100644
index 00000000000..7b6246b1578
--- /dev/null
+++ b/src/test/ui/generator/yield-while-ref-reborrowed.rs
@@ -0,0 +1,49 @@
+// 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 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
+    b.resume();
+}
+
+fn main() { }
diff --git a/src/test/ui/generator/yield-while-ref-reborrowed.stderr b/src/test/ui/generator/yield-while-ref-reborrowed.stderr
new file mode 100644
index 00000000000..7269f729737
--- /dev/null
+++ b/src/test/ui/generator/yield-while-ref-reborrowed.stderr
@@ -0,0 +1,16 @@
+error[E0501]: cannot borrow `x` as immutable because previous closure requires unique access
+  --> $DIR/yield-while-ref-reborrowed.rs:45:20
+   |
+40 |     let mut b = || {
+   |                 -- closure construction occurs here
+41 |         let a = &mut *x;
+   |                       - previous borrow occurs due to use of `x` in closure
+...
+45 |     println!("{}", x); //~ ERROR
+   |                    ^ borrow occurs here
+46 |     b.resume();
+47 | }
+   | - borrow from closure ends here
+
+error: aborting due to previous error
+