diff options
| author | Eduard Burtescu <edy.burt@gmail.com> | 2016-07-28 18:27:11 +0300 |
|---|---|---|
| committer | Eduard Burtescu <edy.burt@gmail.com> | 2016-08-12 06:46:31 +0300 |
| commit | 08bf9f69b9cd96cf2871af1c2ec4dad0258728f2 (patch) | |
| tree | 970287c7db6efa4dd9c51c236cb547ae9591dfc2 /src/test | |
| parent | d92e594c3801a8066f95305c87e53a7ecfb24e9b (diff) | |
| download | rust-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.rs | 70 | ||||
| -rw-r--r-- | src/test/run-pass/impl-trait/auto-trait-leak.rs | 44 |
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") +} |
