about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2017-10-07 16:36:28 +0200
committerJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2018-01-23 05:10:38 +0100
commitccf0d8399e1ef3ed6bf7005650ce42aa646b5cc7 (patch)
tree78166bd01ee1a24b9251e6cdf16dd631d3cf65e1 /src/test
parent47a8eb7c4e24b61a8a9ab4eaff60ef65291aaa56 (diff)
downloadrust-ccf0d8399e1ef3ed6bf7005650ce42aa646b5cc7.tar.gz
rust-ccf0d8399e1ef3ed6bf7005650ce42aa646b5cc7.zip
Adds support for immovable generators. Move checking of invalid borrows across suspension points to borrowck. Fixes #44197, #45259 and #45093.
Diffstat (limited to 'src/test')
-rw-r--r--src/test/compile-fail/static-closures.rs14
-rw-r--r--src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs6
-rw-r--r--src/test/run-pass/generator/issue-44197.rs40
-rw-r--r--src/test/run-pass/generator/live-upvar-across-yield.rs21
-rw-r--r--src/test/run-pass/generator/nested_generators.rs30
-rw-r--r--src/test/run-pass/generator/reborrow-mut-upvar.rs24
-rw-r--r--src/test/run-pass/generator/static-generators.rs24
-rw-r--r--src/test/ui/generator/auto-trait-regions.rs58
-rw-r--r--src/test/ui/generator/auto-trait-regions.stderr35
-rw-r--r--src/test/ui/generator/not-send-sync.stderr8
10 files changed, 255 insertions, 5 deletions
diff --git a/src/test/compile-fail/static-closures.rs b/src/test/compile-fail/static-closures.rs
new file mode 100644
index 00000000000..8593eb5333e
--- /dev/null
+++ b/src/test/compile-fail/static-closures.rs
@@ -0,0 +1,14 @@
+// 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.
+
+fn main() {
+    static || {};
+    //~^ ERROR closures cannot be static
+}
diff --git a/src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs b/src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs
index 5afa9a217e0..10c44c8044b 100644
--- a/src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs
+++ b/src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs
@@ -142,7 +142,11 @@ fn iter_exprs(depth: usize, f: &mut FnMut(P<Expr>)) {
                     variadic: false,
                 });
                 iter_exprs(depth - 1, &mut |e| g(
-                        ExprKind::Closure(CaptureBy::Value, decl.clone(), e, DUMMY_SP)));
+                        ExprKind::Closure(CaptureBy::Value,
+                                          Movability::Movable,
+                                          decl.clone(),
+                                          e,
+                                          DUMMY_SP)));
             },
             10 => {
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::Assign(e, make_x())));
diff --git a/src/test/run-pass/generator/issue-44197.rs b/src/test/run-pass/generator/issue-44197.rs
new file mode 100644
index 00000000000..7cb80ea8b21
--- /dev/null
+++ b/src/test/run-pass/generator/issue-44197.rs
@@ -0,0 +1,40 @@
+// 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(conservative_impl_trait, generators, generator_trait)]
+
+use std::ops::{ Generator, GeneratorState };
+
+fn foo(_: &str) -> String {
+    String::new()
+}
+
+fn bar(baz: String) -> impl Generator<Yield = String, Return = ()> {
+    move || {
+        yield foo(&baz);
+    }
+}
+
+fn foo2(_: &str) -> Result<String, ()> {
+    Err(())
+}
+
+fn bar2(baz: String) -> impl Generator<Yield = String, Return = ()> {
+    move || {
+        if let Ok(quux) = foo2(&baz) {
+            yield quux;
+        }
+    }
+}
+
+fn main() {
+    assert_eq!(bar(String::new()).resume(), GeneratorState::Yielded(String::new()));
+    assert_eq!(bar2(String::new()).resume(), GeneratorState::Complete(()));
+}
diff --git a/src/test/run-pass/generator/live-upvar-across-yield.rs b/src/test/run-pass/generator/live-upvar-across-yield.rs
new file mode 100644
index 00000000000..e34b0b3100c
--- /dev/null
+++ b/src/test/run-pass/generator/live-upvar-across-yield.rs
@@ -0,0 +1,21 @@
+// 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::Generator;
+
+fn main() {
+    let b = |_| 3;
+    let mut a = || {
+        b(yield);
+    };
+    a.resume();
+}
diff --git a/src/test/run-pass/generator/nested_generators.rs b/src/test/run-pass/generator/nested_generators.rs
new file mode 100644
index 00000000000..f70d4144a3c
--- /dev/null
+++ b/src/test/run-pass/generator/nested_generators.rs
@@ -0,0 +1,30 @@
+// 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)]
+#![feature(generator_trait)]
+
+use std::ops::Generator;
+use std::ops::GeneratorState;
+
+fn main() {
+    let _generator = || {
+        let mut sub_generator = || {
+            yield 2;
+        };
+
+        match sub_generator.resume() {
+            GeneratorState::Yielded(x) => {
+                yield x;
+            }
+            _ => panic!(),
+        };
+    };
+}
diff --git a/src/test/run-pass/generator/reborrow-mut-upvar.rs b/src/test/run-pass/generator/reborrow-mut-upvar.rs
new file mode 100644
index 00000000000..8353066bfbe
--- /dev/null
+++ b/src/test/run-pass/generator/reborrow-mut-upvar.rs
@@ -0,0 +1,24 @@
+// 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)]
+
+fn _run(bar: &mut i32) {
+    || {
+        {
+            let _baz = &*bar;
+            yield;
+        }
+
+        *bar = 2;
+    };
+}
+
+fn main() {}
diff --git a/src/test/run-pass/generator/static-generators.rs b/src/test/run-pass/generator/static-generators.rs
new file mode 100644
index 00000000000..daf67294246
--- /dev/null
+++ b/src/test/run-pass/generator/static-generators.rs
@@ -0,0 +1,24 @@
+// 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::{Generator, GeneratorState};
+
+fn main() {
+    let mut generator = static || {
+        let a = true;
+        let b = &a;
+        yield;
+        assert_eq!(b as *const _, &a as *const _);
+    };
+    assert_eq!(generator.resume(), GeneratorState::Yielded(()));
+    assert_eq!(generator.resume(), GeneratorState::Complete(()));
+}
\ No newline at end of file
diff --git a/src/test/ui/generator/auto-trait-regions.rs b/src/test/ui/generator/auto-trait-regions.rs
new file mode 100644
index 00000000000..ac2a414b742
--- /dev/null
+++ b/src/test/ui/generator/auto-trait-regions.rs
@@ -0,0 +1,58 @@
+// 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)]
+#![feature(optin_builtin_traits)]
+
+auto trait Foo {}
+
+struct No;
+
+impl !Foo for No {}
+
+struct A<'a, 'b>(&'a mut bool, &'b mut bool, No);
+
+impl<'a, 'b: 'a> Foo for A<'a, 'b> {}
+
+struct OnlyFooIfStaticRef(No);
+impl Foo for &'static OnlyFooIfStaticRef {}
+
+struct OnlyFooIfRef(No);
+impl<'a> Foo for &'a OnlyFooIfRef {}
+
+fn assert_foo<T: Foo>(f: T) {}
+
+fn main() {
+    // Make sure 'static is erased for generator interiors so we can't match it in trait selection
+    let x: &'static _ = &OnlyFooIfStaticRef(No);
+    let gen = || {
+        let x = x;
+        yield;
+        assert_foo(x);
+    };
+    assert_foo(gen); //~ ERROR the trait bound `No: Foo` is not satisfied
+
+    // Allow impls which matches any lifetime
+    let x = &OnlyFooIfRef(No);
+    let gen = || {
+        let x = x;
+        yield;
+        assert_foo(x);
+    };
+    assert_foo(gen); // ok
+
+    // Disallow impls which relates lifetimes in the generator interior
+    let gen = || {
+        let a = A(&mut true, &mut true, No);
+        yield;
+        assert_foo(a);
+    };
+    assert_foo(gen); //~ ERROR the requirement `for<'r, 's> 'r : 's` is not satisfied
+}
diff --git a/src/test/ui/generator/auto-trait-regions.stderr b/src/test/ui/generator/auto-trait-regions.stderr
new file mode 100644
index 00000000000..37241e61510
--- /dev/null
+++ b/src/test/ui/generator/auto-trait-regions.stderr
@@ -0,0 +1,35 @@
+error[E0277]: the trait bound `No: Foo` is not satisfied in `[generator@$DIR/auto-trait-regions.rs:35:15: 39:6 x:&&'static OnlyFooIfStaticRef for<'r> {&'r OnlyFooIfStaticRef, ()}]`
+  --> $DIR/auto-trait-regions.rs:40:5
+   |
+40 |     assert_foo(gen); //~ ERROR the trait bound `No: Foo` is not satisfied
+   |     ^^^^^^^^^^ within `[generator@$DIR/auto-trait-regions.rs:35:15: 39:6 x:&&'static OnlyFooIfStaticRef for<'r> {&'r OnlyFooIfStaticRef, ()}]`, the trait `Foo` is not implemented for `No`
+   |
+   = help: the following implementations were found:
+             <No as Foo>
+   = note: required because it appears within the type `OnlyFooIfStaticRef`
+   = note: required because it appears within the type `&OnlyFooIfStaticRef`
+   = note: required because it appears within the type `for<'r> {&'r OnlyFooIfStaticRef, ()}`
+   = note: required because it appears within the type `[generator@$DIR/auto-trait-regions.rs:35:15: 39:6 x:&&'static OnlyFooIfStaticRef for<'r> {&'r OnlyFooIfStaticRef, ()}]`
+note: required by `assert_foo`
+  --> $DIR/auto-trait-regions.rs:30:1
+   |
+30 | fn assert_foo<T: Foo>(f: T) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0279]: the requirement `for<'r, 's> 'r : 's` is not satisfied (`expected bound lifetime parameter, found concrete lifetime`)
+  --> $DIR/auto-trait-regions.rs:57:5
+   |
+57 |     assert_foo(gen); //~ ERROR the requirement `for<'r, 's> 'r : 's` is not satisfied
+   |     ^^^^^^^^^^
+   |
+   = note: required because of the requirements on the impl of `for<'r, 's> Foo` for `A<'_, '_>`
+   = note: required because it appears within the type `for<'r, 's> {A<'r, 's>, ()}`
+   = note: required because it appears within the type `[generator@$DIR/auto-trait-regions.rs:52:15: 56:6 for<'r, 's> {A<'r, 's>, ()}]`
+note: required by `assert_foo`
+  --> $DIR/auto-trait-regions.rs:30:1
+   |
+30 | fn assert_foo<T: Foo>(f: T) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/generator/not-send-sync.stderr b/src/test/ui/generator/not-send-sync.stderr
index d30255335a6..e65c8f1546e 100644
--- a/src/test/ui/generator/not-send-sync.stderr
+++ b/src/test/ui/generator/not-send-sync.stderr
@@ -13,15 +13,15 @@ note: required by `main::assert_send`
 17 |     fn assert_send<T: Send>(_: T) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0277]: the trait bound `std::cell::Cell<i32>: std::marker::Sync` is not satisfied in `[generator@$DIR/not-send-sync.rs:19:17: 23:6 (std::cell::Cell<i32>, ())]`
