diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2017-07-15 06:52:49 -0400 |
|---|---|---|
| committer | John Kåre Alsaker <john.kare.alsaker@gmail.com> | 2017-07-28 15:46:27 +0200 |
| commit | 3fdc3fa1ec091d4bec006e0201d29ce54dcbf430 (patch) | |
| tree | cf460785b62304b47839e132e5614caf3e2bac03 /src/test | |
| parent | 188cdf499f5fd6fdce0382367944e0f2a56026f8 (diff) | |
| download | rust-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.rs | 28 | ||||
| -rw-r--r-- | src/test/ui/generator/ref-escapes-but-not-over-yield.stderr | 12 | ||||
| -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.stderr | 10 | ||||
| -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.stderr | 8 | ||||
| -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.stderr | 24 | ||||
| -rw-r--r-- | src/test/ui/generator/yield-while-local-borrowed.rs | 56 | ||||
| -rw-r--r-- | src/test/ui/generator/yield-while-local-borrowed.stderr | 18 | ||||
| -rw-r--r-- | src/test/ui/generator/yield-while-ref-reborrowed.rs | 49 | ||||
| -rw-r--r-- | src/test/ui/generator/yield-while-ref-reborrowed.stderr | 16 |
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 + |
