Update tests for the Send - 'static change.
This commit is contained in:
parent
adfcd93f0c
commit
7a14f4994e
25 changed files with 52 additions and 183 deletions
|
@ -287,7 +287,7 @@ mod tests {
|
||||||
|
|
||||||
pub fn smalltest<F,G>(server: F, client: G)
|
pub fn smalltest<F,G>(server: F, client: G)
|
||||||
where F : FnOnce(UnixStream), F : Send,
|
where F : FnOnce(UnixStream), F : Send,
|
||||||
G : FnOnce(UnixStream), G : Send
|
G : FnOnce(UnixStream), G : Send + 'static
|
||||||
{
|
{
|
||||||
let path1 = next_test_unix();
|
let path1 = next_test_unix();
|
||||||
let path2 = path1.clone();
|
let path2 = path1.clone();
|
||||||
|
|
|
@ -458,7 +458,7 @@ impl Child {
|
||||||
/// the parent waits for the child to exit.
|
/// the parent waits for the child to exit.
|
||||||
pub fn wait_with_output(mut self) -> io::Result<Output> {
|
pub fn wait_with_output(mut self) -> io::Result<Output> {
|
||||||
drop(self.stdin.take());
|
drop(self.stdin.take());
|
||||||
fn read<T: Read + Send>(stream: Option<T>) -> Receiver<io::Result<Vec<u8>>> {
|
fn read<T: Read + Send + 'static>(stream: Option<T>) -> Receiver<io::Result<Vec<u8>>> {
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
match stream {
|
match stream {
|
||||||
Some(stream) => {
|
Some(stream) => {
|
||||||
|
|
|
@ -630,7 +630,7 @@ mod test {
|
||||||
rx.recv().unwrap();
|
rx.recv().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn avoid_copying_the_body<F>(spawnfn: F) where F: FnOnce(Thunk) {
|
fn avoid_copying_the_body<F>(spawnfn: F) where F: FnOnce(Thunk<'static>) {
|
||||||
let (tx, rx) = channel::<uint>();
|
let (tx, rx) = channel::<uint>();
|
||||||
|
|
||||||
let x = box 1;
|
let x = box 1;
|
||||||
|
@ -677,7 +677,7 @@ mod test {
|
||||||
// (well, it would if the constant were 8000+ - I lowered it to be more
|
// (well, it would if the constant were 8000+ - I lowered it to be more
|
||||||
// valgrind-friendly. try this at home, instead..!)
|
// valgrind-friendly. try this at home, instead..!)
|
||||||
static GENERATIONS: uint = 16;
|
static GENERATIONS: uint = 16;
|
||||||
fn child_no(x: uint) -> Thunk {
|
fn child_no(x: uint) -> Thunk<'static> {
|
||||||
return Thunk::new(move|| {
|
return Thunk::new(move|| {
|
||||||
if x < GENERATIONS {
|
if x < GENERATIONS {
|
||||||
Thread::spawn(move|| child_no(x+1).invoke(()));
|
Thread::spawn(move|| child_no(x+1).invoke(()));
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
use std::thread::Thread;
|
use std::thread::Thread;
|
||||||
use std::sync::mpsc::{Receiver, channel};
|
use std::sync::mpsc::{Receiver, channel};
|
||||||
|
|
||||||
pub fn foo<T:Send + Clone>(x: T) -> Receiver<T> {
|
pub fn foo<T:'static + Send + Clone>(x: T) -> Receiver<T> {
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
Thread::spawn(move|| {
|
Thread::spawn(move|| {
|
||||||
tx.send(x.clone());
|
tx.send(x.clone());
|
||||||
|
|
|
@ -229,21 +229,12 @@ unsafe impl<T: 'static> Send for Racy<T> {}
|
||||||
|
|
||||||
/// Executes a closure in parallel over the given iterator over mutable slice.
|
/// Executes a closure in parallel over the given iterator over mutable slice.
|
||||||
/// The closure `f` is run in parallel with an element of `iter`.
|
/// The closure `f` is run in parallel with an element of `iter`.
|
||||||
fn parallel<'a, I, T, F>(iter: I, f: F)
|
fn parallel<'a, I: Iterator, F>(iter: I, ref f: F)
|
||||||
where T: 'a+Send + Sync,
|
where I::Item: Send + 'a,
|
||||||
I: Iterator<Item=&'a mut [T]>,
|
F: Fn(I::Item) + Sync + 'a {
|
||||||
F: Fn(&mut [T]) + Sync {
|
iter.map(|x| {
|
||||||
use std::mem;
|
|
||||||
use std::raw::Repr;
|
|
||||||
|
|
||||||
iter.map(|chunk| {
|
|
||||||
// Need to convert `f` and `chunk` to something that can cross the task
|
|
||||||
// boundary.
|
|
||||||
let f = Racy(&f as *const F as *const uint);
|
|
||||||
let raw = Racy(chunk.repr());
|
|
||||||
Thread::scoped(move|| {
|
Thread::scoped(move|| {
|
||||||
let f = f.0 as *const F;
|
f(x)
|
||||||
unsafe { (*f)(mem::transmute(raw.0)) }
|
|
||||||
})
|
})
|
||||||
}).collect::<Vec<_>>();
|
}).collect::<Vec<_>>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,26 +112,16 @@ fn dot(v: &[f64], u: &[f64]) -> f64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct Racy<T>(T);
|
|
||||||
|
|
||||||
unsafe impl<T: 'static> Send for Racy<T> {}
|
|
||||||
|
|
||||||
// Executes a closure in parallel over the given mutable slice. The closure `f`
|
// Executes a closure in parallel over the given mutable slice. The closure `f`
|
||||||
// is run in parallel and yielded the starting index within `v` as well as a
|
// is run in parallel and yielded the starting index within `v` as well as a
|
||||||
// sub-slice of `v`.
|
// sub-slice of `v`.
|
||||||
fn parallel<T, F>(v: &mut [T], f: F)
|
fn parallel<'a,T, F>(v: &mut [T], ref f: F)
|
||||||
where T: Send + Sync,
|
where T: Send + Sync + 'a,
|
||||||
F: Fn(uint, &mut [T]) + Sync {
|
F: Fn(uint, &mut [T]) + Sync + 'a {
|
||||||
let size = v.len() / os::num_cpus() + 1;
|
let size = v.len() / os::num_cpus() + 1;
|
||||||
|
|
||||||
v.chunks_mut(size).enumerate().map(|(i, chunk)| {
|
v.chunks_mut(size).enumerate().map(|(i, chunk)| {
|
||||||
// Need to convert `f` and `chunk` to something that can cross the task
|
|
||||||
// boundary.
|
|
||||||
let f = Racy(&f as *const _ as *const uint);
|
|
||||||
let raw = Racy(chunk.repr());
|
|
||||||
Thread::scoped(move|| {
|
Thread::scoped(move|| {
|
||||||
let f = f.0 as *const F;
|
f(i * size, chunk)
|
||||||
unsafe { (*f)(i * size, mem::transmute(raw.0)) }
|
|
||||||
})
|
})
|
||||||
}).collect::<Vec<_>>();
|
}).collect::<Vec<_>>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
trait Foo : Send { }
|
trait Foo : Send { }
|
||||||
|
|
||||||
impl <'a> Foo for &'a mut () { }
|
impl Foo for std::rc::Rc<i8> { }
|
||||||
//~^ ERROR the type `&'a mut ()` does not fulfill the required lifetime
|
//~^ ERROR the trait `core::marker::Send` is not implemented
|
||||||
|
|
||||||
fn main() { }
|
fn main() { }
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
|
#![feature(optin_builtin_traits)]
|
||||||
|
|
||||||
use std::marker::Send;
|
use std::marker::Send;
|
||||||
|
|
||||||
enum TestE {
|
enum TestE {
|
||||||
|
@ -16,18 +18,21 @@ enum TestE {
|
||||||
|
|
||||||
struct MyType;
|
struct MyType;
|
||||||
|
|
||||||
|
struct NotSync;
|
||||||
|
impl !Sync for NotSync {}
|
||||||
|
|
||||||
unsafe impl Send for TestE {}
|
unsafe impl Send for TestE {}
|
||||||
unsafe impl Send for MyType {}
|
unsafe impl Send for MyType {}
|
||||||
unsafe impl Send for (MyType, MyType) {}
|
unsafe impl Send for (MyType, MyType) {}
|
||||||
//~^ ERROR builtin traits can only be implemented on structs or enums
|
//~^ ERROR builtin traits can only be implemented on structs or enums
|
||||||
|
|
||||||
unsafe impl Send for &'static MyType {}
|
unsafe impl Send for &'static NotSync {}
|
||||||
//~^ ERROR builtin traits can only be implemented on structs or enums
|
//~^ ERROR builtin traits can only be implemented on structs or enums
|
||||||
|
|
||||||
unsafe impl Send for [MyType] {}
|
unsafe impl Send for [MyType] {}
|
||||||
//~^ ERROR builtin traits can only be implemented on structs or enums
|
//~^ ERROR builtin traits can only be implemented on structs or enums
|
||||||
|
|
||||||
unsafe impl Send for &'static [MyType] {}
|
unsafe impl Send for &'static [NotSync] {}
|
||||||
//~^ ERROR builtin traits can only be implemented on structs or enums
|
//~^ ERROR builtin traits can only be implemented on structs or enums
|
||||||
|
|
||||||
fn is_send<T: Send>() {}
|
fn is_send<T: Send>() {}
|
||||||
|
|
|
@ -17,7 +17,7 @@ struct S<T>;
|
||||||
|
|
||||||
trait Gettable<T> {}
|
trait Gettable<T> {}
|
||||||
|
|
||||||
impl<T: Send + Copy> Gettable<T> for S<T> {}
|
impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
|
||||||
|
|
||||||
fn f<T>(val: T) {
|
fn f<T>(val: T) {
|
||||||
let t: S<T> = S;
|
let t: S<T> = S;
|
||||||
|
|
|
@ -20,7 +20,7 @@ trait Message : Send { }
|
||||||
|
|
||||||
fn object_ref_with_static_bound_not_ok() {
|
fn object_ref_with_static_bound_not_ok() {
|
||||||
assert_send::<&'static (Dummy+'static)>();
|
assert_send::<&'static (Dummy+'static)>();
|
||||||
//~^ ERROR the trait `core::marker::Send` is not implemented
|
//~^ ERROR the trait `core::marker::Sync` is not implemented
|
||||||
}
|
}
|
||||||
|
|
||||||
fn box_object_with_no_bound_not_ok<'a>() {
|
fn box_object_with_no_bound_not_ok<'a>() {
|
||||||
|
@ -28,7 +28,7 @@ fn box_object_with_no_bound_not_ok<'a>() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn object_with_send_bound_ok() {
|
fn object_with_send_bound_ok() {
|
||||||
assert_send::<&'static (Dummy+Send)>();
|
assert_send::<&'static (Dummy+Sync)>();
|
||||||
assert_send::<Box<Dummy+Send>>();
|
assert_send::<Box<Dummy+Send>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,22 +12,22 @@
|
||||||
// is broken into two parts because some errors occur in distinct
|
// is broken into two parts because some errors occur in distinct
|
||||||
// phases in the compiler. See kindck-send-object2.rs as well!
|
// phases in the compiler. See kindck-send-object2.rs as well!
|
||||||
|
|
||||||
fn assert_send<T:Send>() { }
|
fn assert_send<T:Send+'static>() { }
|
||||||
trait Dummy { }
|
trait Dummy { }
|
||||||
|
|
||||||
// careful with object types, who knows what they close over...
|
// careful with object types, who knows what they close over...
|
||||||
fn test51<'a>() {
|
fn test51<'a>() {
|
||||||
assert_send::<&'a Dummy>();
|
assert_send::<&'a Dummy>();
|
||||||
//~^ ERROR the trait `core::marker::Send` is not implemented
|
//~^ ERROR the trait `core::marker::Sync` is not implemented
|
||||||
}
|
}
|
||||||
fn test52<'a>() {
|
fn test52<'a>() {
|
||||||
assert_send::<&'a (Dummy+Send)>();
|
assert_send::<&'a (Dummy+Sync)>();
|
||||||
//~^ ERROR does not fulfill the required lifetime
|
//~^ ERROR does not fulfill the required lifetime
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...unless they are properly bounded
|
// ...unless they are properly bounded
|
||||||
fn test60() {
|
fn test60() {
|
||||||
assert_send::<&'static (Dummy+Send)>();
|
assert_send::<&'static (Dummy+Sync)>();
|
||||||
}
|
}
|
||||||
fn test61() {
|
fn test61() {
|
||||||
assert_send::<Box<Dummy+Send>>();
|
assert_send::<Box<Dummy+Send>>();
|
||||||
|
|
|
@ -14,7 +14,7 @@ fn assert_send<T:Send>() { }
|
||||||
trait Dummy { }
|
trait Dummy { }
|
||||||
|
|
||||||
fn test50() {
|
fn test50() {
|
||||||
assert_send::<&'static Dummy>(); //~ ERROR the trait `core::marker::Send` is not implemented
|
assert_send::<&'static Dummy>(); //~ ERROR the trait `core::marker::Sync` is not implemented
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test53() {
|
fn test53() {
|
||||||
|
@ -23,7 +23,7 @@ fn test53() {
|
||||||
|
|
||||||
// ...unless they are properly bounded
|
// ...unless they are properly bounded
|
||||||
fn test60() {
|
fn test60() {
|
||||||
assert_send::<&'static (Dummy+Send)>();
|
assert_send::<&'static (Dummy+Sync)>();
|
||||||
}
|
}
|
||||||
fn test61() {
|
fn test61() {
|
||||||
assert_send::<Box<Dummy+Send>>();
|
assert_send::<Box<Dummy+Send>>();
|
||||||
|
|
|
@ -18,8 +18,8 @@ fn test31() { assert_send::<String>(); }
|
||||||
fn test32() { assert_send::<Vec<isize> >(); }
|
fn test32() { assert_send::<Vec<isize> >(); }
|
||||||
|
|
||||||
// but not if they own a bad thing
|
// but not if they own a bad thing
|
||||||
fn test40<'a>(_: &'a isize) {
|
fn test40() {
|
||||||
assert_send::<Box<&'a isize>>(); //~ ERROR does not fulfill the required lifetime
|
assert_send::<Box<*mut u8>>(); //~ ERROR `core::marker::Send` is not implemented
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() { }
|
fn main() { }
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
// Copyright 2014 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.
|
|
||||||
|
|
||||||
// Test that borrowed pointers are not sendable unless 'static.
|
|
||||||
|
|
||||||
fn assert_send<T:Send>() { }
|
|
||||||
|
|
||||||
// lifetime pointers with 'static lifetime are ok
|
|
||||||
fn test01() { assert_send::<&'static isize>(); }
|
|
||||||
fn test02() { assert_send::<&'static str>(); }
|
|
||||||
fn test03() { assert_send::<&'static [isize]>(); }
|
|
||||||
|
|
||||||
// whether or not they are mutable
|
|
||||||
fn test10() { assert_send::<&'static mut isize>(); }
|
|
||||||
|
|
||||||
// otherwise lifetime pointers are not ok
|
|
||||||
fn test20<'a>(_: &'a isize) {
|
|
||||||
assert_send::<&'a isize>(); //~ ERROR does not fulfill the required lifetime
|
|
||||||
}
|
|
||||||
fn test21<'a>(_: &'a isize) {
|
|
||||||
assert_send::<&'a str>(); //~ ERROR does not fulfill the required lifetime
|
|
||||||
}
|
|
||||||
fn test22<'a>(_: &'a isize) {
|
|
||||||
assert_send::<&'a [isize]>(); //~ ERROR does not fulfill the required lifetime
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() { }
|
|
|
@ -1,83 +0,0 @@
|
||||||
// Copyright 2012 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.
|
|
||||||
|
|
||||||
// Test which of the builtin types are considered sendable. The tests
|
|
||||||
// in this file all test region bound and lifetime violations that are
|
|
||||||
// detected during type check.
|
|
||||||
|
|
||||||
extern crate core;
|
|
||||||
use core::ptr::Unique;
|
|
||||||
|
|
||||||
fn assert_send<T:Send>() { }
|
|
||||||
trait Dummy:Send { }
|
|
||||||
|
|
||||||
// lifetime pointers with 'static lifetime are ok
|
|
||||||
|
|
||||||
fn static_lifime_ok<'a,T,U:Send>(_: &'a isize) {
|
|
||||||
assert_send::<&'static isize>();
|
|
||||||
assert_send::<&'static str>();
|
|
||||||
assert_send::<&'static [isize]>();
|
|
||||||
|
|
||||||
// whether or not they are mutable
|
|
||||||
assert_send::<&'static mut isize>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// otherwise lifetime pointers are not ok
|
|
||||||
|
|
||||||
fn param_not_ok<'a>(x: &'a isize) {
|
|
||||||
assert_send::<&'a isize>(); //~ ERROR does not fulfill the required lifetime
|
|
||||||
}
|
|
||||||
|
|
||||||
fn param_not_ok1<'a>(_: &'a isize) {
|
|
||||||
assert_send::<&'a str>(); //~ ERROR does not fulfill the required lifetime
|
|
||||||
}
|
|
||||||
|
|
||||||
fn param_not_ok2<'a>(_: &'a isize) {
|
|
||||||
assert_send::<&'a [isize]>(); //~ ERROR does not fulfill the required lifetime
|
|
||||||
}
|
|
||||||
|
|
||||||
// boxes are ok
|
|
||||||
|
|
||||||
fn box_ok() {
|
|
||||||
assert_send::<Box<isize>>();
|
|
||||||
assert_send::<String>();
|
|
||||||
assert_send::<Vec<isize>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// but not if they own a bad thing
|
|
||||||
|
|
||||||
fn box_with_region_not_ok<'a>() {
|
|
||||||
assert_send::<Box<&'a isize>>(); //~ ERROR does not fulfill the required lifetime
|
|
||||||
}
|
|
||||||
|
|
||||||
// objects with insufficient bounds no ok
|
|
||||||
|
|
||||||
fn object_with_random_bound_not_ok<'a>() {
|
|
||||||
assert_send::<&'a (Dummy+'a)>();
|
|
||||||
//~^ ERROR reference has a longer lifetime
|
|
||||||
}
|
|
||||||
|
|
||||||
fn object_with_send_bound_not_ok<'a>() {
|
|
||||||
assert_send::<&'a (Dummy+Send)>();
|
|
||||||
//~^ ERROR does not fulfill the required lifetime
|
|
||||||
}
|
|
||||||
|
|
||||||
// unsafe pointers are ok unless they point at unsendable things
|
|
||||||
|
|
||||||
struct UniqueUnsafePtr(Unique<*const isize>);
|
|
||||||
|
|
||||||
unsafe impl Send for UniqueUnsafePtr {}
|
|
||||||
|
|
||||||
fn unsafe_ok1<'a>(_: &'a isize) {
|
|
||||||
assert_send::<UniqueUnsafePtr>();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
}
|
|
|
@ -8,11 +8,11 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
fn assert_send<T: Send>(_t: T) {}
|
fn assert_static<T: 'static>(_t: T) {}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let line = String::new();
|
let line = String::new();
|
||||||
match [&*line] { //~ ERROR `line` does not live long enough
|
match [&*line] { //~ ERROR `line` does not live long enough
|
||||||
[ word ] => { assert_send(word); }
|
[ word ] => { assert_static(word); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ fn c(x: Box<Foo+Sync+Send>) {
|
||||||
fn d(x: Box<Foo>) {
|
fn d(x: Box<Foo>) {
|
||||||
a(x); //~ ERROR mismatched types
|
a(x); //~ ERROR mismatched types
|
||||||
//~| expected `Box<Foo + Send>`
|
//~| expected `Box<Foo + Send>`
|
||||||
//~| found `Box<Foo + 'static>`
|
//~| found `Box<Foo>`
|
||||||
//~| expected bounds `Send`
|
//~| expected bounds `Send`
|
||||||
//~| found no bounds
|
//~| found no bounds
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ trait Foo : Bar { }
|
||||||
impl <T: Send> Foo for T { }
|
impl <T: Send> Foo for T { }
|
||||||
impl <T: Send> Bar for T { }
|
impl <T: Send> Bar for T { }
|
||||||
|
|
||||||
fn foo<T: Foo>(val: T, chan: Sender<T>) {
|
fn foo<T: Foo + 'static>(val: T, chan: Sender<T>) {
|
||||||
chan.send(val).unwrap();
|
chan.send(val).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ struct X<T>(T);
|
||||||
impl <T: Sync> RequiresShare for X<T> { }
|
impl <T: Sync> RequiresShare for X<T> { }
|
||||||
impl <T: Sync+Send> RequiresRequiresShareAndSend for X<T> { }
|
impl <T: Sync+Send> RequiresRequiresShareAndSend for X<T> { }
|
||||||
|
|
||||||
fn foo<T: RequiresRequiresShareAndSend>(val: T, chan: Sender<T>) {
|
fn foo<T: RequiresRequiresShareAndSend + 'static>(val: T, chan: Sender<T>) {
|
||||||
chan.send(val).unwrap();
|
chan.send(val).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ trait Foo : Send { }
|
||||||
|
|
||||||
impl <T: Send> Foo for T { }
|
impl <T: Send> Foo for T { }
|
||||||
|
|
||||||
fn foo<T: Foo>(val: T, chan: Sender<T>) {
|
fn foo<T: Foo + 'static>(val: T, chan: Sender<T>) {
|
||||||
chan.send(val).unwrap();
|
chan.send(val).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,13 +13,13 @@
|
||||||
|
|
||||||
use std::sync::mpsc::{Sender, channel};
|
use std::sync::mpsc::{Sender, channel};
|
||||||
|
|
||||||
trait Foo : Send + Sized {
|
trait Foo : Send + Sized + 'static {
|
||||||
fn foo(self, tx: Sender<Self>) {
|
fn foo(self, tx: Sender<Self>) {
|
||||||
tx.send(self).unwrap();
|
tx.send(self).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <T: Send> Foo for T { }
|
impl <T: Send + 'static> Foo for T { }
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
|
|
|
@ -14,12 +14,12 @@ use std::thunk::Thunk;
|
||||||
|
|
||||||
pub trait Promisable: Send + Sync {}
|
pub trait Promisable: Send + Sync {}
|
||||||
impl<T: Send + Sync> Promisable for T {}
|
impl<T: Send + Sync> Promisable for T {}
|
||||||
pub fn propagate<T, E, F, G>(action: F) -> Thunk<Result<T, E>, Result<T, E>>
|
pub fn propagate<'a, T, E, F, G>(action: F) -> Thunk<'a,Result<T, E>, Result<T, E>>
|
||||||
where
|
where
|
||||||
T: Promisable + Clone,
|
T: Promisable + Clone + 'a,
|
||||||
E: Promisable + Clone,
|
E: Promisable + Clone + 'a,
|
||||||
F: FnOnce(&T) -> Result<T, E> + Send,
|
F: FnOnce(&T) -> Result<T, E> + Send + 'a,
|
||||||
G: FnOnce(Result<T, E>) -> Result<T, E> {
|
G: FnOnce(Result<T, E>) -> Result<T, E> + 'a {
|
||||||
Thunk::with_arg(move |result: Result<T, E>| {
|
Thunk::with_arg(move |result: Result<T, E>| {
|
||||||
match result {
|
match result {
|
||||||
Ok(ref t) => action(t),
|
Ok(ref t) => action(t),
|
||||||
|
|
|
@ -14,7 +14,7 @@ struct DST { a: u32, b: str }
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// get_tydesc should support unsized types
|
// get_tydesc should support unsized types
|
||||||
assert!(unsafe {(
|
assert_eq!(unsafe {(
|
||||||
// Slice
|
// Slice
|
||||||
(*std::intrinsics::get_tydesc::<[u8]>()).name,
|
(*std::intrinsics::get_tydesc::<[u8]>()).name,
|
||||||
// str
|
// str
|
||||||
|
@ -25,5 +25,5 @@ fn main() {
|
||||||
(*std::intrinsics::get_tydesc::<NT>()).name,
|
(*std::intrinsics::get_tydesc::<NT>()).name,
|
||||||
// DST
|
// DST
|
||||||
(*std::intrinsics::get_tydesc::<DST>()).name
|
(*std::intrinsics::get_tydesc::<DST>()).name
|
||||||
)} == ("[u8]", "str", "core::marker::Copy + 'static", "NT", "DST"));
|
)}, ("[u8]", "str", "core::marker::Copy", "NT", "DST"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,11 +13,11 @@ use std::thunk::Thunk;
|
||||||
|
|
||||||
static generations: uint = 1024+256+128+49;
|
static generations: uint = 1024+256+128+49;
|
||||||
|
|
||||||
fn spawn(f: Thunk) {
|
fn spawn(f: Thunk<'static>) {
|
||||||
Builder::new().stack_size(32 * 1024).spawn(move|| f.invoke(()));
|
Builder::new().stack_size(32 * 1024).spawn(move|| f.invoke(()));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn child_no(x: uint) -> Thunk {
|
fn child_no(x: uint) -> Thunk<'static> {
|
||||||
Thunk::new(move|| {
|
Thunk::new(move|| {
|
||||||
if x < generations {
|
if x < generations {
|
||||||
spawn(child_no(x+1));
|
spawn(child_no(x+1));
|
||||||
|
|
|
@ -16,7 +16,7 @@ struct Command<K, V> {
|
||||||
val: V
|
val: V
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cache_server<K:Send,V:Send>(mut tx: Sender<Sender<Command<K, V>>>) {
|
fn cache_server<K:Send+'static,V:Send+'static>(mut tx: Sender<Sender<Command<K, V>>>) {
|
||||||
let (tx1, _rx) = channel();
|
let (tx1, _rx) = channel();
|
||||||
tx.send(tx1);
|
tx.send(tx1);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue