librustc: Ensure that type parameters are in the right positions in paths.
This removes the stacking of type parameters that occurs when invoking trait methods, and fixes all places in the standard library that were relying on it. It is somewhat awkward in places; I think we'll probably want something like the `Foo::<for T>::new()` syntax.
This commit is contained in:
parent
3b6314c39b
commit
8693943676
70 changed files with 1130 additions and 528 deletions
|
@ -661,7 +661,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_basic() {
|
fn test_basic() {
|
||||||
let mut m = DList::new::<~int>();
|
let mut m: DList<~int> = DList::new();
|
||||||
assert_eq!(m.pop_front(), None);
|
assert_eq!(m.pop_front(), None);
|
||||||
assert_eq!(m.pop_back(), None);
|
assert_eq!(m.pop_back(), None);
|
||||||
assert_eq!(m.pop_front(), None);
|
assert_eq!(m.pop_front(), None);
|
||||||
|
@ -768,7 +768,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_rotate() {
|
fn test_rotate() {
|
||||||
let mut n = DList::new::<int>();
|
let mut n: DList<int> = DList::new();
|
||||||
n.rotate_backward(); check_links(&n);
|
n.rotate_backward(); check_links(&n);
|
||||||
assert_eq!(n.len(), 0);
|
assert_eq!(n.len(), 0);
|
||||||
n.rotate_forward(); check_links(&n);
|
n.rotate_forward(); check_links(&n);
|
||||||
|
@ -1033,7 +1033,7 @@ mod tests {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn fuzz_test(sz: int) {
|
fn fuzz_test(sz: int) {
|
||||||
let mut m = DList::new::<int>();
|
let mut m: DList<int> = DList::new();
|
||||||
let mut v = ~[];
|
let mut v = ~[];
|
||||||
for i in range(0, sz) {
|
for i in range(0, sz) {
|
||||||
check_links(&m);
|
check_links(&m);
|
||||||
|
@ -1078,7 +1078,7 @@ mod tests {
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_push_front(b: &mut test::BenchHarness) {
|
fn bench_push_front(b: &mut test::BenchHarness) {
|
||||||
let mut m = DList::new::<int>();
|
let mut m: DList<int> = DList::new();
|
||||||
do b.iter {
|
do b.iter {
|
||||||
m.push_front(0);
|
m.push_front(0);
|
||||||
}
|
}
|
||||||
|
@ -1086,7 +1086,7 @@ mod tests {
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_push_back(b: &mut test::BenchHarness) {
|
fn bench_push_back(b: &mut test::BenchHarness) {
|
||||||
let mut m = DList::new::<int>();
|
let mut m: DList<int> = DList::new();
|
||||||
do b.iter {
|
do b.iter {
|
||||||
m.push_back(0);
|
m.push_back(0);
|
||||||
}
|
}
|
||||||
|
@ -1094,7 +1094,7 @@ mod tests {
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_push_back_pop_back(b: &mut test::BenchHarness) {
|
fn bench_push_back_pop_back(b: &mut test::BenchHarness) {
|
||||||
let mut m = DList::new::<int>();
|
let mut m: DList<int> = DList::new();
|
||||||
do b.iter {
|
do b.iter {
|
||||||
m.push_back(0);
|
m.push_back(0);
|
||||||
m.pop_back();
|
m.pop_back();
|
||||||
|
@ -1103,7 +1103,7 @@ mod tests {
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_push_front_pop_front(b: &mut test::BenchHarness) {
|
fn bench_push_front_pop_front(b: &mut test::BenchHarness) {
|
||||||
let mut m = DList::new::<int>();
|
let mut m: DList<int> = DList::new();
|
||||||
do b.iter {
|
do b.iter {
|
||||||
m.push_front(0);
|
m.push_front(0);
|
||||||
m.pop_front();
|
m.pop_front();
|
||||||
|
@ -1112,7 +1112,7 @@ mod tests {
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_rotate_forward(b: &mut test::BenchHarness) {
|
fn bench_rotate_forward(b: &mut test::BenchHarness) {
|
||||||
let mut m = DList::new::<int>();
|
let mut m: DList<int> = DList::new();
|
||||||
m.push_front(0);
|
m.push_front(0);
|
||||||
m.push_front(1);
|
m.push_front(1);
|
||||||
do b.iter {
|
do b.iter {
|
||||||
|
@ -1122,7 +1122,7 @@ mod tests {
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_rotate_backward(b: &mut test::BenchHarness) {
|
fn bench_rotate_backward(b: &mut test::BenchHarness) {
|
||||||
let mut m = DList::new::<int>();
|
let mut m: DList<int> = DList::new();
|
||||||
m.push_front(0);
|
m.push_front(0);
|
||||||
m.push_front(1);
|
m.push_front(1);
|
||||||
do b.iter {
|
do b.iter {
|
||||||
|
|
|
@ -359,7 +359,7 @@ impl Integer for BigUint {
|
||||||
|
|
||||||
fn div_mod_floor_inner(a: BigUint, b: BigUint) -> (BigUint, BigUint) {
|
fn div_mod_floor_inner(a: BigUint, b: BigUint) -> (BigUint, BigUint) {
|
||||||
let mut m = a;
|
let mut m = a;
|
||||||
let mut d = Zero::zero::<BigUint>();
|
let mut d: BigUint = Zero::zero();
|
||||||
let mut n = 1;
|
let mut n = 1;
|
||||||
while m >= b {
|
while m >= b {
|
||||||
let (d0, d_unit, b_unit) = div_estimate(&m, &b, n);
|
let (d0, d_unit, b_unit) = div_estimate(&m, &b, n);
|
||||||
|
@ -411,8 +411,9 @@ impl Integer for BigUint {
|
||||||
if shift == 0 {
|
if shift == 0 {
|
||||||
return (BigUint::new(d), One::one(), (*b).clone());
|
return (BigUint::new(d), One::one(), (*b).clone());
|
||||||
}
|
}
|
||||||
|
let one: BigUint = One::one();
|
||||||
return (BigUint::from_slice(d).shl_unit(shift),
|
return (BigUint::from_slice(d).shl_unit(shift),
|
||||||
One::one::<BigUint>().shl_unit(shift),
|
one.shl_unit(shift),
|
||||||
b.shl_unit(shift));
|
b.shl_unit(shift));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1445,11 +1446,18 @@ mod biguint_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_is_even() {
|
fn test_is_even() {
|
||||||
assert!(FromStr::from_str::<BigUint>("1").unwrap().is_odd());
|
let one: Option<BigUint> = FromStr::from_str("1");
|
||||||
assert!(FromStr::from_str::<BigUint>("2").unwrap().is_even());
|
let two: Option<BigUint> = FromStr::from_str("2");
|
||||||
assert!(FromStr::from_str::<BigUint>("1000").unwrap().is_even());
|
let thousand: Option<BigUint> = FromStr::from_str("1000");
|
||||||
assert!(FromStr::from_str::<BigUint>("1000000000000000000000").unwrap().is_even());
|
let big: Option<BigUint> =
|
||||||
assert!(FromStr::from_str::<BigUint>("1000000000000000000001").unwrap().is_odd());
|
FromStr::from_str("1000000000000000000000");
|
||||||
|
let bigger: Option<BigUint> =
|
||||||
|
FromStr::from_str("1000000000000000000001");
|
||||||
|
assert!(one.unwrap().is_odd());
|
||||||
|
assert!(two.unwrap().is_even());
|
||||||
|
assert!(thousand.unwrap().is_even());
|
||||||
|
assert!(big.unwrap().is_even());
|
||||||
|
assert!(bigger.unwrap().is_odd());
|
||||||
assert!((BigUint::from_uint(1) << 64).is_even());
|
assert!((BigUint::from_uint(1) << 64).is_even());
|
||||||
assert!(((BigUint::from_uint(1) << 64) + BigUint::from_uint(1)).is_odd());
|
assert!(((BigUint::from_uint(1) << 64) + BigUint::from_uint(1)).is_odd());
|
||||||
}
|
}
|
||||||
|
@ -1534,15 +1542,19 @@ mod biguint_tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(FromStrRadix::from_str_radix::<BigUint>("Z", 10), None);
|
let zed: Option<BigUint> = FromStrRadix::from_str_radix("Z", 10);
|
||||||
assert_eq!(FromStrRadix::from_str_radix::<BigUint>("_", 2), None);
|
assert_eq!(zed, None);
|
||||||
assert_eq!(FromStrRadix::from_str_radix::<BigUint>("-1", 10), None);
|
let blank: Option<BigUint> = FromStrRadix::from_str_radix("_", 2);
|
||||||
|
assert_eq!(blank, None);
|
||||||
|
let minus_one: Option<BigUint> = FromStrRadix::from_str_radix("-1",
|
||||||
|
10);
|
||||||
|
assert_eq!(minus_one, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_factor() {
|
fn test_factor() {
|
||||||
fn factor(n: uint) -> BigUint {
|
fn factor(n: uint) -> BigUint {
|
||||||
let mut f= One::one::<BigUint>();
|
let mut f: BigUint = One::one();
|
||||||
for i in range(2, n + 1) {
|
for i in range(2, n + 1) {
|
||||||
// FIXME(#6102): Assignment operator for BigInt causes ICE
|
// FIXME(#6102): Assignment operator for BigInt causes ICE
|
||||||
// f *= BigUint::from_uint(i);
|
// f *= BigUint::from_uint(i);
|
||||||
|
@ -1939,17 +1951,24 @@ mod bigint_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_abs_sub() {
|
fn test_abs_sub() {
|
||||||
assert_eq!((-One::one::<BigInt>()).abs_sub(&One::one()), Zero::zero());
|
let zero: BigInt = Zero::zero();
|
||||||
assert_eq!(One::one::<BigInt>().abs_sub(&One::one()), Zero::zero());
|
let one: BigInt = One::one();
|
||||||
assert_eq!(One::one::<BigInt>().abs_sub(&Zero::zero()), One::one());
|
assert_eq!((-one).abs_sub(&one), zero);
|
||||||
assert_eq!(One::one::<BigInt>().abs_sub(&-One::one::<BigInt>()),
|
let one: BigInt = One::one();
|
||||||
IntConvertible::from_int(2));
|
let zero: BigInt = Zero::zero();
|
||||||
|
assert_eq!(one.abs_sub(&one), zero);
|
||||||
|
let one: BigInt = One::one();
|
||||||
|
let zero: BigInt = Zero::zero();
|
||||||
|
assert_eq!(one.abs_sub(&zero), one);
|
||||||
|
let one: BigInt = One::one();
|
||||||
|
assert_eq!(one.abs_sub(&-one), IntConvertible::from_int(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_to_str_radix() {
|
fn test_to_str_radix() {
|
||||||
fn check(n: int, ans: &str) {
|
fn check(n: int, ans: &str) {
|
||||||
assert!(ans == IntConvertible::from_int::<BigInt>(n).to_str_radix(10));
|
let n: BigInt = IntConvertible::from_int(n);
|
||||||
|
assert!(ans == n.to_str_radix(10));
|
||||||
}
|
}
|
||||||
check(10, "10");
|
check(10, "10");
|
||||||
check(1, "1");
|
check(1, "1");
|
||||||
|
@ -1962,7 +1981,10 @@ mod bigint_tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_from_str_radix() {
|
fn test_from_str_radix() {
|
||||||
fn check(s: &str, ans: Option<int>) {
|
fn check(s: &str, ans: Option<int>) {
|
||||||
let ans = ans.map_move(|n| IntConvertible::from_int::<BigInt>(n));
|
let ans = ans.map_move(|n| {
|
||||||
|
let x: BigInt = IntConvertible::from_int(n);
|
||||||
|
x
|
||||||
|
});
|
||||||
assert_eq!(FromStrRadix::from_str_radix(s, 10), ans);
|
assert_eq!(FromStrRadix::from_str_radix(s, 10), ans);
|
||||||
}
|
}
|
||||||
check("10", Some(10));
|
check("10", Some(10));
|
||||||
|
@ -1980,7 +2002,8 @@ mod bigint_tests {
|
||||||
BigInt::new(Minus, ~[1, 1, 1]));
|
BigInt::new(Minus, ~[1, 1, 1]));
|
||||||
assert!(-BigInt::new(Minus, ~[1, 1, 1]) ==
|
assert!(-BigInt::new(Minus, ~[1, 1, 1]) ==
|
||||||
BigInt::new(Plus, ~[1, 1, 1]));
|
BigInt::new(Plus, ~[1, 1, 1]));
|
||||||
assert_eq!(-Zero::zero::<BigInt>(), Zero::zero::<BigInt>());
|
let zero: BigInt = Zero::zero();
|
||||||
|
assert_eq!(-zero, zero);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -269,9 +269,13 @@ impl<T: FromStr + Clone + Integer + Ord>
|
||||||
/// Parses `numer/denom`.
|
/// Parses `numer/denom`.
|
||||||
fn from_str(s: &str) -> Option<Ratio<T>> {
|
fn from_str(s: &str) -> Option<Ratio<T>> {
|
||||||
let split: ~[&str] = s.splitn_iter('/', 1).collect();
|
let split: ~[&str] = s.splitn_iter('/', 1).collect();
|
||||||
if split.len() < 2 { return None; }
|
if split.len() < 2 {
|
||||||
do FromStr::from_str::<T>(split[0]).chain |a| {
|
return None
|
||||||
do FromStr::from_str::<T>(split[1]).chain |b| {
|
}
|
||||||
|
let a_option: Option<T> = FromStr::from_str(split[0]);
|
||||||
|
do a_option.chain |a| {
|
||||||
|
let b_option: Option<T> = FromStr::from_str(split[1]);
|
||||||
|
do b_option.chain |b| {
|
||||||
Some(Ratio::new(a.clone(), b.clone()))
|
Some(Ratio::new(a.clone(), b.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -282,10 +286,15 @@ impl<T: FromStrRadix + Clone + Integer + Ord>
|
||||||
/// Parses `numer/denom` where the numbers are in base `radix`.
|
/// Parses `numer/denom` where the numbers are in base `radix`.
|
||||||
fn from_str_radix(s: &str, radix: uint) -> Option<Ratio<T>> {
|
fn from_str_radix(s: &str, radix: uint) -> Option<Ratio<T>> {
|
||||||
let split: ~[&str] = s.splitn_iter('/', 1).collect();
|
let split: ~[&str] = s.splitn_iter('/', 1).collect();
|
||||||
if split.len() < 2 { None }
|
if split.len() < 2 {
|
||||||
else {
|
None
|
||||||
do FromStrRadix::from_str_radix::<T>(split[0], radix).chain |a| {
|
} else {
|
||||||
do FromStrRadix::from_str_radix::<T>(split[1], radix).chain |b| {
|
let a_option: Option<T> = FromStrRadix::from_str_radix(split[0],
|
||||||
|
radix);
|
||||||
|
do a_option.chain |a| {
|
||||||
|
let b_option: Option<T> =
|
||||||
|
FromStrRadix::from_str_radix(split[1], radix);
|
||||||
|
do b_option.chain |b| {
|
||||||
Some(Ratio::new(a.clone(), b.clone()))
|
Some(Ratio::new(a.clone(), b.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -496,7 +505,8 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_from_str_fail() {
|
fn test_from_str_fail() {
|
||||||
fn test(s: &str) {
|
fn test(s: &str) {
|
||||||
assert_eq!(FromStr::from_str::<Rational>(s), None);
|
let rational: Option<Rational> = FromStr::from_str(s);
|
||||||
|
assert_eq!(rational, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
let xs = ["0 /1", "abc", "", "1/", "--1/2","3/2/1"];
|
let xs = ["0 /1", "abc", "", "1/", "--1/2","3/2/1"];
|
||||||
|
@ -536,7 +546,8 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_from_str_radix_fail() {
|
fn test_from_str_radix_fail() {
|
||||||
fn test(s: &str) {
|
fn test(s: &str) {
|
||||||
assert_eq!(FromStrRadix::from_str_radix::<Rational>(s, 3), None);
|
let radix: Option<Rational> = FromStrRadix::from_str_radix(s, 3);
|
||||||
|
assert_eq!(radix, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
let xs = ["0 /1", "abc", "", "1/", "--1/2","3/2/1", "3/2"];
|
let xs = ["0 /1", "abc", "", "1/", "--1/2","3/2/1", "3/2"];
|
||||||
|
|
|
@ -338,27 +338,36 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_fail]
|
#[should_fail]
|
||||||
fn test_empty_pop() { let mut heap = PriorityQueue::new::<int>(); heap.pop(); }
|
fn test_empty_pop() {
|
||||||
|
let mut heap: PriorityQueue<int> = PriorityQueue::new();
|
||||||
|
heap.pop();
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_empty_maybe_pop() {
|
fn test_empty_maybe_pop() {
|
||||||
let mut heap = PriorityQueue::new::<int>();
|
let mut heap: PriorityQueue<int> = PriorityQueue::new();
|
||||||
assert!(heap.maybe_pop().is_none());
|
assert!(heap.maybe_pop().is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_fail]
|
#[should_fail]
|
||||||
fn test_empty_top() { let empty = PriorityQueue::new::<int>(); empty.top(); }
|
fn test_empty_top() {
|
||||||
|
let empty: PriorityQueue<int> = PriorityQueue::new();
|
||||||
|
empty.top();
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_empty_maybe_top() {
|
fn test_empty_maybe_top() {
|
||||||
let empty = PriorityQueue::new::<int>();
|
let empty: PriorityQueue<int> = PriorityQueue::new();
|
||||||
assert!(empty.maybe_top().is_none());
|
assert!(empty.maybe_top().is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_fail]
|
#[should_fail]
|
||||||
fn test_empty_replace() { let mut heap = PriorityQueue::new(); heap.replace(5); }
|
fn test_empty_replace() {
|
||||||
|
let mut heap: PriorityQueue<int> = PriorityQueue::new();
|
||||||
|
heap.replace(5);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_from_iter() {
|
fn test_from_iter() {
|
||||||
|
|
|
@ -483,7 +483,7 @@ mod tests {
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_new(b: &mut test::BenchHarness) {
|
fn bench_new(b: &mut test::BenchHarness) {
|
||||||
do b.iter {
|
do b.iter {
|
||||||
let _ = RingBuf::new::<u64>();
|
let _: RingBuf<u64> = RingBuf::new();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -879,7 +879,8 @@ mod test_treemap {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn find_empty() {
|
fn find_empty() {
|
||||||
let m = TreeMap::new::<int, int>(); assert!(m.find(&5) == None);
|
let m: TreeMap<int,int> = TreeMap::new();
|
||||||
|
assert!(m.find(&5) == None);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1006,7 +1007,7 @@ mod test_treemap {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_rand_int() {
|
fn test_rand_int() {
|
||||||
let mut map = TreeMap::new::<int, int>();
|
let mut map: TreeMap<int,int> = TreeMap::new();
|
||||||
let mut ctrl = ~[];
|
let mut ctrl = ~[];
|
||||||
|
|
||||||
check_equal(ctrl, &map);
|
check_equal(ctrl, &map);
|
||||||
|
|
|
@ -387,7 +387,7 @@ fn path_node(ids: ~[ast::ident]) -> ast::Path {
|
||||||
ast::Path {
|
ast::Path {
|
||||||
span: dummy_sp(),
|
span: dummy_sp(),
|
||||||
global: false,
|
global: false,
|
||||||
segments: ids.consume_iter().transform(|identifier| ast::PathSegment {
|
segments: ids.move_iter().map(|identifier| ast::PathSegment {
|
||||||
identifier: identifier,
|
identifier: identifier,
|
||||||
lifetime: None,
|
lifetime: None,
|
||||||
types: opt_vec::Empty,
|
types: opt_vec::Empty,
|
||||||
|
@ -399,7 +399,7 @@ fn path_node_global(ids: ~[ast::ident]) -> ast::Path {
|
||||||
ast::Path {
|
ast::Path {
|
||||||
span: dummy_sp(),
|
span: dummy_sp(),
|
||||||
global: true,
|
global: true,
|
||||||
segments: ids.consume_iter().transform(|identifier| ast::PathSegment {
|
segments: ids.move_iter().map(|identifier| ast::PathSegment {
|
||||||
identifier: identifier,
|
identifier: identifier,
|
||||||
lifetime: None,
|
lifetime: None,
|
||||||
types: opt_vec::Empty,
|
types: opt_vec::Empty,
|
||||||
|
|
|
@ -335,15 +335,19 @@ fn item_to_def_like(item: ebml::Doc, did: ast::def_id, cnum: ast::CrateNum)
|
||||||
let purity = if fam == UnsafeStaticMethod { ast::unsafe_fn } else
|
let purity = if fam == UnsafeStaticMethod { ast::unsafe_fn } else
|
||||||
{ ast::impure_fn };
|
{ ast::impure_fn };
|
||||||
// def_static_method carries an optional field of its enclosing
|
// def_static_method carries an optional field of its enclosing
|
||||||
// *trait*, but not an inclosing Impl (if this is an inherent
|
// trait or enclosing impl (if this is an inherent static method).
|
||||||
// static method). So we need to detect whether this is in
|
// So we need to detect whether this is in a trait or not, which
|
||||||
// a trait or not, which we do through the mildly hacky
|
// we do through the mildly hacky way of checking whether there is
|
||||||
// way of checking whether there is a trait_method_sort.
|
// a trait_method_sort.
|
||||||
let trait_did_opt = if reader::maybe_get_doc(
|
let provenance = if reader::maybe_get_doc(
|
||||||
item, tag_item_trait_method_sort).is_some() {
|
item, tag_item_trait_method_sort).is_some() {
|
||||||
Some(item_reqd_and_translated_parent_item(cnum, item))
|
ast::FromTrait(item_reqd_and_translated_parent_item(cnum,
|
||||||
} else { None };
|
item))
|
||||||
dl_def(ast::def_static_method(did, trait_did_opt, purity))
|
} else {
|
||||||
|
ast::FromImpl(item_reqd_and_translated_parent_item(cnum,
|
||||||
|
item))
|
||||||
|
};
|
||||||
|
dl_def(ast::def_static_method(did, provenance, purity))
|
||||||
}
|
}
|
||||||
Type | ForeignType => dl_def(ast::def_ty(did)),
|
Type | ForeignType => dl_def(ast::def_ty(did)),
|
||||||
Mod => dl_def(ast::def_mod(did)),
|
Mod => dl_def(ast::def_mod(did)),
|
||||||
|
|
|
@ -141,7 +141,7 @@ fn parse_path(st: &mut PState) -> @ast::Path {
|
||||||
return @ast::Path {
|
return @ast::Path {
|
||||||
span: dummy_sp(),
|
span: dummy_sp(),
|
||||||
global: false,
|
global: false,
|
||||||
segments: idents.consume_iter().transform(|identifier| {
|
segments: idents.move_iter().map(|identifier| {
|
||||||
ast::PathSegment {
|
ast::PathSegment {
|
||||||
identifier: identifier,
|
identifier: identifier,
|
||||||
lifetime: None,
|
lifetime: None,
|
||||||
|
|
|
@ -374,9 +374,16 @@ impl tr for ast::def {
|
||||||
fn tr(&self, xcx: @ExtendedDecodeContext) -> ast::def {
|
fn tr(&self, xcx: @ExtendedDecodeContext) -> ast::def {
|
||||||
match *self {
|
match *self {
|
||||||
ast::def_fn(did, p) => ast::def_fn(did.tr(xcx), p),
|
ast::def_fn(did, p) => ast::def_fn(did.tr(xcx), p),
|
||||||
ast::def_static_method(did, did2_opt, p) => {
|
ast::def_static_method(did, wrapped_did2, p) => {
|
||||||
ast::def_static_method(did.tr(xcx),
|
ast::def_static_method(did.tr(xcx),
|
||||||
did2_opt.map(|did2| did2.tr(xcx)),
|
match wrapped_did2 {
|
||||||
|
ast::FromTrait(did2) => {
|
||||||
|
ast::FromTrait(did2.tr(xcx))
|
||||||
|
}
|
||||||
|
ast::FromImpl(did2) => {
|
||||||
|
ast::FromImpl(did2.tr(xcx))
|
||||||
|
}
|
||||||
|
},
|
||||||
p)
|
p)
|
||||||
}
|
}
|
||||||
ast::def_method(did0, did1) => {
|
ast::def_method(did0, did1) => {
|
||||||
|
|
|
@ -392,10 +392,12 @@ impl GatherLoanCtxt {
|
||||||
}
|
}
|
||||||
ty::AutoBorrowObj(r, m) => {
|
ty::AutoBorrowObj(r, m) => {
|
||||||
let cmt_deref = mcx.cat_deref_fn_or_obj(expr, cmt, 0);
|
let cmt_deref = mcx.cat_deref_fn_or_obj(expr, cmt, 0);
|
||||||
|
let loan_mutability =
|
||||||
|
LoanMutability::from_ast_mutability(m);
|
||||||
self.guarantee_valid(expr.id,
|
self.guarantee_valid(expr.id,
|
||||||
expr.span,
|
expr.span,
|
||||||
cmt_deref,
|
cmt_deref,
|
||||||
m,
|
loan_mutability,
|
||||||
r)
|
r)
|
||||||
}
|
}
|
||||||
ty::AutoUnsafe(_) => {}
|
ty::AutoUnsafe(_) => {}
|
||||||
|
|
|
@ -8,9 +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.
|
||||||
|
|
||||||
// A pass that checks to make sure private fields and methods aren't used
|
//! A pass that checks to make sure private fields and methods aren't used
|
||||||
// outside their scopes.
|
//! outside their scopes.
|
||||||
|
|
||||||
|
|
||||||
use metadata::csearch;
|
use metadata::csearch;
|
||||||
use middle::ty::{ty_struct, ty_enum};
|
use middle::ty::{ty_struct, ty_enum};
|
||||||
|
|
|
@ -55,6 +55,12 @@ pub type BindingMap = HashMap<ident,binding_info>;
|
||||||
// Trait method resolution
|
// Trait method resolution
|
||||||
pub type TraitMap = HashMap<NodeId,@mut ~[def_id]>;
|
pub type TraitMap = HashMap<NodeId,@mut ~[def_id]>;
|
||||||
|
|
||||||
|
// A summary of the generics on a trait.
|
||||||
|
struct TraitGenerics {
|
||||||
|
has_lifetime: bool,
|
||||||
|
type_parameter_count: uint,
|
||||||
|
}
|
||||||
|
|
||||||
// This is the replacement export map. It maps a module to all of the exports
|
// This is the replacement export map. It maps a module to all of the exports
|
||||||
// within.
|
// within.
|
||||||
pub type ExportMap2 = @mut HashMap<NodeId, ~[Export2]>;
|
pub type ExportMap2 = @mut HashMap<NodeId, ~[Export2]>;
|
||||||
|
@ -1321,9 +1327,12 @@ impl Resolver {
|
||||||
method.span);
|
method.span);
|
||||||
let def = match method.explicit_self.node {
|
let def = match method.explicit_self.node {
|
||||||
sty_static => {
|
sty_static => {
|
||||||
// Static methods become `def_fn`s.
|
// Static methods become
|
||||||
def_fn(local_def(method.id),
|
// `def_static_method`s.
|
||||||
method.purity)
|
def_static_method(local_def(method.id),
|
||||||
|
FromImpl(local_def(
|
||||||
|
item.id)),
|
||||||
|
method.purity)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// Non-static methods become
|
// Non-static methods become
|
||||||
|
@ -1373,7 +1382,7 @@ impl Resolver {
|
||||||
sty_static => {
|
sty_static => {
|
||||||
// Static methods become `def_static_method`s.
|
// Static methods become `def_static_method`s.
|
||||||
def_static_method(local_def(ty_m.id),
|
def_static_method(local_def(ty_m.id),
|
||||||
Some(local_def(item.id)),
|
FromTrait(local_def(item.id)),
|
||||||
ty_m.purity)
|
ty_m.purity)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -2115,7 +2124,7 @@ impl Resolver {
|
||||||
fn path_idents_to_str(@mut self, path: &Path) -> ~str {
|
fn path_idents_to_str(@mut self, path: &Path) -> ~str {
|
||||||
let identifiers: ~[ast::ident] = path.segments
|
let identifiers: ~[ast::ident] = path.segments
|
||||||
.iter()
|
.iter()
|
||||||
.transform(|seg| seg.identifier)
|
.map(|seg| seg.identifier)
|
||||||
.collect();
|
.collect();
|
||||||
self.idents_to_str(identifiers)
|
self.idents_to_str(identifiers)
|
||||||
}
|
}
|
||||||
|
@ -4161,6 +4170,22 @@ impl Resolver {
|
||||||
Some(&primitive_type) => {
|
Some(&primitive_type) => {
|
||||||
result_def =
|
result_def =
|
||||||
Some(def_prim_ty(primitive_type));
|
Some(def_prim_ty(primitive_type));
|
||||||
|
|
||||||
|
if path.segments
|
||||||
|
.iter()
|
||||||
|
.any(|s| s.lifetime.is_some()) {
|
||||||
|
self.session.span_err(path.span,
|
||||||
|
"lifetime parameters \
|
||||||
|
are not allowed on \
|
||||||
|
this type")
|
||||||
|
} else if path.segments
|
||||||
|
.iter()
|
||||||
|
.any(|s| s.types.len() > 0) {
|
||||||
|
self.session.span_err(path.span,
|
||||||
|
"type parameters are \
|
||||||
|
not allowed on this \
|
||||||
|
type")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// Continue.
|
// Continue.
|
||||||
|
@ -4170,12 +4195,17 @@ impl Resolver {
|
||||||
|
|
||||||
match result_def {
|
match result_def {
|
||||||
None => {
|
None => {
|
||||||
match self.resolve_path(ty.id, path, TypeNS, true, visitor) {
|
match self.resolve_path(ty.id,
|
||||||
|
path,
|
||||||
|
TypeNS,
|
||||||
|
true,
|
||||||
|
visitor) {
|
||||||
Some(def) => {
|
Some(def) => {
|
||||||
debug!("(resolving type) resolved `%s` to \
|
debug!("(resolving type) resolved `%s` to \
|
||||||
type %?",
|
type %?",
|
||||||
self.session.str_of(
|
self.session.str_of(path.segments
|
||||||
path.segments.last().identifier),
|
.last()
|
||||||
|
.identifier),
|
||||||
def);
|
def);
|
||||||
result_def = Some(def);
|
result_def = Some(def);
|
||||||
}
|
}
|
||||||
|
@ -4184,9 +4214,7 @@ impl Resolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(_) => {
|
Some(_) => {} // Continue.
|
||||||
// Continue.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match result_def {
|
match result_def {
|
||||||
|
@ -4364,7 +4392,7 @@ impl Resolver {
|
||||||
// Check the types in the path pattern.
|
// Check the types in the path pattern.
|
||||||
for ty in path.segments
|
for ty in path.segments
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map_(|seg| seg.types.iter()) {
|
.flat_map(|seg| seg.types.iter()) {
|
||||||
self.resolve_type(ty, visitor);
|
self.resolve_type(ty, visitor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4399,7 +4427,7 @@ impl Resolver {
|
||||||
// Check the types in the path pattern.
|
// Check the types in the path pattern.
|
||||||
for ty in path.segments
|
for ty in path.segments
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map_(|s| s.types.iter()) {
|
.flat_map(|s| s.types.iter()) {
|
||||||
self.resolve_type(ty, visitor);
|
self.resolve_type(ty, visitor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4432,7 +4460,7 @@ impl Resolver {
|
||||||
// Check the types in the path pattern.
|
// Check the types in the path pattern.
|
||||||
for ty in path.segments
|
for ty in path.segments
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map_(|s| s.types.iter()) {
|
.flat_map(|s| s.types.iter()) {
|
||||||
self.resolve_type(ty, visitor);
|
self.resolve_type(ty, visitor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4529,7 +4557,7 @@ impl Resolver {
|
||||||
visitor: &mut ResolveVisitor)
|
visitor: &mut ResolveVisitor)
|
||||||
-> Option<def> {
|
-> Option<def> {
|
||||||
// First, resolve the types.
|
// First, resolve the types.
|
||||||
for ty in path.segments.iter().flat_map_(|s| s.types.iter()) {
|
for ty in path.segments.iter().flat_map(|s| s.types.iter()) {
|
||||||
self.resolve_type(ty, visitor);
|
self.resolve_type(ty, visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4553,11 +4581,13 @@ impl Resolver {
|
||||||
match (def, unqualified_def) {
|
match (def, unqualified_def) {
|
||||||
(Some(d), Some(ud)) if d == ud => {
|
(Some(d), Some(ud)) if d == ud => {
|
||||||
self.session.add_lint(unnecessary_qualification,
|
self.session.add_lint(unnecessary_qualification,
|
||||||
id, path.span,
|
id,
|
||||||
|
path.span,
|
||||||
~"unnecessary qualification");
|
~"unnecessary qualification");
|
||||||
}
|
}
|
||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
|
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -117,10 +117,13 @@ pub fn trans(bcx: @mut Block, expr: @ast::expr) -> Callee {
|
||||||
|
|
||||||
fn trans_def(bcx: @mut Block, def: ast::def, ref_expr: @ast::expr) -> Callee {
|
fn trans_def(bcx: @mut Block, def: ast::def, ref_expr: @ast::expr) -> Callee {
|
||||||
match def {
|
match def {
|
||||||
ast::def_fn(did, _) | ast::def_static_method(did, None, _) => {
|
ast::def_fn(did, _) |
|
||||||
|
ast::def_static_method(did, ast::FromImpl(_), _) => {
|
||||||
fn_callee(bcx, trans_fn_ref(bcx, did, ref_expr.id))
|
fn_callee(bcx, trans_fn_ref(bcx, did, ref_expr.id))
|
||||||
}
|
}
|
||||||
ast::def_static_method(impl_did, Some(trait_did), _) => {
|
ast::def_static_method(impl_did,
|
||||||
|
ast::FromTrait(trait_did),
|
||||||
|
_) => {
|
||||||
fn_callee(bcx, meth::trans_static_method_callee(bcx, impl_did,
|
fn_callee(bcx, meth::trans_static_method_callee(bcx, impl_did,
|
||||||
trait_did,
|
trait_did,
|
||||||
ref_expr.id))
|
ref_expr.id))
|
||||||
|
|
|
@ -824,14 +824,17 @@ fn trans_def_datum_unadjusted(bcx: @mut Block,
|
||||||
{
|
{
|
||||||
let _icx = push_ctxt("trans_def_datum_unadjusted");
|
let _icx = push_ctxt("trans_def_datum_unadjusted");
|
||||||
|
|
||||||
let fn_data = match def {
|
match def {
|
||||||
ast::def_fn(did, _) | ast::def_static_method(did, None, _) => {
|
ast::def_fn(did, _) |
|
||||||
|
ast::def_static_method(did, ast::FromImpl(_), _) => {
|
||||||
callee::trans_fn_ref(bcx, did, ref_expr.id)
|
callee::trans_fn_ref(bcx, did, ref_expr.id)
|
||||||
}
|
}
|
||||||
ast::def_static_method(impl_did, Some(trait_did), _) => {
|
ast::def_static_method(impl_did, ast::FromTrait(trait_did), _) => {
|
||||||
meth::trans_static_method_callee(bcx, impl_did,
|
let fn_data = meth::trans_static_method_callee(bcx,
|
||||||
trait_did,
|
impl_did,
|
||||||
ref_expr.id)
|
trait_did,
|
||||||
|
ref_expr.id);
|
||||||
|
return fn_data_to_datum(bcx, ref_expr, impl_did, fn_data);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
bcx.tcx().sess.span_bug(ref_expr.span, fmt!(
|
bcx.tcx().sess.span_bug(ref_expr.span, fmt!(
|
||||||
|
|
|
@ -178,7 +178,7 @@ fn ast_path_substs<AC:AstConv,RS:region_scope + Clone + 'static>(
|
||||||
|
|
||||||
// Convert the type parameters supplied by the user.
|
// Convert the type parameters supplied by the user.
|
||||||
let supplied_type_parameter_count =
|
let supplied_type_parameter_count =
|
||||||
path.segments.iter().flat_map_(|s| s.types.iter()).len_();
|
path.segments.iter().flat_map(|s| s.types.iter()).len();
|
||||||
if decl_generics.type_param_defs.len() != supplied_type_parameter_count {
|
if decl_generics.type_param_defs.len() != supplied_type_parameter_count {
|
||||||
this.tcx().sess.span_fatal(
|
this.tcx().sess.span_fatal(
|
||||||
path.span,
|
path.span,
|
||||||
|
@ -188,8 +188,8 @@ fn ast_path_substs<AC:AstConv,RS:region_scope + Clone + 'static>(
|
||||||
}
|
}
|
||||||
let tps = path.segments
|
let tps = path.segments
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map_(|s| s.types.iter())
|
.flat_map(|s| s.types.iter())
|
||||||
.transform(|a_t| ast_ty_to_ty(this, rscope, a_t))
|
.map(|a_t| ast_ty_to_ty(this, rscope, a_t))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
substs {
|
substs {
|
||||||
|
|
|
@ -128,7 +128,12 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::pat, path: &ast::Path,
|
||||||
Some((enm, var)) => {
|
Some((enm, var)) => {
|
||||||
// Assign the pattern the type of the *enum*, not the variant.
|
// Assign the pattern the type of the *enum*, not the variant.
|
||||||
let enum_tpt = ty::lookup_item_type(tcx, enm);
|
let enum_tpt = ty::lookup_item_type(tcx, enm);
|
||||||
instantiate_path(pcx.fcx, path, enum_tpt, pat.span, pat.id);
|
instantiate_path(pcx.fcx,
|
||||||
|
path,
|
||||||
|
enum_tpt,
|
||||||
|
v_def,
|
||||||
|
pat.span,
|
||||||
|
pat.id);
|
||||||
|
|
||||||
// check that the type of the value being matched is a subtype
|
// check that the type of the value being matched is a subtype
|
||||||
// of the type of the pattern:
|
// of the type of the pattern:
|
||||||
|
@ -185,7 +190,12 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::pat, path: &ast::Path,
|
||||||
} else {
|
} else {
|
||||||
ctor_tpt
|
ctor_tpt
|
||||||
};
|
};
|
||||||
instantiate_path(pcx.fcx, path, struct_tpt, pat.span, pat.id);
|
instantiate_path(pcx.fcx,
|
||||||
|
path,
|
||||||
|
struct_tpt,
|
||||||
|
s_def,
|
||||||
|
pat.span,
|
||||||
|
pat.id);
|
||||||
|
|
||||||
// Check that the type of the value being matched is a subtype of
|
// Check that the type of the value being matched is a subtype of
|
||||||
// the type of the pattern.
|
// the type of the pattern.
|
||||||
|
|
|
@ -1132,8 +1132,160 @@ pub enum DerefArgs {
|
||||||
DoDerefArgs
|
DoDerefArgs
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn break_here() {
|
// Given the provenance of a static method, returns the generics of the static
|
||||||
debug!("break here!");
|
// method's container.
|
||||||
|
fn generics_of_static_method_container(type_context: ty::ctxt,
|
||||||
|
provenance: ast::MethodProvenance)
|
||||||
|
-> ty::Generics {
|
||||||
|
match provenance {
|
||||||
|
ast::FromTrait(trait_def_id) => {
|
||||||
|
ty::lookup_trait_def(type_context, trait_def_id).generics
|
||||||
|
}
|
||||||
|
ast::FromImpl(impl_def_id) => {
|
||||||
|
ty::lookup_item_type(type_context, impl_def_id).generics
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verifies that type parameters supplied in paths are in the right
|
||||||
|
// locations.
|
||||||
|
fn check_type_parameter_positions_in_path(function_context: @mut FnCtxt,
|
||||||
|
path: &ast::Path,
|
||||||
|
def: ast::def) {
|
||||||
|
// We only care about checking the case in which the path has two or
|
||||||
|
// more segments.
|
||||||
|
if path.segments.len() < 2 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that no lifetimes or type parameters are present anywhere
|
||||||
|
// except the final two elements of the path.
|
||||||
|
for i in range(0, path.segments.len() - 2) {
|
||||||
|
match path.segments[i].lifetime {
|
||||||
|
None => {}
|
||||||
|
Some(lifetime) => {
|
||||||
|
function_context.tcx()
|
||||||
|
.sess
|
||||||
|
.span_err(lifetime.span,
|
||||||
|
"lifetime parameters may not \
|
||||||
|
appear here")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for typ in path.segments[i].types.iter() {
|
||||||
|
function_context.tcx()
|
||||||
|
.sess
|
||||||
|
.span_err(typ.span,
|
||||||
|
"type parameters may not appear here")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there are no parameters at all, there is nothing more to do; the
|
||||||
|
// rest of typechecking will (attempt to) infer everything.
|
||||||
|
if path.segments
|
||||||
|
.iter()
|
||||||
|
.all(|s| s.lifetime.is_none() && s.types.is_empty()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
match def {
|
||||||
|
// If this is a static method of a trait or implementation, then
|
||||||
|
// ensure that the segment of the path which names the trait or
|
||||||
|
// implementation (the penultimate segment) is annotated with the
|
||||||
|
// right number of type parameters.
|
||||||
|
ast::def_static_method(_, provenance, _) => {
|
||||||
|
let generics =
|
||||||
|
generics_of_static_method_container(function_context.ccx.tcx,
|
||||||
|
provenance);
|
||||||
|
let name = match provenance {
|
||||||
|
ast::FromTrait(_) => "trait",
|
||||||
|
ast::FromImpl(_) => "impl",
|
||||||
|
};
|
||||||
|
|
||||||
|
let trait_segment = &path.segments[path.segments.len() - 2];
|
||||||
|
|
||||||
|
// Make sure lifetime parameterization agrees with the trait or
|
||||||
|
// implementation type.
|
||||||
|
match (generics.region_param, trait_segment.lifetime) {
|
||||||
|
(Some(_), None) => {
|
||||||
|
function_context.tcx()
|
||||||
|
.sess
|
||||||
|
.span_err(path.span,
|
||||||
|
fmt!("this %s has a lifetime \
|
||||||
|
parameter but no \
|
||||||
|
lifetime was specified",
|
||||||
|
name))
|
||||||
|
}
|
||||||
|
(None, Some(_)) => {
|
||||||
|
function_context.tcx()
|
||||||
|
.sess
|
||||||
|
.span_err(path.span,
|
||||||
|
fmt!("this %s has no lifetime \
|
||||||
|
parameter but a lifetime \
|
||||||
|
was specified",
|
||||||
|
name))
|
||||||
|
}
|
||||||
|
(Some(_), Some(_)) | (None, None) => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the number of type parameters supplied on the trait
|
||||||
|
// or implementation segment equals the number of type parameters
|
||||||
|
// on the trait or implementation definition.
|
||||||
|
let trait_type_parameter_count = generics.type_param_defs.len();
|
||||||
|
let supplied_type_parameter_count = trait_segment.types.len();
|
||||||
|
if trait_type_parameter_count != supplied_type_parameter_count {
|
||||||
|
let trait_count_suffix = if trait_type_parameter_count == 1 {
|
||||||
|
""
|
||||||
|
} else {
|
||||||
|
"s"
|
||||||
|
};
|
||||||
|
let supplied_count_suffix =
|
||||||
|
if supplied_type_parameter_count == 1 {
|
||||||
|
""
|
||||||
|
} else {
|
||||||
|
"s"
|
||||||
|
};
|
||||||
|
function_context.tcx()
|
||||||
|
.sess
|
||||||
|
.span_err(path.span,
|
||||||
|
fmt!("the %s referenced by this \
|
||||||
|
path has %u type \
|
||||||
|
parameter%s, but %u type \
|
||||||
|
parameter%s were supplied",
|
||||||
|
name,
|
||||||
|
trait_type_parameter_count,
|
||||||
|
trait_count_suffix,
|
||||||
|
supplied_type_parameter_count,
|
||||||
|
supplied_count_suffix))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
// Verify that no lifetimes or type parameters are present on
|
||||||
|
// the penultimate segment of the path.
|
||||||
|
let segment = &path.segments[path.segments.len() - 2];
|
||||||
|
match segment.lifetime {
|
||||||
|
None => {}
|
||||||
|
Some(lifetime) => {
|
||||||
|
function_context.tcx()
|
||||||
|
.sess
|
||||||
|
.span_err(lifetime.span,
|
||||||
|
"lifetime parameters may not
|
||||||
|
appear here")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for typ in segment.types.iter() {
|
||||||
|
function_context.tcx()
|
||||||
|
.sess
|
||||||
|
.span_err(typ.span,
|
||||||
|
"type parameters may not appear \
|
||||||
|
here");
|
||||||
|
function_context.tcx()
|
||||||
|
.sess
|
||||||
|
.span_note(typ.span,
|
||||||
|
fmt!("this is a %?", def));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Invariant:
|
/// Invariant:
|
||||||
|
@ -2333,8 +2485,9 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
|
||||||
ast::expr_path(ref pth) => {
|
ast::expr_path(ref pth) => {
|
||||||
let defn = lookup_def(fcx, pth.span, id);
|
let defn = lookup_def(fcx, pth.span, id);
|
||||||
|
|
||||||
|
check_type_parameter_positions_in_path(fcx, pth, defn);
|
||||||
let tpt = ty_param_bounds_and_ty_for_def(fcx, expr.span, defn);
|
let tpt = ty_param_bounds_and_ty_for_def(fcx, expr.span, defn);
|
||||||
instantiate_path(fcx, pth, tpt, expr.span, expr.id);
|
instantiate_path(fcx, pth, tpt, defn, expr.span, expr.id);
|
||||||
}
|
}
|
||||||
ast::expr_self => {
|
ast::expr_self => {
|
||||||
let definition = lookup_def(fcx, expr.span, id);
|
let definition = lookup_def(fcx, expr.span, id);
|
||||||
|
@ -3141,11 +3294,12 @@ pub fn ty_param_bounds_and_ty_for_def(fcx: @mut FnCtxt,
|
||||||
pub fn instantiate_path(fcx: @mut FnCtxt,
|
pub fn instantiate_path(fcx: @mut FnCtxt,
|
||||||
pth: &ast::Path,
|
pth: &ast::Path,
|
||||||
tpt: ty_param_bounds_and_ty,
|
tpt: ty_param_bounds_and_ty,
|
||||||
|
def: ast::def,
|
||||||
span: span,
|
span: span,
|
||||||
node_id: ast::NodeId) {
|
node_id: ast::NodeId) {
|
||||||
debug!(">>> instantiate_path");
|
debug!(">>> instantiate_path");
|
||||||
|
|
||||||
let ty_param_count = tpt.generics.type_param_defs.len();
|
let mut ty_param_count = tpt.generics.type_param_defs.len();
|
||||||
let mut ty_substs_len = 0;
|
let mut ty_substs_len = 0;
|
||||||
for segment in pth.segments.iter() {
|
for segment in pth.segments.iter() {
|
||||||
ty_substs_len += segment.types.len()
|
ty_substs_len += segment.types.len()
|
||||||
|
@ -3180,6 +3334,21 @@ pub fn instantiate_path(fcx: @mut FnCtxt,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Special case: If there is a self parameter, omit it from the list of
|
||||||
|
// type parameters.
|
||||||
|
//
|
||||||
|
// Here we calculate the "user type parameter count", which is the number
|
||||||
|
// of type parameters actually manifest in the AST. This will differ from
|
||||||
|
// the internal type parameter count when there are self types involved.
|
||||||
|
let (user_type_parameter_count, self_parameter_index) = match def {
|
||||||
|
ast::def_static_method(_, provenance @ ast::FromTrait(_), _) => {
|
||||||
|
let generics = generics_of_static_method_container(fcx.ccx.tcx,
|
||||||
|
provenance);
|
||||||
|
(ty_param_count - 1, Some(generics.type_param_defs.len()))
|
||||||
|
}
|
||||||
|
_ => (ty_param_count, None),
|
||||||
|
};
|
||||||
|
|
||||||
// determine values for type parameters, using the values given by
|
// determine values for type parameters, using the values given by
|
||||||
// the user (if any) and otherwise using fresh type variables
|
// the user (if any) and otherwise using fresh type variables
|
||||||
let tps = if ty_substs_len == 0 {
|
let tps = if ty_substs_len == 0 {
|
||||||
|
@ -3188,33 +3357,44 @@ pub fn instantiate_path(fcx: @mut FnCtxt,
|
||||||
fcx.ccx.tcx.sess.span_err
|
fcx.ccx.tcx.sess.span_err
|
||||||
(span, "this item does not take type parameters");
|
(span, "this item does not take type parameters");
|
||||||
fcx.infcx().next_ty_vars(ty_param_count)
|
fcx.infcx().next_ty_vars(ty_param_count)
|
||||||
} else if ty_substs_len > ty_param_count {
|
} else if ty_substs_len > user_type_parameter_count {
|
||||||
fcx.ccx.tcx.sess.span_err
|
fcx.ccx.tcx.sess.span_err
|
||||||
(span,
|
(span,
|
||||||
fmt!("too many type parameters provided: expected %u, found %u",
|
fmt!("too many type parameters provided: expected %u, found %u",
|
||||||
ty_param_count, ty_substs_len));
|
user_type_parameter_count, ty_substs_len));
|
||||||
fcx.infcx().next_ty_vars(ty_param_count)
|
fcx.infcx().next_ty_vars(ty_param_count)
|
||||||
} else if ty_substs_len < ty_param_count {
|
} else if ty_substs_len < user_type_parameter_count {
|
||||||
let is_static_method = match fcx.ccx.tcx.def_map.find(&node_id) {
|
|
||||||
Some(&ast::def_static_method(*)) => true,
|
|
||||||
_ => false
|
|
||||||
};
|
|
||||||
fcx.ccx.tcx.sess.span_err
|
fcx.ccx.tcx.sess.span_err
|
||||||
(span,
|
(span,
|
||||||
fmt!("not enough type parameters provided: expected %u, found %u",
|
fmt!("not enough type parameters provided: expected %u, found %u",
|
||||||
ty_param_count, ty_substs_len));
|
user_type_parameter_count, ty_substs_len));
|
||||||
if is_static_method {
|
|
||||||
fcx.ccx.tcx.sess.span_note
|
|
||||||
(span, "Static methods have an extra implicit type parameter -- \
|
|
||||||
did you omit the type parameter for the `Self` type?");
|
|
||||||
}
|
|
||||||
fcx.infcx().next_ty_vars(ty_param_count)
|
fcx.infcx().next_ty_vars(ty_param_count)
|
||||||
} else {
|
} else {
|
||||||
pth.segments
|
// Build up the list of type parameters, inserting the self parameter
|
||||||
.iter()
|
// at the appropriate position.
|
||||||
.flat_map_(|s| s.types.iter())
|
let mut result = ~[];
|
||||||
.transform(|aty| fcx.to_ty(aty))
|
let mut pushed = false;
|
||||||
.collect()
|
for (i, ast_type) in pth.segments
|
||||||
|
.iter()
|
||||||
|
.flat_map(|segment| segment.types.iter())
|
||||||
|
.enumerate() {
|
||||||
|
match self_parameter_index {
|
||||||
|
Some(index) if index == i => {
|
||||||
|
result.push(fcx.infcx().next_ty_vars(1)[0]);
|
||||||
|
pushed = true;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
result.push(fcx.to_ty(ast_type))
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the self parameter goes at the end, insert it there.
|
||||||
|
if !pushed && self_parameter_index.is_some() {
|
||||||
|
result.push(fcx.infcx().next_ty_vars(1)[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(result.len(), ty_param_count)
|
||||||
|
result
|
||||||
};
|
};
|
||||||
|
|
||||||
let substs = substs {
|
let substs = substs {
|
||||||
|
|
|
@ -276,7 +276,7 @@ pub mod raw {
|
||||||
use rt::local::Local;
|
use rt::local::Local;
|
||||||
use rt::task::Task;
|
use rt::task::Task;
|
||||||
|
|
||||||
do Local::borrow::<Task, *()> |task| {
|
do Local::borrow |task: &mut Task| {
|
||||||
task.heap.realloc(ptr as *libc::c_void, size) as *()
|
task.heap.realloc(ptr as *libc::c_void, size) as *()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,7 +100,7 @@ fn test_basic() {
|
||||||
#[test]
|
#[test]
|
||||||
#[should_fail]
|
#[should_fail]
|
||||||
fn test_take_empty() {
|
fn test_take_empty() {
|
||||||
let value_cell = Cell::new_empty::<~int>();
|
let value_cell: Cell<~int> = Cell::new_empty();
|
||||||
value_cell.take();
|
value_cell.take();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -884,10 +884,17 @@ impl<T> Poly for T {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// n.b. use 'const' to get an implementation for both '*mut' and '*' at the same
|
impl<T> Pointer for *T {
|
||||||
// time.
|
fn fmt(t: &*T, f: &mut Formatter) {
|
||||||
impl<T> Pointer for *const T {
|
f.flags |= 1 << (parse::FlagAlternate as uint);
|
||||||
fn fmt(t: &*const T, f: &mut Formatter) {
|
do ::uint::to_str_bytes(*t as uint, 16) |buf| {
|
||||||
|
f.pad_integral(buf, "0x", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Pointer for *mut T {
|
||||||
|
fn fmt(t: &*mut T, f: &mut Formatter) {
|
||||||
f.flags |= 1 << (parse::FlagAlternate as uint);
|
f.flags |= 1 << (parse::FlagAlternate as uint);
|
||||||
do ::uint::to_str_bytes(*t as uint, 16) |buf| {
|
do ::uint::to_str_bytes(*t as uint, 16) |buf| {
|
||||||
f.pad_integral(buf, "0x", true);
|
f.pad_integral(buf, "0x", true);
|
||||||
|
|
|
@ -869,21 +869,21 @@ mod test_map {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_find_or_insert() {
|
fn test_find_or_insert() {
|
||||||
let mut m = HashMap::new::<int, int>();
|
let mut m: HashMap<int,int> = HashMap::new();
|
||||||
assert_eq!(*m.find_or_insert(1, 2), 2);
|
assert_eq!(*m.find_or_insert(1, 2), 2);
|
||||||
assert_eq!(*m.find_or_insert(1, 3), 2);
|
assert_eq!(*m.find_or_insert(1, 3), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_find_or_insert_with() {
|
fn test_find_or_insert_with() {
|
||||||
let mut m = HashMap::new::<int, int>();
|
let mut m: HashMap<int,int> = HashMap::new();
|
||||||
assert_eq!(*m.find_or_insert_with(1, |_| 2), 2);
|
assert_eq!(*m.find_or_insert_with(1, |_| 2), 2);
|
||||||
assert_eq!(*m.find_or_insert_with(1, |_| 3), 2);
|
assert_eq!(*m.find_or_insert_with(1, |_| 3), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_insert_or_update_with() {
|
fn test_insert_or_update_with() {
|
||||||
let mut m = HashMap::new::<int, int>();
|
let mut m: HashMap<int,int> = HashMap::new();
|
||||||
assert_eq!(*m.insert_or_update_with(1, 2, |_,x| *x+=1), 2);
|
assert_eq!(*m.insert_or_update_with(1, 2, |_,x| *x+=1), 2);
|
||||||
assert_eq!(*m.insert_or_update_with(1, 2, |_,x| *x+=1), 3);
|
assert_eq!(*m.insert_or_update_with(1, 2, |_,x| *x+=1), 3);
|
||||||
}
|
}
|
||||||
|
|
|
@ -660,7 +660,10 @@ pub trait AdditiveIterator<A> {
|
||||||
|
|
||||||
impl<A: Add<A, A> + Zero, T: Iterator<A>> AdditiveIterator<A> for T {
|
impl<A: Add<A, A> + Zero, T: Iterator<A>> AdditiveIterator<A> for T {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sum(&mut self) -> A { self.fold(Zero::zero::<A>(), |s, x| s + x) }
|
fn sum(&mut self) -> A {
|
||||||
|
let zero: A = Zero::zero();
|
||||||
|
self.fold(zero, |s, x| s + x)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A trait for iterators over elements whose elements can be multiplied
|
/// A trait for iterators over elements whose elements can be multiplied
|
||||||
|
@ -685,7 +688,10 @@ pub trait MultiplicativeIterator<A> {
|
||||||
|
|
||||||
impl<A: Mul<A, A> + One, T: Iterator<A>> MultiplicativeIterator<A> for T {
|
impl<A: Mul<A, A> + One, T: Iterator<A>> MultiplicativeIterator<A> for T {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn product(&mut self) -> A { self.fold(One::one::<A>(), |p, x| p * x) }
|
fn product(&mut self) -> A {
|
||||||
|
let one: A = One::one();
|
||||||
|
self.fold(one, |p, x| p * x)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A trait for iterators over elements which can be compared to one another.
|
/// A trait for iterators over elements which can be compared to one another.
|
||||||
|
|
|
@ -59,7 +59,8 @@ fn newsched_log_str(msg: ~str) {
|
||||||
use rt::local::Local;
|
use rt::local::Local;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
match Local::try_unsafe_borrow::<Task>() {
|
let optional_task: Option<*mut Task> = Local::try_unsafe_borrow();
|
||||||
|
match optional_task {
|
||||||
Some(local) => {
|
Some(local) => {
|
||||||
// Use the available logger
|
// Use the available logger
|
||||||
(*local).logger.log(Left(msg));
|
(*local).logger.log(Left(msg));
|
||||||
|
|
|
@ -182,7 +182,7 @@ impl ApproxEq<f32> for f32 {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn approx_eq(&self, other: &f32) -> bool {
|
fn approx_eq(&self, other: &f32) -> bool {
|
||||||
self.approx_eq_eps(other, &ApproxEq::approx_epsilon::<f32, f32>())
|
self.approx_eq_eps(other, &1.0e-6)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -561,11 +561,14 @@ impl Real for f32 {
|
||||||
|
|
||||||
/// Converts to degrees, assuming the number is in radians
|
/// Converts to degrees, assuming the number is in radians
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_degrees(&self) -> f32 { *self * (180.0 / Real::pi::<f32>()) }
|
fn to_degrees(&self) -> f32 { *self * (180.0f32 / Real::pi()) }
|
||||||
|
|
||||||
/// Converts to radians, assuming the number is in degrees
|
/// Converts to radians, assuming the number is in degrees
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_radians(&self) -> f32 { *self * (Real::pi::<f32>() / 180.0) }
|
fn to_radians(&self) -> f32 {
|
||||||
|
let value: f32 = Real::pi();
|
||||||
|
*self * (value / 180.0f32)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Bounded for f32 {
|
impl Bounded for f32 {
|
||||||
|
@ -578,10 +581,10 @@ impl Bounded for f32 {
|
||||||
|
|
||||||
impl Primitive for f32 {
|
impl Primitive for f32 {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn bits() -> uint { 32 }
|
fn bits(_: Option<f32>) -> uint { 32 }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn bytes() -> uint { Primitive::bits::<f32>() / 8 }
|
fn bytes(_: Option<f32>) -> uint { Primitive::bits(Some(0f32)) / 8 }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Float for f32 {
|
impl Float for f32 {
|
||||||
|
@ -638,25 +641,25 @@ impl Float for f32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mantissa_digits() -> uint { 24 }
|
fn mantissa_digits(_: Option<f32>) -> uint { 24 }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn digits() -> uint { 6 }
|
fn digits(_: Option<f32>) -> uint { 6 }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn epsilon() -> f32 { 1.19209290e-07 }
|
fn epsilon() -> f32 { 1.19209290e-07 }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn min_exp() -> int { -125 }
|
fn min_exp(_: Option<f32>) -> int { -125 }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn max_exp() -> int { 128 }
|
fn max_exp(_: Option<f32>) -> int { 128 }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn min_10_exp() -> int { -37 }
|
fn min_10_exp(_: Option<f32>) -> int { -37 }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn max_10_exp() -> int { 38 }
|
fn max_10_exp(_: Option<f32>) -> int { 38 }
|
||||||
|
|
||||||
/// Constructs a floating point number by multiplying `x` by 2 raised to the power of `exp`
|
/// Constructs a floating point number by multiplying `x` by 2 raised to the power of `exp`
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -949,9 +952,11 @@ mod tests {
|
||||||
assert_eq!(1f32.clamp(&2f32, &4f32), 2f32);
|
assert_eq!(1f32.clamp(&2f32, &4f32), 2f32);
|
||||||
assert_eq!(8f32.clamp(&2f32, &4f32), 4f32);
|
assert_eq!(8f32.clamp(&2f32, &4f32), 4f32);
|
||||||
assert_eq!(3f32.clamp(&2f32, &4f32), 3f32);
|
assert_eq!(3f32.clamp(&2f32, &4f32), 3f32);
|
||||||
assert!(3f32.clamp(&Float::NaN::<f32>(), &4f32).is_NaN());
|
|
||||||
assert!(3f32.clamp(&2f32, &Float::NaN::<f32>()).is_NaN());
|
let nan: f32 = Float::NaN();
|
||||||
assert!(Float::NaN::<f32>().clamp(&2f32, &4f32).is_NaN());
|
assert!(3f32.clamp(&nan, &4f32).is_NaN());
|
||||||
|
assert!(3f32.clamp(&2f32, &nan).is_NaN());
|
||||||
|
assert!(nan.clamp(&2f32, &4f32).is_NaN());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1028,9 +1033,13 @@ mod tests {
|
||||||
fn test_asinh() {
|
fn test_asinh() {
|
||||||
assert_eq!(0.0f32.asinh(), 0.0f32);
|
assert_eq!(0.0f32.asinh(), 0.0f32);
|
||||||
assert_eq!((-0.0f32).asinh(), -0.0f32);
|
assert_eq!((-0.0f32).asinh(), -0.0f32);
|
||||||
assert_eq!(Float::infinity::<f32>().asinh(), Float::infinity::<f32>());
|
|
||||||
assert_eq!(Float::neg_infinity::<f32>().asinh(), Float::neg_infinity::<f32>());
|
let inf: f32 = Float::infinity();
|
||||||
assert!(Float::NaN::<f32>().asinh().is_NaN());
|
let neg_inf: f32 = Float::neg_infinity();
|
||||||
|
let nan: f32 = Float::NaN();
|
||||||
|
assert_eq!(inf.asinh(), inf);
|
||||||
|
assert_eq!(neg_inf.asinh(), neg_inf);
|
||||||
|
assert!(nan.asinh().is_NaN());
|
||||||
assert_approx_eq!(2.0f32.asinh(), 1.443635475178810342493276740273105f32);
|
assert_approx_eq!(2.0f32.asinh(), 1.443635475178810342493276740273105f32);
|
||||||
assert_approx_eq!((-2.0f32).asinh(), -1.443635475178810342493276740273105f32);
|
assert_approx_eq!((-2.0f32).asinh(), -1.443635475178810342493276740273105f32);
|
||||||
}
|
}
|
||||||
|
@ -1039,9 +1048,13 @@ mod tests {
|
||||||
fn test_acosh() {
|
fn test_acosh() {
|
||||||
assert_eq!(1.0f32.acosh(), 0.0f32);
|
assert_eq!(1.0f32.acosh(), 0.0f32);
|
||||||
assert!(0.999f32.acosh().is_NaN());
|
assert!(0.999f32.acosh().is_NaN());
|
||||||
assert_eq!(Float::infinity::<f32>().acosh(), Float::infinity::<f32>());
|
|
||||||
assert!(Float::neg_infinity::<f32>().acosh().is_NaN());
|
let inf: f32 = Float::infinity();
|
||||||
assert!(Float::NaN::<f32>().acosh().is_NaN());
|
let neg_inf: f32 = Float::neg_infinity();
|
||||||
|
let nan: f32 = Float::NaN();
|
||||||
|
assert_eq!(inf.acosh(), inf);
|
||||||
|
assert!(neg_inf.acosh().is_NaN());
|
||||||
|
assert!(nan.acosh().is_NaN());
|
||||||
assert_approx_eq!(2.0f32.acosh(), 1.31695789692481670862504634730796844f32);
|
assert_approx_eq!(2.0f32.acosh(), 1.31695789692481670862504634730796844f32);
|
||||||
assert_approx_eq!(3.0f32.acosh(), 1.76274717403908605046521864995958461f32);
|
assert_approx_eq!(3.0f32.acosh(), 1.76274717403908605046521864995958461f32);
|
||||||
}
|
}
|
||||||
|
@ -1050,34 +1063,61 @@ mod tests {
|
||||||
fn test_atanh() {
|
fn test_atanh() {
|
||||||
assert_eq!(0.0f32.atanh(), 0.0f32);
|
assert_eq!(0.0f32.atanh(), 0.0f32);
|
||||||
assert_eq!((-0.0f32).atanh(), -0.0f32);
|
assert_eq!((-0.0f32).atanh(), -0.0f32);
|
||||||
assert_eq!(1.0f32.atanh(), Float::infinity::<f32>());
|
|
||||||
assert_eq!((-1.0f32).atanh(), Float::neg_infinity::<f32>());
|
let inf32: f32 = Float::infinity();
|
||||||
|
let neg_inf32: f32 = Float::neg_infinity();
|
||||||
|
assert_eq!(1.0f32.atanh(), inf32);
|
||||||
|
assert_eq!((-1.0f32).atanh(), neg_inf32);
|
||||||
|
|
||||||
assert!(2f64.atanh().atanh().is_NaN());
|
assert!(2f64.atanh().atanh().is_NaN());
|
||||||
assert!((-2f64).atanh().atanh().is_NaN());
|
assert!((-2f64).atanh().atanh().is_NaN());
|
||||||
assert!(Float::infinity::<f64>().atanh().is_NaN());
|
|
||||||
assert!(Float::neg_infinity::<f64>().atanh().is_NaN());
|
let inf64: f32 = Float::infinity();
|
||||||
assert!(Float::NaN::<f32>().atanh().is_NaN());
|
let neg_inf64: f32 = Float::neg_infinity();
|
||||||
|
let nan32: f32 = Float::NaN();
|
||||||
|
assert!(inf64.atanh().is_NaN());
|
||||||
|
assert!(neg_inf64.atanh().is_NaN());
|
||||||
|
assert!(nan32.atanh().is_NaN());
|
||||||
|
|
||||||
assert_approx_eq!(0.5f32.atanh(), 0.54930614433405484569762261846126285f32);
|
assert_approx_eq!(0.5f32.atanh(), 0.54930614433405484569762261846126285f32);
|
||||||
assert_approx_eq!((-0.5f32).atanh(), -0.54930614433405484569762261846126285f32);
|
assert_approx_eq!((-0.5f32).atanh(), -0.54930614433405484569762261846126285f32);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_real_consts() {
|
fn test_real_consts() {
|
||||||
assert_approx_eq!(Real::two_pi::<f32>(), 2f32 * Real::pi::<f32>());
|
let pi: f32 = Real::pi();
|
||||||
assert_approx_eq!(Real::frac_pi_2::<f32>(), Real::pi::<f32>() / 2f32);
|
let two_pi: f32 = Real::two_pi();
|
||||||
assert_approx_eq!(Real::frac_pi_3::<f32>(), Real::pi::<f32>() / 3f32);
|
let frac_pi_2: f32 = Real::frac_pi_2();
|
||||||
assert_approx_eq!(Real::frac_pi_4::<f32>(), Real::pi::<f32>() / 4f32);
|
let frac_pi_3: f32 = Real::frac_pi_3();
|
||||||
assert_approx_eq!(Real::frac_pi_6::<f32>(), Real::pi::<f32>() / 6f32);
|
let frac_pi_4: f32 = Real::frac_pi_4();
|
||||||
assert_approx_eq!(Real::frac_pi_8::<f32>(), Real::pi::<f32>() / 8f32);
|
let frac_pi_6: f32 = Real::frac_pi_6();
|
||||||
assert_approx_eq!(Real::frac_1_pi::<f32>(), 1f32 / Real::pi::<f32>());
|
let frac_pi_8: f32 = Real::frac_pi_8();
|
||||||
assert_approx_eq!(Real::frac_2_pi::<f32>(), 2f32 / Real::pi::<f32>());
|
let frac_1_pi: f32 = Real::frac_1_pi();
|
||||||
assert_approx_eq!(Real::frac_2_sqrtpi::<f32>(), 2f32 / Real::pi::<f32>().sqrt());
|
let frac_2_pi: f32 = Real::frac_2_pi();
|
||||||
assert_approx_eq!(Real::sqrt2::<f32>(), 2f32.sqrt());
|
let frac_2_sqrtpi: f32 = Real::frac_2_sqrtpi();
|
||||||
assert_approx_eq!(Real::frac_1_sqrt2::<f32>(), 1f32 / 2f32.sqrt());
|
let sqrt2: f32 = Real::sqrt2();
|
||||||
assert_approx_eq!(Real::log2_e::<f32>(), Real::e::<f32>().log2());
|
let frac_1_sqrt2: f32 = Real::frac_1_sqrt2();
|
||||||
assert_approx_eq!(Real::log10_e::<f32>(), Real::e::<f32>().log10());
|
let e: f32 = Real::e();
|
||||||
assert_approx_eq!(Real::ln_2::<f32>(), 2f32.ln());
|
let log2_e: f32 = Real::log2_e();
|
||||||
assert_approx_eq!(Real::ln_10::<f32>(), 10f32.ln());
|
let log10_e: f32 = Real::log10_e();
|
||||||
|
let ln_2: f32 = Real::ln_2();
|
||||||
|
let ln_10: f32 = Real::ln_10();
|
||||||
|
|
||||||
|
assert_approx_eq!(two_pi, 2f32 * pi);
|
||||||
|
assert_approx_eq!(frac_pi_2, pi / 2f32);
|
||||||
|
assert_approx_eq!(frac_pi_3, pi / 3f32);
|
||||||
|
assert_approx_eq!(frac_pi_4, pi / 4f32);
|
||||||
|
assert_approx_eq!(frac_pi_6, pi / 6f32);
|
||||||
|
assert_approx_eq!(frac_pi_8, pi / 8f32);
|
||||||
|
assert_approx_eq!(frac_1_pi, 1f32 / pi);
|
||||||
|
assert_approx_eq!(frac_2_pi, 2f32 / pi);
|
||||||
|
assert_approx_eq!(frac_2_sqrtpi, 2f32 / pi.sqrt());
|
||||||
|
assert_approx_eq!(sqrt2, 2f32.sqrt());
|
||||||
|
assert_approx_eq!(frac_1_sqrt2, 1f32 / 2f32.sqrt());
|
||||||
|
assert_approx_eq!(log2_e, e.log2());
|
||||||
|
assert_approx_eq!(log10_e, e.log10());
|
||||||
|
assert_approx_eq!(ln_2, 2f32.ln());
|
||||||
|
assert_approx_eq!(ln_10, 10f32.ln());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1153,17 +1193,23 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_primitive() {
|
fn test_primitive() {
|
||||||
assert_eq!(Primitive::bits::<f32>(), sys::size_of::<f32>() * 8);
|
let none: Option<f32> = None;
|
||||||
assert_eq!(Primitive::bytes::<f32>(), sys::size_of::<f32>());
|
assert_eq!(Primitive::bits(none), sys::size_of::<f32>() * 8);
|
||||||
|
assert_eq!(Primitive::bytes(none), sys::size_of::<f32>());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_is_normal() {
|
fn test_is_normal() {
|
||||||
assert!(!Float::NaN::<f32>().is_normal());
|
let nan: f32 = Float::NaN();
|
||||||
assert!(!Float::infinity::<f32>().is_normal());
|
let inf: f32 = Float::infinity();
|
||||||
assert!(!Float::neg_infinity::<f32>().is_normal());
|
let neg_inf: f32 = Float::neg_infinity();
|
||||||
assert!(!Zero::zero::<f32>().is_normal());
|
let zero: f32 = Zero::zero();
|
||||||
assert!(!Float::neg_zero::<f32>().is_normal());
|
let neg_zero: f32 = Float::neg_zero();
|
||||||
|
assert!(!nan.is_normal());
|
||||||
|
assert!(!inf.is_normal());
|
||||||
|
assert!(!neg_inf.is_normal());
|
||||||
|
assert!(!zero.is_normal());
|
||||||
|
assert!(!neg_zero.is_normal());
|
||||||
assert!(1f32.is_normal());
|
assert!(1f32.is_normal());
|
||||||
assert!(1e-37f32.is_normal());
|
assert!(1e-37f32.is_normal());
|
||||||
assert!(!1e-38f32.is_normal());
|
assert!(!1e-38f32.is_normal());
|
||||||
|
@ -1171,11 +1217,16 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_classify() {
|
fn test_classify() {
|
||||||
assert_eq!(Float::NaN::<f32>().classify(), FPNaN);
|
let nan: f32 = Float::NaN();
|
||||||
assert_eq!(Float::infinity::<f32>().classify(), FPInfinite);
|
let inf: f32 = Float::infinity();
|
||||||
assert_eq!(Float::neg_infinity::<f32>().classify(), FPInfinite);
|
let neg_inf: f32 = Float::neg_infinity();
|
||||||
assert_eq!(Zero::zero::<f32>().classify(), FPZero);
|
let zero: f32 = Zero::zero();
|
||||||
assert_eq!(Float::neg_zero::<f32>().classify(), FPZero);
|
let neg_zero: f32 = Float::neg_zero();
|
||||||
|
assert_eq!(nan.classify(), FPNaN);
|
||||||
|
assert_eq!(inf.classify(), FPInfinite);
|
||||||
|
assert_eq!(neg_inf.classify(), FPInfinite);
|
||||||
|
assert_eq!(zero.classify(), FPZero);
|
||||||
|
assert_eq!(neg_zero.classify(), FPZero);
|
||||||
assert_eq!(1f32.classify(), FPNormal);
|
assert_eq!(1f32.classify(), FPNormal);
|
||||||
assert_eq!(1e-37f32.classify(), FPNormal);
|
assert_eq!(1e-37f32.classify(), FPNormal);
|
||||||
assert_eq!(1e-38f32.classify(), FPSubnormal);
|
assert_eq!(1e-38f32.classify(), FPSubnormal);
|
||||||
|
@ -1192,11 +1243,13 @@ mod tests {
|
||||||
|
|
||||||
assert_eq!(Float::ldexp(0f32, -123), 0f32);
|
assert_eq!(Float::ldexp(0f32, -123), 0f32);
|
||||||
assert_eq!(Float::ldexp(-0f32, -123), -0f32);
|
assert_eq!(Float::ldexp(-0f32, -123), -0f32);
|
||||||
assert_eq!(Float::ldexp(Float::infinity::<f32>(), -123),
|
|
||||||
Float::infinity::<f32>());
|
let inf: f32 = Float::infinity();
|
||||||
assert_eq!(Float::ldexp(Float::neg_infinity::<f32>(), -123),
|
let neg_inf: f32 = Float::neg_infinity();
|
||||||
Float::neg_infinity::<f32>());
|
let nan: f32 = Float::NaN();
|
||||||
assert!(Float::ldexp(Float::NaN::<f32>(), -123).is_NaN());
|
assert_eq!(Float::ldexp(inf, -123), inf);
|
||||||
|
assert_eq!(Float::ldexp(neg_inf, -123), neg_inf);
|
||||||
|
assert!(Float::ldexp(nan, -123).is_NaN());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1214,10 +1267,12 @@ mod tests {
|
||||||
|
|
||||||
assert_eq!(0f32.frexp(), (0f32, 0));
|
assert_eq!(0f32.frexp(), (0f32, 0));
|
||||||
assert_eq!((-0f32).frexp(), (-0f32, 0));
|
assert_eq!((-0f32).frexp(), (-0f32, 0));
|
||||||
assert_eq!(match Float::infinity::<f32>().frexp() { (x, _) => x },
|
|
||||||
Float::infinity::<f32>())
|
let inf: f32 = Float::infinity();
|
||||||
assert_eq!(match Float::neg_infinity::<f32>().frexp() { (x, _) => x },
|
let neg_inf: f32 = Float::neg_infinity();
|
||||||
Float::neg_infinity::<f32>())
|
let nan: f32 = Float::NaN();
|
||||||
assert!(match Float::NaN::<f32>().frexp() { (x, _) => x.is_NaN() })
|
assert_eq!(match inf.frexp() { (x, _) => x }, inf)
|
||||||
|
assert_eq!(match neg_inf.frexp() { (x, _) => x }, neg_inf)
|
||||||
|
assert!(match nan.frexp() { (x, _) => x.is_NaN() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -205,7 +205,7 @@ impl ApproxEq<f64> for f64 {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn approx_eq(&self, other: &f64) -> bool {
|
fn approx_eq(&self, other: &f64) -> bool {
|
||||||
self.approx_eq_eps(other, &ApproxEq::approx_epsilon::<f64, f64>())
|
self.approx_eq_eps(other, &1.0e-6)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -578,11 +578,14 @@ impl Real for f64 {
|
||||||
|
|
||||||
/// Converts to degrees, assuming the number is in radians
|
/// Converts to degrees, assuming the number is in radians
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_degrees(&self) -> f64 { *self * (180.0 / Real::pi::<f64>()) }
|
fn to_degrees(&self) -> f64 { *self * (180.0f64 / Real::pi()) }
|
||||||
|
|
||||||
/// Converts to radians, assuming the number is in degrees
|
/// Converts to radians, assuming the number is in degrees
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_radians(&self) -> f64 { *self * (Real::pi::<f64>() / 180.0) }
|
fn to_radians(&self) -> f64 {
|
||||||
|
let value: f64 = Real::pi();
|
||||||
|
*self * (value / 180.0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RealExt for f64 {
|
impl RealExt for f64 {
|
||||||
|
@ -625,10 +628,10 @@ impl Bounded for f64 {
|
||||||
|
|
||||||
impl Primitive for f64 {
|
impl Primitive for f64 {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn bits() -> uint { 64 }
|
fn bits(_: Option<f64>) -> uint { 64 }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn bytes() -> uint { Primitive::bits::<f64>() / 8 }
|
fn bytes(_: Option<f64>) -> uint { Primitive::bits(Some(0f64)) / 8 }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Float for f64 {
|
impl Float for f64 {
|
||||||
|
@ -685,25 +688,25 @@ impl Float for f64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mantissa_digits() -> uint { 53 }
|
fn mantissa_digits(_: Option<f64>) -> uint { 53 }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn digits() -> uint { 15 }
|
fn digits(_: Option<f64>) -> uint { 15 }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn epsilon() -> f64 { 2.2204460492503131e-16 }
|
fn epsilon() -> f64 { 2.2204460492503131e-16 }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn min_exp() -> int { -1021 }
|
fn min_exp(_: Option<f64>) -> int { -1021 }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn max_exp() -> int { 1024 }
|
fn max_exp(_: Option<f64>) -> int { 1024 }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn min_10_exp() -> int { -307 }
|
fn min_10_exp(_: Option<f64>) -> int { -307 }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn max_10_exp() -> int { 308 }
|
fn max_10_exp(_: Option<f64>) -> int { 308 }
|
||||||
|
|
||||||
/// Constructs a floating point number by multiplying `x` by 2 raised to the power of `exp`
|
/// Constructs a floating point number by multiplying `x` by 2 raised to the power of `exp`
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -983,16 +986,20 @@ mod tests {
|
||||||
fn test_min() {
|
fn test_min() {
|
||||||
assert_eq!(1f64.min(&2f64), 1f64);
|
assert_eq!(1f64.min(&2f64), 1f64);
|
||||||
assert_eq!(2f64.min(&1f64), 1f64);
|
assert_eq!(2f64.min(&1f64), 1f64);
|
||||||
assert!(1f64.min(&Float::NaN::<f64>()).is_NaN());
|
|
||||||
assert!(Float::NaN::<f64>().min(&1f64).is_NaN());
|
let nan: f64 = Float::NaN();
|
||||||
|
assert!(1f64.min(&nan).is_NaN());
|
||||||
|
assert!(nan.min(&1f64).is_NaN());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_max() {
|
fn test_max() {
|
||||||
assert_eq!(1f64.max(&2f64), 2f64);
|
assert_eq!(1f64.max(&2f64), 2f64);
|
||||||
assert_eq!(2f64.max(&1f64), 2f64);
|
assert_eq!(2f64.max(&1f64), 2f64);
|
||||||
assert!(1f64.max(&Float::NaN::<f64>()).is_NaN());
|
|
||||||
assert!(Float::NaN::<f64>().max(&1f64).is_NaN());
|
let nan: f64 = Float::NaN();
|
||||||
|
assert!(1f64.max(&nan).is_NaN());
|
||||||
|
assert!(nan.max(&1f64).is_NaN());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1000,9 +1007,11 @@ mod tests {
|
||||||
assert_eq!(1f64.clamp(&2f64, &4f64), 2f64);
|
assert_eq!(1f64.clamp(&2f64, &4f64), 2f64);
|
||||||
assert_eq!(8f64.clamp(&2f64, &4f64), 4f64);
|
assert_eq!(8f64.clamp(&2f64, &4f64), 4f64);
|
||||||
assert_eq!(3f64.clamp(&2f64, &4f64), 3f64);
|
assert_eq!(3f64.clamp(&2f64, &4f64), 3f64);
|
||||||
assert!(3f64.clamp(&Float::NaN::<f64>(), &4f64).is_NaN());
|
|
||||||
assert!(3f64.clamp(&2f64, &Float::NaN::<f64>()).is_NaN());
|
let nan: f64 = Float::NaN();
|
||||||
assert!(Float::NaN::<f64>().clamp(&2f64, &4f64).is_NaN());
|
assert!(3f64.clamp(&nan, &4f64).is_NaN());
|
||||||
|
assert!(3f64.clamp(&2f64, &nan).is_NaN());
|
||||||
|
assert!(nan.clamp(&2f64, &4f64).is_NaN());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1079,9 +1088,13 @@ mod tests {
|
||||||
fn test_asinh() {
|
fn test_asinh() {
|
||||||
assert_eq!(0.0f64.asinh(), 0.0f64);
|
assert_eq!(0.0f64.asinh(), 0.0f64);
|
||||||
assert_eq!((-0.0f64).asinh(), -0.0f64);
|
assert_eq!((-0.0f64).asinh(), -0.0f64);
|
||||||
assert_eq!(Float::infinity::<f64>().asinh(), Float::infinity::<f64>());
|
|
||||||
assert_eq!(Float::neg_infinity::<f64>().asinh(), Float::neg_infinity::<f64>());
|
let inf: f64 = Float::infinity();
|
||||||
assert!(Float::NaN::<f64>().asinh().is_NaN());
|
let neg_inf: f64 = Float::neg_infinity();
|
||||||
|
let nan: f64 = Float::NaN();
|
||||||
|
assert_eq!(inf.asinh(), inf);
|
||||||
|
assert_eq!(neg_inf.asinh(), neg_inf);
|
||||||
|
assert!(nan.asinh().is_NaN());
|
||||||
assert_approx_eq!(2.0f64.asinh(), 1.443635475178810342493276740273105f64);
|
assert_approx_eq!(2.0f64.asinh(), 1.443635475178810342493276740273105f64);
|
||||||
assert_approx_eq!((-2.0f64).asinh(), -1.443635475178810342493276740273105f64);
|
assert_approx_eq!((-2.0f64).asinh(), -1.443635475178810342493276740273105f64);
|
||||||
}
|
}
|
||||||
|
@ -1090,9 +1103,13 @@ mod tests {
|
||||||
fn test_acosh() {
|
fn test_acosh() {
|
||||||
assert_eq!(1.0f64.acosh(), 0.0f64);
|
assert_eq!(1.0f64.acosh(), 0.0f64);
|
||||||
assert!(0.999f64.acosh().is_NaN());
|
assert!(0.999f64.acosh().is_NaN());
|
||||||
assert_eq!(Float::infinity::<f64>().acosh(), Float::infinity::<f64>());
|
|
||||||
assert!(Float::neg_infinity::<f64>().acosh().is_NaN());
|
let inf: f64 = Float::infinity();
|
||||||
assert!(Float::NaN::<f64>().acosh().is_NaN());
|
let neg_inf: f64 = Float::neg_infinity();
|
||||||
|
let nan: f64 = Float::NaN();
|
||||||
|
assert_eq!(inf.acosh(), inf);
|
||||||
|
assert!(neg_inf.acosh().is_NaN());
|
||||||
|
assert!(nan.acosh().is_NaN());
|
||||||
assert_approx_eq!(2.0f64.acosh(), 1.31695789692481670862504634730796844f64);
|
assert_approx_eq!(2.0f64.acosh(), 1.31695789692481670862504634730796844f64);
|
||||||
assert_approx_eq!(3.0f64.acosh(), 1.76274717403908605046521864995958461f64);
|
assert_approx_eq!(3.0f64.acosh(), 1.76274717403908605046521864995958461f64);
|
||||||
}
|
}
|
||||||
|
@ -1101,34 +1118,56 @@ mod tests {
|
||||||
fn test_atanh() {
|
fn test_atanh() {
|
||||||
assert_eq!(0.0f64.atanh(), 0.0f64);
|
assert_eq!(0.0f64.atanh(), 0.0f64);
|
||||||
assert_eq!((-0.0f64).atanh(), -0.0f64);
|
assert_eq!((-0.0f64).atanh(), -0.0f64);
|
||||||
assert_eq!(1.0f64.atanh(), Float::infinity::<f64>());
|
|
||||||
assert_eq!((-1.0f64).atanh(), Float::neg_infinity::<f64>());
|
let inf: f64 = Float::infinity();
|
||||||
|
let neg_inf: f64 = Float::neg_infinity();
|
||||||
|
let nan: f64 = Float::NaN();
|
||||||
|
assert_eq!(1.0f64.atanh(), inf);
|
||||||
|
assert_eq!((-1.0f64).atanh(), neg_inf);
|
||||||
assert!(2f64.atanh().atanh().is_NaN());
|
assert!(2f64.atanh().atanh().is_NaN());
|
||||||
assert!((-2f64).atanh().atanh().is_NaN());
|
assert!((-2f64).atanh().atanh().is_NaN());
|
||||||
assert!(Float::infinity::<f64>().atanh().is_NaN());
|
assert!(inf.atanh().is_NaN());
|
||||||
assert!(Float::neg_infinity::<f64>().atanh().is_NaN());
|
assert!(neg_inf.atanh().is_NaN());
|
||||||
assert!(Float::NaN::<f64>().atanh().is_NaN());
|
assert!(nan.atanh().is_NaN());
|
||||||
assert_approx_eq!(0.5f64.atanh(), 0.54930614433405484569762261846126285f64);
|
assert_approx_eq!(0.5f64.atanh(), 0.54930614433405484569762261846126285f64);
|
||||||
assert_approx_eq!((-0.5f64).atanh(), -0.54930614433405484569762261846126285f64);
|
assert_approx_eq!((-0.5f64).atanh(), -0.54930614433405484569762261846126285f64);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_real_consts() {
|
fn test_real_consts() {
|
||||||
assert_approx_eq!(Real::two_pi::<f64>(), 2.0 * Real::pi::<f64>());
|
let pi: f64 = Real::pi();
|
||||||
assert_approx_eq!(Real::frac_pi_2::<f64>(), Real::pi::<f64>() / 2f64);
|
let two_pi: f64 = Real::two_pi();
|
||||||
assert_approx_eq!(Real::frac_pi_3::<f64>(), Real::pi::<f64>() / 3f64);
|
let frac_pi_2: f64 = Real::frac_pi_2();
|
||||||
assert_approx_eq!(Real::frac_pi_4::<f64>(), Real::pi::<f64>() / 4f64);
|
let frac_pi_3: f64 = Real::frac_pi_3();
|
||||||
assert_approx_eq!(Real::frac_pi_6::<f64>(), Real::pi::<f64>() / 6f64);
|
let frac_pi_4: f64 = Real::frac_pi_4();
|
||||||
assert_approx_eq!(Real::frac_pi_8::<f64>(), Real::pi::<f64>() / 8f64);
|
let frac_pi_6: f64 = Real::frac_pi_6();
|
||||||
assert_approx_eq!(Real::frac_1_pi::<f64>(), 1f64 / Real::pi::<f64>());
|
let frac_pi_8: f64 = Real::frac_pi_8();
|
||||||
assert_approx_eq!(Real::frac_2_pi::<f64>(), 2f64 / Real::pi::<f64>());
|
let frac_1_pi: f64 = Real::frac_1_pi();
|
||||||
assert_approx_eq!(Real::frac_2_sqrtpi::<f64>(), 2f64 / Real::pi::<f64>().sqrt());
|
let frac_2_pi: f64 = Real::frac_2_pi();
|
||||||
assert_approx_eq!(Real::sqrt2::<f64>(), 2f64.sqrt());
|
let frac_2_sqrtpi: f64 = Real::frac_2_sqrtpi();
|
||||||
assert_approx_eq!(Real::frac_1_sqrt2::<f64>(), 1f64 / 2f64.sqrt());
|
let sqrt2: f64 = Real::sqrt2();
|
||||||
assert_approx_eq!(Real::log2_e::<f64>(), Real::e::<f64>().log2());
|
let frac_1_sqrt2: f64 = Real::frac_1_sqrt2();
|
||||||
assert_approx_eq!(Real::log10_e::<f64>(), Real::e::<f64>().log10());
|
let e: f64 = Real::e();
|
||||||
assert_approx_eq!(Real::ln_2::<f64>(), 2f64.ln());
|
let log2_e: f64 = Real::log2_e();
|
||||||
assert_approx_eq!(Real::ln_10::<f64>(), 10f64.ln());
|
let log10_e: f64 = Real::log10_e();
|
||||||
|
let ln_2: f64 = Real::ln_2();
|
||||||
|
let ln_10: f64 = Real::ln_10();
|
||||||
|
|
||||||
|
assert_approx_eq!(two_pi, 2.0 * pi);
|
||||||
|
assert_approx_eq!(frac_pi_2, pi / 2f64);
|
||||||
|
assert_approx_eq!(frac_pi_3, pi / 3f64);
|
||||||
|
assert_approx_eq!(frac_pi_4, pi / 4f64);
|
||||||
|
assert_approx_eq!(frac_pi_6, pi / 6f64);
|
||||||
|
assert_approx_eq!(frac_pi_8, pi / 8f64);
|
||||||
|
assert_approx_eq!(frac_1_pi, 1f64 / pi);
|
||||||
|
assert_approx_eq!(frac_2_pi, 2f64 / pi);
|
||||||
|
assert_approx_eq!(frac_2_sqrtpi, 2f64 / pi.sqrt());
|
||||||
|
assert_approx_eq!(sqrt2, 2f64.sqrt());
|
||||||
|
assert_approx_eq!(frac_1_sqrt2, 1f64 / 2f64.sqrt());
|
||||||
|
assert_approx_eq!(log2_e, e.log2());
|
||||||
|
assert_approx_eq!(log10_e, e.log10());
|
||||||
|
assert_approx_eq!(ln_2, 2f64.ln());
|
||||||
|
assert_approx_eq!(ln_10, 10f64.ln());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1204,17 +1243,23 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_primitive() {
|
fn test_primitive() {
|
||||||
assert_eq!(Primitive::bits::<f64>(), sys::size_of::<f64>() * 8);
|
let none: Option<f64> = None;
|
||||||
assert_eq!(Primitive::bytes::<f64>(), sys::size_of::<f64>());
|
assert_eq!(Primitive::bits(none), sys::size_of::<f64>() * 8);
|
||||||
|
assert_eq!(Primitive::bytes(none), sys::size_of::<f64>());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_is_normal() {
|
fn test_is_normal() {
|
||||||
assert!(!Float::NaN::<f64>().is_normal());
|
let nan: f64 = Float::NaN();
|
||||||
assert!(!Float::infinity::<f64>().is_normal());
|
let inf: f64 = Float::infinity();
|
||||||
assert!(!Float::neg_infinity::<f64>().is_normal());
|
let neg_inf: f64 = Float::neg_infinity();
|
||||||
assert!(!Zero::zero::<f64>().is_normal());
|
let zero: f64 = Zero::zero();
|
||||||
assert!(!Float::neg_zero::<f64>().is_normal());
|
let neg_zero: f64 = Float::neg_zero();
|
||||||
|
assert!(!nan.is_normal());
|
||||||
|
assert!(!inf.is_normal());
|
||||||
|
assert!(!neg_inf.is_normal());
|
||||||
|
assert!(!zero.is_normal());
|
||||||
|
assert!(!neg_zero.is_normal());
|
||||||
assert!(1f64.is_normal());
|
assert!(1f64.is_normal());
|
||||||
assert!(1e-307f64.is_normal());
|
assert!(1e-307f64.is_normal());
|
||||||
assert!(!1e-308f64.is_normal());
|
assert!(!1e-308f64.is_normal());
|
||||||
|
@ -1222,11 +1267,16 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_classify() {
|
fn test_classify() {
|
||||||
assert_eq!(Float::NaN::<f64>().classify(), FPNaN);
|
let nan: f64 = Float::NaN();
|
||||||
assert_eq!(Float::infinity::<f64>().classify(), FPInfinite);
|
let inf: f64 = Float::infinity();
|
||||||
assert_eq!(Float::neg_infinity::<f64>().classify(), FPInfinite);
|
let neg_inf: f64 = Float::neg_infinity();
|
||||||
assert_eq!(Zero::zero::<f64>().classify(), FPZero);
|
let zero: f64 = Zero::zero();
|
||||||
assert_eq!(Float::neg_zero::<f64>().classify(), FPZero);
|
let neg_zero: f64 = Float::neg_zero();
|
||||||
|
assert_eq!(nan.classify(), FPNaN);
|
||||||
|
assert_eq!(inf.classify(), FPInfinite);
|
||||||
|
assert_eq!(neg_inf.classify(), FPInfinite);
|
||||||
|
assert_eq!(zero.classify(), FPZero);
|
||||||
|
assert_eq!(neg_zero.classify(), FPZero);
|
||||||
assert_eq!(1e-307f64.classify(), FPNormal);
|
assert_eq!(1e-307f64.classify(), FPNormal);
|
||||||
assert_eq!(1e-308f64.classify(), FPSubnormal);
|
assert_eq!(1e-308f64.classify(), FPSubnormal);
|
||||||
}
|
}
|
||||||
|
@ -1242,11 +1292,13 @@ mod tests {
|
||||||
|
|
||||||
assert_eq!(Float::ldexp(0f64, -123), 0f64);
|
assert_eq!(Float::ldexp(0f64, -123), 0f64);
|
||||||
assert_eq!(Float::ldexp(-0f64, -123), -0f64);
|
assert_eq!(Float::ldexp(-0f64, -123), -0f64);
|
||||||
assert_eq!(Float::ldexp(Float::infinity::<f64>(), -123),
|
|
||||||
Float::infinity::<f64>());
|
let inf: f64 = Float::infinity();
|
||||||
assert_eq!(Float::ldexp(Float::neg_infinity::<f64>(), -123),
|
let neg_inf: f64 = Float::neg_infinity();
|
||||||
Float::neg_infinity::<f64>());
|
let nan: f64 = Float::NaN();
|
||||||
assert!(Float::ldexp(Float::NaN::<f64>(), -123).is_NaN());
|
assert_eq!(Float::ldexp(inf, -123), inf);
|
||||||
|
assert_eq!(Float::ldexp(neg_inf, -123), neg_inf);
|
||||||
|
assert!(Float::ldexp(nan, -123).is_NaN());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1264,10 +1316,12 @@ mod tests {
|
||||||
|
|
||||||
assert_eq!(0f64.frexp(), (0f64, 0));
|
assert_eq!(0f64.frexp(), (0f64, 0));
|
||||||
assert_eq!((-0f64).frexp(), (-0f64, 0));
|
assert_eq!((-0f64).frexp(), (-0f64, 0));
|
||||||
assert_eq!(match Float::infinity::<f64>().frexp() { (x, _) => x },
|
|
||||||
Float::infinity::<f64>())
|
let inf: f64 = Float::infinity();
|
||||||
assert_eq!(match Float::neg_infinity::<f64>().frexp() { (x, _) => x },
|
let neg_inf: f64 = Float::neg_infinity();
|
||||||
Float::neg_infinity::<f64>())
|
let nan: f64 = Float::NaN();
|
||||||
assert!(match Float::NaN::<f64>().frexp() { (x, _) => x.is_NaN() })
|
assert_eq!(match inf.frexp() { (x, _) => x }, inf)
|
||||||
|
assert_eq!(match neg_inf.frexp() { (x, _) => x }, neg_inf)
|
||||||
|
assert!(match nan.frexp() { (x, _) => x.is_NaN() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -342,7 +342,7 @@ impl ApproxEq<float> for float {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn approx_eq(&self, other: &float) -> bool {
|
fn approx_eq(&self, other: &float) -> bool {
|
||||||
self.approx_eq_eps(other, &ApproxEq::approx_epsilon::<float, float>())
|
self.approx_eq_eps(other, &1.0e-6)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -783,32 +783,56 @@ impl Signed for float {
|
||||||
|
|
||||||
impl Bounded for float {
|
impl Bounded for float {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn min_value() -> float { Bounded::min_value::<f64>() as float }
|
fn min_value() -> float {
|
||||||
|
let x: f64 = Bounded::min_value();
|
||||||
|
x as float
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn max_value() -> float { Bounded::max_value::<f64>() as float }
|
fn max_value() -> float {
|
||||||
|
let x: f64 = Bounded::max_value();
|
||||||
|
x as float
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Primitive for float {
|
impl Primitive for float {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn bits() -> uint { Primitive::bits::<f64>() }
|
fn bits(_: Option<float>) -> uint {
|
||||||
|
let bits: uint = Primitive::bits(Some(0f64));
|
||||||
|
bits
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn bytes() -> uint { Primitive::bytes::<f64>() }
|
fn bytes(_: Option<float>) -> uint {
|
||||||
|
let bytes: uint = Primitive::bytes(Some(0f64));
|
||||||
|
bytes
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Float for float {
|
impl Float for float {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn NaN() -> float { Float::NaN::<f64>() as float }
|
fn NaN() -> float {
|
||||||
|
let value: f64 = Float::NaN();
|
||||||
|
value as float
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn infinity() -> float { Float::infinity::<f64>() as float }
|
fn infinity() -> float {
|
||||||
|
let value: f64 = Float::infinity();
|
||||||
|
value as float
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn neg_infinity() -> float { Float::neg_infinity::<f64>() as float }
|
fn neg_infinity() -> float {
|
||||||
|
let value: f64 = Float::neg_infinity();
|
||||||
|
value as float
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn neg_zero() -> float { Float::neg_zero::<f64>() as float }
|
fn neg_zero() -> float {
|
||||||
|
let value: f64 = Float::neg_zero();
|
||||||
|
value as float
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns `true` if the number is NaN
|
/// Returns `true` if the number is NaN
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -832,30 +856,46 @@ impl Float for float {
|
||||||
fn classify(&self) -> FPCategory { (*self as f64).classify() }
|
fn classify(&self) -> FPCategory { (*self as f64).classify() }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mantissa_digits() -> uint { Float::mantissa_digits::<f64>() }
|
fn mantissa_digits(_: Option<float>) -> uint {
|
||||||
|
Float::mantissa_digits(Some(0f64))
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn digits() -> uint { Float::digits::<f64>() }
|
fn digits(_: Option<float>) -> uint {
|
||||||
|
Float::digits(Some(0f64))
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn epsilon() -> float { Float::epsilon::<f64>() as float }
|
fn epsilon() -> float {
|
||||||
|
let value: f64 = Float::epsilon();
|
||||||
|
value as float
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn min_exp() -> int { Float::min_exp::<f64>() }
|
fn min_exp(_: Option<float>) -> int {
|
||||||
|
Float::min_exp(Some(0f64))
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn max_exp() -> int { Float::max_exp::<f64>() }
|
fn max_exp(_: Option<float>) -> int {
|
||||||
|
Float::max_exp(Some(0f64))
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn min_10_exp() -> int { Float::min_10_exp::<f64>() }
|
fn min_10_exp(_: Option<float>) -> int {
|
||||||
|
Float::min_10_exp(Some(0f64))
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn max_10_exp() -> int { Float::max_10_exp::<f64>() }
|
fn max_10_exp(_: Option<float>) -> int {
|
||||||
|
Float::max_10_exp(Some(0f64))
|
||||||
|
}
|
||||||
|
|
||||||
/// Constructs a floating point number by multiplying `x` by 2 raised to the power of `exp`
|
/// Constructs a floating point number by multiplying `x` by 2 raised to the power of `exp`
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ldexp(x: float, exp: int) -> float {
|
fn ldexp(x: float, exp: int) -> float {
|
||||||
Float::ldexp(x as f64, exp) as float
|
let value: f64 = Float::ldexp(x as f64, exp);
|
||||||
|
value as float
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -937,9 +977,10 @@ mod tests {
|
||||||
assert_eq!(1f.clamp(&2f, &4f), 2f);
|
assert_eq!(1f.clamp(&2f, &4f), 2f);
|
||||||
assert_eq!(8f.clamp(&2f, &4f), 4f);
|
assert_eq!(8f.clamp(&2f, &4f), 4f);
|
||||||
assert_eq!(3f.clamp(&2f, &4f), 3f);
|
assert_eq!(3f.clamp(&2f, &4f), 3f);
|
||||||
assert!(3f.clamp(&Float::NaN::<float>(), &4f).is_NaN());
|
let nan: float = Float::NaN();
|
||||||
assert!(3f.clamp(&2f, &Float::NaN::<float>()).is_NaN());
|
assert!(3f.clamp(&nan, &4f).is_NaN());
|
||||||
assert!(Float::NaN::<float>().clamp(&2f, &4f).is_NaN());
|
assert!(3f.clamp(&2f, &nan).is_NaN());
|
||||||
|
assert!(nan.clamp(&2f, &4f).is_NaN());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1016,9 +1057,13 @@ mod tests {
|
||||||
fn test_asinh() {
|
fn test_asinh() {
|
||||||
assert_eq!(0.0f.asinh(), 0.0f);
|
assert_eq!(0.0f.asinh(), 0.0f);
|
||||||
assert_eq!((-0.0f).asinh(), -0.0f);
|
assert_eq!((-0.0f).asinh(), -0.0f);
|
||||||
assert_eq!(Float::infinity::<float>().asinh(), Float::infinity::<float>());
|
|
||||||
assert_eq!(Float::neg_infinity::<float>().asinh(), Float::neg_infinity::<float>());
|
let inf: float = Float::infinity();
|
||||||
assert!(Float::NaN::<float>().asinh().is_NaN());
|
let neg_inf: float = Float::neg_infinity();
|
||||||
|
let nan: float = Float::NaN();
|
||||||
|
assert_eq!(inf.asinh(), inf);
|
||||||
|
assert_eq!(neg_inf.asinh(), neg_inf);
|
||||||
|
assert!(nan.asinh().is_NaN());
|
||||||
assert_approx_eq!(2.0f.asinh(), 1.443635475178810342493276740273105f);
|
assert_approx_eq!(2.0f.asinh(), 1.443635475178810342493276740273105f);
|
||||||
assert_approx_eq!((-2.0f).asinh(), -1.443635475178810342493276740273105f);
|
assert_approx_eq!((-2.0f).asinh(), -1.443635475178810342493276740273105f);
|
||||||
}
|
}
|
||||||
|
@ -1027,9 +1072,13 @@ mod tests {
|
||||||
fn test_acosh() {
|
fn test_acosh() {
|
||||||
assert_eq!(1.0f.acosh(), 0.0f);
|
assert_eq!(1.0f.acosh(), 0.0f);
|
||||||
assert!(0.999f.acosh().is_NaN());
|
assert!(0.999f.acosh().is_NaN());
|
||||||
assert_eq!(Float::infinity::<float>().acosh(), Float::infinity::<float>());
|
|
||||||
assert!(Float::neg_infinity::<float>().acosh().is_NaN());
|
let inf: float = Float::infinity();
|
||||||
assert!(Float::NaN::<float>().acosh().is_NaN());
|
let neg_inf: float = Float::neg_infinity();
|
||||||
|
let nan: float = Float::NaN();
|
||||||
|
assert_eq!(inf.acosh(), inf);
|
||||||
|
assert!(neg_inf.acosh().is_NaN());
|
||||||
|
assert!(nan.acosh().is_NaN());
|
||||||
assert_approx_eq!(2.0f.acosh(), 1.31695789692481670862504634730796844f);
|
assert_approx_eq!(2.0f.acosh(), 1.31695789692481670862504634730796844f);
|
||||||
assert_approx_eq!(3.0f.acosh(), 1.76274717403908605046521864995958461f);
|
assert_approx_eq!(3.0f.acosh(), 1.76274717403908605046521864995958461f);
|
||||||
}
|
}
|
||||||
|
@ -1038,34 +1087,58 @@ mod tests {
|
||||||
fn test_atanh() {
|
fn test_atanh() {
|
||||||
assert_eq!(0.0f.atanh(), 0.0f);
|
assert_eq!(0.0f.atanh(), 0.0f);
|
||||||
assert_eq!((-0.0f).atanh(), -0.0f);
|
assert_eq!((-0.0f).atanh(), -0.0f);
|
||||||
assert_eq!(1.0f.atanh(), Float::infinity::<float>());
|
|
||||||
assert_eq!((-1.0f).atanh(), Float::neg_infinity::<float>());
|
let inf: float = Float::infinity();
|
||||||
|
let neg_inf: float = Float::neg_infinity();
|
||||||
|
let inf64: f64 = Float::infinity();
|
||||||
|
let neg_inf64: f64 = Float::neg_infinity();
|
||||||
|
let nan: float = Float::NaN();
|
||||||
|
assert_eq!(1.0f.atanh(), inf);
|
||||||
|
assert_eq!((-1.0f).atanh(), neg_inf);
|
||||||
assert!(2f64.atanh().atanh().is_NaN());
|
assert!(2f64.atanh().atanh().is_NaN());
|
||||||
assert!((-2f64).atanh().atanh().is_NaN());
|
assert!((-2f64).atanh().atanh().is_NaN());
|
||||||
assert!(Float::infinity::<f64>().atanh().is_NaN());
|
assert!(inf64.atanh().is_NaN());
|
||||||
assert!(Float::neg_infinity::<f64>().atanh().is_NaN());
|
assert!(neg_inf64.atanh().is_NaN());
|
||||||
assert!(Float::NaN::<float>().atanh().is_NaN());
|
assert!(nan.atanh().is_NaN());
|
||||||
assert_approx_eq!(0.5f.atanh(), 0.54930614433405484569762261846126285f);
|
assert_approx_eq!(0.5f.atanh(), 0.54930614433405484569762261846126285f);
|
||||||
assert_approx_eq!((-0.5f).atanh(), -0.54930614433405484569762261846126285f);
|
assert_approx_eq!((-0.5f).atanh(), -0.54930614433405484569762261846126285f);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_real_consts() {
|
fn test_real_consts() {
|
||||||
assert_approx_eq!(Real::two_pi::<float>(), 2f * Real::pi::<float>());
|
let pi: float = Real::pi();
|
||||||
assert_approx_eq!(Real::frac_pi_2::<float>(), Real::pi::<float>() / 2f);
|
let two_pi: float = Real::two_pi();
|
||||||
assert_approx_eq!(Real::frac_pi_3::<float>(), Real::pi::<float>() / 3f);
|
let frac_pi_2: float = Real::frac_pi_2();
|
||||||
assert_approx_eq!(Real::frac_pi_4::<float>(), Real::pi::<float>() / 4f);
|
let frac_pi_3: float = Real::frac_pi_3();
|
||||||
assert_approx_eq!(Real::frac_pi_6::<float>(), Real::pi::<float>() / 6f);
|
let frac_pi_4: float = Real::frac_pi_4();
|
||||||
assert_approx_eq!(Real::frac_pi_8::<float>(), Real::pi::<float>() / 8f);
|
let frac_pi_6: float = Real::frac_pi_6();
|
||||||
assert_approx_eq!(Real::frac_1_pi::<float>(), 1f / Real::pi::<float>());
|
let frac_pi_8: float = Real::frac_pi_8();
|
||||||
assert_approx_eq!(Real::frac_2_pi::<float>(), 2f / Real::pi::<float>());
|
let frac_1_pi: float = Real::frac_1_pi();
|
||||||
assert_approx_eq!(Real::frac_2_sqrtpi::<float>(), 2f / Real::pi::<float>().sqrt());
|
let frac_2_pi: float = Real::frac_2_pi();
|
||||||
assert_approx_eq!(Real::sqrt2::<float>(), 2f.sqrt());
|
let frac_2_sqrtpi: float = Real::frac_2_sqrtpi();
|
||||||
assert_approx_eq!(Real::frac_1_sqrt2::<float>(), 1f / 2f.sqrt());
|
let sqrt2: float = Real::sqrt2();
|
||||||
assert_approx_eq!(Real::log2_e::<float>(), Real::e::<float>().log2());
|
let frac_1_sqrt2: float = Real::frac_1_sqrt2();
|
||||||
assert_approx_eq!(Real::log10_e::<float>(), Real::e::<float>().log10());
|
let e: float = Real::e();
|
||||||
assert_approx_eq!(Real::ln_2::<float>(), 2f.ln());
|
let log2_e: float = Real::log2_e();
|
||||||
assert_approx_eq!(Real::ln_10::<float>(), 10f.ln());
|
let log10_e: float = Real::log10_e();
|
||||||
|
let ln_2: float = Real::ln_2();
|
||||||
|
let ln_10: float = Real::ln_10();
|
||||||
|
|
||||||
|
assert_approx_eq!(two_pi, 2f * pi);
|
||||||
|
assert_approx_eq!(frac_pi_2, pi / 2f);
|
||||||
|
assert_approx_eq!(frac_pi_3, pi / 3f);
|
||||||
|
assert_approx_eq!(frac_pi_4, pi / 4f);
|
||||||
|
assert_approx_eq!(frac_pi_6, pi / 6f);
|
||||||
|
assert_approx_eq!(frac_pi_8, pi / 8f);
|
||||||
|
assert_approx_eq!(frac_1_pi, 1f / pi);
|
||||||
|
assert_approx_eq!(frac_2_pi, 2f / pi);
|
||||||
|
assert_approx_eq!(frac_2_sqrtpi, 2f / pi.sqrt());
|
||||||
|
assert_approx_eq!(sqrt2, 2f.sqrt());
|
||||||
|
assert_approx_eq!(frac_1_sqrt2, 1f / 2f.sqrt());
|
||||||
|
assert_approx_eq!(log2_e, e.log2());
|
||||||
|
assert_approx_eq!(log10_e, e.log10());
|
||||||
|
assert_approx_eq!(ln_2, 2f.ln());
|
||||||
|
assert_approx_eq!(ln_10, 10f.ln());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1141,17 +1214,23 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_primitive() {
|
fn test_primitive() {
|
||||||
assert_eq!(Primitive::bits::<float>(), sys::size_of::<float>() * 8);
|
let none: Option<float> = None;
|
||||||
assert_eq!(Primitive::bytes::<float>(), sys::size_of::<float>());
|
assert_eq!(Primitive::bits(none), sys::size_of::<float>() * 8);
|
||||||
|
assert_eq!(Primitive::bytes(none), sys::size_of::<float>());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_is_normal() {
|
fn test_is_normal() {
|
||||||
assert!(!Float::NaN::<float>().is_normal());
|
let nan: float = Float::NaN();
|
||||||
assert!(!Float::infinity::<float>().is_normal());
|
let inf: float = Float::infinity();
|
||||||
assert!(!Float::neg_infinity::<float>().is_normal());
|
let neg_inf: float = Float::neg_infinity();
|
||||||
assert!(!Zero::zero::<float>().is_normal());
|
let zero: float = Zero::zero();
|
||||||
assert!(!Float::neg_zero::<float>().is_normal());
|
let neg_zero: float = Float::neg_zero();
|
||||||
|
assert!(!nan.is_normal());
|
||||||
|
assert!(!inf.is_normal());
|
||||||
|
assert!(!neg_inf.is_normal());
|
||||||
|
assert!(!zero.is_normal());
|
||||||
|
assert!(!neg_zero.is_normal());
|
||||||
assert!(1f.is_normal());
|
assert!(1f.is_normal());
|
||||||
assert!(1e-307f.is_normal());
|
assert!(1e-307f.is_normal());
|
||||||
assert!(!1e-308f.is_normal());
|
assert!(!1e-308f.is_normal());
|
||||||
|
@ -1159,11 +1238,16 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_classify() {
|
fn test_classify() {
|
||||||
assert_eq!(Float::NaN::<float>().classify(), FPNaN);
|
let nan: float = Float::NaN();
|
||||||
assert_eq!(Float::infinity::<float>().classify(), FPInfinite);
|
let inf: float = Float::infinity();
|
||||||
assert_eq!(Float::neg_infinity::<float>().classify(), FPInfinite);
|
let neg_inf: float = Float::neg_infinity();
|
||||||
assert_eq!(Zero::zero::<float>().classify(), FPZero);
|
let zero: float = Zero::zero();
|
||||||
assert_eq!(Float::neg_zero::<float>().classify(), FPZero);
|
let neg_zero: float = Float::neg_zero();
|
||||||
|
assert_eq!(nan.classify(), FPNaN);
|
||||||
|
assert_eq!(inf.classify(), FPInfinite);
|
||||||
|
assert_eq!(neg_inf.classify(), FPInfinite);
|
||||||
|
assert_eq!(zero.classify(), FPZero);
|
||||||
|
assert_eq!(neg_zero.classify(), FPZero);
|
||||||
assert_eq!(1f.classify(), FPNormal);
|
assert_eq!(1f.classify(), FPNormal);
|
||||||
assert_eq!(1e-307f.classify(), FPNormal);
|
assert_eq!(1e-307f.classify(), FPNormal);
|
||||||
assert_eq!(1e-308f.classify(), FPSubnormal);
|
assert_eq!(1e-308f.classify(), FPSubnormal);
|
||||||
|
@ -1180,11 +1264,13 @@ mod tests {
|
||||||
|
|
||||||
assert_eq!(Float::ldexp(0f, -123), 0f);
|
assert_eq!(Float::ldexp(0f, -123), 0f);
|
||||||
assert_eq!(Float::ldexp(-0f, -123), -0f);
|
assert_eq!(Float::ldexp(-0f, -123), -0f);
|
||||||
assert_eq!(Float::ldexp(Float::infinity::<float>(), -123),
|
|
||||||
Float::infinity::<float>());
|
let inf: float = Float::infinity();
|
||||||
assert_eq!(Float::ldexp(Float::neg_infinity::<float>(), -123),
|
let neg_inf: float = Float::neg_infinity();
|
||||||
Float::neg_infinity::<float>());
|
let nan: float = Float::NaN();
|
||||||
assert!(Float::ldexp(Float::NaN::<float>(), -123).is_NaN());
|
assert_eq!(Float::ldexp(inf, -123), inf);
|
||||||
|
assert_eq!(Float::ldexp(neg_inf, -123), neg_inf);
|
||||||
|
assert!(Float::ldexp(nan, -123).is_NaN());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1202,11 +1288,13 @@ mod tests {
|
||||||
|
|
||||||
assert_eq!(0f.frexp(), (0f, 0));
|
assert_eq!(0f.frexp(), (0f, 0));
|
||||||
assert_eq!((-0f).frexp(), (-0f, 0));
|
assert_eq!((-0f).frexp(), (-0f, 0));
|
||||||
assert_eq!(match Float::infinity::<float>().frexp() { (x, _) => x },
|
|
||||||
Float::infinity::<float>())
|
let inf: float = Float::infinity();
|
||||||
assert_eq!(match Float::neg_infinity::<float>().frexp() { (x, _) => x },
|
let neg_inf: float = Float::neg_infinity();
|
||||||
Float::neg_infinity::<float>())
|
let nan: float = Float::NaN();
|
||||||
assert!(match Float::NaN::<float>().frexp() { (x, _) => x.is_NaN() })
|
assert_eq!(match inf.frexp() { (x, _) => x }, inf);
|
||||||
|
assert_eq!(match neg_inf.frexp() { (x, _) => x }, neg_inf);
|
||||||
|
assert!(match nan.frexp() { (x, _) => x.is_NaN() })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -466,10 +466,10 @@ impl Int for $T {}
|
||||||
|
|
||||||
impl Primitive for $T {
|
impl Primitive for $T {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn bits() -> uint { bits }
|
fn bits(_: Option<$T>) -> uint { bits }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn bytes() -> uint { bits / 8 }
|
fn bytes(_: Option<$T>) -> uint { bits / 8 }
|
||||||
}
|
}
|
||||||
|
|
||||||
// String conversion functions and impl str -> num
|
// String conversion functions and impl str -> num
|
||||||
|
@ -754,8 +754,9 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_primitive() {
|
fn test_primitive() {
|
||||||
assert_eq!(Primitive::bits::<$T>(), sys::size_of::<$T>() * 8);
|
let none: Option<$T> = None;
|
||||||
assert_eq!(Primitive::bytes::<$T>(), sys::size_of::<$T>());
|
assert_eq!(Primitive::bits(none), sys::size_of::<$T>() * 8);
|
||||||
|
assert_eq!(Primitive::bytes(none), sys::size_of::<$T>());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -272,8 +272,8 @@ pub trait Primitive: Num
|
||||||
+ Div<Self,Self>
|
+ Div<Self,Self>
|
||||||
+ Rem<Self,Self> {
|
+ Rem<Self,Self> {
|
||||||
// FIXME (#5527): These should be associated constants
|
// FIXME (#5527): These should be associated constants
|
||||||
fn bits() -> uint;
|
fn bits(unused_self: Option<Self>) -> uint;
|
||||||
fn bytes() -> uint;
|
fn bytes(unused_self: Option<Self>) -> uint;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A collection of traits relevant to primitive signed and unsigned integers
|
/// A collection of traits relevant to primitive signed and unsigned integers
|
||||||
|
@ -314,13 +314,13 @@ pub trait Float: Real
|
||||||
fn is_normal(&self) -> bool;
|
fn is_normal(&self) -> bool;
|
||||||
fn classify(&self) -> FPCategory;
|
fn classify(&self) -> FPCategory;
|
||||||
|
|
||||||
fn mantissa_digits() -> uint;
|
fn mantissa_digits(unused_self: Option<Self>) -> uint;
|
||||||
fn digits() -> uint;
|
fn digits(unused_self: Option<Self>) -> uint;
|
||||||
fn epsilon() -> Self;
|
fn epsilon() -> Self;
|
||||||
fn min_exp() -> int;
|
fn min_exp(unused_self: Option<Self>) -> int;
|
||||||
fn max_exp() -> int;
|
fn max_exp(unused_self: Option<Self>) -> int;
|
||||||
fn min_10_exp() -> int;
|
fn min_10_exp(unused_self: Option<Self>) -> int;
|
||||||
fn max_10_exp() -> int;
|
fn max_10_exp(unused_self: Option<Self>) -> int;
|
||||||
|
|
||||||
fn ldexp(x: Self, exp: int) -> Self;
|
fn ldexp(x: Self, exp: int) -> Self;
|
||||||
fn frexp(&self) -> (Self, int);
|
fn frexp(&self) -> (Self, int);
|
||||||
|
@ -484,9 +484,9 @@ impl<T: CheckedAdd+CheckedSub+Zero+Ord+Bounded> Saturating for T {
|
||||||
match self.checked_add(&v) {
|
match self.checked_add(&v) {
|
||||||
Some(x) => x,
|
Some(x) => x,
|
||||||
None => if v >= Zero::zero() {
|
None => if v >= Zero::zero() {
|
||||||
Bounded::max_value::<T>()
|
Bounded::max_value()
|
||||||
} else {
|
} else {
|
||||||
Bounded::min_value::<T>()
|
Bounded::min_value()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -496,9 +496,9 @@ impl<T: CheckedAdd+CheckedSub+Zero+Ord+Bounded> Saturating for T {
|
||||||
match self.checked_sub(&v) {
|
match self.checked_sub(&v) {
|
||||||
Some(x) => x,
|
Some(x) => x,
|
||||||
None => if v >= Zero::zero() {
|
None => if v >= Zero::zero() {
|
||||||
Bounded::min_value::<T>()
|
Bounded::min_value()
|
||||||
} else {
|
} else {
|
||||||
Bounded::max_value::<T>()
|
Bounded::max_value()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -404,10 +404,10 @@ impl ToStrRadix for $T {
|
||||||
|
|
||||||
impl Primitive for $T {
|
impl Primitive for $T {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn bits() -> uint { bits }
|
fn bits(_: Option<$T>) -> uint { bits }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn bytes() -> uint { bits / 8 }
|
fn bytes(_: Option<$T>) -> uint { bits / 8 }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitCount for $T {
|
impl BitCount for $T {
|
||||||
|
@ -532,8 +532,9 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_primitive() {
|
fn test_primitive() {
|
||||||
assert_eq!(Primitive::bits::<$T>(), sys::size_of::<$T>() * 8);
|
let none: Option<$T> = None;
|
||||||
assert_eq!(Primitive::bytes::<$T>(), sys::size_of::<$T>());
|
assert_eq!(Primitive::bits(none), sys::size_of::<$T>() * 8);
|
||||||
|
assert_eq!(Primitive::bytes(none), sys::size_of::<$T>());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -13,7 +13,7 @@ use c_str::ToCStr;
|
||||||
use cast::transmute;
|
use cast::transmute;
|
||||||
use io::{Writer, WriterUtil};
|
use io::{Writer, WriterUtil};
|
||||||
use io;
|
use io;
|
||||||
use libc::{c_char, c_void, size_t, STDERR_FILENO};
|
use libc::{c_char, size_t, STDERR_FILENO};
|
||||||
use option::{Option, None, Some};
|
use option::{Option, None, Some};
|
||||||
use ptr::RawPtr;
|
use ptr::RawPtr;
|
||||||
use rt::env;
|
use rt::env;
|
||||||
|
|
|
@ -159,7 +159,7 @@ impl<T> ChanOne<T> {
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
let recvr = Cell::new(recvr);
|
let recvr = Cell::new(recvr);
|
||||||
do Local::borrow::<Scheduler, ()> |sched| {
|
do Local::borrow |sched: &mut Scheduler| {
|
||||||
sched.enqueue_blocked_task(recvr.take());
|
sched.enqueue_blocked_task(recvr.take());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -199,7 +199,7 @@ impl<T> PortOne<T> {
|
||||||
if !this.optimistic_check() {
|
if !this.optimistic_check() {
|
||||||
// No data available yet.
|
// No data available yet.
|
||||||
// Switch to the scheduler to put the ~Task into the Packet state.
|
// Switch to the scheduler to put the ~Task into the Packet state.
|
||||||
let sched = Local::take::<Scheduler>();
|
let sched: ~Scheduler = Local::take();
|
||||||
do sched.deschedule_running_task_and_then |sched, task| {
|
do sched.deschedule_running_task_and_then |sched, task| {
|
||||||
this.block_on(sched, task);
|
this.block_on(sched, task);
|
||||||
}
|
}
|
||||||
|
@ -221,7 +221,7 @@ impl<T> SelectInner for PortOne<T> {
|
||||||
// The optimistic check is never necessary for correctness. For testing
|
// The optimistic check is never necessary for correctness. For testing
|
||||||
// purposes, making it randomly return false simulates a racing sender.
|
// purposes, making it randomly return false simulates a racing sender.
|
||||||
use rand::{Rand};
|
use rand::{Rand};
|
||||||
let actually_check = do Local::borrow::<Scheduler, bool> |sched| {
|
let actually_check = do Local::borrow |sched: &mut Scheduler| {
|
||||||
Rand::rand(&mut sched.rng)
|
Rand::rand(&mut sched.rng)
|
||||||
};
|
};
|
||||||
if actually_check {
|
if actually_check {
|
||||||
|
|
|
@ -359,7 +359,7 @@ impl FromStr for SocketAddr {
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use from_str::FromStr;
|
use from_str::FromStr;
|
||||||
use option::{Some, None};
|
use option::{Option, Some, None};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_from_str_ipv4() {
|
fn test_from_str_ipv4() {
|
||||||
|
@ -368,13 +368,17 @@ mod test {
|
||||||
assert_eq!(Some(Ipv4Addr(0, 0, 0, 0)), FromStr::from_str("0.0.0.0"));
|
assert_eq!(Some(Ipv4Addr(0, 0, 0, 0)), FromStr::from_str("0.0.0.0"));
|
||||||
|
|
||||||
// out of range
|
// out of range
|
||||||
assert_eq!(None, FromStr::from_str::<IpAddr>("256.0.0.1"));
|
let none: Option<IpAddr> = FromStr::from_str("256.0.0.1");
|
||||||
|
assert_eq!(None, none);
|
||||||
// too short
|
// too short
|
||||||
assert_eq!(None, FromStr::from_str::<IpAddr>("255.0.0"));
|
let none: Option<IpAddr> = FromStr::from_str("255.0.0");
|
||||||
|
assert_eq!(None, none);
|
||||||
// too long
|
// too long
|
||||||
assert_eq!(None, FromStr::from_str::<IpAddr>("255.0.0.1.2"));
|
let none: Option<IpAddr> = FromStr::from_str("255.0.0.1.2");
|
||||||
|
assert_eq!(None, none);
|
||||||
// no number between dots
|
// no number between dots
|
||||||
assert_eq!(None, FromStr::from_str::<IpAddr>("255.0..1"));
|
let none: Option<IpAddr> = FromStr::from_str("255.0..1");
|
||||||
|
assert_eq!(None, none);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -389,15 +393,20 @@ mod test {
|
||||||
FromStr::from_str("2a02:6b8::11:11"));
|
FromStr::from_str("2a02:6b8::11:11"));
|
||||||
|
|
||||||
// too long group
|
// too long group
|
||||||
assert_eq!(None, FromStr::from_str::<IpAddr>("::00000"));
|
let none: Option<IpAddr> = FromStr::from_str("::00000");
|
||||||
|
assert_eq!(None, none);
|
||||||
// too short
|
// too short
|
||||||
assert_eq!(None, FromStr::from_str::<IpAddr>("1:2:3:4:5:6:7"));
|
let none: Option<IpAddr> = FromStr::from_str("1:2:3:4:5:6:7");
|
||||||
|
assert_eq!(None, none);
|
||||||
// too long
|
// too long
|
||||||
assert_eq!(None, FromStr::from_str::<IpAddr>("1:2:3:4:5:6:7:8:9"));
|
let none: Option<IpAddr> = FromStr::from_str("1:2:3:4:5:6:7:8:9");
|
||||||
|
assert_eq!(None, none);
|
||||||
// triple colon
|
// triple colon
|
||||||
assert_eq!(None, FromStr::from_str::<IpAddr>("1:2:::6:7:8"));
|
let none: Option<IpAddr> = FromStr::from_str("1:2:::6:7:8");
|
||||||
|
assert_eq!(None, none);
|
||||||
// two double colons
|
// two double colons
|
||||||
assert_eq!(None, FromStr::from_str::<IpAddr>("1:2::6::8"));
|
let none: Option<IpAddr> = FromStr::from_str("1:2::6::8");
|
||||||
|
assert_eq!(None, none);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -412,11 +421,15 @@ mod test {
|
||||||
FromStr::from_str("2001:db8:122:c000:2:2100:192.0.2.33"));
|
FromStr::from_str("2001:db8:122:c000:2:2100:192.0.2.33"));
|
||||||
|
|
||||||
// colon after v4
|
// colon after v4
|
||||||
assert_eq!(None, FromStr::from_str::<IpAddr>("::127.0.0.1:"));
|
let none: Option<IpAddr> = FromStr::from_str("::127.0.0.1:");
|
||||||
|
assert_eq!(None, none);
|
||||||
// not enought groups
|
// not enought groups
|
||||||
assert_eq!(None, FromStr::from_str::<IpAddr>("1.2.3.4.5:127.0.0.1"));
|
let none: Option<IpAddr> = FromStr::from_str("1.2.3.4.5:127.0.0.1");
|
||||||
|
assert_eq!(None, none);
|
||||||
// too many groups
|
// too many groups
|
||||||
assert_eq!(None, FromStr::from_str::<IpAddr>("1.2.3.4.5:6:7:127.0.0.1"));
|
let none: Option<IpAddr> =
|
||||||
|
FromStr::from_str("1.2.3.4.5:6:7:127.0.0.1");
|
||||||
|
assert_eq!(None, none);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -429,13 +442,17 @@ mod test {
|
||||||
FromStr::from_str("[::127.0.0.1]:22"));
|
FromStr::from_str("[::127.0.0.1]:22"));
|
||||||
|
|
||||||
// without port
|
// without port
|
||||||
assert_eq!(None, FromStr::from_str::<SocketAddr>("127.0.0.1"));
|
let none: Option<SocketAddr> = FromStr::from_str("127.0.0.1");
|
||||||
|
assert_eq!(None, none);
|
||||||
// without port
|
// without port
|
||||||
assert_eq!(None, FromStr::from_str::<SocketAddr>("127.0.0.1:"));
|
let none: Option<SocketAddr> = FromStr::from_str("127.0.0.1:");
|
||||||
|
assert_eq!(None, none);
|
||||||
// wrong brackets around v4
|
// wrong brackets around v4
|
||||||
assert_eq!(None, FromStr::from_str::<SocketAddr>("[127.0.0.1]:22"));
|
let none: Option<SocketAddr> = FromStr::from_str("[127.0.0.1]:22");
|
||||||
|
assert_eq!(None, none);
|
||||||
// port out of range
|
// port out of range
|
||||||
assert_eq!(None, FromStr::from_str::<SocketAddr>("127.0.0.1:123456"));
|
let none: Option<SocketAddr> = FromStr::from_str("127.0.0.1:123456");
|
||||||
|
assert_eq!(None, none);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -29,7 +29,7 @@ impl TcpStream {
|
||||||
pub fn connect(addr: SocketAddr) -> Option<TcpStream> {
|
pub fn connect(addr: SocketAddr) -> Option<TcpStream> {
|
||||||
let stream = unsafe {
|
let stream = unsafe {
|
||||||
rtdebug!("borrowing io to connect");
|
rtdebug!("borrowing io to connect");
|
||||||
let io = Local::unsafe_borrow::<IoFactoryObject>();
|
let io: *mut IoFactoryObject = Local::unsafe_borrow();
|
||||||
rtdebug!("about to connect");
|
rtdebug!("about to connect");
|
||||||
(*io).tcp_connect(addr)
|
(*io).tcp_connect(addr)
|
||||||
};
|
};
|
||||||
|
@ -100,7 +100,7 @@ pub struct TcpListener(~RtioTcpListenerObject);
|
||||||
impl TcpListener {
|
impl TcpListener {
|
||||||
pub fn bind(addr: SocketAddr) -> Option<TcpListener> {
|
pub fn bind(addr: SocketAddr) -> Option<TcpListener> {
|
||||||
let listener = unsafe {
|
let listener = unsafe {
|
||||||
let io = Local::unsafe_borrow::<IoFactoryObject>();
|
let io: *mut IoFactoryObject = Local::unsafe_borrow();
|
||||||
(*io).tcp_bind(addr)
|
(*io).tcp_bind(addr)
|
||||||
};
|
};
|
||||||
match listener {
|
match listener {
|
||||||
|
|
|
@ -20,7 +20,10 @@ pub struct UdpSocket(~RtioUdpSocketObject);
|
||||||
|
|
||||||
impl UdpSocket {
|
impl UdpSocket {
|
||||||
pub fn bind(addr: SocketAddr) -> Option<UdpSocket> {
|
pub fn bind(addr: SocketAddr) -> Option<UdpSocket> {
|
||||||
let socket = unsafe { (*Local::unsafe_borrow::<IoFactoryObject>()).udp_bind(addr) };
|
let socket = unsafe {
|
||||||
|
let factory: *mut IoFactoryObject = Local::unsafe_borrow();
|
||||||
|
(*factory).udp_bind(addr)
|
||||||
|
};
|
||||||
match socket {
|
match socket {
|
||||||
Ok(s) => Some(UdpSocket(s)),
|
Ok(s) => Some(UdpSocket(s)),
|
||||||
Err(ioerr) => {
|
Err(ioerr) => {
|
||||||
|
|
|
@ -22,7 +22,7 @@ impl Timer {
|
||||||
pub fn new() -> Option<Timer> {
|
pub fn new() -> Option<Timer> {
|
||||||
let timer = unsafe {
|
let timer = unsafe {
|
||||||
rtdebug!("Timer::init: borrowing io to init timer");
|
rtdebug!("Timer::init: borrowing io to init timer");
|
||||||
let io = Local::unsafe_borrow::<IoFactoryObject>();
|
let io: *mut IoFactoryObject = Local::unsafe_borrow();
|
||||||
rtdebug!("about to init timer");
|
rtdebug!("about to init timer");
|
||||||
(*io).timer_init()
|
(*io).timer_init()
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,7 +19,7 @@ use cell::Cell;
|
||||||
pub trait Local {
|
pub trait Local {
|
||||||
fn put(value: ~Self);
|
fn put(value: ~Self);
|
||||||
fn take() -> ~Self;
|
fn take() -> ~Self;
|
||||||
fn exists() -> bool;
|
fn exists(unused_value: Option<Self>) -> bool;
|
||||||
fn borrow<T>(f: &fn(&mut Self) -> T) -> T;
|
fn borrow<T>(f: &fn(&mut Self) -> T) -> T;
|
||||||
unsafe fn unsafe_take() -> ~Self;
|
unsafe fn unsafe_take() -> ~Self;
|
||||||
unsafe fn unsafe_borrow() -> *mut Self;
|
unsafe fn unsafe_borrow() -> *mut Self;
|
||||||
|
@ -31,7 +31,7 @@ impl Local for Task {
|
||||||
fn put(value: ~Task) { unsafe { local_ptr::put(value) } }
|
fn put(value: ~Task) { unsafe { local_ptr::put(value) } }
|
||||||
#[inline]
|
#[inline]
|
||||||
fn take() -> ~Task { unsafe { local_ptr::take() } }
|
fn take() -> ~Task { unsafe { local_ptr::take() } }
|
||||||
fn exists() -> bool { local_ptr::exists() }
|
fn exists(_: Option<Task>) -> bool { local_ptr::exists() }
|
||||||
fn borrow<T>(f: &fn(&mut Task) -> T) -> T {
|
fn borrow<T>(f: &fn(&mut Task) -> T) -> T {
|
||||||
let mut res: Option<T> = None;
|
let mut res: Option<T> = None;
|
||||||
let res_ptr: *mut Option<T> = &mut res;
|
let res_ptr: *mut Option<T> = &mut res;
|
||||||
|
@ -59,7 +59,7 @@ impl Local for Task {
|
||||||
impl Local for Scheduler {
|
impl Local for Scheduler {
|
||||||
fn put(value: ~Scheduler) {
|
fn put(value: ~Scheduler) {
|
||||||
let value = Cell::new(value);
|
let value = Cell::new(value);
|
||||||
do Local::borrow::<Task,()> |task| {
|
do Local::borrow |task: &mut Task| {
|
||||||
let task = task;
|
let task = task;
|
||||||
task.sched = Some(value.take());
|
task.sched = Some(value.take());
|
||||||
};
|
};
|
||||||
|
@ -68,12 +68,12 @@ impl Local for Scheduler {
|
||||||
fn take() -> ~Scheduler {
|
fn take() -> ~Scheduler {
|
||||||
unsafe {
|
unsafe {
|
||||||
// XXX: Unsafe for speed
|
// XXX: Unsafe for speed
|
||||||
let task = Local::unsafe_borrow::<Task>();
|
let task: *mut Task = Local::unsafe_borrow();
|
||||||
(*task).sched.take_unwrap()
|
(*task).sched.take_unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn exists() -> bool {
|
fn exists(_: Option<Scheduler>) -> bool {
|
||||||
do Local::borrow::<Task,bool> |task| {
|
do Local::borrow |task: &mut Task| {
|
||||||
match task.sched {
|
match task.sched {
|
||||||
Some(ref _task) => true,
|
Some(ref _task) => true,
|
||||||
None => false
|
None => false
|
||||||
|
@ -81,7 +81,7 @@ impl Local for Scheduler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn borrow<T>(f: &fn(&mut Scheduler) -> T) -> T {
|
fn borrow<T>(f: &fn(&mut Scheduler) -> T) -> T {
|
||||||
do Local::borrow::<Task, T> |task| {
|
do Local::borrow |task: &mut Task| {
|
||||||
match task.sched {
|
match task.sched {
|
||||||
Some(~ref mut task) => {
|
Some(~ref mut task) => {
|
||||||
f(task)
|
f(task)
|
||||||
|
@ -94,7 +94,8 @@ impl Local for Scheduler {
|
||||||
}
|
}
|
||||||
unsafe fn unsafe_take() -> ~Scheduler { rtabort!("unimpl") }
|
unsafe fn unsafe_take() -> ~Scheduler { rtabort!("unimpl") }
|
||||||
unsafe fn unsafe_borrow() -> *mut Scheduler {
|
unsafe fn unsafe_borrow() -> *mut Scheduler {
|
||||||
match (*Local::unsafe_borrow::<Task>()).sched {
|
let task: *mut Task = Local::unsafe_borrow();
|
||||||
|
match (*task).sched {
|
||||||
Some(~ref mut sched) => {
|
Some(~ref mut sched) => {
|
||||||
let s: *mut Scheduler = &mut *sched;
|
let s: *mut Scheduler = &mut *sched;
|
||||||
return s;
|
return s;
|
||||||
|
@ -105,6 +106,7 @@ impl Local for Scheduler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unsafe fn try_unsafe_borrow() -> Option<*mut Scheduler> {
|
unsafe fn try_unsafe_borrow() -> Option<*mut Scheduler> {
|
||||||
|
let task_opt: Option<*mut Task> = Local::try_unsafe_borrow();
|
||||||
match Local::try_unsafe_borrow::<Task>() {
|
match Local::try_unsafe_borrow::<Task>() {
|
||||||
Some(task) => {
|
Some(task) => {
|
||||||
match (*task).sched {
|
match (*task).sched {
|
||||||
|
@ -124,15 +126,17 @@ impl Local for Scheduler {
|
||||||
impl Local for IoFactoryObject {
|
impl Local for IoFactoryObject {
|
||||||
fn put(_value: ~IoFactoryObject) { rtabort!("unimpl") }
|
fn put(_value: ~IoFactoryObject) { rtabort!("unimpl") }
|
||||||
fn take() -> ~IoFactoryObject { rtabort!("unimpl") }
|
fn take() -> ~IoFactoryObject { rtabort!("unimpl") }
|
||||||
fn exists() -> bool { rtabort!("unimpl") }
|
fn exists(_: Option<IoFactoryObject>) -> bool { rtabort!("unimpl") }
|
||||||
fn borrow<T>(_f: &fn(&mut IoFactoryObject) -> T) -> T { rtabort!("unimpl") }
|
fn borrow<T>(_f: &fn(&mut IoFactoryObject) -> T) -> T { rtabort!("unimpl") }
|
||||||
unsafe fn unsafe_take() -> ~IoFactoryObject { rtabort!("unimpl") }
|
unsafe fn unsafe_take() -> ~IoFactoryObject { rtabort!("unimpl") }
|
||||||
unsafe fn unsafe_borrow() -> *mut IoFactoryObject {
|
unsafe fn unsafe_borrow() -> *mut IoFactoryObject {
|
||||||
let sched = Local::unsafe_borrow::<Scheduler>();
|
let sched: *mut Scheduler = Local::unsafe_borrow();
|
||||||
let io: *mut IoFactoryObject = (*sched).event_loop.io().unwrap();
|
let io: *mut IoFactoryObject = (*sched).event_loop.io().unwrap();
|
||||||
return io;
|
return io;
|
||||||
}
|
}
|
||||||
unsafe fn try_unsafe_borrow() -> Option<*mut IoFactoryObject> { rtabort!("unimpl") }
|
unsafe fn try_unsafe_borrow() -> Option<*mut IoFactoryObject> {
|
||||||
|
rtabort!("unimpl")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -198,7 +202,7 @@ mod test {
|
||||||
let task = ~Task::new_root(&mut sched.stack_pool, None, || {});
|
let task = ~Task::new_root(&mut sched.stack_pool, None, || {});
|
||||||
Local::put(task);
|
Local::put(task);
|
||||||
|
|
||||||
let res = do Local::borrow::<Task,bool> |_task| {
|
let res = do Local::borrow |_task: &mut Task| {
|
||||||
true
|
true
|
||||||
};
|
};
|
||||||
assert!(res)
|
assert!(res)
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
use libc;
|
use libc;
|
||||||
use libc::{c_void, uintptr_t, size_t};
|
use libc::{c_void, uintptr_t, size_t};
|
||||||
use ops::Drop;
|
use ops::Drop;
|
||||||
use option::{Some, None};
|
use option::{Option, None, Some};
|
||||||
use rt::local::Local;
|
use rt::local::Local;
|
||||||
use rt::task::Task;
|
use rt::task::Task;
|
||||||
use unstable::raw;
|
use unstable::raw;
|
||||||
|
@ -89,7 +89,8 @@ impl Drop for LocalHeap {
|
||||||
// A little compatibility function
|
// A little compatibility function
|
||||||
pub unsafe fn local_free(ptr: *libc::c_char) {
|
pub unsafe fn local_free(ptr: *libc::c_char) {
|
||||||
// XXX: Unsafe borrow for speed. Lame.
|
// XXX: Unsafe borrow for speed. Lame.
|
||||||
match Local::try_unsafe_borrow::<Task>() {
|
let task_ptr: Option<*mut Task> = Local::try_unsafe_borrow();
|
||||||
|
match task_ptr {
|
||||||
Some(task) => {
|
Some(task) => {
|
||||||
(*task).heap.free(ptr as *libc::c_void);
|
(*task).heap.free(ptr as *libc::c_void);
|
||||||
}
|
}
|
||||||
|
@ -98,7 +99,7 @@ pub unsafe fn local_free(ptr: *libc::c_char) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn live_allocs() -> *raw::Box<()> {
|
pub fn live_allocs() -> *raw::Box<()> {
|
||||||
let region = do Local::borrow::<Task, *BoxedRegion> |task| {
|
let region = do Local::borrow |task: &mut Task| {
|
||||||
task.heap.boxed_region
|
task.heap.boxed_region
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ use cell::Cell;
|
||||||
use clone::Clone;
|
use clone::Clone;
|
||||||
use container::Container;
|
use container::Container;
|
||||||
use iterator::{Iterator, range};
|
use iterator::{Iterator, range};
|
||||||
use option::{Some, None};
|
use option::{Option, None, Some};
|
||||||
use ptr::RawPtr;
|
use ptr::RawPtr;
|
||||||
use rt::local::Local;
|
use rt::local::Local;
|
||||||
use rt::sched::{Scheduler, Shutdown};
|
use rt::sched::{Scheduler, Shutdown};
|
||||||
|
@ -408,7 +408,8 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
|
||||||
|
|
||||||
pub fn in_sched_context() -> bool {
|
pub fn in_sched_context() -> bool {
|
||||||
unsafe {
|
unsafe {
|
||||||
match Local::try_unsafe_borrow::<Task>() {
|
let task_ptr: Option<*mut Task> = Local::try_unsafe_borrow();
|
||||||
|
match task_ptr {
|
||||||
Some(task) => {
|
Some(task) => {
|
||||||
match (*task).task_type {
|
match (*task).task_type {
|
||||||
SchedTask => true,
|
SchedTask => true,
|
||||||
|
@ -422,7 +423,8 @@ pub fn in_sched_context() -> bool {
|
||||||
|
|
||||||
pub fn in_green_task_context() -> bool {
|
pub fn in_green_task_context() -> bool {
|
||||||
unsafe {
|
unsafe {
|
||||||
match Local::try_unsafe_borrow::<Task>() {
|
let task: Option<*mut Task> = Local::try_unsafe_borrow();
|
||||||
|
match task {
|
||||||
Some(task) => {
|
Some(task) => {
|
||||||
match (*task).task_type {
|
match (*task).task_type {
|
||||||
GreenTask(_) => true,
|
GreenTask(_) => true,
|
||||||
|
|
|
@ -169,7 +169,7 @@ impl Scheduler {
|
||||||
// successfully run the input task. Start by running the
|
// successfully run the input task. Start by running the
|
||||||
// scheduler. Grab it out of TLS - performing the scheduler
|
// scheduler. Grab it out of TLS - performing the scheduler
|
||||||
// action will have given it away.
|
// action will have given it away.
|
||||||
let sched = Local::take::<Scheduler>();
|
let sched: ~Scheduler = Local::take();
|
||||||
|
|
||||||
rtdebug!("starting scheduler %u", sched.sched_id());
|
rtdebug!("starting scheduler %u", sched.sched_id());
|
||||||
sched.run();
|
sched.run();
|
||||||
|
@ -185,7 +185,7 @@ impl Scheduler {
|
||||||
// cleaning up the memory it uses. As we didn't actually call
|
// cleaning up the memory it uses. As we didn't actually call
|
||||||
// task.run() on the scheduler task we never get through all
|
// task.run() on the scheduler task we never get through all
|
||||||
// the cleanup code it runs.
|
// the cleanup code it runs.
|
||||||
let mut stask = Local::take::<Task>();
|
let mut stask: ~Task = Local::take();
|
||||||
|
|
||||||
rtdebug!("stopping scheduler %u", stask.sched.get_ref().sched_id());
|
rtdebug!("stopping scheduler %u", stask.sched.get_ref().sched_id());
|
||||||
|
|
||||||
|
@ -212,7 +212,7 @@ impl Scheduler {
|
||||||
// Our scheduler must be in the task before the event loop
|
// Our scheduler must be in the task before the event loop
|
||||||
// is started.
|
// is started.
|
||||||
let self_sched = Cell::new(self_sched);
|
let self_sched = Cell::new(self_sched);
|
||||||
do Local::borrow::<Task,()> |stask| {
|
do Local::borrow |stask: &mut Task| {
|
||||||
stask.sched = Some(self_sched.take());
|
stask.sched = Some(self_sched.take());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -234,7 +234,7 @@ impl Scheduler {
|
||||||
// already have a scheduler stored in our local task, so we
|
// already have a scheduler stored in our local task, so we
|
||||||
// start off by taking it. This is the only path through the
|
// start off by taking it. This is the only path through the
|
||||||
// scheduler where we get the scheduler this way.
|
// scheduler where we get the scheduler this way.
|
||||||
let mut sched = Local::take::<Scheduler>();
|
let mut sched: ~Scheduler = Local::take();
|
||||||
|
|
||||||
// Assume that we need to continue idling unless we reach the
|
// Assume that we need to continue idling unless we reach the
|
||||||
// end of this function without performing an action.
|
// end of this function without performing an action.
|
||||||
|
@ -522,7 +522,7 @@ impl Scheduler {
|
||||||
// The current task is grabbed from TLS, not taken as an input.
|
// The current task is grabbed from TLS, not taken as an input.
|
||||||
// Doing an unsafe_take to avoid writing back a null pointer -
|
// Doing an unsafe_take to avoid writing back a null pointer -
|
||||||
// We're going to call `put` later to do that.
|
// We're going to call `put` later to do that.
|
||||||
let current_task: ~Task = unsafe { Local::unsafe_take::<Task>() };
|
let current_task: ~Task = unsafe { Local::unsafe_take() };
|
||||||
|
|
||||||
// Check that the task is not in an atomically() section (e.g.,
|
// Check that the task is not in an atomically() section (e.g.,
|
||||||
// holding a pthread mutex, which could deadlock the scheduler).
|
// holding a pthread mutex, which could deadlock the scheduler).
|
||||||
|
@ -581,7 +581,7 @@ impl Scheduler {
|
||||||
// run the cleanup job, as expected by the previously called
|
// run the cleanup job, as expected by the previously called
|
||||||
// swap_contexts function.
|
// swap_contexts function.
|
||||||
unsafe {
|
unsafe {
|
||||||
let task = Local::unsafe_borrow::<Task>();
|
let task: *mut Task = Local::unsafe_borrow::<Task>();
|
||||||
(*task).sched.get_mut_ref().run_cleanup_job();
|
(*task).sched.get_mut_ref().run_cleanup_job();
|
||||||
|
|
||||||
// Must happen after running the cleanup job (of course).
|
// Must happen after running the cleanup job (of course).
|
||||||
|
@ -692,7 +692,7 @@ impl Scheduler {
|
||||||
|
|
||||||
pub fn run_task_later(next_task: ~Task) {
|
pub fn run_task_later(next_task: ~Task) {
|
||||||
let next_task = Cell::new(next_task);
|
let next_task = Cell::new(next_task);
|
||||||
do Local::borrow::<Scheduler,()> |sched| {
|
do Local::borrow |sched: &mut Scheduler| {
|
||||||
sched.enqueue_task(next_task.take());
|
sched.enqueue_task(next_task.take());
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1024,12 +1024,12 @@ mod test {
|
||||||
// exit before emptying the work queue
|
// exit before emptying the work queue
|
||||||
do run_in_newsched_task {
|
do run_in_newsched_task {
|
||||||
do spawntask {
|
do spawntask {
|
||||||
let sched = Local::take::<Scheduler>();
|
let sched: ~Scheduler = Local::take();
|
||||||
do sched.deschedule_running_task_and_then |sched, task| {
|
do sched.deschedule_running_task_and_then |sched, task| {
|
||||||
let task = Cell::new(task);
|
let task = Cell::new(task);
|
||||||
do sched.event_loop.callback_ms(10) {
|
do sched.event_loop.callback_ms(10) {
|
||||||
rtdebug!("in callback");
|
rtdebug!("in callback");
|
||||||
let mut sched = Local::take::<Scheduler>();
|
let mut sched: ~Scheduler = Local::take();
|
||||||
sched.enqueue_blocked_task(task.take());
|
sched.enqueue_blocked_task(task.take());
|
||||||
Local::put(sched);
|
Local::put(sched);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,3 +26,4 @@ pub trait SelectInner {
|
||||||
pub trait SelectPortInner<T> {
|
pub trait SelectPortInner<T> {
|
||||||
fn recv_ready(self) -> Option<T>;
|
fn recv_ready(self) -> Option<T>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ impl Task {
|
||||||
pub fn build_homed_child(stack_size: Option<uint>, f: ~fn(), home: SchedHome) -> ~Task {
|
pub fn build_homed_child(stack_size: Option<uint>, f: ~fn(), home: SchedHome) -> ~Task {
|
||||||
let f = Cell::new(f);
|
let f = Cell::new(f);
|
||||||
let home = Cell::new(home);
|
let home = Cell::new(home);
|
||||||
do Local::borrow::<Task, ~Task> |running_task| {
|
do Local::borrow |running_task: &mut Task| {
|
||||||
let mut sched = running_task.sched.take_unwrap();
|
let mut sched = running_task.sched.take_unwrap();
|
||||||
let new_task = ~running_task.new_child_homed(&mut sched.stack_pool,
|
let new_task = ~running_task.new_child_homed(&mut sched.stack_pool,
|
||||||
stack_size,
|
stack_size,
|
||||||
|
@ -111,7 +111,7 @@ impl Task {
|
||||||
pub fn build_homed_root(stack_size: Option<uint>, f: ~fn(), home: SchedHome) -> ~Task {
|
pub fn build_homed_root(stack_size: Option<uint>, f: ~fn(), home: SchedHome) -> ~Task {
|
||||||
let f = Cell::new(f);
|
let f = Cell::new(f);
|
||||||
let home = Cell::new(home);
|
let home = Cell::new(home);
|
||||||
do Local::borrow::<Task, ~Task> |running_task| {
|
do Local::borrow |running_task: &mut Task| {
|
||||||
let mut sched = running_task.sched.take_unwrap();
|
let mut sched = running_task.sched.take_unwrap();
|
||||||
let new_task = ~Task::new_root_homed(&mut sched.stack_pool,
|
let new_task = ~Task::new_root_homed(&mut sched.stack_pool,
|
||||||
stack_size,
|
stack_size,
|
||||||
|
@ -305,7 +305,7 @@ impl Task {
|
||||||
// Grab both the scheduler and the task from TLS and check if the
|
// Grab both the scheduler and the task from TLS and check if the
|
||||||
// task is executing on an appropriate scheduler.
|
// task is executing on an appropriate scheduler.
|
||||||
pub fn on_appropriate_sched() -> bool {
|
pub fn on_appropriate_sched() -> bool {
|
||||||
do Local::borrow::<Task,bool> |task| {
|
do Local::borrow |task: &mut Task| {
|
||||||
let sched_id = task.sched.get_ref().sched_id();
|
let sched_id = task.sched.get_ref().sched_id();
|
||||||
let sched_run_anything = task.sched.get_ref().run_anything;
|
let sched_run_anything = task.sched.get_ref().run_anything;
|
||||||
match task.task_type {
|
match task.task_type {
|
||||||
|
@ -369,7 +369,7 @@ impl Coroutine {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
||||||
// Again - might work while safe, or it might not.
|
// Again - might work while safe, or it might not.
|
||||||
do Local::borrow::<Scheduler,()> |sched| {
|
do Local::borrow |sched: &mut Scheduler| {
|
||||||
sched.run_cleanup_job();
|
sched.run_cleanup_job();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,7 +378,7 @@ impl Coroutine {
|
||||||
// simply unsafe_borrow it to get this reference. We
|
// simply unsafe_borrow it to get this reference. We
|
||||||
// need to still have the task in TLS though, so we
|
// need to still have the task in TLS though, so we
|
||||||
// need to unsafe_borrow.
|
// need to unsafe_borrow.
|
||||||
let task = Local::unsafe_borrow::<Task>();
|
let task: *mut Task = Local::unsafe_borrow();
|
||||||
|
|
||||||
do (*task).run {
|
do (*task).run {
|
||||||
// N.B. Removing `start` from the start wrapper
|
// N.B. Removing `start` from the start wrapper
|
||||||
|
@ -397,7 +397,7 @@ impl Coroutine {
|
||||||
}
|
}
|
||||||
|
|
||||||
// We remove the sched from the Task in TLS right now.
|
// We remove the sched from the Task in TLS right now.
|
||||||
let sched = Local::take::<Scheduler>();
|
let sched: ~Scheduler = Local::take();
|
||||||
// ... allowing us to give it away when performing a
|
// ... allowing us to give it away when performing a
|
||||||
// scheduling operation.
|
// scheduling operation.
|
||||||
sched.terminate_current_task()
|
sched.terminate_current_task()
|
||||||
|
|
|
@ -51,7 +51,7 @@ impl<T> Tube<T> {
|
||||||
// There's a waiting task. Wake it up
|
// There's a waiting task. Wake it up
|
||||||
rtdebug!("waking blocked tube");
|
rtdebug!("waking blocked tube");
|
||||||
let task = (*state).blocked_task.take_unwrap();
|
let task = (*state).blocked_task.take_unwrap();
|
||||||
let sched = Local::take::<Scheduler>();
|
let sched: ~Scheduler = Local::take();
|
||||||
sched.resume_blocked_task_immediately(task);
|
sched.resume_blocked_task_immediately(task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ impl<T> Tube<T> {
|
||||||
rtdebug!("blocking on tube recv");
|
rtdebug!("blocking on tube recv");
|
||||||
assert!(self.p.refcount() > 1); // There better be somebody to wake us up
|
assert!(self.p.refcount() > 1); // There better be somebody to wake us up
|
||||||
assert!((*state).blocked_task.is_none());
|
assert!((*state).blocked_task.is_none());
|
||||||
let sched = Local::take::<Scheduler>();
|
let sched: ~Scheduler = Local::take();
|
||||||
do sched.deschedule_running_task_and_then |_, task| {
|
do sched.deschedule_running_task_and_then |_, task| {
|
||||||
(*state).blocked_task = Some(task);
|
(*state).blocked_task = Some(task);
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ mod test {
|
||||||
let mut tube: Tube<int> = Tube::new();
|
let mut tube: Tube<int> = Tube::new();
|
||||||
let tube_clone = tube.clone();
|
let tube_clone = tube.clone();
|
||||||
let tube_clone_cell = Cell::new(tube_clone);
|
let tube_clone_cell = Cell::new(tube_clone);
|
||||||
let sched = Local::take::<Scheduler>();
|
let sched: ~Scheduler = Local::take();
|
||||||
do sched.deschedule_running_task_and_then |sched, task| {
|
do sched.deschedule_running_task_and_then |sched, task| {
|
||||||
let mut tube_clone = tube_clone_cell.take();
|
let mut tube_clone = tube_clone_cell.take();
|
||||||
tube_clone.send(1);
|
tube_clone.send(1);
|
||||||
|
@ -119,7 +119,7 @@ mod test {
|
||||||
let mut tube: Tube<int> = Tube::new();
|
let mut tube: Tube<int> = Tube::new();
|
||||||
let tube_clone = tube.clone();
|
let tube_clone = tube.clone();
|
||||||
let tube_clone = Cell::new(tube_clone);
|
let tube_clone = Cell::new(tube_clone);
|
||||||
let sched = Local::take::<Scheduler>();
|
let sched: ~Scheduler = Local::take();
|
||||||
do sched.deschedule_running_task_and_then |sched, task| {
|
do sched.deschedule_running_task_and_then |sched, task| {
|
||||||
let tube_clone = Cell::new(tube_clone.take());
|
let tube_clone = Cell::new(tube_clone.take());
|
||||||
do sched.event_loop.callback {
|
do sched.event_loop.callback {
|
||||||
|
@ -143,7 +143,7 @@ mod test {
|
||||||
let mut tube: Tube<int> = Tube::new();
|
let mut tube: Tube<int> = Tube::new();
|
||||||
let tube_clone = tube.clone();
|
let tube_clone = tube.clone();
|
||||||
let tube_clone = Cell::new(tube_clone);
|
let tube_clone = Cell::new(tube_clone);
|
||||||
let sched = Local::take::<Scheduler>();
|
let sched: ~Scheduler = Local::take();
|
||||||
do sched.deschedule_running_task_and_then |sched, task| {
|
do sched.deschedule_running_task_and_then |sched, task| {
|
||||||
callback_send(tube_clone.take(), 0);
|
callback_send(tube_clone.take(), 0);
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ mod test {
|
||||||
if i == 100 { return; }
|
if i == 100 { return; }
|
||||||
|
|
||||||
let tube = Cell::new(Cell::new(tube));
|
let tube = Cell::new(Cell::new(tube));
|
||||||
do Local::borrow::<Scheduler, ()> |sched| {
|
do Local::borrow |sched: &mut Scheduler| {
|
||||||
let tube = tube.take();
|
let tube = tube.take();
|
||||||
do sched.event_loop.callback {
|
do sched.event_loop.callback {
|
||||||
let mut tube = tube.take();
|
let mut tube = tube.take();
|
||||||
|
|
|
@ -375,7 +375,7 @@ mod test_remote {
|
||||||
let mut tube = Tube::new();
|
let mut tube = Tube::new();
|
||||||
let tube_clone = tube.clone();
|
let tube_clone = tube.clone();
|
||||||
let remote_cell = Cell::new_empty();
|
let remote_cell = Cell::new_empty();
|
||||||
do Local::borrow::<Scheduler, ()>() |sched| {
|
do Local::borrow |sched: &mut Scheduler| {
|
||||||
let tube_clone = tube_clone.clone();
|
let tube_clone = tube_clone.clone();
|
||||||
let tube_clone_cell = Cell::new(tube_clone);
|
let tube_clone_cell = Cell::new(tube_clone);
|
||||||
let remote = do sched.event_loop.remote_callback {
|
let remote = do sched.event_loop.remote_callback {
|
||||||
|
@ -416,7 +416,7 @@ impl IoFactory for UvIoFactory {
|
||||||
|
|
||||||
// Block this task and take ownership, switch to scheduler context
|
// Block this task and take ownership, switch to scheduler context
|
||||||
do task::unkillable { // FIXME(#8674)
|
do task::unkillable { // FIXME(#8674)
|
||||||
let scheduler = Local::take::<Scheduler>();
|
let scheduler: ~Scheduler = Local::take();
|
||||||
do scheduler.deschedule_running_task_and_then |_, task| {
|
do scheduler.deschedule_running_task_and_then |_, task| {
|
||||||
|
|
||||||
let mut tcp = TcpWatcher::new(self.uv_loop());
|
let mut tcp = TcpWatcher::new(self.uv_loop());
|
||||||
|
@ -434,7 +434,7 @@ impl IoFactory for UvIoFactory {
|
||||||
unsafe { (*result_cell_ptr).put_back(res); }
|
unsafe { (*result_cell_ptr).put_back(res); }
|
||||||
|
|
||||||
// Context switch
|
// Context switch
|
||||||
let scheduler = Local::take::<Scheduler>();
|
let scheduler: ~Scheduler = Local::take();
|
||||||
scheduler.resume_blocked_task_immediately(task_cell.take());
|
scheduler.resume_blocked_task_immediately(task_cell.take());
|
||||||
}
|
}
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
|
@ -464,11 +464,11 @@ impl IoFactory for UvIoFactory {
|
||||||
}
|
}
|
||||||
Err(uverr) => {
|
Err(uverr) => {
|
||||||
do task::unkillable { // FIXME(#8674)
|
do task::unkillable { // FIXME(#8674)
|
||||||
let scheduler = Local::take::<Scheduler>();
|
let scheduler: ~Scheduler = Local::take();
|
||||||
do scheduler.deschedule_running_task_and_then |_, task| {
|
do scheduler.deschedule_running_task_and_then |_, task| {
|
||||||
let task_cell = Cell::new(task);
|
let task_cell = Cell::new(task);
|
||||||
do watcher.as_stream().close {
|
do watcher.as_stream().close {
|
||||||
let scheduler = Local::take::<Scheduler>();
|
let scheduler: ~Scheduler = Local::take();
|
||||||
scheduler.resume_blocked_task_immediately(task_cell.take());
|
scheduler.resume_blocked_task_immediately(task_cell.take());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -487,11 +487,11 @@ impl IoFactory for UvIoFactory {
|
||||||
}
|
}
|
||||||
Err(uverr) => {
|
Err(uverr) => {
|
||||||
do task::unkillable { // FIXME(#8674)
|
do task::unkillable { // FIXME(#8674)
|
||||||
let scheduler = Local::take::<Scheduler>();
|
let scheduler: ~Scheduler = Local::take();
|
||||||
do scheduler.deschedule_running_task_and_then |_, task| {
|
do scheduler.deschedule_running_task_and_then |_, task| {
|
||||||
let task_cell = Cell::new(task);
|
let task_cell = Cell::new(task);
|
||||||
do watcher.close {
|
do watcher.close {
|
||||||
let scheduler = Local::take::<Scheduler>();
|
let scheduler: ~Scheduler = Local::take();
|
||||||
scheduler.resume_blocked_task_immediately(task_cell.take());
|
scheduler.resume_blocked_task_immediately(task_cell.take());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -625,7 +625,7 @@ impl Drop for UvTcpListener {
|
||||||
do scheduler.deschedule_running_task_and_then |_, task| {
|
do scheduler.deschedule_running_task_and_then |_, task| {
|
||||||
let task_cell = Cell::new(task);
|
let task_cell = Cell::new(task);
|
||||||
do self_.watcher().as_stream().close {
|
do self_.watcher().as_stream().close {
|
||||||
let scheduler = Local::take::<Scheduler>();
|
let scheduler: ~Scheduler = Local::take();
|
||||||
scheduler.resume_blocked_task_immediately(task_cell.take());
|
scheduler.resume_blocked_task_immediately(task_cell.take());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -717,7 +717,7 @@ impl Drop for UvTcpStream {
|
||||||
do scheduler.deschedule_running_task_and_then |_, task| {
|
do scheduler.deschedule_running_task_and_then |_, task| {
|
||||||
let task_cell = Cell::new(task);
|
let task_cell = Cell::new(task);
|
||||||
do self_.watcher.as_stream().close {
|
do self_.watcher.as_stream().close {
|
||||||
let scheduler = Local::take::<Scheduler>();
|
let scheduler: ~Scheduler = Local::take();
|
||||||
scheduler.resume_blocked_task_immediately(task_cell.take());
|
scheduler.resume_blocked_task_immediately(task_cell.take());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -765,7 +765,7 @@ impl RtioTcpStream for UvTcpStream {
|
||||||
|
|
||||||
unsafe { (*result_cell_ptr).put_back(result); }
|
unsafe { (*result_cell_ptr).put_back(result); }
|
||||||
|
|
||||||
let scheduler = Local::take::<Scheduler>();
|
let scheduler: ~Scheduler = Local::take::<Scheduler>();
|
||||||
scheduler.resume_blocked_task_immediately(task_cell.take());
|
scheduler.resume_blocked_task_immediately(task_cell.take());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -793,7 +793,7 @@ impl RtioTcpStream for UvTcpStream {
|
||||||
|
|
||||||
unsafe { (*result_cell_ptr).put_back(result); }
|
unsafe { (*result_cell_ptr).put_back(result); }
|
||||||
|
|
||||||
let scheduler = Local::take::<Scheduler>();
|
let scheduler: ~Scheduler = Local::take();
|
||||||
scheduler.resume_blocked_task_immediately(task_cell.take());
|
scheduler.resume_blocked_task_immediately(task_cell.take());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -876,7 +876,7 @@ impl Drop for UvUdpSocket {
|
||||||
do scheduler.deschedule_running_task_and_then |_, task| {
|
do scheduler.deschedule_running_task_and_then |_, task| {
|
||||||
let task_cell = Cell::new(task);
|
let task_cell = Cell::new(task);
|
||||||
do self_.watcher.close {
|
do self_.watcher.close {
|
||||||
let scheduler = Local::take::<Scheduler>();
|
let scheduler: ~Scheduler = Local::take();
|
||||||
scheduler.resume_blocked_task_immediately(task_cell.take());
|
scheduler.resume_blocked_task_immediately(task_cell.take());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -917,7 +917,7 @@ impl RtioUdpSocket for UvUdpSocket {
|
||||||
|
|
||||||
unsafe { (*result_cell_ptr).put_back(result); }
|
unsafe { (*result_cell_ptr).put_back(result); }
|
||||||
|
|
||||||
let scheduler = Local::take::<Scheduler>();
|
let scheduler: ~Scheduler = Local::take();
|
||||||
scheduler.resume_blocked_task_immediately(task_cell.take());
|
scheduler.resume_blocked_task_immediately(task_cell.take());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -944,7 +944,7 @@ impl RtioUdpSocket for UvUdpSocket {
|
||||||
|
|
||||||
unsafe { (*result_cell_ptr).put_back(result); }
|
unsafe { (*result_cell_ptr).put_back(result); }
|
||||||
|
|
||||||
let scheduler = Local::take::<Scheduler>();
|
let scheduler: ~Scheduler = Local::take();
|
||||||
scheduler.resume_blocked_task_immediately(task_cell.take());
|
scheduler.resume_blocked_task_immediately(task_cell.take());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1094,7 +1094,7 @@ impl Drop for UvTimer {
|
||||||
do scheduler.deschedule_running_task_and_then |_, task| {
|
do scheduler.deschedule_running_task_and_then |_, task| {
|
||||||
let task_cell = Cell::new(task);
|
let task_cell = Cell::new(task);
|
||||||
do self_.watcher.close {
|
do self_.watcher.close {
|
||||||
let scheduler = Local::take::<Scheduler>();
|
let scheduler: ~Scheduler = Local::take();
|
||||||
scheduler.resume_blocked_task_immediately(task_cell.take());
|
scheduler.resume_blocked_task_immediately(task_cell.take());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1110,7 +1110,7 @@ impl RtioTimer for UvTimer {
|
||||||
let task_cell = Cell::new(task);
|
let task_cell = Cell::new(task);
|
||||||
do self_.watcher.start(msecs, 0) |_, status| {
|
do self_.watcher.start(msecs, 0) |_, status| {
|
||||||
assert!(status.is_none());
|
assert!(status.is_none());
|
||||||
let scheduler = Local::take::<Scheduler>();
|
let scheduler: ~Scheduler = Local::take();
|
||||||
scheduler.resume_blocked_task_immediately(task_cell.take());
|
scheduler.resume_blocked_task_immediately(task_cell.take());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1254,7 +1254,7 @@ impl RtioFileStream for UvFileStream {
|
||||||
fn test_simple_io_no_connect() {
|
fn test_simple_io_no_connect() {
|
||||||
do run_in_newsched_task {
|
do run_in_newsched_task {
|
||||||
unsafe {
|
unsafe {
|
||||||
let io = Local::unsafe_borrow::<IoFactoryObject>();
|
let io: *mut IoFactoryObject = Local::unsafe_borrow();
|
||||||
let addr = next_test_ip4();
|
let addr = next_test_ip4();
|
||||||
let maybe_chan = (*io).tcp_connect(addr);
|
let maybe_chan = (*io).tcp_connect(addr);
|
||||||
assert!(maybe_chan.is_err());
|
assert!(maybe_chan.is_err());
|
||||||
|
@ -1266,7 +1266,7 @@ fn test_simple_io_no_connect() {
|
||||||
fn test_simple_udp_io_bind_only() {
|
fn test_simple_udp_io_bind_only() {
|
||||||
do run_in_newsched_task {
|
do run_in_newsched_task {
|
||||||
unsafe {
|
unsafe {
|
||||||
let io = Local::unsafe_borrow::<IoFactoryObject>();
|
let io: *mut IoFactoryObject = Local::unsafe_borrow();
|
||||||
let addr = next_test_ip4();
|
let addr = next_test_ip4();
|
||||||
let maybe_socket = (*io).udp_bind(addr);
|
let maybe_socket = (*io).udp_bind(addr);
|
||||||
assert!(maybe_socket.is_ok());
|
assert!(maybe_socket.is_ok());
|
||||||
|
@ -1430,7 +1430,7 @@ fn test_simple_tcp_server_and_client() {
|
||||||
// Start the server first so it's listening when we connect
|
// Start the server first so it's listening when we connect
|
||||||
do spawntask {
|
do spawntask {
|
||||||
unsafe {
|
unsafe {
|
||||||
let io = Local::unsafe_borrow::<IoFactoryObject>();
|
let io: *mut IoFactoryObject = Local::unsafe_borrow();
|
||||||
let mut listener = (*io).tcp_bind(addr).unwrap();
|
let mut listener = (*io).tcp_bind(addr).unwrap();
|
||||||
let mut stream = listener.accept().unwrap();
|
let mut stream = listener.accept().unwrap();
|
||||||
let mut buf = [0, .. 2048];
|
let mut buf = [0, .. 2048];
|
||||||
|
@ -1445,7 +1445,7 @@ fn test_simple_tcp_server_and_client() {
|
||||||
|
|
||||||
do spawntask {
|
do spawntask {
|
||||||
unsafe {
|
unsafe {
|
||||||
let io = Local::unsafe_borrow::<IoFactoryObject>();
|
let io: *mut IoFactoryObject = Local::unsafe_borrow();
|
||||||
let mut stream = (*io).tcp_connect(addr).unwrap();
|
let mut stream = (*io).tcp_connect(addr).unwrap();
|
||||||
stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
|
stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
|
||||||
}
|
}
|
||||||
|
@ -1540,7 +1540,7 @@ fn test_simple_udp_server_and_client() {
|
||||||
|
|
||||||
do spawntask {
|
do spawntask {
|
||||||
unsafe {
|
unsafe {
|
||||||
let io = Local::unsafe_borrow::<IoFactoryObject>();
|
let io: *mut IoFactoryObject = Local::unsafe_borrow();
|
||||||
let mut server_socket = (*io).udp_bind(server_addr).unwrap();
|
let mut server_socket = (*io).udp_bind(server_addr).unwrap();
|
||||||
let mut buf = [0, .. 2048];
|
let mut buf = [0, .. 2048];
|
||||||
let (nread,src) = server_socket.recvfrom(buf).unwrap();
|
let (nread,src) = server_socket.recvfrom(buf).unwrap();
|
||||||
|
@ -1555,7 +1555,7 @@ fn test_simple_udp_server_and_client() {
|
||||||
|
|
||||||
do spawntask {
|
do spawntask {
|
||||||
unsafe {
|
unsafe {
|
||||||
let io = Local::unsafe_borrow::<IoFactoryObject>();
|
let io: *mut IoFactoryObject = Local::unsafe_borrow();
|
||||||
let mut client_socket = (*io).udp_bind(client_addr).unwrap();
|
let mut client_socket = (*io).udp_bind(client_addr).unwrap();
|
||||||
client_socket.sendto([0, 1, 2, 3, 4, 5, 6, 7], server_addr);
|
client_socket.sendto([0, 1, 2, 3, 4, 5, 6, 7], server_addr);
|
||||||
}
|
}
|
||||||
|
@ -1569,7 +1569,7 @@ fn test_read_and_block() {
|
||||||
let addr = next_test_ip4();
|
let addr = next_test_ip4();
|
||||||
|
|
||||||
do spawntask {
|
do spawntask {
|
||||||
let io = unsafe { Local::unsafe_borrow::<IoFactoryObject>() };
|
let io: *mut IoFactoryObject = unsafe { Local::unsafe_borrow() };
|
||||||
let mut listener = unsafe { (*io).tcp_bind(addr).unwrap() };
|
let mut listener = unsafe { (*io).tcp_bind(addr).unwrap() };
|
||||||
let mut stream = listener.accept().unwrap();
|
let mut stream = listener.accept().unwrap();
|
||||||
let mut buf = [0, .. 2048];
|
let mut buf = [0, .. 2048];
|
||||||
|
@ -1588,7 +1588,7 @@ fn test_read_and_block() {
|
||||||
reads += 1;
|
reads += 1;
|
||||||
|
|
||||||
do task::unkillable { // FIXME(#8674)
|
do task::unkillable { // FIXME(#8674)
|
||||||
let scheduler = Local::take::<Scheduler>();
|
let scheduler: ~Scheduler = Local::take();
|
||||||
// Yield to the other task in hopes that it
|
// Yield to the other task in hopes that it
|
||||||
// will trigger a read callback while we are
|
// will trigger a read callback while we are
|
||||||
// not ready for it
|
// not ready for it
|
||||||
|
@ -1605,7 +1605,7 @@ fn test_read_and_block() {
|
||||||
|
|
||||||
do spawntask {
|
do spawntask {
|
||||||
unsafe {
|
unsafe {
|
||||||
let io = Local::unsafe_borrow::<IoFactoryObject>();
|
let io: *mut IoFactoryObject = Local::unsafe_borrow();
|
||||||
let mut stream = (*io).tcp_connect(addr).unwrap();
|
let mut stream = (*io).tcp_connect(addr).unwrap();
|
||||||
stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
|
stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
|
||||||
stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
|
stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
|
||||||
|
@ -1625,7 +1625,7 @@ fn test_read_read_read() {
|
||||||
|
|
||||||
do spawntask {
|
do spawntask {
|
||||||
unsafe {
|
unsafe {
|
||||||
let io = Local::unsafe_borrow::<IoFactoryObject>();
|
let io: *mut IoFactoryObject = Local::unsafe_borrow();
|
||||||
let mut listener = (*io).tcp_bind(addr).unwrap();
|
let mut listener = (*io).tcp_bind(addr).unwrap();
|
||||||
let mut stream = listener.accept().unwrap();
|
let mut stream = listener.accept().unwrap();
|
||||||
let buf = [1, .. 2048];
|
let buf = [1, .. 2048];
|
||||||
|
@ -1639,7 +1639,7 @@ fn test_read_read_read() {
|
||||||
|
|
||||||
do spawntask {
|
do spawntask {
|
||||||
unsafe {
|
unsafe {
|
||||||
let io = Local::unsafe_borrow::<IoFactoryObject>();
|
let io: *mut IoFactoryObject = Local::unsafe_borrow();
|
||||||
let mut stream = (*io).tcp_connect(addr).unwrap();
|
let mut stream = (*io).tcp_connect(addr).unwrap();
|
||||||
let mut buf = [0, .. 2048];
|
let mut buf = [0, .. 2048];
|
||||||
let mut total_bytes_read = 0;
|
let mut total_bytes_read = 0;
|
||||||
|
@ -1665,7 +1665,7 @@ fn test_udp_twice() {
|
||||||
|
|
||||||
do spawntask {
|
do spawntask {
|
||||||
unsafe {
|
unsafe {
|
||||||
let io = Local::unsafe_borrow::<IoFactoryObject>();
|
let io: *mut IoFactoryObject = Local::unsafe_borrow();
|
||||||
let mut client = (*io).udp_bind(client_addr).unwrap();
|
let mut client = (*io).udp_bind(client_addr).unwrap();
|
||||||
assert!(client.sendto([1], server_addr).is_ok());
|
assert!(client.sendto([1], server_addr).is_ok());
|
||||||
assert!(client.sendto([2], server_addr).is_ok());
|
assert!(client.sendto([2], server_addr).is_ok());
|
||||||
|
@ -1674,7 +1674,7 @@ fn test_udp_twice() {
|
||||||
|
|
||||||
do spawntask {
|
do spawntask {
|
||||||
unsafe {
|
unsafe {
|
||||||
let io = Local::unsafe_borrow::<IoFactoryObject>();
|
let io: *mut IoFactoryObject = Local::unsafe_borrow();
|
||||||
let mut server = (*io).udp_bind(server_addr).unwrap();
|
let mut server = (*io).udp_bind(server_addr).unwrap();
|
||||||
let mut buf1 = [0];
|
let mut buf1 = [0];
|
||||||
let mut buf2 = [0];
|
let mut buf2 = [0];
|
||||||
|
@ -1702,7 +1702,7 @@ fn test_udp_many_read() {
|
||||||
|
|
||||||
do spawntask {
|
do spawntask {
|
||||||
unsafe {
|
unsafe {
|
||||||
let io = Local::unsafe_borrow::<IoFactoryObject>();
|
let io: *mut IoFactoryObject = Local::unsafe_borrow();
|
||||||
let mut server_out = (*io).udp_bind(server_out_addr).unwrap();
|
let mut server_out = (*io).udp_bind(server_out_addr).unwrap();
|
||||||
let mut server_in = (*io).udp_bind(server_in_addr).unwrap();
|
let mut server_in = (*io).udp_bind(server_in_addr).unwrap();
|
||||||
let msg = [1, .. 2048];
|
let msg = [1, .. 2048];
|
||||||
|
@ -1725,7 +1725,7 @@ fn test_udp_many_read() {
|
||||||
|
|
||||||
do spawntask {
|
do spawntask {
|
||||||
unsafe {
|
unsafe {
|
||||||
let io = Local::unsafe_borrow::<IoFactoryObject>();
|
let io: *mut IoFactoryObject = Local::unsafe_borrow();
|
||||||
let mut client_out = (*io).udp_bind(client_out_addr).unwrap();
|
let mut client_out = (*io).udp_bind(client_out_addr).unwrap();
|
||||||
let mut client_in = (*io).udp_bind(client_in_addr).unwrap();
|
let mut client_in = (*io).udp_bind(client_in_addr).unwrap();
|
||||||
let mut total_bytes_recv = 0;
|
let mut total_bytes_recv = 0;
|
||||||
|
@ -1754,7 +1754,7 @@ fn test_udp_many_read() {
|
||||||
fn test_timer_sleep_simple() {
|
fn test_timer_sleep_simple() {
|
||||||
do run_in_newsched_task {
|
do run_in_newsched_task {
|
||||||
unsafe {
|
unsafe {
|
||||||
let io = Local::unsafe_borrow::<IoFactoryObject>();
|
let io: *mut IoFactoryObject = Local::unsafe_borrow();
|
||||||
let timer = (*io).timer_init();
|
let timer = (*io).timer_init();
|
||||||
do timer.map_move |mut t| { t.sleep(1) };
|
do timer.map_move |mut t| { t.sleep(1) };
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ pub fn select<A: Select>(ports: &mut [A]) -> uint {
|
||||||
|
|
||||||
do (|| {
|
do (|| {
|
||||||
let c = Cell::new(c.take());
|
let c = Cell::new(c.take());
|
||||||
let sched = Local::take::<Scheduler>();
|
let sched: ~Scheduler = Local::take();
|
||||||
do sched.deschedule_running_task_and_then |sched, task| {
|
do sched.deschedule_running_task_and_then |sched, task| {
|
||||||
let task_handles = task.make_selectable(ports.len());
|
let task_handles = task.make_selectable(ports.len());
|
||||||
|
|
||||||
|
|
|
@ -143,7 +143,7 @@ pub fn begin_unwind_(msg: *c_char, file: *c_char, line: size_t) -> ! {
|
||||||
if in_green_task_context() {
|
if in_green_task_context() {
|
||||||
// XXX: Logging doesn't work here - the check to call the log
|
// XXX: Logging doesn't work here - the check to call the log
|
||||||
// function never passes - so calling the log function directly.
|
// function never passes - so calling the log function directly.
|
||||||
do Local::borrow::<Task, ()> |task| {
|
do Local::borrow |task: &mut Task| {
|
||||||
let msg = match task.name {
|
let msg = match task.name {
|
||||||
Some(ref name) =>
|
Some(ref name) =>
|
||||||
fmt!("task '%s' failed at '%s', %s:%i",
|
fmt!("task '%s' failed at '%s', %s:%i",
|
||||||
|
@ -160,7 +160,7 @@ pub fn begin_unwind_(msg: *c_char, file: *c_char, line: size_t) -> ! {
|
||||||
msg, file, line as int);
|
msg, file, line as int);
|
||||||
}
|
}
|
||||||
|
|
||||||
let task = Local::unsafe_borrow::<Task>();
|
let task: *mut Task = Local::unsafe_borrow();
|
||||||
if (*task).unwinder.unwinding {
|
if (*task).unwinder.unwinding {
|
||||||
rtabort!("unwinding again");
|
rtabort!("unwinding again");
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ impl Handle {
|
||||||
pub fn new() -> Handle {
|
pub fn new() -> Handle {
|
||||||
use rt::local::Local;
|
use rt::local::Local;
|
||||||
unsafe {
|
unsafe {
|
||||||
let task = Local::unsafe_borrow::<Task>();
|
let task: *mut Task = Local::unsafe_borrow();
|
||||||
NewHandle(&mut (*task).storage)
|
NewHandle(&mut (*task).storage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -526,7 +526,7 @@ pub fn with_task_name<U>(blk: &fn(Option<&str>) -> U) -> U {
|
||||||
use rt::task::Task;
|
use rt::task::Task;
|
||||||
|
|
||||||
if in_green_task_context() {
|
if in_green_task_context() {
|
||||||
do Local::borrow::<Task, U> |task| {
|
do Local::borrow |task: &mut Task| {
|
||||||
match task.name {
|
match task.name {
|
||||||
Some(ref name) => blk(Some(name.as_slice())),
|
Some(ref name) => blk(Some(name.as_slice())),
|
||||||
None => blk(None)
|
None => blk(None)
|
||||||
|
@ -545,7 +545,7 @@ pub fn deschedule() {
|
||||||
|
|
||||||
// FIXME #6842: What does yield really mean in newsched?
|
// FIXME #6842: What does yield really mean in newsched?
|
||||||
// FIXME(#7544): Optimize this, since we know we won't block.
|
// FIXME(#7544): Optimize this, since we know we won't block.
|
||||||
let sched = Local::take::<Scheduler>();
|
let sched: ~Scheduler = Local::take();
|
||||||
do sched.deschedule_running_task_and_then |sched, task| {
|
do sched.deschedule_running_task_and_then |sched, task| {
|
||||||
sched.enqueue_blocked_task(task);
|
sched.enqueue_blocked_task(task);
|
||||||
}
|
}
|
||||||
|
@ -556,7 +556,7 @@ pub fn failing() -> bool {
|
||||||
|
|
||||||
use rt::task::Task;
|
use rt::task::Task;
|
||||||
|
|
||||||
do Local::borrow::<Task, bool> |local| {
|
do Local::borrow |local: &mut Task| {
|
||||||
local.unwinder.unwinding
|
local.unwinder.unwinding
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -582,7 +582,7 @@ pub fn unkillable<U>(f: &fn() -> U) -> U {
|
||||||
unsafe {
|
unsafe {
|
||||||
if in_green_task_context() {
|
if in_green_task_context() {
|
||||||
// The inhibits/allows might fail and need to borrow the task.
|
// The inhibits/allows might fail and need to borrow the task.
|
||||||
let t = Local::unsafe_borrow::<Task>();
|
let t: *mut Task = Local::unsafe_borrow();
|
||||||
do (|| {
|
do (|| {
|
||||||
(*t).death.inhibit_kill((*t).unwinder.unwinding);
|
(*t).death.inhibit_kill((*t).unwinder.unwinding);
|
||||||
f()
|
f()
|
||||||
|
@ -616,7 +616,7 @@ pub fn rekillable<U>(f: &fn() -> U) -> U {
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
if in_green_task_context() {
|
if in_green_task_context() {
|
||||||
let t = Local::unsafe_borrow::<Task>();
|
let t: *mut Task = Local::unsafe_borrow();
|
||||||
do (|| {
|
do (|| {
|
||||||
(*t).death.allow_kill((*t).unwinder.unwinding);
|
(*t).death.allow_kill((*t).unwinder.unwinding);
|
||||||
f()
|
f()
|
||||||
|
@ -1032,7 +1032,7 @@ fn test_try_fail() {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn get_sched_id() -> int {
|
fn get_sched_id() -> int {
|
||||||
do Local::borrow::<::rt::sched::Scheduler, int> |sched| {
|
do Local::borrow |sched: &mut ::rt::sched::Scheduler| {
|
||||||
sched.sched_id() as int
|
sched.sched_id() as int
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -449,7 +449,7 @@ impl RuntimeGlue {
|
||||||
fn kill_task(mut handle: KillHandle) {
|
fn kill_task(mut handle: KillHandle) {
|
||||||
do handle.kill().map_move |killed_task| {
|
do handle.kill().map_move |killed_task| {
|
||||||
let killed_task = Cell::new(killed_task);
|
let killed_task = Cell::new(killed_task);
|
||||||
do Local::borrow::<Scheduler, ()> |sched| {
|
do Local::borrow |sched: &mut Scheduler| {
|
||||||
sched.enqueue_task(killed_task.take());
|
sched.enqueue_task(killed_task.take());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -460,7 +460,7 @@ impl RuntimeGlue {
|
||||||
unsafe {
|
unsafe {
|
||||||
// Can't use safe borrow, because the taskgroup destructor needs to
|
// Can't use safe borrow, because the taskgroup destructor needs to
|
||||||
// access the scheduler again to send kill signals to other tasks.
|
// access the scheduler again to send kill signals to other tasks.
|
||||||
let me = Local::unsafe_borrow::<Task>();
|
let me: *mut Task = Local::unsafe_borrow();
|
||||||
blk((*me).death.kill_handle.get_ref(), (*me).unwinder.unwinding)
|
blk((*me).death.kill_handle.get_ref(), (*me).unwinder.unwinding)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -470,7 +470,7 @@ impl RuntimeGlue {
|
||||||
unsafe {
|
unsafe {
|
||||||
// Can't use safe borrow, because creating new hashmaps for the
|
// Can't use safe borrow, because creating new hashmaps for the
|
||||||
// tasksets requires an rng, which needs to borrow the sched.
|
// tasksets requires an rng, which needs to borrow the sched.
|
||||||
let me = Local::unsafe_borrow::<Task>();
|
let me: *mut Task = Local::unsafe_borrow();
|
||||||
blk(match (*me).taskgroup {
|
blk(match (*me).taskgroup {
|
||||||
None => {
|
None => {
|
||||||
// First task in its (unlinked/unsupervised) taskgroup.
|
// First task in its (unlinked/unsupervised) taskgroup.
|
||||||
|
@ -574,7 +574,7 @@ pub fn spawn_raw(mut opts: TaskOpts, f: ~fn()) {
|
||||||
// If child data is 'None', the enlist is vacuously successful.
|
// If child data is 'None', the enlist is vacuously successful.
|
||||||
let enlist_success = do child_data.take().map_move_default(true) |child_data| {
|
let enlist_success = do child_data.take().map_move_default(true) |child_data| {
|
||||||
let child_data = Cell::new(child_data); // :(
|
let child_data = Cell::new(child_data); // :(
|
||||||
do Local::borrow::<Task, bool> |me| {
|
do Local::borrow |me: &mut Task| {
|
||||||
let (child_tg, ancestors) = child_data.take();
|
let (child_tg, ancestors) = child_data.take();
|
||||||
let mut ancestors = ancestors;
|
let mut ancestors = ancestors;
|
||||||
let handle = me.death.kill_handle.get_ref();
|
let handle = me.death.kill_handle.get_ref();
|
||||||
|
@ -608,7 +608,7 @@ pub fn spawn_raw(mut opts: TaskOpts, f: ~fn()) {
|
||||||
} else {
|
} else {
|
||||||
unsafe {
|
unsafe {
|
||||||
// Creating a 1:1 task:thread ...
|
// Creating a 1:1 task:thread ...
|
||||||
let sched = Local::unsafe_borrow::<Scheduler>();
|
let sched: *mut Scheduler = Local::unsafe_borrow();
|
||||||
let sched_handle = (*sched).make_handle();
|
let sched_handle = (*sched).make_handle();
|
||||||
|
|
||||||
// Since this is a 1:1 scheduler we create a queue not in
|
// Since this is a 1:1 scheduler we create a queue not in
|
||||||
|
|
|
@ -176,7 +176,7 @@ macro_rules! tuple_impls {
|
||||||
impl<$($T:Zero),+> Zero for ($($T,)+) {
|
impl<$($T:Zero),+> Zero for ($($T,)+) {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn zero() -> ($($T,)+) {
|
fn zero() -> ($($T,)+) {
|
||||||
($(Zero::zero::<$T>(),)+)
|
($({ let x: $T = Zero::zero(); x},)+)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_zero(&self) -> bool {
|
fn is_zero(&self) -> bool {
|
||||||
|
|
|
@ -538,7 +538,8 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn option_empty() {
|
fn option_empty() {
|
||||||
assert!(AtomicOption::empty::<()>().is_empty(SeqCst));
|
let mut option: AtomicOption<()> = AtomicOption::empty();
|
||||||
|
assert!(option.is_empty(SeqCst));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
use c_str::ToCStr;
|
use c_str::ToCStr;
|
||||||
use cast::transmute;
|
use cast::transmute;
|
||||||
use libc::{c_char, c_void, size_t, uintptr_t};
|
use libc::{c_char, c_void, size_t, uintptr_t};
|
||||||
use option::{Some, None};
|
use option::{Option, None, Some};
|
||||||
use sys;
|
use sys;
|
||||||
use rt::task::Task;
|
use rt::task::Task;
|
||||||
use rt::local::Local;
|
use rt::local::Local;
|
||||||
|
@ -37,7 +37,8 @@ pub fn fail_bounds_check(file: *c_char, line: size_t,
|
||||||
#[lang="malloc"]
|
#[lang="malloc"]
|
||||||
pub unsafe fn local_malloc(td: *c_char, size: uintptr_t) -> *c_char {
|
pub unsafe fn local_malloc(td: *c_char, size: uintptr_t) -> *c_char {
|
||||||
// XXX: Unsafe borrow for speed. Lame.
|
// XXX: Unsafe borrow for speed. Lame.
|
||||||
match Local::try_unsafe_borrow::<Task>() {
|
let task: Option<*mut Task> = Local::try_unsafe_borrow();
|
||||||
|
match task {
|
||||||
Some(task) => {
|
Some(task) => {
|
||||||
(*task).heap.alloc(td as *c_void, size as uint) as *c_char
|
(*task).heap.alloc(td as *c_void, size as uint) as *c_char
|
||||||
}
|
}
|
||||||
|
|
|
@ -279,7 +279,8 @@ pub unsafe fn atomically<U>(f: &fn() -> U) -> U {
|
||||||
use rt::task::{Task, GreenTask, SchedTask};
|
use rt::task::{Task, GreenTask, SchedTask};
|
||||||
use rt::local::Local;
|
use rt::local::Local;
|
||||||
|
|
||||||
match Local::try_unsafe_borrow::<Task>() {
|
let task_opt: Option<*mut Task> = Local::try_unsafe_borrow();
|
||||||
|
match task_opt {
|
||||||
Some(t) => {
|
Some(t) => {
|
||||||
match (*t).task_type {
|
match (*t).task_type {
|
||||||
GreenTask(_) => {
|
GreenTask(_) => {
|
||||||
|
|
|
@ -174,12 +174,16 @@ impl Generics {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
|
||||||
|
pub enum MethodProvenance {
|
||||||
|
FromTrait(def_id),
|
||||||
|
FromImpl(def_id),
|
||||||
|
}
|
||||||
|
|
||||||
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
|
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
|
||||||
pub enum def {
|
pub enum def {
|
||||||
def_fn(def_id, purity),
|
def_fn(def_id, purity),
|
||||||
def_static_method(/* method */ def_id,
|
def_static_method(/* method */ def_id, MethodProvenance, purity),
|
||||||
/* trait */ Option<def_id>,
|
|
||||||
purity),
|
|
||||||
def_self(NodeId),
|
def_self(NodeId),
|
||||||
def_self_ty(/* trait id */ NodeId),
|
def_self_ty(/* trait id */ NodeId),
|
||||||
def_mod(def_id),
|
def_mod(def_id),
|
||||||
|
@ -716,7 +720,7 @@ impl ToStr for float_ty {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NB Eq method appears below.
|
// NB Eq method appears below.
|
||||||
#[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
|
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
|
||||||
pub struct Ty {
|
pub struct Ty {
|
||||||
id: NodeId,
|
id: NodeId,
|
||||||
node: ty_,
|
node: ty_,
|
||||||
|
|
|
@ -74,6 +74,13 @@ pub trait AstBuilder {
|
||||||
// statements
|
// statements
|
||||||
fn stmt_expr(&self, expr: @ast::expr) -> @ast::stmt;
|
fn stmt_expr(&self, expr: @ast::expr) -> @ast::stmt;
|
||||||
fn stmt_let(&self, sp: span, mutbl: bool, ident: ast::ident, ex: @ast::expr) -> @ast::stmt;
|
fn stmt_let(&self, sp: span, mutbl: bool, ident: ast::ident, ex: @ast::expr) -> @ast::stmt;
|
||||||
|
fn stmt_let_typed(&self,
|
||||||
|
sp: span,
|
||||||
|
mutbl: bool,
|
||||||
|
ident: ast::ident,
|
||||||
|
typ: ast::Ty,
|
||||||
|
ex: @ast::expr)
|
||||||
|
-> @ast::stmt;
|
||||||
|
|
||||||
// blocks
|
// blocks
|
||||||
fn block(&self, span: span, stmts: ~[@ast::stmt], expr: Option<@ast::expr>) -> ast::Block;
|
fn block(&self, span: span, stmts: ~[@ast::stmt], expr: Option<@ast::expr>) -> ast::Block;
|
||||||
|
@ -241,8 +248,8 @@ impl AstBuilder for @ExtCtxt {
|
||||||
types: ~[ast::Ty])
|
types: ~[ast::Ty])
|
||||||
-> ast::Path {
|
-> ast::Path {
|
||||||
let last_identifier = idents.pop();
|
let last_identifier = idents.pop();
|
||||||
let mut segments: ~[ast::PathSegment] = idents.consume_iter()
|
let mut segments: ~[ast::PathSegment] = idents.move_iter()
|
||||||
.transform(|ident| {
|
.map(|ident| {
|
||||||
ast::PathSegment {
|
ast::PathSegment {
|
||||||
identifier: ident,
|
identifier: ident,
|
||||||
lifetime: None,
|
lifetime: None,
|
||||||
|
@ -400,6 +407,26 @@ impl AstBuilder for @ExtCtxt {
|
||||||
@respan(sp, ast::stmt_decl(@decl, self.next_id()))
|
@respan(sp, ast::stmt_decl(@decl, self.next_id()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn stmt_let_typed(&self,
|
||||||
|
sp: span,
|
||||||
|
mutbl: bool,
|
||||||
|
ident: ast::ident,
|
||||||
|
typ: ast::Ty,
|
||||||
|
ex: @ast::expr)
|
||||||
|
-> @ast::stmt {
|
||||||
|
let pat = self.pat_ident(sp, ident);
|
||||||
|
let local = @ast::Local {
|
||||||
|
is_mutbl: mutbl,
|
||||||
|
ty: typ,
|
||||||
|
pat: pat,
|
||||||
|
init: Some(ex),
|
||||||
|
id: self.next_id(),
|
||||||
|
span: sp,
|
||||||
|
};
|
||||||
|
let decl = respan(sp, ast::decl_local(local));
|
||||||
|
@respan(sp, ast::stmt_decl(@decl, self.next_id()))
|
||||||
|
}
|
||||||
|
|
||||||
fn block(&self, span: span, stmts: ~[@ast::stmt], expr: Option<@expr>) -> ast::Block {
|
fn block(&self, span: span, stmts: ~[@ast::stmt], expr: Option<@expr>) -> ast::Block {
|
||||||
self.block_all(span, ~[], stmts, expr)
|
self.block_all(span, ~[], stmts, expr)
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,24 +76,34 @@ fn rand_substructure(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr {
|
||||||
|
|
||||||
let variant_count = cx.expr_uint(span, variants.len());
|
let variant_count = cx.expr_uint(span, variants.len());
|
||||||
|
|
||||||
// need to specify the uint-ness of the random number
|
|
||||||
let uint_ty = cx.ty_ident(span, cx.ident_of("uint"));
|
|
||||||
let r_ty = cx.ty_ident(span, cx.ident_of("R"));
|
let r_ty = cx.ty_ident(span, cx.ident_of("R"));
|
||||||
let rand_name = cx.path_all(span,
|
let rand_name = cx.path_all(span,
|
||||||
true,
|
true,
|
||||||
rand_ident.clone(),
|
rand_ident.clone(),
|
||||||
None,
|
None,
|
||||||
~[ uint_ty, r_ty ]);
|
~[]);
|
||||||
let rand_name = cx.expr_path(rand_name);
|
let rand_name = cx.expr_path(rand_name);
|
||||||
|
|
||||||
// ::std::rand::Rand::rand::<uint>(rng)
|
// ::std::rand::Rand::rand(rng)
|
||||||
let rv_call = cx.expr_call(span,
|
let rv_call = cx.expr_call(span,
|
||||||
rand_name,
|
rand_name,
|
||||||
~[ rng[0].duplicate(cx) ]);
|
~[ rng[0].duplicate(cx) ]);
|
||||||
|
|
||||||
|
// need to specify the uint-ness of the random number
|
||||||
|
let uint_ty = cx.ty_ident(span, cx.ident_of("uint"));
|
||||||
|
let value_ident = cx.ident_of("__value");
|
||||||
|
let let_statement = cx.stmt_let_typed(span,
|
||||||
|
false,
|
||||||
|
value_ident,
|
||||||
|
uint_ty,
|
||||||
|
rv_call);
|
||||||
|
|
||||||
// rand() % variants.len()
|
// rand() % variants.len()
|
||||||
let rand_variant = cx.expr_binary(span, ast::rem,
|
let value_ref = cx.expr_ident(span, value_ident);
|
||||||
rv_call, variant_count);
|
let rand_variant = cx.expr_binary(span,
|
||||||
|
ast::rem,
|
||||||
|
value_ref,
|
||||||
|
variant_count);
|
||||||
|
|
||||||
let mut arms = do variants.iter().enumerate().map |(i, id_sum)| {
|
let mut arms = do variants.iter().enumerate().map |(i, id_sum)| {
|
||||||
let i_expr = cx.expr_uint(span, i);
|
let i_expr = cx.expr_uint(span, i);
|
||||||
|
@ -111,7 +121,10 @@ fn rand_substructure(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr {
|
||||||
// _ => {} at the end. Should never occur
|
// _ => {} at the end. Should never occur
|
||||||
arms.push(cx.arm_unreachable(span));
|
arms.push(cx.arm_unreachable(span));
|
||||||
|
|
||||||
cx.expr_match(span, rand_variant, arms)
|
let match_expr = cx.expr_match(span, rand_variant, arms);
|
||||||
|
|
||||||
|
let block = cx.block(span, ~[ let_statement ], Some(match_expr));
|
||||||
|
cx.expr_block(block)
|
||||||
}
|
}
|
||||||
_ => cx.bug("Non-static method in `deriving(Rand)`")
|
_ => cx.bug("Non-static method in `deriving(Rand)`")
|
||||||
};
|
};
|
||||||
|
|
|
@ -399,8 +399,8 @@ mod test {
|
||||||
types: ~[],
|
types: ~[],
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
}),
|
||||||
span: sp(0, 6))
|
span: sp(0, 6)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1374,7 +1374,7 @@ impl Parser {
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
match found {
|
match found {
|
||||||
Some(INTERPOLATED(token::nt_path(path))) => {
|
Some(INTERPOLATED(token::nt_path(~path))) => {
|
||||||
return PathAndBounds {
|
return PathAndBounds {
|
||||||
path: path,
|
path: path,
|
||||||
bounds: None,
|
bounds: None,
|
||||||
|
@ -1483,7 +1483,7 @@ impl Parser {
|
||||||
let mut path_segments = ~[];
|
let mut path_segments = ~[];
|
||||||
let mut bounds = None;
|
let mut bounds = None;
|
||||||
let last_segment_index = segments.len() - 1;
|
let last_segment_index = segments.len() - 1;
|
||||||
for (i, segment_and_bounds) in segments.consume_iter().enumerate() {
|
for (i, segment_and_bounds) in segments.move_iter().enumerate() {
|
||||||
let PathSegmentAndBoundSet {
|
let PathSegmentAndBoundSet {
|
||||||
segment: segment,
|
segment: segment,
|
||||||
bound_set: bound_set
|
bound_set: bound_set
|
||||||
|
@ -4840,7 +4840,7 @@ impl Parser {
|
||||||
let path = ast::Path {
|
let path = ast::Path {
|
||||||
span: mk_sp(lo, self.span.hi),
|
span: mk_sp(lo, self.span.hi),
|
||||||
global: false,
|
global: false,
|
||||||
segments: path.consume_iter().transform(|identifier| {
|
segments: path.move_iter().map(|identifier| {
|
||||||
ast::PathSegment {
|
ast::PathSegment {
|
||||||
identifier: identifier,
|
identifier: identifier,
|
||||||
lifetime: None,
|
lifetime: None,
|
||||||
|
@ -4876,7 +4876,7 @@ impl Parser {
|
||||||
let path = ast::Path {
|
let path = ast::Path {
|
||||||
span: mk_sp(lo, self.span.hi),
|
span: mk_sp(lo, self.span.hi),
|
||||||
global: false,
|
global: false,
|
||||||
segments: path.consume_iter().transform(|identifier| {
|
segments: path.move_iter().map(|identifier| {
|
||||||
ast::PathSegment {
|
ast::PathSegment {
|
||||||
identifier: identifier,
|
identifier: identifier,
|
||||||
lifetime: None,
|
lifetime: None,
|
||||||
|
@ -4894,7 +4894,7 @@ impl Parser {
|
||||||
let path = ast::Path {
|
let path = ast::Path {
|
||||||
span: mk_sp(lo, self.span.hi),
|
span: mk_sp(lo, self.span.hi),
|
||||||
global: false,
|
global: false,
|
||||||
segments: path.consume_iter().transform(|identifier| {
|
segments: path.move_iter().map(|identifier| {
|
||||||
ast::PathSegment {
|
ast::PathSegment {
|
||||||
identifier: identifier,
|
identifier: identifier,
|
||||||
lifetime: None,
|
lifetime: None,
|
||||||
|
@ -4916,7 +4916,7 @@ impl Parser {
|
||||||
let path = ast::Path {
|
let path = ast::Path {
|
||||||
span: mk_sp(lo, self.span.hi),
|
span: mk_sp(lo, self.span.hi),
|
||||||
global: false,
|
global: false,
|
||||||
segments: path.consume_iter().transform(|identifier| {
|
segments: path.move_iter().map(|identifier| {
|
||||||
ast::PathSegment {
|
ast::PathSegment {
|
||||||
identifier: identifier,
|
identifier: identifier,
|
||||||
lifetime: None,
|
lifetime: None,
|
||||||
|
|
|
@ -320,7 +320,7 @@ pub fn walk_ty<E:Clone, V:Visitor<E>>(visitor: &mut V, typ: &Ty, env: E) {
|
||||||
|
|
||||||
pub fn walk_path<E:Clone, V:Visitor<E>>(visitor: &mut V, path: &Path, env: E) {
|
pub fn walk_path<E:Clone, V:Visitor<E>>(visitor: &mut V, path: &Path, env: E) {
|
||||||
for segment in path.segments.iter() {
|
for segment in path.segments.iter() {
|
||||||
for typ in path.types.iter() {
|
for typ in segment.types.iter() {
|
||||||
visitor.visit_ty(typ, env.clone())
|
visitor.visit_ty(typ, env.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
37
src/test/compile-fail/bad-mid-path-type-params.rs
Normal file
37
src/test/compile-fail/bad-mid-path-type-params.rs
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
#[no_std];
|
||||||
|
|
||||||
|
struct S<T> {
|
||||||
|
contents: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> S<T> {
|
||||||
|
fn new<U>(x: T, _: U) -> S<T> {
|
||||||
|
S {
|
||||||
|
contents: x,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Trait<T> {
|
||||||
|
fn new<U>(x: T, y: U) -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct S2 {
|
||||||
|
contents: int,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Trait<int> for S2 {
|
||||||
|
fn new<U>(x: int, _: U) -> S2 {
|
||||||
|
S2 {
|
||||||
|
contents: x,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _ = S::new::<int,float>(1, 1.0); //~ ERROR the impl referenced by this path has 1 type parameter, but 0 type parameters were supplied
|
||||||
|
let _ = S::<'self,int>::new::<float>(1, 1.0); //~ ERROR this impl has no lifetime parameter
|
||||||
|
let _: S2 = Trait::new::<int,float>(1, 1.0); //~ ERROR the trait referenced by this path has 1 type parameter, but 0 type parameters were supplied
|
||||||
|
let _: S2 = Trait::<'self,int>::new::<float>(1, 1.0); //~ ERROR this trait has no lifetime parameter
|
||||||
|
}
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
// Copyright 2013 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.
|
|
||||||
|
|
||||||
pub trait Nummy {
|
|
||||||
fn from_inty<T>() -> Self;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Nummy for float {
|
|
||||||
fn from_inty<T>() -> float { 0.0 }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let _1:float = Nummy::from_inty::<int>(); //~ ERROR not enough type
|
|
||||||
//~^ NOTE Static methods have an extra implicit type parameter
|
|
||||||
}
|
|
|
@ -23,17 +23,17 @@ let x: u64<int>; //~ ERROR type parameters are not allowed on this type
|
||||||
let x: float<int>; //~ ERROR type parameters are not allowed on this type
|
let x: float<int>; //~ ERROR type parameters are not allowed on this type
|
||||||
let x: char<int>; //~ ERROR type parameters are not allowed on this type
|
let x: char<int>; //~ ERROR type parameters are not allowed on this type
|
||||||
|
|
||||||
let x: int<'static>; //~ ERROR region parameters are not allowed on this type
|
let x: int<'static>; //~ ERROR lifetime parameters are not allowed on this type
|
||||||
let x: i8<'static>; //~ ERROR region parameters are not allowed on this type
|
let x: i8<'static>; //~ ERROR lifetime parameters are not allowed on this type
|
||||||
let x: i16<'static>; //~ ERROR region parameters are not allowed on this type
|
let x: i16<'static>; //~ ERROR lifetime parameters are not allowed on this type
|
||||||
let x: i32<'static>; //~ ERROR region parameters are not allowed on this type
|
let x: i32<'static>; //~ ERROR lifetime parameters are not allowed on this type
|
||||||
let x: i64<'static>; //~ ERROR region parameters are not allowed on this type
|
let x: i64<'static>; //~ ERROR lifetime parameters are not allowed on this type
|
||||||
let x: uint<'static>; //~ ERROR region parameters are not allowed on this type
|
let x: uint<'static>; //~ ERROR lifetime parameters are not allowed on this type
|
||||||
let x: u8<'static>; //~ ERROR region parameters are not allowed on this type
|
let x: u8<'static>; //~ ERROR lifetime parameters are not allowed on this type
|
||||||
let x: u16<'static>; //~ ERROR region parameters are not allowed on this type
|
let x: u16<'static>; //~ ERROR lifetime parameters are not allowed on this type
|
||||||
let x: u32<'static>; //~ ERROR region parameters are not allowed on this type
|
let x: u32<'static>; //~ ERROR lifetime parameters are not allowed on this type
|
||||||
let x: u64<'static>; //~ ERROR region parameters are not allowed on this type
|
let x: u64<'static>; //~ ERROR lifetime parameters are not allowed on this type
|
||||||
let x: float<'static>; //~ ERROR region parameters are not allowed on this type
|
let x: float<'static>; //~ ERROR lifetime parameters are not allowed on this type
|
||||||
let x: char<'static>; //~ ERROR region parameters are not allowed on this type
|
let x: char<'static>; //~ ERROR lifetime parameters are not allowed on this type
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,8 +25,4 @@ fn a_fn3<'a,'b>(e: a_class<'a>) -> a_class<'b> {
|
||||||
//~^ ERROR cannot infer an appropriate lifetime
|
//~^ ERROR cannot infer an appropriate lifetime
|
||||||
}
|
}
|
||||||
|
|
||||||
fn a_fn4<'a,'b>() {
|
|
||||||
let _: int<'a> = 1; //~ ERROR region parameters are not allowed on this type
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() { }
|
fn main() { }
|
||||||
|
|
|
@ -6,5 +6,5 @@ mod a {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let _ = a::S::new(); //~ ERROR function `new` is private
|
let _ = a::S::new(); //~ ERROR method `new` is private
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// xfail-pretty
|
||||||
|
|
||||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||||
// file at the top-level directory of this distribution and at
|
// file at the top-level directory of this distribution and at
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
|
|
@ -36,5 +36,6 @@ struct Lots {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
assert!(Zero::zero::<Lots>().is_zero());
|
let lots: Lots = Zero::zero();
|
||||||
|
assert!(lots.is_zero());
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,11 +13,12 @@ extern mod extra;
|
||||||
use std::num::Float;
|
use std::num::Float;
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let nan = Float::NaN::<float>();
|
let nan: float = Float::NaN();
|
||||||
assert!((nan).is_NaN());
|
assert!((nan).is_NaN());
|
||||||
|
|
||||||
let inf = Float::infinity::<float>();
|
let inf: float = Float::infinity();
|
||||||
assert_eq!(-inf, Float::neg_infinity::<float>());
|
let neg_inf: float = Float::neg_infinity();
|
||||||
|
assert_eq!(-inf, neg_inf);
|
||||||
|
|
||||||
assert!( nan != nan);
|
assert!( nan != nan);
|
||||||
assert!( nan != -nan);
|
assert!( nan != -nan);
|
||||||
|
|
|
@ -10,7 +10,24 @@ impl<T> S<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
trait Trait<T> {
|
||||||
let _ = S::<int>::new::<float>(1, 1.0);
|
fn new<U>(x: T, y: U) -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct S2 {
|
||||||
|
contents: int,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Trait<int> for S2 {
|
||||||
|
fn new<U>(x: int, _: U) -> S2 {
|
||||||
|
S2 {
|
||||||
|
contents: x,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _ = S::<int>::new::<float>(1, 1.0);
|
||||||
|
let _: S2 = Trait::<int>::new::<float>(1, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ fn main () {
|
||||||
|
|
||||||
assert_eq!(0i.thing(3.14, 1), (3.14, 1));
|
assert_eq!(0i.thing(3.14, 1), (3.14, 1));
|
||||||
assert_eq!(B::staticthing(&0i, 3.14, 1), (3.14, 1));
|
assert_eq!(B::staticthing(&0i, 3.14, 1), (3.14, 1));
|
||||||
assert_eq!(B::staticthing::<float, int, int>(&0i, 3.14, 1), (3.14, 1));
|
assert_eq!(B::<float>::staticthing::<int>(&0i, 3.14, 1), (3.14, 1));
|
||||||
|
|
||||||
assert_eq!(g(0i, 3.14, 1), (3.14, 1));
|
assert_eq!(g(0i, 3.14, 1), (3.14, 1));
|
||||||
assert_eq!(g(false, 3.14, 1), (3.14, 1));
|
assert_eq!(g(false, 3.14, 1), (3.14, 1));
|
||||||
|
|
|
@ -14,7 +14,7 @@ mod base {
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
pub trait HasNew<T> {
|
pub trait HasNew<T> {
|
||||||
fn new() -> T;
|
fn new() -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Foo {
|
pub struct Foo {
|
||||||
|
@ -41,6 +41,6 @@ mod base {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let _f: base::Foo = base::HasNew::new::<base::Foo, base::Foo>();
|
let _f: base::Foo = base::HasNew::<base::Foo>::new();
|
||||||
let _b: base::Bar = base::HasNew::new::<base::Bar, base::Bar>();
|
let _b: base::Bar = base::HasNew::<base::Bar>::new();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue