Skip to content

Commit c37ccac

Browse files
committed
Add a run-pass test for existential traits in ARCs.
1 parent 21aeb0f commit c37ccac

File tree

1 file changed

+103
-0
lines changed

1 file changed

+103
-0
lines changed
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// Copyright 2013 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+
// Tests that a heterogeneous list of existential types can be put inside an ARC
12+
// and shared between tasks as long as all types fulfill Const+Owned.
13+
14+
// xfail-fast
15+
16+
extern mod extra;
17+
use extra::arc;
18+
use std::comm;
19+
use std::task;
20+
use std::cell;
21+
22+
trait Pet {
23+
fn name(&self, blk: &fn(&str));
24+
fn num_legs(&self) -> uint;
25+
fn of_good_pedigree(&self) -> bool;
26+
}
27+
28+
struct Catte {
29+
num_whiskers: uint,
30+
name: ~str,
31+
}
32+
33+
struct Dogge {
34+
bark_decibels: uint,
35+
tricks_known: uint,
36+
name: ~str,
37+
}
38+
39+
struct Goldfyshe {
40+
swim_speed: uint,
41+
name: ~str,
42+
}
43+
44+
impl Pet for Catte {
45+
fn name(&self, blk: &fn(&str)) { blk(self.name) }
46+
fn num_legs(&self) -> uint { 4 }
47+
fn of_good_pedigree(&self) -> bool { self.num_whiskers >= 4 }
48+
}
49+
impl Pet for Dogge {
50+
fn name(&self, blk: &fn(&str)) { blk(self.name) }
51+
fn num_legs(&self) -> uint { 4 }
52+
fn of_good_pedigree(&self) -> bool {
53+
self.bark_decibels < 70 || self.tricks_known > 20
54+
}
55+
}
56+
impl Pet for Goldfyshe {
57+
fn name(&self, blk: &fn(&str)) { blk(self.name) }
58+
fn num_legs(&self) -> uint { 0 }
59+
fn of_good_pedigree(&self) -> bool { self.swim_speed >= 500 }
60+
}
61+
62+
fn main() {
63+
let catte = Catte { num_whiskers: 7, name: ~"alonzo_church" };
64+
let dogge1 = Dogge { bark_decibels: 100, tricks_known: 42, name: ~"alan_turing" };
65+
let dogge2 = Dogge { bark_decibels: 55, tricks_known: 11, name: ~"albert_einstein" };
66+
let fishe = Goldfyshe { swim_speed: 998, name: ~"alec_guinness" };
67+
let arc = arc::ARC(~[~catte as ~Pet:Const+Owned,
68+
~dogge1 as ~Pet:Const+Owned,
69+
~fishe as ~Pet:Const+Owned,
70+
~dogge2 as ~Pet:Const+Owned]);
71+
let (p1,c1) = comm::stream();
72+
let arc1 = cell::Cell::new(arc.clone());
73+
do task::spawn { check_legs(arc1.take()); c1.send(()); }
74+
let (p2,c2) = comm::stream();
75+
let arc2 = cell::Cell::new(arc.clone());
76+
do task::spawn { check_names(arc2.take()); c2.send(()); }
77+
let (p3,c3) = comm::stream();
78+
let arc3 = cell::Cell::new(arc.clone());
79+
do task::spawn { check_pedigree(arc3.take()); c3.send(()); }
80+
p1.recv();
81+
p2.recv();
82+
p3.recv();
83+
}
84+
85+
fn check_legs(arc: arc::ARC<~[~Pet:Const+Owned]>) {
86+
let mut legs = 0;
87+
for arc.get().iter().advance |pet| {
88+
legs += pet.num_legs();
89+
}
90+
assert!(legs == 12);
91+
}
92+
fn check_names(arc: arc::ARC<~[~Pet:Const+Owned]>) {
93+
for arc.get().iter().advance |pet| {
94+
do pet.name |name| {
95+
assert!(name[0] == 'a' as u8 && name[1] == 'l' as u8);
96+
}
97+
}
98+
}
99+
fn check_pedigree(arc: arc::ARC<~[~Pet:Const+Owned]>) {
100+
for arc.get().iter().advance |pet| {
101+
assert!(pet.of_good_pedigree());
102+
}
103+
}

0 commit comments

Comments
 (0)