]> git.lizzy.rs Git - rust.git/blob - src/test/compile-fail/impl-trait/auto-trait-leak.rs
Changed issue number to 36105
[rust.git] / src / test / compile-fail / impl-trait / auto-trait-leak.rs
1 // Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 // ignore-tidy-linelength
12
13 #![feature(conservative_impl_trait)]
14
15 use std::cell::Cell;
16 use std::rc::Rc;
17
18 // Fast path, main can see the concrete type returned.
19 fn before() -> impl Fn(i32) {
20     let p = Rc::new(Cell::new(0));
21     move |x| p.set(x)
22 }
23
24 fn send<T: Send>(_: T) {}
25
26 fn main() {
27     send(before());
28     //~^ ERROR the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` is not satisfied
29     //~| NOTE `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
30     //~| NOTE required because it appears within the type `[closure
31     //~| NOTE required because it appears within the type `impl std::ops::Fn<(i32,)>`
32     //~| NOTE required by `send`
33
34     send(after());
35     //~^ ERROR the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` is not satisfied
36     //~| NOTE `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
37     //~| NOTE required because it appears within the type `[closure
38     //~| NOTE required because it appears within the type `impl std::ops::Fn<(i32,)>`
39     //~| NOTE required by `send`
40 }
41
42 // Deferred path, main has to wait until typeck finishes,
43 // to check if the return type of after is Send.
44 fn after() -> impl Fn(i32) {
45     let p = Rc::new(Cell::new(0));
46     move |x| p.set(x)
47 }
48
49 // Cycles should work as the deferred obligations are
50 // independently resolved and only require the concrete
51 // return type, which can't depend on the obligation.
52 fn cycle1() -> impl Clone {
53     send(cycle2().clone());
54     //~^ ERROR the trait bound `std::rc::Rc<std::string::String>: std::marker::Send` is not satisfied
55     //~| NOTE `std::rc::Rc<std::string::String>` cannot be sent between threads safely
56     //~| NOTE required because it appears within the type `impl std::clone::Clone`
57     //~| NOTE required by `send`
58
59     Rc::new(Cell::new(5))
60 }
61
62 fn cycle2() -> impl Clone {
63     send(cycle1().clone());
64     //~^ ERROR the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` is not satisfied
65     //~| NOTE `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
66     //~| NOTE required because it appears within the type `impl std::clone::Clone`
67     //~| NOTE required by `send`
68
69     Rc::new(String::from("foo"))
70 }