about summary refs log tree commit diff
path: root/src/test/ui
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui')
-rw-r--r--src/test/ui/impl-trait/auto-trait-leak.rs69
-rw-r--r--src/test/ui/impl-trait/auto-trait-leak.stderr70
2 files changed, 139 insertions, 0 deletions
diff --git a/src/test/ui/impl-trait/auto-trait-leak.rs b/src/test/ui/impl-trait/auto-trait-leak.rs
new file mode 100644
index 00000000000..8a5033e7647
--- /dev/null
+++ b/src/test/ui/impl-trait/auto-trait-leak.rs
@@ -0,0 +1,69 @@
+// 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 {
+    //~^ ERROR unsupported cyclic reference between types/traits detected
+    //~| cyclic reference
+    //~| NOTE the cycle begins when processing `cycle1`...
+    //~| NOTE ...which then requires processing `cycle1::{{impl-Trait}}`...
+    //~| NOTE ...which then again requires processing `cycle1`, completing the cycle.
+    send(cycle2().clone());
+
+    Rc::new(Cell::new(5))
+}
+
+fn cycle2() -> impl Clone {
+    //~^ NOTE ...which then requires processing `cycle2::{{impl-Trait}}`...
+    //~| NOTE ...which then requires processing `cycle2`...
+    send(cycle1().clone());
+
+    Rc::new(String::from("foo"))
+}
diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr
new file mode 100644
index 00000000000..90476eb2d0d
--- /dev/null
+++ b/src/test/ui/impl-trait/auto-trait-leak.stderr
@@ -0,0 +1,70 @@
+error[E0277]: the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` is not satisfied in `impl std::ops::Fn<(i32,)>`
+  --> $DIR/auto-trait-leak.rs:27:5
+   |
+27 |     send(before());
+   |     ^^^^ `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
+   |
+   = help: within `impl std::ops::Fn<(i32,)>`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::cell::Cell<i32>>`
+   = note: required because it appears within the type `[closure@$DIR/auto-trait-leak.rs:21:5: 21:22 p:std::rc::Rc<std::cell::Cell<i32>>]`
+   = note: required because it appears within the type `impl std::ops::Fn<(i32,)>`
+   = note: required by `send`
+
+error[E0277]: the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` is not satisfied in `impl std::ops::Fn<(i32,)>`
+  --> $DIR/auto-trait-leak.rs:34:5
+   |
+34 |     send(after());
+   |     ^^^^ `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
+   |
+   = help: within `impl std::ops::Fn<(i32,)>`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::cell::Cell<i32>>`
+   = note: required because it appears within the type `[closure@$DIR/auto-trait-leak.rs:46:5: 46:22 p:std::rc::Rc<std::cell::Cell<i32>>]`
+   = note: required because it appears within the type `impl std::ops::Fn<(i32,)>`
+   = note: required by `send`
+
+error[E0391]: unsupported cyclic reference between types/traits detected
+  --> $DIR/auto-trait-leak.rs:52:1
+   |
+52 | / fn cycle1() -> impl Clone {
+53 | |     //~^ ERROR unsupported cyclic reference between types/traits detected
+54 | |     //~| cyclic reference
+55 | |     //~| NOTE the cycle begins when processing `cycle1`...
+...  |
+60 | |     Rc::new(Cell::new(5))
+61 | | }
+   | |_^ cyclic reference
+   |
+note: the cycle begins when processing `cycle1`...
+  --> $DIR/auto-trait-leak.rs:52:1
+   |
+52 | / fn cycle1() -> impl Clone {
+53 | |     //~^ ERROR unsupported cyclic reference between types/traits detected
+54 | |     //~| cyclic reference
+55 | |     //~| NOTE the cycle begins when processing `cycle1`...
+...  |
+60 | |     Rc::new(Cell::new(5))
+61 | | }
+   | |_^
+note: ...which then requires processing `cycle2::{{impl-Trait}}`...
+  --> $DIR/auto-trait-leak.rs:63:16
+   |
+63 | fn cycle2() -> impl Clone {
+   |                ^^^^^^^^^^
+note: ...which then requires processing `cycle2`...
+  --> $DIR/auto-trait-leak.rs:63:1
+   |
+63 | / fn cycle2() -> impl Clone {
+64 | |     //~^ NOTE ...which then requires processing `cycle2::{{impl-Trait}}`...
+65 | |     //~| NOTE ...which then requires processing `cycle2`...
+66 | |     send(cycle1().clone());
+67 | |
+68 | |     Rc::new(String::from("foo"))
+69 | | }
+   | |_^
+note: ...which then requires processing `cycle1::{{impl-Trait}}`...
+  --> $DIR/auto-trait-leak.rs:52:16
+   |
+52 | fn cycle1() -> impl Clone {
+   |                ^^^^^^^^^^
+   = note: ...which then again requires processing `cycle1`, completing the cycle.
+
+error: aborting due to 3 previous errors
+