diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2017-07-14 19:02:07 -0400 |
|---|---|---|
| committer | John Kåre Alsaker <john.kare.alsaker@gmail.com> | 2017-07-28 15:46:25 +0200 |
| commit | 264c3f4952f1ff182502aa0885ca479c42cec17c (patch) | |
| tree | 91b0e57d06ff70e11cb286d060b1764a97383b4e /src | |
| parent | 8e82b19c6b293aca9ad8bbcb755346803d1eb61d (diff) | |
| download | rust-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.rs | 144 |
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() { } |