+error[E0277]: the trait bound `std::cell::Cell<i32>: std::marker::Sync` is not satisfied in `[generator@$DIR/not-send-sync.rs:19:17: 23:6 {std::cell::Cell<i32>, ()}]`
   --> $DIR/not-send-sync.rs:19:5
    |
 19 |     assert_sync(|| {
    |     ^^^^^^^^^^^ `std::cell::Cell<i32>` cannot be shared between threads safely
    |
-   = help: within `[generator@$DIR/not-send-sync.rs:19:17: 23:6 (std::cell::Cell<i32>, ())]`, the trait `std::marker::Sync` is not implemented for `std::cell::Cell<i32>`
-   = note: required because it appears within the type `(std::cell::Cell<i32>, ())`
-   = note: required because it appears within the type `[generator@$DIR/not-send-sync.rs:19:17: 23:6 (std::cell::Cell<i32>, ())]`
+   = help: within `[generator@$DIR/not-send-sync.rs:19:17: 23:6 {std::cell::Cell<i32>, ()}]`, the trait `std::marker::Sync` is not implemented for `std::cell::Cell<i32>`
+   = note: required because it appears within the type `{std::cell::Cell<i32>, ()}`
+   = note: required because it appears within the type `[generator@$DIR/not-send-sync.rs:19:17: 23:6 {std::cell::Cell<i32>, ()}]`
 note: required by `main::assert_sync`
   --> $DIR/not-send-sync.rs:16:5
    |