about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorEduard Burtescu <edy.burt@gmail.com>2016-07-28 18:27:11 +0300
committerEduard Burtescu <edy.burt@gmail.com>2016-08-12 06:46:31 +0300
commit08bf9f69b9cd96cf2871af1c2ec4dad0258728f2 (patch)
tree970287c7db6efa4dd9c51c236cb547ae9591dfc2 /src/test
parentd92e594c3801a8066f95305c87e53a7ecfb24e9b (diff)
downloadrust-08bf9f69b9cd96cf2871af1c2ec4dad0258728f2.tar.gz
rust-08bf9f69b9cd96cf2871af1c2ec4dad0258728f2.zip
typeck: leak auto trait obligations through impl Trait.
Diffstat (limited to 'src/test')
-rw-r--r--src/test/compile-fail/impl-trait/auto-trait-leak.rs70
-rw-r--r--src/test/run-pass/impl-trait/auto-trait-leak.rs44
2 files changed, 114 insertions, 0 deletions
diff --git a/src/test/compile-fail/impl-trait/auto-trait-leak.rs b/src/test/compile-fail/impl-trait/auto-trait-leak.rs
new file mode 100644
index 00000000000..2c78ce2db29
--- /dev/null
+++ b/src/test/compile-fail/impl-trait/auto-trait-leak.rs
@@ -0,0 +1,70 @@
+// Copyright 2016 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.
+
+// ignore-tidy-linelength
+
+#![feature(conservative_impl_trait)]
+
+use std::cell::Cell;
+use std::rc::Rc;
+
+// Fast path, main can see the concrete type returned.
+fn before() -> impl Fn(i32) {
+    let p = Rc::new(Cell::new(0));
+    move |x| p.set(x)
+}
+
+fn send<T: Send>(_: T) {}
+
+fn main() {
+    send(before());
+    //~^ ERROR the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` is not satisfied
+    //~| NOTE `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
+    //~| NOTE required because it appears within the type `[closure
+    //~| NOTE required because it appears within the type `impl std::ops::Fn<(i32,)>`
+    //~| NOTE required by `send`
+
+    send(after());
+    //~^ ERROR the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` is not satisfied
+    //~| NOTE `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
+    //~| NOTE required because it appears within the type `[closure
+    //~| NOTE required because it appears within the type `impl std::ops::Fn<(i32,)>`
+    //~| NOTE required by `send`
+}
+
+// Deferred path, main has to wait until typeck finishes,
+// to check if the return type of after is Send.
+fn after() -> impl Fn(i32) {
+    let p = Rc::new(Cell::new(0));
+    move |x| p.set(x)
+}
+
+// Cycles should work as the deferred obligations are
+// independently resolved and only require the concrete
+// return type, which can't depend on the obligation.
+fn cycle1() -> impl Clone {
+    send(cycle2().clone());
+    //~^ ERROR the trait bound `std::rc::Rc<std::string::String>: std::marker::Send` is not satisfied
+    //~| NOTE `std::rc::Rc<std::string::String>` cannot be sent between threads safely
+    //~| NOTE required because it appears within the type `impl std::clone::Clone`
+    //~| NOTE required by `send`
+
+    Rc::new(Cell::new(5))
+}
+
+fn cycle2() -> impl Clone {
+    send(cycle1().clone());
+    //~^ ERROR the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` is not satisfied
+    //~| NOTE `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
+    //~| NOTE required because it appears within the type `impl std::clone::Clone`
+    //~| NOTE required by `send`
+
+    Rc::new(String::from("foo"))
+}
diff --git a/src/test/run-pass/impl-trait/auto-trait-leak.rs b/src/test/run-pass/impl-trait/auto-trait-leak.rs
new file mode 100644
index 00000000000..c1201e7fa4f
--- /dev/null
+++ b/src/test/run-pass/impl-trait/auto-trait-leak.rs
@@ -0,0 +1,44 @@
+// Copyright 2016 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)]
+
+// Fast path, main can see the concrete type returned.
+fn before() -> impl FnMut(i32) {
+    let mut p = Box::new(0);
+    move |x| *p = x
+}
+
+fn send<T: Send>(_: T) {}
+
+fn main() {
+    send(before());
+    send(after());
+}
+
+// Deferred path, main has to wait until typeck finishes,
+// to check if the return type of after is Send.
+fn after() -> impl FnMut(i32) {
+    let mut p = Box::new(0);
+    move |x| *p = x
+}
+
+// Cycles should work as the deferred obligations are
+// independently resolved and only require the concrete
+// return type, which can't depend on the obligation.
+fn cycle1() -> impl Clone {
+    send(cycle2().clone());
+    5
+}
+
+fn cycle2() -> impl Clone {
+    send(cycle1().clone());
+    String::from("foo")
+}