diff options
Diffstat (limited to 'src/test/ui')
| -rw-r--r-- | src/test/ui/impl-trait/auto-trait-leak.rs | 69 | ||||
| -rw-r--r-- | src/test/ui/impl-trait/auto-trait-leak.stderr | 70 |
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 + |
