diff --git a/doc/rust.md b/doc/rust.md index 8924ee6f4f60c..e559af62e360c 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -889,10 +889,10 @@ declared, in an angle-bracket-enclosed, comma-separated list following the function name. ~~~~ {.xfail-test} -fn iter(seq: &[T], f: fn(T)) { +fn iter(seq: &[T], f: &fn(T)) { for seq.each |elt| { f(elt); } } -fn map(seq: &[T], f: fn(T) -> U) -> ~[U] { +fn map(seq: &[T], f: &fn(T) -> U) -> ~[U] { let mut acc = ~[]; for seq.each |elt| { acc.push(f(elt)); } acc @@ -1198,7 +1198,7 @@ These appear after the trait name, using the same syntax used in [generic functi trait Seq { fn len() -> uint; fn elt_at(n: uint) -> T; - fn iter(fn(T)); + fn iter(&fn(T)); } ~~~~ @@ -2074,7 +2074,7 @@ and moving values from the environment into the lambda expression's captured env An example of a lambda expression: ~~~~ -fn ten_times(f: fn(int)) { +fn ten_times(f: &fn(int)) { let mut i = 0; while i < 10 { f(i); @@ -2177,7 +2177,7 @@ If the `expr` is a [field expression](#field-expressions), it is parsed as thoug In this example, both calls to `f` are equivalent: ~~~~ -# fn f(f: fn(int)) { } +# fn f(f: &fn(int)) { } # fn g(i: int) { } f(|j| g(j)); @@ -2755,7 +2755,7 @@ and the cast expression in `main`. Within the body of an item that has type parameter declarations, the names of its type parameters are types: ~~~~~~~ -fn map(f: fn(A) -> B, xs: &[A]) -> ~[B] { +fn map(f: &fn(A) -> B, xs: &[A]) -> ~[B] { if xs.len() == 0 { return ~[]; } let first: B = f(xs[0]); let rest: ~[B] = map(f, xs.slice(1, xs.len())); diff --git a/doc/tutorial.md b/doc/tutorial.md index 79553d5aa6ed0..e4775e1b11b4d 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -681,45 +681,6 @@ the value of `North` is 0, `East` is 1, `South` is 2, and `West` is 3. When an enum is C-like, you can apply the `as` cast operator to convert it to its discriminator value as an `int`. - - -There is a special case for enums with a single variant, which are -sometimes called "newtype-style enums" (after Haskell's "newtype" -feature). These are used to define new types in such a way that the -new name is not just a synonym for an existing type, but its own -distinct type: `type` creates a structural synonym, while this form of -`enum` creates a nominal synonym. If you say: - -~~~~ -enum GizmoId = int; -~~~~ - -That is a shorthand for this: - -~~~~ -enum GizmoId { GizmoId(int) } -~~~~ - -You can extract the contents of such an enum type with the -dereference (`*`) unary operator: - -~~~~ -# enum GizmoId = int; -let my_gizmo_id: GizmoId = GizmoId(10); -let id_int: int = *my_gizmo_id; -~~~~ - -Types like this can be useful to differentiate between data that have -the same type but must be used in different ways. - -~~~~ -enum Inches = int; -enum Centimeters = int; -~~~~ - -The above definitions allow for a simple way for programs to avoid -confusing numbers that correspond to different units. - For enum types with multiple variants, destructuring is the only way to get at their contents. All variant constructors can be used as patterns, as in this definition of `area`: @@ -789,10 +750,10 @@ match mytup { ## Tuple structs -Rust also has _nominal tuples_, which behave like both structs and tuples, -except that nominal tuple types have names -(so `Foo(1, 2)` has a different type from `Bar(1, 2)`), -and nominal tuple types' _fields_ do not have names. +Rust also has _tuple structs_, which behave like both structs and tuples, +except that, unlike tuples, tuple structs have names (so `Foo(1, 2)` has a +different type from `Bar(1, 2)`), and tuple structs' _fields_ do not have +names. For example: ~~~~ @@ -803,6 +764,37 @@ match mytup { } ~~~~ + + +There is a special case for tuple structs with a single field, which are +sometimes called "newtypes" (after Haskell's "newtype" feature). These are +used to define new types in such a way that the new name is not just a +synonym for an existing type but is rather its own distinct type. + +~~~~ +struct GizmoId(int); +~~~~ + +For convenience, you can extract the contents of such a struct with the +dereference (`*`) unary operator: + +~~~~ +# struct GizmoId(int); +let my_gizmo_id: GizmoId = GizmoId(10); +let id_int: int = *my_gizmo_id; +~~~~ + +Types like this can be useful to differentiate between data that have +the same type but must be used in different ways. + +~~~~ +struct Inches(int); +struct Centimeters(int); +~~~~ + +The above definitions allow for a simple way for programs to avoid +confusing numbers that correspond to different units. + # Functions We've already seen several function definitions. Like all other static @@ -1369,7 +1361,7 @@ the enclosing scope. ~~~~ # use println = core::io::println; -fn call_closure_with_ten(b: fn(int)) { b(10); } +fn call_closure_with_ten(b: &fn(int)) { b(10); } let captured_var = 20; let closure = |arg| println(fmt!("captured_var=%d, arg=%d", captured_var, arg)); @@ -1455,7 +1447,7 @@ should almost always declare the type of that argument as `fn()`. That way, callers may pass any kind of closure. ~~~~ -fn call_twice(f: fn()) { f(); f(); } +fn call_twice(f: &fn()) { f(); f(); } let closure = || { "I'm a closure, and it doesn't matter what type I am"; }; fn function() { "I'm a normal function"; } call_twice(closure); @@ -1475,7 +1467,7 @@ Consider this function that iterates over a vector of integers, passing in a pointer to each integer in the vector: ~~~~ -fn each(v: &[int], op: fn(v: &int)) { +fn each(v: &[int], op: &fn(v: &int)) { let mut n = 0; while n < v.len() { op(&v[n]); @@ -1496,7 +1488,7 @@ argument, we can write it in a way that has a pleasant, block-like structure. ~~~~ -# fn each(v: &[int], op: fn(v: &int)) { } +# fn each(v: &[int], op: &fn(v: &int)) { } # fn do_some_work(i: &int) { } each([1, 2, 3], |n| { do_some_work(n); @@ -1507,7 +1499,7 @@ This is such a useful pattern that Rust has a special form of function call that can be written more like a built-in control structure: ~~~~ -# fn each(v: &[int], op: fn(v: &int)) { } +# fn each(v: &[int], op: &fn(v: &int)) { } # fn do_some_work(i: &int) { } do each([1, 2, 3]) |n| { do_some_work(n); @@ -1554,7 +1546,7 @@ Consider again our `each` function, this time improved to break early when the iteratee returns `false`: ~~~~ -fn each(v: &[int], op: fn(v: &int) -> bool) { +fn each(v: &[int], op: &fn(v: &int) -> bool) { let mut n = 0; while n < v.len() { if !op(&v[n]) { @@ -1778,7 +1770,7 @@ vector consisting of the result of applying `function` to each element of `vector`: ~~~~ -fn map(vector: &[T], function: fn(v: &T) -> U) -> ~[U] { +fn map(vector: &[T], function: &fn(v: &T) -> U) -> ~[U] { let mut accumulator = ~[]; for vec::each(vector) |element| { accumulator.push(function(element)); @@ -1977,12 +1969,12 @@ types might look like the following: ~~~~ trait Seq { fn len(&self) -> uint; - fn iter(&self, b: fn(v: &T)); + fn iter(&self, b: &fn(v: &T)); } impl Seq for ~[T] { fn len(&self) -> uint { vec::len(*self) } - fn iter(&self, b: fn(v: &T)) { + fn iter(&self, b: &fn(v: &T)) { for vec::each(*self) |elt| { b(elt); } } } @@ -2294,7 +2286,7 @@ struct level. Note that fields and methods are _public_ by default. pub mod farm { # pub type Chicken = int; # type Cow = int; -# enum Human = int; +# struct Human(int); # impl Human { fn rest(&self) { } } # pub fn make_me_a_farm() -> Farm { Farm { chickens: ~[], cows: ~[], farmer: Human(0) } } pub struct Farm { diff --git a/src/compiletest/header.rs b/src/compiletest/header.rs index daa3036687c44..7d0a4d7dcc805 100644 --- a/src/compiletest/header.rs +++ b/src/compiletest/header.rs @@ -103,7 +103,7 @@ pub fn is_test_ignored(config: config, testfile: &Path) -> bool { } } -fn iter_header(testfile: &Path, it: fn(~str) -> bool) -> bool { +fn iter_header(testfile: &Path, it: &fn(~str) -> bool) -> bool { let rdr = io::file_reader(testfile).get(); while !rdr.eof() { let ln = rdr.read_line(); diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index e0db543250d66..f95a530831b93 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -530,7 +530,7 @@ fn compose_and_run(config: config, testfile: &Path, } fn make_compile_args(config: config, props: TestProps, extras: ~[~str], - xform: fn(config, (&Path)) -> Path, + xform: &fn(config, (&Path)) -> Path, testfile: &Path) -> ProcArgs { let prog = config.rustc_path; let mut args = ~[testfile.to_str(), diff --git a/src/etc/emacs/rust-mode.el b/src/etc/emacs/rust-mode.el index 5a6acbaddda0a..f81f6bb618187 100644 --- a/src/etc/emacs/rust-mode.el +++ b/src/etc/emacs/rust-mode.el @@ -7,6 +7,7 @@ (require 'cm-mode) (require 'cc-mode) +(eval-when-compile (require 'cl)) (defun rust-electric-brace (arg) (interactive "*P") diff --git a/src/etc/kate/rust.xml b/src/etc/kate/rust.xml index 0359a56f7c184..1551cebcf02c2 100644 --- a/src/etc/kate/rust.xml +++ b/src/etc/kate/rust.xml @@ -17,7 +17,6 @@ as - assert break const copy @@ -69,6 +68,7 @@ Shl Shr Index + Not bool diff --git a/src/libcore/at_vec.rs b/src/libcore/at_vec.rs index 7a2a15a5421dc..fa19e24aa0830 100644 --- a/src/libcore/at_vec.rs +++ b/src/libcore/at_vec.rs @@ -61,7 +61,7 @@ pub pure fn capacity(v: @[const T]) -> uint { */ #[inline(always)] pub pure fn build_sized(size: uint, - builder: &fn(push: pure fn(v: A))) -> @[A] { + builder: &fn(push: &pure fn(v: A))) -> @[A] { let mut vec: @[const A] = @[]; unsafe { raw::reserve(&mut vec, size); } builder(|+x| unsafe { raw::push(&mut vec, x) }); @@ -79,7 +79,7 @@ pub pure fn build_sized(size: uint, * onto the vector being constructed. */ #[inline(always)] -pub pure fn build(builder: &fn(push: pure fn(v: A))) -> @[A] { +pub pure fn build(builder: &fn(push: &pure fn(v: A))) -> @[A] { build_sized(4, builder) } @@ -97,7 +97,7 @@ pub pure fn build(builder: &fn(push: pure fn(v: A))) -> @[A] { */ #[inline(always)] pub pure fn build_sized_opt(size: Option, - builder: &fn(push: pure fn(v: A))) -> @[A] { + builder: &fn(push: &pure fn(v: A))) -> @[A] { build_sized(size.get_or_default(4), builder) } diff --git a/src/libcore/bool.rs b/src/libcore/bool.rs index 13b8d0fc907fd..512855d8f86c0 100644 --- a/src/libcore/bool.rs +++ b/src/libcore/bool.rs @@ -67,7 +67,7 @@ pub pure fn to_str(v: bool) -> ~str { if v { ~"true" } else { ~"false" } } * Iterates over all truth values by passing them to `blk` in an unspecified * order */ -pub fn all_values(blk: fn(v: bool)) { +pub fn all_values(blk: &fn(v: bool)) { blk(true); blk(false); } diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 8df0037b2afe3..da247c648fc8c 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -15,6 +15,7 @@ use prelude::*; /// /// Similar to a mutable option type, but friendlier. +#[deriving_eq] pub struct Cell { mut value: Option } @@ -54,7 +55,7 @@ pub impl Cell { } // Calls a closure with a reference to the value. - fn with_ref(&self, op: fn(v: &T) -> R) -> R { + fn with_ref(&self, op: &fn(v: &T) -> R) -> R { let v = self.take(); let r = op(&v); self.put_back(v); diff --git a/src/libcore/cleanup.rs b/src/libcore/cleanup.rs index bf1ea5f1150a7..faa6db45df2f6 100644 --- a/src/libcore/cleanup.rs +++ b/src/libcore/cleanup.rs @@ -124,7 +124,7 @@ struct AnnihilateStats { n_bytes_freed: uint } -unsafe fn each_live_alloc(f: fn(box: *mut BoxRepr, uniq: bool) -> bool) { +unsafe fn each_live_alloc(f: &fn(box: *mut BoxRepr, uniq: bool) -> bool) { use managed; let task: *Task = transmute(rustrt::rust_get_task()); diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs index 6580ce55ddd66..297c4438039f0 100644 --- a/src/libcore/clone.rs +++ b/src/libcore/clone.rs @@ -19,3 +19,31 @@ impl Clone for () { #[inline(always)] fn clone(&self) -> () { () } } + +macro_rules! clone_impl( + ($t:ty) => { + impl Clone for $t { + #[inline(always)] + fn clone(&self) -> $t { *self } + } + } +) + +clone_impl!(int) +clone_impl!(i8) +clone_impl!(i16) +clone_impl!(i32) +clone_impl!(i64) + +clone_impl!(uint) +clone_impl!(u8) +clone_impl!(u16) +clone_impl!(u32) +clone_impl!(u64) + +clone_impl!(float) +clone_impl!(f32) +clone_impl!(f64) + +clone_impl!(bool) +clone_impl!(char) diff --git a/src/libcore/container.rs b/src/libcore/container.rs index 36424d1bfaaa3..4f1f6004aad77 100644 --- a/src/libcore/container.rs +++ b/src/libcore/container.rs @@ -30,10 +30,10 @@ pub trait Map: Mutable { pure fn contains_key(&self, key: &K) -> bool; /// Visit all keys - pure fn each_key(&self, f: fn(&K) -> bool); + pure fn each_key(&self, f: &fn(&K) -> bool); /// Visit all values - pure fn each_value(&self, f: fn(&V) -> bool); + pure fn each_value(&self, f: &fn(&V) -> bool); /// Return the value corresponding to the key in the map pure fn find(&self, key: &K) -> Option<&self/V>; @@ -71,14 +71,14 @@ pub trait Set: Mutable { pure fn is_superset(&self, other: &Self) -> bool; /// Visit the values representing the difference - pure fn difference(&self, other: &Self, f: fn(&T) -> bool); + pure fn difference(&self, other: &Self, f: &fn(&T) -> bool); /// Visit the values representing the symmetric difference - pure fn symmetric_difference(&self, other: &Self, f: fn(&T) -> bool); + pure fn symmetric_difference(&self, other: &Self, f: &fn(&T) -> bool); /// Visit the values representing the intersection - pure fn intersection(&self, other: &Self, f: fn(&T) -> bool); + pure fn intersection(&self, other: &Self, f: &fn(&T) -> bool); /// Visit the values representing the union - pure fn union(&self, other: &Self, f: fn(&T) -> bool); + pure fn union(&self, other: &Self, f: &fn(&T) -> bool); } diff --git a/src/libcore/core.rc b/src/libcore/core.rc index 79a5d297178e3..026f49cac45b1 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -51,11 +51,14 @@ Implicitly, all crates behave as if they included the following prologue: #[warn(vecs_implicitly_copyable)]; #[deny(non_camel_case_types)]; #[allow(deprecated_mutable_fields)]; +#[deny(deprecated_self)]; +#[allow(deprecated_drop)]; // On Linux, link to the runtime with -lrt. #[cfg(target_os = "linux")] pub mod linkhack { #[link_args="-lrustrt -lrt"] + #[link_args = "-lpthread"] extern { } } @@ -142,8 +145,6 @@ pub mod option; pub mod result; pub mod either; pub mod dlist; -#[path="iter-trait.rs"] #[merge = "iter-trait/dlist.rs"] -pub mod dlist_iter; pub mod hashmap; pub mod cell; pub mod trie; @@ -242,7 +243,8 @@ pub mod unicode; #[path = "num/cmath.rs"] pub mod cmath; pub mod stackwalk; - +#[path = "rt/mod.rs"] +pub mod rt; // A curious inner-module that's not exported that contains the binding // 'core' so that macro-expanded references to core::error and such diff --git a/src/libcore/dlist.rs b/src/libcore/dlist.rs index 5654d4b9c9b58..1b5d03d9eb8cd 100644 --- a/src/libcore/dlist.rs +++ b/src/libcore/dlist.rs @@ -18,6 +18,8 @@ Do not use ==, !=, <, etc on doubly-linked lists -- it may not terminate. */ +use iter; +use iter::BaseIter; use kinds::Copy; use managed; use option::{None, Option, Some}; @@ -397,7 +399,7 @@ pub impl DList { } /// Iterate over nodes. - pure fn each_node(@mut self, f: fn(@mut DListNode) -> bool) { + pure fn each_node(@mut self, f: &fn(@mut DListNode) -> bool) { let mut link = self.peek_n(); while link.is_some() { let nobe = link.get(); @@ -489,7 +491,7 @@ pub impl DList { let mut v = vec::with_capacity(self.size); unsafe { // Take this out of the unchecked when iter's functions are pure - for self.eachi |index,data| { + for iter::eachi(&self) |index,data| { v[index] = *data; } } @@ -497,6 +499,46 @@ pub impl DList { } } +impl BaseIter for @mut DList { + /** + * Iterates through the current contents. + * + * Attempts to access this dlist during iteration are allowed (to + * allow for e.g. breadth-first search with in-place enqueues), but + * removing the current node is forbidden. + */ + pure fn each(&self, f: &fn(v: &T) -> bool) { + let mut link = self.peek_n(); + while option::is_some(&link) { + let nobe = option::get(link); + fail_unless!(nobe.linked); + + { + let frozen_nobe = &*nobe; + if !f(&frozen_nobe.data) { break; } + } + + // Check (weakly) that the user didn't do a remove. + if self.size == 0 { + fail!(~"The dlist became empty during iteration??") + } + if !nobe.linked || + (!((nobe.prev.is_some() + || managed::mut_ptr_eq(self.hd.expect(~"headless dlist?"), + nobe)) + && (nobe.next.is_some() + || managed::mut_ptr_eq(self.tl.expect(~"tailless dlist?"), + nobe)))) { + fail!(~"Removing a dlist node during iteration is forbidden!") + } + link = nobe.next_link(); + } + } + + #[inline(always)] + pure fn size_hint(&self) -> Option { Some(self.len()) } +} + #[cfg(test)] mod tests { use dlist::{DList, concat, from_vec, new_dlist_node}; diff --git a/src/libcore/either.rs b/src/libcore/either.rs index e26f94261f9f9..e4b7bbbd99e87 100644 --- a/src/libcore/either.rs +++ b/src/libcore/either.rs @@ -24,8 +24,8 @@ pub enum Either { } #[inline(always)] -pub fn either(f_left: fn(&T) -> V, - f_right: fn(&U) -> V, value: &Either) -> V { +pub fn either(f_left: &fn(&T) -> V, + f_right: &fn(&U) -> V, value: &Either) -> V { /*! * Applies a function based on the given either value * @@ -148,7 +148,7 @@ pub pure fn unwrap_right(eith: Either) -> U { pub impl Either { #[inline(always)] - fn either(&self, f_left: fn(&T) -> V, f_right: fn(&U) -> V) -> V { + fn either(&self, f_left: &fn(&T) -> V, f_right: &fn(&U) -> V) -> V { either(f_left, f_right, self) } diff --git a/src/libcore/hashmap.rs b/src/libcore/hashmap.rs index 783f96d9b9e81..2adcee495a738 100644 --- a/src/libcore/hashmap.rs +++ b/src/libcore/hashmap.rs @@ -86,7 +86,7 @@ pub mod linear { #[inline(always)] pure fn bucket_sequence(&self, hash: uint, - op: fn(uint) -> bool) -> uint { + op: &fn(uint) -> bool) -> uint { let start_idx = self.to_bucket(hash); let len_buckets = self.buckets.len(); let mut idx = start_idx; @@ -263,7 +263,7 @@ pub mod linear { } fn search(&self, hash: uint, - op: fn(x: &Option>) -> bool) { + op: &fn(x: &Option>) -> bool) { let _ = self.bucket_sequence(hash, |i| op(&self.buckets[i])); } } @@ -272,7 +272,7 @@ pub mod linear { BaseIter<(&self/K, &self/V)> for LinearMap { /// Visit all key-value pairs - pure fn each(&self, blk: fn(&(&self/K, &self/V)) -> bool) { + pure fn each(&self, blk: &fn(&(&self/K, &self/V)) -> bool) { for uint::range(0, self.buckets.len()) |i| { let mut broke = false; do self.buckets[i].map |bucket| { @@ -315,12 +315,12 @@ pub mod linear { } /// Visit all keys - pure fn each_key(&self, blk: fn(k: &K) -> bool) { + pure fn each_key(&self, blk: &fn(k: &K) -> bool) { self.each(|&(k, _)| blk(k)) } /// Visit all values - pure fn each_value(&self, blk: fn(v: &V) -> bool) { + pure fn each_value(&self, blk: &fn(v: &V) -> bool) { self.each(|&(_, v)| blk(v)) } @@ -428,7 +428,7 @@ pub mod linear { /// Return the value corresponding to the key in the map, or create, /// insert, and return a new value if it doesn't exist. - fn find_or_insert_with(&mut self, k: K, f: fn(&K) -> V) -> &self/V { + fn find_or_insert_with(&mut self, k: K, f: &fn(&K) -> V) -> &self/V { if self.size >= self.resize_at { // n.b.: We could also do this after searching, so // that we do not resize if this call to insert is @@ -457,7 +457,7 @@ pub mod linear { } } - fn consume(&mut self, f: fn(K, V)) { + fn consume(&mut self, f: &fn(K, V)) { let mut buckets = ~[]; self.buckets <-> buckets; self.size = 0; @@ -526,7 +526,7 @@ pub mod linear { impl BaseIter for LinearSet { /// Visit all values in order - pure fn each(&self, f: fn(&T) -> bool) { self.map.each_key(f) } + pure fn each(&self, f: &fn(&T) -> bool) { self.map.each_key(f) } pure fn size_hint(&self) -> Option { Some(self.len()) } } @@ -583,7 +583,7 @@ pub mod linear { } /// Visit the values representing the difference - pure fn difference(&self, other: &LinearSet, f: fn(&T) -> bool) { + pure fn difference(&self, other: &LinearSet, f: &fn(&T) -> bool) { for self.each |v| { if !other.contains(v) { if !f(v) { return } @@ -593,13 +593,15 @@ pub mod linear { /// Visit the values representing the symmetric difference pure fn symmetric_difference(&self, other: &LinearSet, - f: fn(&T) -> bool) { + f: &fn(&T) -> bool) { self.difference(other, f); other.difference(self, f); } /// Visit the values representing the intersection - pure fn intersection(&self, other: &LinearSet, f: fn(&T) -> bool) { + pure fn intersection(&self, + other: &LinearSet, + f: &fn(&T) -> bool) { for self.each |v| { if other.contains(v) { if !f(v) { return } @@ -608,7 +610,7 @@ pub mod linear { } /// Visit the values representing the union - pure fn union(&self, other: &LinearSet, f: fn(&T) -> bool) { + pure fn union(&self, other: &LinearSet, f: &fn(&T) -> bool) { for self.each |v| { if !f(v) { return } } diff --git a/src/libcore/io.rs b/src/libcore/io.rs index 4634eb8793d95..b04bb15f5e30b 100644 --- a/src/libcore/io.rs +++ b/src/libcore/io.rs @@ -118,13 +118,13 @@ pub trait ReaderUtil { fn read_whole_stream(&self) -> ~[u8]; /// Iterate over every byte until the iterator breaks or EOF. - fn each_byte(&self, it: fn(int) -> bool); + fn each_byte(&self, it: &fn(int) -> bool); /// Iterate over every char until the iterator breaks or EOF. - fn each_char(&self, it: fn(char) -> bool); + fn each_char(&self, it: &fn(char) -> bool); /// Iterate over every line until the iterator breaks or EOF. - fn each_line(&self, it: fn(&str) -> bool); + fn each_line(&self, it: &fn(&str) -> bool); /// Read n (between 1 and 8) little-endian unsigned integer bytes. fn read_le_uint_n(&self, nbytes: uint) -> u64; @@ -315,19 +315,19 @@ impl ReaderUtil for T { bytes } - fn each_byte(&self, it: fn(int) -> bool) { + fn each_byte(&self, it: &fn(int) -> bool) { while !self.eof() { if !it(self.read_byte()) { break; } } } - fn each_char(&self, it: fn(char) -> bool) { + fn each_char(&self, it: &fn(char) -> bool) { while !self.eof() { if !it(self.read_char()) { break; } } } - fn each_line(&self, it: fn(s: &str) -> bool) { + fn each_line(&self, it: &fn(s: &str) -> bool) { while !self.eof() { if !it(self.read_line()) { break; } } @@ -618,11 +618,11 @@ impl Reader for BytesReader/&self { fn tell(&self) -> uint { self.pos } } -pub pure fn with_bytes_reader(bytes: &[u8], f: fn(@Reader) -> t) -> t { +pub pure fn with_bytes_reader(bytes: &[u8], f: &fn(@Reader) -> t) -> t { f(@BytesReader { bytes: bytes, pos: 0u } as @Reader) } -pub pure fn with_str_reader(s: &str, f: fn(@Reader) -> T) -> T { +pub pure fn with_str_reader(s: &str, f: &fn(@Reader) -> T) -> T { str::byte_slice(s, |bytes| with_bytes_reader(bytes, f)) } @@ -819,7 +819,7 @@ pub fn mk_file_writer(path: &Path, flags: &[FileFlag]) } pub fn u64_to_le_bytes(n: u64, size: uint, - f: fn(v: &[u8]) -> T) -> T { + f: &fn(v: &[u8]) -> T) -> T { fail_unless!(size <= 8u); match size { 1u => f(&[n as u8]), @@ -851,7 +851,7 @@ pub fn u64_to_le_bytes(n: u64, size: uint, } pub fn u64_to_be_bytes(n: u64, size: uint, - f: fn(v: &[u8]) -> T) -> T { + f: &fn(v: &[u8]) -> T) -> T { fail_unless!(size <= 8u); match size { 1u => f(&[n as u8]), @@ -1142,14 +1142,14 @@ pub pure fn BytesWriter() -> BytesWriter { BytesWriter { bytes: ~[], mut pos: 0u } } -pub pure fn with_bytes_writer(f: fn(Writer)) -> ~[u8] { +pub pure fn with_bytes_writer(f: &fn(Writer)) -> ~[u8] { let wr = @BytesWriter(); f(wr as Writer); let @BytesWriter{bytes, _} = wr; return bytes; } -pub pure fn with_str_writer(f: fn(Writer)) -> ~str { +pub pure fn with_str_writer(f: &fn(Writer)) -> ~str { let mut v = with_bytes_writer(f); // FIXME (#3758): This should not be needed. @@ -1251,7 +1251,7 @@ pub mod fsync { // FIXME (#2004) find better way to create resources within lifetime of // outer res pub fn FILE_res_sync(file: &FILERes, opt_level: Option, - blk: fn(v: Res<*libc::FILE>)) { + blk: &fn(v: Res<*libc::FILE>)) { unsafe { blk(Res(Arg { val: file.f, opt_level: opt_level, @@ -1266,7 +1266,7 @@ pub mod fsync { // fsync fd after executing blk pub fn fd_res_sync(fd: &FdRes, opt_level: Option, - blk: fn(v: Res)) { + blk: &fn(v: Res)) { blk(Res(Arg { val: fd.fd, opt_level: opt_level, fsync_fn: |fd, l| os::fsync_fd(fd, l) as int @@ -1278,7 +1278,7 @@ pub mod fsync { // Call o.fsync after executing blk pub fn obj_sync(o: FSyncable, opt_level: Option, - blk: fn(v: Res)) { + blk: &fn(v: Res)) { blk(Res(Arg { val: o, opt_level: opt_level, fsync_fn: |o, l| o.fsync(l) diff --git a/src/libcore/iter-trait.rs b/src/libcore/iter-trait.rs deleted file mode 100644 index 7c4a99133bbdb..0000000000000 --- a/src/libcore/iter-trait.rs +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// This makes use of a clever hack that brson came up with to -// workaround our lack of traits and lack of macros. See core.{rc,rs} for -// how this file is used. - -use cmp::{Eq, Ord}; -use iter::BaseIter; -use iter; -use kinds::Copy; -use option::Option; - -use self::inst::{IMPL_T, EACH, SIZE_HINT}; - -impl iter::BaseIter for IMPL_T { - #[inline(always)] - pure fn each(&self, blk: fn(v: &A) -> bool) { EACH(self, blk) } - #[inline(always)] - pure fn size_hint(&self) -> Option { SIZE_HINT(self) } -} - -impl iter::ExtendedIter for IMPL_T { - #[inline(always)] - pure fn eachi(&self, blk: fn(uint, v: &A) -> bool) { - iter::eachi(self, blk) - } - #[inline(always)] - pure fn all(&self, blk: fn(&A) -> bool) -> bool { - iter::all(self, blk) - } - #[inline(always)] - pure fn any(&self, blk: fn(&A) -> bool) -> bool { - iter::any(self, blk) - } - #[inline(always)] - pure fn foldl(&self, b0: B, blk: fn(&B, &A) -> B) -> B { - iter::foldl(self, b0, blk) - } - #[inline(always)] - pure fn position(&self, f: fn(&A) -> bool) -> Option { - iter::position(self, f) - } - #[inline(always)] - pure fn map_to_vec(&self, op: fn(&A) -> B) -> ~[B] { - iter::map_to_vec(self, op) - } - #[inline(always)] - pure fn flat_map_to_vec>(&self, op: fn(&A) -> IB) - -> ~[B] { - iter::flat_map_to_vec(self, op) - } - -} - -impl iter::EqIter for IMPL_T { - #[inline(always)] - pure fn contains(&self, x: &A) -> bool { iter::contains(self, x) } - #[inline(always)] - pure fn count(&self, x: &A) -> uint { iter::count(self, x) } -} - -impl iter::CopyableIter for IMPL_T { - #[inline(always)] - pure fn filter_to_vec(&self, pred: fn(&A) -> bool) -> ~[A] { - iter::filter_to_vec(self, pred) - } - #[inline(always)] - pure fn to_vec(&self) -> ~[A] { iter::to_vec(self) } - #[inline(always)] - pure fn find(&self, f: fn(&A) -> bool) -> Option { - iter::find(self, f) - } -} - -impl iter::CopyableOrderedIter for IMPL_T { - #[inline(always)] - pure fn min(&self) -> A { iter::min(self) } - #[inline(always)] - pure fn max(&self) -> A { iter::max(self) } -} - diff --git a/src/libcore/iter-trait/dlist.rs b/src/libcore/iter-trait/dlist.rs deleted file mode 100644 index 245c1db2bb4b8..0000000000000 --- a/src/libcore/iter-trait/dlist.rs +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -mod inst { - use dlist::DList; - use managed; - use option::{Option, Some}; - use option; - - #[allow(non_camel_case_types)] - pub type IMPL_T = @mut DList; - - /** - * Iterates through the current contents. - * - * Attempts to access this dlist during iteration are allowed (to - * allow for e.g. breadth-first search with in-place enqueues), but - * removing the current node is forbidden. - */ - pub pure fn EACH(self: &IMPL_T, f: fn(v: &A) -> bool) { - let mut link = self.peek_n(); - while option::is_some(&link) { - let nobe = option::get(link); - fail_unless!(nobe.linked); - - { - let frozen_nobe = &*nobe; - if !f(&frozen_nobe.data) { break; } - } - - // Check (weakly) that the user didn't do a remove. - if self.size == 0 { - fail!(~"The dlist became empty during iteration??") - } - if !nobe.linked || - (!((nobe.prev.is_some() - || managed::mut_ptr_eq(self.hd.expect(~"headless dlist?"), - nobe)) - && (nobe.next.is_some() - || managed::mut_ptr_eq(self.tl.expect(~"tailless dlist?"), - nobe)))) { - fail!(~"Removing a dlist node during iteration is forbidden!") - } - link = nobe.next_link(); - } - } - - #[inline(always)] - pub pure fn SIZE_HINT(self: &IMPL_T) -> Option { - Some(self.len()) - } -} diff --git a/src/libcore/iter-trait/option.rs b/src/libcore/iter-trait/option.rs deleted file mode 100644 index 986dbf7f3d186..0000000000000 --- a/src/libcore/iter-trait/option.rs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -mod inst { - use option::{None, Option, Some}; - - #[allow(non_camel_case_types)] - pub type IMPL_T = Option; - - #[inline(always)] - pub pure fn EACH(self: &IMPL_T, f: fn(v: &A) -> bool) { - match *self { - None => (), - Some(ref a) => { f(a); } - } - } - - #[inline(always)] - pub pure fn SIZE_HINT(self: &IMPL_T) -> Option { - match *self { - None => Some(0), - Some(_) => Some(1) - } - } -} diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index c92f747fc9872..8931b4088263e 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -23,22 +23,22 @@ use vec; pub type InitOp = &self/fn(uint) -> T; pub trait BaseIter { - pure fn each(&self, blk: fn(v: &A) -> bool); + pure fn each(&self, blk: &fn(v: &A) -> bool); pure fn size_hint(&self) -> Option; } pub trait ReverseIter: BaseIter { - pure fn each_reverse(&self, blk: fn(&A) -> bool); + pure fn each_reverse(&self, blk: &fn(&A) -> bool); } pub trait ExtendedIter { - pure fn eachi(&self, blk: fn(uint, v: &A) -> bool); - pure fn all(&self, blk: fn(&A) -> bool) -> bool; - pure fn any(&self, blk: fn(&A) -> bool) -> bool; - pure fn foldl(&self, b0: B, blk: fn(&B, &A) -> B) -> B; - pure fn position(&self, f: fn(&A) -> bool) -> Option; - pure fn map_to_vec(&self, op: fn(&A) -> B) -> ~[B]; - pure fn flat_map_to_vec>(&self, op: fn(&A) -> IB) + pure fn eachi(&self, blk: &fn(uint, v: &A) -> bool); + pure fn all(&self, blk: &fn(&A) -> bool) -> bool; + pure fn any(&self, blk: &fn(&A) -> bool) -> bool; + pure fn foldl(&self, b0: B, blk: &fn(&B, &A) -> B) -> B; + pure fn position(&self, f: &fn(&A) -> bool) -> Option; + pure fn map_to_vec(&self, op: &fn(&A) -> B) -> ~[B]; + pure fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) -> ~[B]; } @@ -48,13 +48,13 @@ pub trait EqIter { } pub trait Times { - pure fn times(&self, it: fn() -> bool); + pure fn times(&self, it: &fn() -> bool); } pub trait CopyableIter { - pure fn filter_to_vec(&self, pred: fn(&A) -> bool) -> ~[A]; + pure fn filter_to_vec(&self, pred: &fn(&A) -> bool) -> ~[A]; pure fn to_vec(&self) -> ~[A]; - pure fn find(&self, p: fn(&A) -> bool) -> Option; + pure fn find(&self, p: &fn(&A) -> bool) -> Option; } pub trait CopyableOrderedIter { @@ -86,12 +86,12 @@ pub trait Buildable { * onto the sequence being constructed. */ static pure fn build_sized(size: uint, - builder: fn(push: pure fn(A))) -> Self; + builder: &fn(push: &pure fn(A))) -> Self; } #[inline(always)] pub pure fn eachi>(self: &IA, - blk: fn(uint, &A) -> bool) { + blk: &fn(uint, &A) -> bool) { let mut i = 0; for self.each |a| { if !blk(i, a) { break; } @@ -101,7 +101,7 @@ pub pure fn eachi>(self: &IA, #[inline(always)] pub pure fn all>(self: &IA, - blk: fn(&A) -> bool) -> bool { + blk: &fn(&A) -> bool) -> bool { for self.each |a| { if !blk(a) { return false; } } @@ -110,7 +110,7 @@ pub pure fn all>(self: &IA, #[inline(always)] pub pure fn any>(self: &IA, - blk: fn(&A) -> bool) -> bool { + blk: &fn(&A) -> bool) -> bool { for self.each |a| { if blk(a) { return true; } } @@ -119,7 +119,7 @@ pub pure fn any>(self: &IA, #[inline(always)] pub pure fn filter_to_vec>( - self: &IA, prd: fn(&A) -> bool) -> ~[A] { + self: &IA, prd: &fn(&A) -> bool) -> ~[A] { do vec::build_sized_opt(self.size_hint()) |push| { for self.each |a| { if prd(a) { push(*a); } @@ -129,7 +129,7 @@ pub pure fn filter_to_vec>( #[inline(always)] pub pure fn map_to_vec>(self: &IA, - op: fn(&A) -> B) + op: &fn(&A) -> B) -> ~[B] { do vec::build_sized_opt(self.size_hint()) |push| { for self.each |a| { @@ -140,7 +140,7 @@ pub pure fn map_to_vec>(self: &IA, #[inline(always)] pub pure fn flat_map_to_vec,IB:BaseIter>( - self: &IA, op: fn(&A) -> IB) -> ~[B] { + self: &IA, op: &fn(&A) -> IB) -> ~[B] { do vec::build |push| { for self.each |a| { for op(a).each |&b| { @@ -152,7 +152,7 @@ pub pure fn flat_map_to_vec,IB:BaseIter>( #[inline(always)] pub pure fn foldl>(self: &IA, b0: B, - blk: fn(&B, &A) -> B) + blk: &fn(&B, &A) -> B) -> B { let mut b = b0; for self.each |a| { @@ -186,7 +186,7 @@ pub pure fn count>(self: &IA, x: &A) -> uint { } #[inline(always)] -pub pure fn position>(self: &IA, f: fn(&A) -> bool) +pub pure fn position>(self: &IA, f: &fn(&A) -> bool) -> Option { let mut i = 0; @@ -202,7 +202,7 @@ pub pure fn position>(self: &IA, f: fn(&A) -> bool) // it would have to be implemented with foldr, which is too inefficient. #[inline(always)] -pub pure fn repeat(times: uint, blk: fn() -> bool) { +pub pure fn repeat(times: uint, blk: &fn() -> bool) { let mut i = 0; while i < times { if !blk() { break } @@ -242,7 +242,7 @@ pub pure fn max>(self: &IA) -> A { #[inline(always)] pub pure fn find>(self: &IA, - f: fn(&A) -> bool) -> Option { + f: &fn(&A) -> bool) -> Option { for self.each |i| { if f(i) { return Some(*i) } } @@ -262,7 +262,7 @@ pub pure fn find>(self: &IA, * onto the sequence being constructed. */ #[inline(always)] -pub pure fn build>(builder: fn(push: pure fn(A))) +pub pure fn build>(builder: &fn(push: &pure fn(A))) -> B { Buildable::build_sized(4, builder) } @@ -283,7 +283,7 @@ pub pure fn build>(builder: fn(push: pure fn(A))) #[inline(always)] pub pure fn build_sized_opt>( size: Option, - builder: fn(push: pure fn(A))) -> B { + builder: &fn(push: &pure fn(A))) -> B { Buildable::build_sized(size.get_or_default(4), builder) } @@ -292,7 +292,7 @@ pub pure fn build_sized_opt>( /// Applies a function to each element of an iterable and returns the results. #[inline(always)] -pub fn map,U,BU: Buildable>(v: &IT, f: fn(&T) -> U) +pub fn map,U,BU: Buildable>(v: &IT, f: &fn(&T) -> U) -> BU { do build_sized_opt(v.size_hint()) |push| { for v.each() |elem| { diff --git a/src/libcore/libc.rs b/src/libcore/libc.rs index b59824969bb85..7f293b98e24a9 100644 --- a/src/libcore/libc.rs +++ b/src/libcore/libc.rs @@ -534,6 +534,8 @@ pub mod types { pub type LPCWSTR = *WCHAR; pub type LPCSTR = *CHAR; + pub type LPCTSTR = *CHAR; + pub type LPTCH = *CHAR; pub type LPWSTR = *mut WCHAR; pub type LPSTR = *mut CHAR; @@ -792,6 +794,7 @@ pub mod consts { pub const ERROR_SUCCESS : int = 0; pub const ERROR_INSUFFICIENT_BUFFER : int = 122; + pub const INVALID_HANDLE_VALUE: int = -1; } } @@ -1115,6 +1118,7 @@ pub mod funcs { pub mod string { use libc::types::common::c95::c_void; use libc::types::os::arch::c95::{c_char, c_int, size_t}; + use libc::types::os::arch::c95::{wchar_t}; pub extern { unsafe fn strcpy(dst: *c_char, src: *c_char) -> *c_char; @@ -1138,6 +1142,7 @@ pub mod funcs { unsafe fn strtok(s: *c_char, t: *c_char) -> *c_char; unsafe fn strxfrm(s: *c_char, ct: *c_char, n: size_t) -> size_t; + unsafe fn wcslen(buf: *wchar_t) -> size_t; // These are fine to execute on the Rust stack. They must be, // in fact, because LLVM generates calls to them! @@ -1381,9 +1386,28 @@ pub mod funcs { use libc::types::os::arch::c95::{c_char, c_int, c_long}; pub extern { + // default bindings for opendir and readdir in + // non-macos unix + #[cfg(target_os = "linux")] + #[cfg(target_os = "android")] + #[cfg(target_os = "freebsd")] unsafe fn opendir(dirname: *c_char) -> *DIR; - unsafe fn closedir(dirp: *DIR) -> c_int; + #[cfg(target_os = "linux")] + #[cfg(target_os = "android")] + #[cfg(target_os = "freebsd")] unsafe fn readdir(dirp: *DIR) -> *dirent_t; + // on OSX (particularly when running with a + // 64bit kernel), we have an issue where there + // are separate bindings for opendir and readdir, + // which we have to explicitly link, as below. + #[cfg(target_os = "macos")] + #[link_name = "opendir$INODE64"] + unsafe fn opendir(dirname: *c_char) -> *DIR; + #[cfg(target_os = "macos")] + #[link_name = "readdir$INODE64"] + unsafe fn readdir(dirp: *DIR) -> *dirent_t; + + unsafe fn closedir(dirp: *DIR) -> c_int; unsafe fn rewinddir(dirp: *DIR); unsafe fn seekdir(dirp: *DIR, loc: c_long); unsafe fn telldir(dirp: *DIR) -> c_long; @@ -1594,8 +1618,9 @@ pub mod funcs { pub mod kernel32 { use libc::types::os::arch::extra::{BOOL, DWORD, HMODULE}; - use libc::types::os::arch::extra::{LPCWSTR, LPWSTR}; + use libc::types::os::arch::extra::{LPCWSTR, LPWSTR, LPTCH}; use libc::types::os::arch::extra::{LPSECURITY_ATTRIBUTES}; + use libc::types::os::arch::extra::{HANDLE}; #[abi = "stdcall"] pub extern { @@ -1605,6 +1630,8 @@ pub mod funcs { -> DWORD; unsafe fn SetEnvironmentVariableW(n: LPCWSTR, v: LPCWSTR) -> BOOL; + unsafe fn GetEnvironmentStringsA() -> LPTCH; + unsafe fn FreeEnvironmentStringsA(env_ptr: LPTCH) -> BOOL; unsafe fn GetModuleFileNameW(hModule: HMODULE, lpFilename: LPWSTR, @@ -1623,6 +1650,13 @@ pub mod funcs { unsafe fn SetCurrentDirectoryW(lpPathName: LPCWSTR) -> BOOL; unsafe fn GetLastError() -> DWORD; + unsafe fn FindFirstFileW(fileName: *u16, + findFileData: HANDLE) + -> HANDLE; + unsafe fn FindNextFileW(findFile: HANDLE, + findFileData: HANDLE) + -> BOOL; + unsafe fn FindClose(findFile: HANDLE) -> BOOL; } } diff --git a/src/libcore/nil.rs b/src/libcore/nil.rs index cf2af7e38cc6b..742e5a047d6ca 100644 --- a/src/libcore/nil.rs +++ b/src/libcore/nil.rs @@ -15,7 +15,7 @@ Functions for the unit type. */ #[cfg(notest)] -use cmp::{Eq, Ord}; +use cmp::{Eq, Ord, TotalOrd, Ordering, Equal}; #[cfg(notest)] impl Eq for () { @@ -37,3 +37,8 @@ impl Ord for () { pure fn gt(&self, _other: &()) -> bool { false } } +#[cfg(notest)] +impl TotalOrd for () { + #[inline(always)] + pure fn cmp(&self, _other: &()) -> Ordering { Equal } +} diff --git a/src/libcore/num/int-template.rs b/src/libcore/num/int-template.rs index 2f59b4c50de04..cef8542823a67 100644 --- a/src/libcore/num/int-template.rs +++ b/src/libcore/num/int-template.rs @@ -100,7 +100,7 @@ pub pure fn is_nonnegative(x: T) -> bool { x >= 0 as T } */ #[inline(always)] /// Iterate over the range [`start`,`start`+`step`..`stop`) -pub pure fn range_step(start: T, stop: T, step: T, it: fn(T) -> bool) { +pub pure fn range_step(start: T, stop: T, step: T, it: &fn(T) -> bool) { let mut i = start; if step == 0 { fail!(~"range_step called with step == 0"); @@ -119,13 +119,13 @@ pub pure fn range_step(start: T, stop: T, step: T, it: fn(T) -> bool) { #[inline(always)] /// Iterate over the range [`lo`..`hi`) -pub pure fn range(lo: T, hi: T, it: fn(T) -> bool) { +pub pure fn range(lo: T, hi: T, it: &fn(T) -> bool) { range_step(lo, hi, 1 as T, it); } #[inline(always)] /// Iterate over the range [`hi`..`lo`) -pub pure fn range_rev(hi: T, lo: T, it: fn(T) -> bool) { +pub pure fn range_rev(hi: T, lo: T, it: &fn(T) -> bool) { range_step(hi, lo, -1 as T, it); } @@ -237,7 +237,7 @@ impl FromStrRadix for T { /// Convert to a string as a byte slice in a given base. #[inline(always)] -pub pure fn to_str_bytes(n: T, radix: uint, f: fn(v: &[u8]) -> U) -> U { +pub pure fn to_str_bytes(n: T, radix: uint, f: &fn(v: &[u8]) -> U) -> U { let (buf, _) = strconv::to_str_bytes_common(&n, radix, false, strconv::SignNeg, strconv::DigAll); f(buf) diff --git a/src/libcore/num/uint-template.rs b/src/libcore/num/uint-template.rs index 11bd7dbfd3ad9..9abbfb03d7a56 100644 --- a/src/libcore/num/uint-template.rs +++ b/src/libcore/num/uint-template.rs @@ -67,7 +67,10 @@ pub pure fn is_nonnegative(x: T) -> bool { x >= 0 as T } * Iterate over the range [`start`,`start`+`step`..`stop`) * */ -pub pure fn range_step(start: T, stop: T, step: T_SIGNED, it: fn(T) -> bool) { +pub pure fn range_step(start: T, + stop: T, + step: T_SIGNED, + it: &fn(T) -> bool) { let mut i = start; if step == 0 { fail!(~"range_step called with step == 0"); @@ -88,13 +91,13 @@ pub pure fn range_step(start: T, stop: T, step: T_SIGNED, it: fn(T) -> bool) { #[inline(always)] /// Iterate over the range [`lo`..`hi`) -pub pure fn range(lo: T, hi: T, it: fn(T) -> bool) { +pub pure fn range(lo: T, hi: T, it: &fn(T) -> bool) { range_step(lo, hi, 1 as T_SIGNED, it); } #[inline(always)] /// Iterate over the range [`hi`..`lo`) -pub pure fn range_rev(hi: T, lo: T, it: fn(T) -> bool) { +pub pure fn range_rev(hi: T, lo: T, it: &fn(T) -> bool) { range_step(hi, lo, -1 as T_SIGNED, it); } @@ -200,7 +203,7 @@ impl FromStrRadix for T { /// Convert to a string as a byte slice in a given base. #[inline(always)] -pub pure fn to_str_bytes(n: T, radix: uint, f: fn(v: &[u8]) -> U) -> U { +pub pure fn to_str_bytes(n: T, radix: uint, f: &fn(v: &[u8]) -> U) -> U { let (buf, _) = strconv::to_str_bytes_common(&n, radix, false, strconv::SignNeg, strconv::DigAll); f(buf) diff --git a/src/libcore/num/uint-template/uint.rs b/src/libcore/num/uint-template/uint.rs index 6814b0e754199..f73ff4442ceee 100644 --- a/src/libcore/num/uint-template/uint.rs +++ b/src/libcore/num/uint-template/uint.rs @@ -101,7 +101,7 @@ pub mod inst { * `true` If execution proceeded correctly, `false` if it was interrupted, * that is if `it` returned `false` at any point. */ - pub pure fn iterate(lo: uint, hi: uint, it: fn(uint) -> bool) -> bool { + pub pure fn iterate(lo: uint, hi: uint, it: &fn(uint) -> bool) -> bool { let mut i = lo; while i < hi { if (!it(i)) { return false; } @@ -122,7 +122,7 @@ pub mod inst { * use with integer literals of inferred integer-type as * the self-value (eg. `for 100.times { ... }`). */ - pure fn times(&self, it: fn() -> bool) { + pure fn times(&self, it: &fn() -> bool) { let mut i = *self; while i > 0 { if !it() { break } diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 7b0e4d07b53b8..6a38eff0343bd 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -130,8 +130,29 @@ pub pure fn get_ref(opt: &r/Option) -> &r/T { } } +pub pure fn get_mut_ref(opt: &r/mut Option) -> &r/mut T { + /*! + Gets a mutable reference to the value inside an option. + + # Failure + + Fails if the value equals `None` + + # Safety note + + In general, because this function may fail, its use is discouraged + (calling `get` on `None` is akin to dereferencing a null pointer). + Instead, prefer to use pattern matching and handle the `None` + case explicitly. + */ + match *opt { + Some(ref mut x) => x, + None => fail!(~"option::get_mut_ref none") + } +} + #[inline(always)] -pub pure fn map(opt: &r/Option, f: fn(x: &r/T) -> U) -> Option { +pub pure fn map(opt: &r/Option, f: &fn(x: &r/T) -> U) -> Option { //! Maps a `some` value by reference from one type to another match *opt { Some(ref x) => Some(f(x)), None => None } @@ -139,7 +160,7 @@ pub pure fn map(opt: &r/Option, f: fn(x: &r/T) -> U) -> Option { #[inline(always)] pub pure fn map_consume(opt: Option, - f: fn(v: T) -> U) -> Option { + f: &fn(v: T) -> U) -> Option { /*! * As `map`, but consumes the option and gives `f` ownership to avoid * copying. @@ -149,7 +170,7 @@ pub pure fn map_consume(opt: Option, #[inline(always)] pub pure fn chain(opt: Option, - f: fn(t: T) -> Option) -> Option { + f: &fn(t: T) -> Option) -> Option { /*! * Update an optional value by optionally running its content through a * function that returns an option. @@ -163,7 +184,7 @@ pub pure fn chain(opt: Option, #[inline(always)] pub pure fn chain_ref(opt: &Option, - f: fn(x: &T) -> Option) -> Option { + f: &fn(x: &T) -> Option) -> Option { /*! * Update an optional value by optionally running its content by reference * through a function that returns an option. @@ -184,7 +205,7 @@ pub pure fn or(opta: Option, optb: Option) -> Option { } #[inline(always)] -pub pure fn while_some(x: Option, blk: fn(v: T) -> Option) { +pub pure fn while_some(x: Option, blk: &fn(v: T) -> Option) { //! Applies a function zero or more times until the result is none. let mut opt = x; @@ -223,7 +244,7 @@ pub pure fn get_or_default(opt: Option, def: T) -> T { #[inline(always)] pub pure fn map_default(opt: &r/Option, def: U, - f: fn(&r/T) -> U) -> U { + f: &fn(&r/T) -> U) -> U { //! Applies a function to the contained value or returns a default match *opt { None => def, Some(ref t) => f(t) } @@ -279,7 +300,7 @@ pub pure fn expect(opt: Option, reason: &str) -> T { impl BaseIter for Option { /// Performs an operation on the contained value by reference #[inline(always)] - pure fn each(&self, f: fn(x: &self/T) -> bool) { + pure fn each(&self, f: &fn(x: &self/T) -> bool) { match *self { None => (), Some(ref t) => { f(t); } } } @@ -303,43 +324,43 @@ pub impl Option { * through a function that returns an option. */ #[inline(always)] - pure fn chain_ref(&self, f: fn(x: &T) -> Option) -> Option { + pure fn chain_ref(&self, f: &fn(x: &T) -> Option) -> Option { chain_ref(self, f) } /// Maps a `some` value from one type to another by reference #[inline(always)] - pure fn map(&self, f: fn(&self/T) -> U) -> Option { map(self, f) } + pure fn map(&self, f: &fn(&self/T) -> U) -> Option { map(self, f) } /// As `map`, but consumes the option and gives `f` ownership to avoid /// copying. #[inline(always)] - pure fn map_consume(self, f: fn(v: T) -> U) -> Option { + pure fn map_consume(self, f: &fn(v: T) -> U) -> Option { map_consume(self, f) } /// Applies a function to the contained value or returns a default #[inline(always)] - pure fn map_default(&self, def: U, f: fn(&self/T) -> U) -> U { + pure fn map_default(&self, def: U, f: &fn(&self/T) -> U) -> U { map_default(self, def, f) } /// As `map_default`, but consumes the option and gives `f` /// ownership to avoid copying. #[inline(always)] - pure fn map_consume_default(self, def: U, f: fn(v: T) -> U) -> U { + pure fn map_consume_default(self, def: U, f: &fn(v: T) -> U) -> U { match self { None => def, Some(v) => f(v) } } /// Apply a function to the contained value or do nothing - fn mutate(&mut self, f: fn(T) -> T) { + fn mutate(&mut self, f: &fn(T) -> T) { if self.is_some() { *self = Some(f(self.swap_unwrap())); } } /// Apply a function to the contained value or set it to a default - fn mutate_default(&mut self, def: T, f: fn(T) -> T) { + fn mutate_default(&mut self, def: T, f: &fn(T) -> T) { if self.is_some() { *self = Some(f(self.swap_unwrap())); } else { @@ -364,6 +385,23 @@ pub impl Option { #[inline(always)] pure fn get_ref(&self) -> &self/T { get_ref(self) } + /** + Gets a mutable reference to the value inside an option. + + # Failure + + Fails if the value equals `None` + + # Safety note + + In general, because this function may fail, its use is discouraged + (calling `get` on `None` is akin to dereferencing a null pointer). + Instead, prefer to use pattern matching and handle the `None` + case explicitly. + */ + #[inline(always)] + pure fn get_mut_ref(&mut self) -> &self/mut T { get_mut_ref(self) } + /** * Gets the value out of an option without copying. * @@ -420,7 +458,7 @@ pub impl Option { /// Applies a function zero or more times until the result is none. #[inline(always)] - pure fn while_some(self, blk: fn(v: T) -> Option) { + pure fn while_some(self, blk: &fn(v: T) -> Option) { while_some(self, blk) } } diff --git a/src/libcore/os.rs b/src/libcore/os.rs index 5c73e45364be7..aa4a6feb76f71 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -58,28 +58,33 @@ pub mod rustrt { pub extern { unsafe fn rust_get_argc() -> c_int; unsafe fn rust_get_argv() -> **c_char; - unsafe fn rust_getcwd() -> ~str; unsafe fn rust_path_is_dir(path: *libc::c_char) -> c_int; unsafe fn rust_path_exists(path: *libc::c_char) -> c_int; - unsafe fn rust_list_files2(&&path: ~str) -> ~[~str]; unsafe fn rust_process_wait(handle: c_int) -> c_int; unsafe fn rust_set_exit_status(code: libc::intptr_t); } } pub const TMPBUF_SZ : uint = 1000u; +const BUF_BYTES : uint = 2048u; pub fn getcwd() -> Path { + let buf = [0 as libc::c_char, ..BUF_BYTES]; unsafe { - Path(rustrt::rust_getcwd()) + if(0 as *libc::c_char == libc::getcwd( + &buf[0], + BUF_BYTES as libc::size_t)) { + fail!(); + } + Path(str::raw::from_c_str(&buf[0])) } } -pub fn as_c_charp(s: &str, f: fn(*c_char) -> T) -> T { +pub fn as_c_charp(s: &str, f: &fn(*c_char) -> T) -> T { str::as_c_str(s, |b| f(b as *c_char)) } -pub fn fill_charp_buf(f: fn(*mut c_char, size_t) -> bool) +pub fn fill_charp_buf(f: &fn(*mut c_char, size_t) -> bool) -> Option<~str> { let mut buf = vec::from_elem(TMPBUF_SZ, 0u8 as c_char); do vec::as_mut_buf(buf) |b, sz| { @@ -103,7 +108,7 @@ pub mod win32 { use os::TMPBUF_SZ; use libc::types::os::arch::extra::DWORD; - pub fn fill_utf16_buf_and_decode(f: fn(*mut u16, DWORD) -> DWORD) + pub fn fill_utf16_buf_and_decode(f: &fn(*mut u16, DWORD) -> DWORD) -> Option<~str> { unsafe { let mut n = TMPBUF_SZ as DWORD; @@ -133,7 +138,7 @@ pub mod win32 { } } - pub fn as_utf16_p(s: &str, f: fn(*u16) -> T) -> T { + pub fn as_utf16_p(s: &str, f: &fn(*u16) -> T) -> T { let mut t = str::to_utf16(s); // Null terminate before passing on. t += ~[0u16]; @@ -164,20 +169,68 @@ fn with_env_lock(f: &fn() -> T) -> T { } pub fn env() -> ~[(~str,~str)] { - extern { - unsafe fn rust_env_pairs() -> ~[~str]; - } - unsafe { - do with_env_lock { + #[cfg(windows)] + unsafe fn get_env_pairs() -> ~[~str] { + use libc::types::os::arch::extra::LPTCH; + use libc::funcs::extra::kernel32::{ + GetEnvironmentStringsA, + FreeEnvironmentStringsA + }; + let ch = GetEnvironmentStringsA(); + if (ch as uint == 0) { + fail!(fmt!("os::env() failure getting env string from OS: %s", + os::last_os_error())); + } + let mut curr_ptr: uint = ch as uint; + let mut result = ~[]; + while(*(curr_ptr as *libc::c_char) != 0 as libc::c_char) { + let env_pair = str::raw::from_c_str( + curr_ptr as *libc::c_char); + result.push(env_pair); + curr_ptr += + libc::strlen(curr_ptr as *libc::c_char) as uint + + 1; + } + FreeEnvironmentStringsA(ch); + result + } + #[cfg(unix)] + unsafe fn get_env_pairs() -> ~[~str] { + extern mod rustrt { + unsafe fn rust_env_pairs() -> **libc::c_char; + } + let environ = rustrt::rust_env_pairs(); + if (environ as uint == 0) { + fail!(fmt!("os::env() failure getting env string from OS: %s", + os::last_os_error())); + } + let mut result = ~[]; + ptr::array_each(environ, |e| { + let env_pair = str::raw::from_c_str(e); + log(debug, fmt!("get_env_pairs: %s", + env_pair)); + result.push(env_pair); + }); + result + } + + fn env_convert(input: ~[~str]) -> ~[(~str, ~str)] { let mut pairs = ~[]; - for vec::each(rust_env_pairs()) |p| { - let vs = str::splitn_char(*p, '=', 1u); - fail_unless!(vec::len(vs) == 2u); + for input.each |p| { + let vs = str::splitn_char(*p, '=', 1); + log(debug, + fmt!("splitting: len: %u", + vs.len())); + fail_unless!(vs.len() == 2); pairs.push((copy vs[0], copy vs[1])); } pairs } + do with_env_lock { + let unparsed_environ = get_env_pairs(); + env_convert(unparsed_environ) + } } } @@ -518,11 +571,11 @@ pub fn tmpdir() -> Path { } } /// Recursively walk a directory structure -pub fn walk_dir(p: &Path, f: fn(&Path) -> bool) { +pub fn walk_dir(p: &Path, f: &fn(&Path) -> bool) { walk_dir_(p, f); - fn walk_dir_(p: &Path, f: fn(&Path) -> bool) -> bool { + fn walk_dir_(p: &Path, f: &fn(&Path) -> bool) -> bool { let mut keepgoing = true; do list_dir(p).each |q| { let path = &p.push(*q); @@ -615,13 +668,97 @@ pub fn make_dir(p: &Path, mode: c_int) -> bool { #[allow(non_implicitly_copyable_typarams)] pub fn list_dir(p: &Path) -> ~[~str] { unsafe { - #[cfg(unix)] - fn star(p: &Path) -> Path { copy *p } - + #[cfg(target_os = "linux")] + #[cfg(target_os = "android")] + #[cfg(target_os = "freebsd")] + #[cfg(target_os = "macos")] + unsafe fn get_list(p: &Path) -> ~[~str] { + use libc::{DIR, dirent_t}; + use libc::{opendir, readdir, closedir}; + extern mod rustrt { + unsafe fn rust_list_dir_val(ptr: *dirent_t) + -> *libc::c_char; + } + let input = p.to_str(); + let mut strings = ~[]; + let input_ptr = ::cast::transmute(&input[0]); + log(debug, "os::list_dir -- BEFORE OPENDIR"); + let dir_ptr = opendir(input_ptr); + if (dir_ptr as uint != 0) { + log(debug, "os::list_dir -- opendir() SUCCESS"); + let mut entry_ptr = readdir(dir_ptr); + while (entry_ptr as uint != 0) { + strings.push( + str::raw::from_c_str( + rustrt::rust_list_dir_val( + entry_ptr))); + entry_ptr = readdir(dir_ptr); + } + closedir(dir_ptr); + } + else { + log(debug, "os::list_dir -- opendir() FAILURE"); + } + log(debug, + fmt!("os::list_dir -- AFTER -- #: %?", + strings.len())); + strings + } #[cfg(windows)] - fn star(p: &Path) -> Path { p.push("*") } - - do rustrt::rust_list_files2(star(p).to_str()).filtered |filename| { + unsafe fn get_list(p: &Path) -> ~[~str] { + use libc::types::os::arch::extra::{LPCTSTR, HANDLE, BOOL}; + use libc::consts::os::extra::INVALID_HANDLE_VALUE; + use libc::wcslen; + use libc::funcs::extra::kernel32::{ + FindFirstFileW, + FindNextFileW, + FindClose, + }; + use os::win32::{ + as_utf16_p + }; + use unstable::exchange_alloc::{malloc_raw, free_raw}; + #[nolink] + extern mod rustrt { + unsafe fn rust_list_dir_wfd_size() -> libc::size_t; + unsafe fn rust_list_dir_wfd_fp_buf(wfd: *libc::c_void) + -> *u16; + } + fn star(p: &Path) -> Path { p.push("*") } + do as_utf16_p(star(p).to_str()) |path_ptr| { + let mut strings = ~[]; + let wfd_ptr = malloc_raw( + rustrt::rust_list_dir_wfd_size() as uint); + let find_handle = + FindFirstFileW( + path_ptr, + ::cast::transmute(wfd_ptr)); + if find_handle as int != INVALID_HANDLE_VALUE { + let mut more_files = 1 as libc::c_int; + while more_files != 0 { + let fp_buf = rustrt::rust_list_dir_wfd_fp_buf( + wfd_ptr); + if fp_buf as uint == 0 { + fail!(~"os::list_dir() failure:"+ + ~" got null ptr from wfd"); + } + else { + let fp_vec = vec::from_buf( + fp_buf, wcslen(fp_buf) as uint); + let fp_str = str::from_utf16(fp_vec); + strings.push(fp_str); + } + more_files = FindNextFileW( + find_handle, + ::cast::transmute(wfd_ptr)); + } + FindClose(find_handle); + free_raw(wfd_ptr); + } + strings + } + } + do get_list(p).filtered |filename| { *filename != ~"." && *filename != ~".." } } @@ -1274,9 +1411,8 @@ mod tests { setenv(~"USERPROFILE", ~"/home/PaloAlto"); fail_unless!(os::homedir() == Some(Path("/home/MountainView"))); - option::iter(&oldhome, |s| setenv(~"HOME", *s)); - option::iter(&olduserprofile, - |s| setenv(~"USERPROFILE", *s)); + oldhome.each(|s| {setenv(~"HOME", *s);true}); + olduserprofile.each(|s| {setenv(~"USERPROFILE", *s);true}); } #[test] diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs index afb7aef25a3a0..fd823e9dda0d7 100644 --- a/src/libcore/pipes.rs +++ b/src/libcore/pipes.rs @@ -246,7 +246,7 @@ pub fn packet() -> *Packet { #[doc(hidden)] pub fn entangle_buffer( buffer: ~Buffer, - init: fn(*libc::c_void, x: &T) -> *Packet) + init: &fn(*libc::c_void, x: &T) -> *Packet) -> (SendPacketBuffered, RecvPacketBuffered) { let p = init(unsafe { reinterpret_cast(&buffer) }, &buffer.data); diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index ebf41dc48f405..ace70d7f061d3 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -19,6 +19,8 @@ use sys; #[cfg(test)] use vec; #[cfg(test)] use str; #[cfg(notest)] use cmp::{Eq, Ord}; +use debug; +use uint; pub mod libc_ { use libc::c_void; @@ -82,7 +84,7 @@ pub unsafe fn buf_len(buf: **T) -> uint { /// Return the first offset `i` such that `f(buf[i]) == true`. #[inline(always)] -pub unsafe fn position(buf: *T, f: fn(&T) -> bool) -> uint { +pub unsafe fn position(buf: *T, f: &fn(&T) -> bool) -> uint { let mut i = 0; loop { if f(&(*offset(buf, i))) { return i; } @@ -181,6 +183,46 @@ pub pure fn ref_eq(thing: &a/T, other: &b/T) -> bool { to_uint(thing) == to_uint(other) } +/** + Given a **T (pointer to an array of pointers), + iterate through each *T, up to the provided `len`, + passing to the provided callback function + + SAFETY NOTE: Pointer-arithmetic. Dragons be here. +*/ +pub unsafe fn array_each_with_len(arr: **T, len: uint, cb: &fn(*T)) { + log(debug, "array_each_with_len: before iterate"); + if (arr as uint == 0) { + fail!(~"ptr::array_each_with_len failure: arr input is null pointer"); + } + //let start_ptr = *arr; + uint::iterate(0, len, |e| { + let n = offset(arr, e); + cb(*n); + true + }); + log(debug, "array_each_with_len: after iterate"); +} + +/** + Given a null-pointer-terminated **T (pointer to + an array of pointers), iterate through each *T, + passing to the provided callback function + + SAFETY NOTE: This will only work with a null-terminated + pointer array. Barely less-dodgey Pointer Arithmetic. + Dragons be here. +*/ +pub unsafe fn array_each(arr: **T, cb: &fn(*T)) { + if (arr as uint == 0) { + fail!(~"ptr::array_each_with_len failure: arr input is null pointer"); + } + let len = buf_len(arr); + log(debug, fmt!("array_each inferred len: %u", + len)); + array_each_with_len(arr, len, cb); +} + pub trait Ptr { pure fn is_null(&self) -> bool; pure fn is_not_null(&self) -> bool; @@ -389,3 +431,95 @@ pub fn test_is_null() { fail_unless!(!mq.is_null()); fail_unless!(mq.is_not_null()); } + +#[cfg(test)] +pub mod ptr_tests { + use debug; + use ptr; + use str; + use libc; + use vec; + #[test] + pub fn test_ptr_array_each_with_len() { + unsafe { + let one = ~"oneOne"; + let two = ~"twoTwo"; + let three = ~"threeThree"; + let arr: ~[*i8] = ~[ + ::cast::transmute(&one[0]), + ::cast::transmute(&two[0]), + ::cast::transmute(&three[0]), + ]; + let expected_arr = [ + one, two, three + ]; + let arr_ptr = &arr[0]; + let mut ctr = 0; + let mut iteration_count = 0; + ptr::array_each_with_len(arr_ptr, vec::len(arr), + |e| { + let actual = str::raw::from_c_str(e); + let expected = copy expected_arr[ctr]; + log(debug, + fmt!("test_ptr_array_each e: %s, a: %s", + expected, actual)); + fail_unless!(actual == expected); + ctr += 1; + iteration_count += 1; + }); + fail_unless!(iteration_count == 3u); + } + } + #[test] + pub fn test_ptr_array_each() { + unsafe { + let one = ~"oneOne"; + let two = ~"twoTwo"; + let three = ~"threeThree"; + let arr: ~[*i8] = ~[ + ::cast::transmute(&one[0]), + ::cast::transmute(&two[0]), + ::cast::transmute(&three[0]), + // fake a null terminator + 0 as *i8 + ]; + let expected_arr = [ + one, two, three + ]; + let arr_ptr = &arr[0]; + let mut ctr = 0; + let mut iteration_count = 0; + ptr::array_each(arr_ptr, |e| { + let actual = str::raw::from_c_str(e); + let expected = copy expected_arr[ctr]; + log(debug, + fmt!("test_ptr_array_each e: %s, a: %s", + expected, actual)); + fail_unless!(actual == expected); + ctr += 1; + iteration_count += 1; + }); + fail_unless!(iteration_count == 3); + } + } + #[test] + #[should_fail] + #[ignore(cfg(windows))] + pub fn test_ptr_array_each_with_len_null_ptr() { + unsafe { + ptr::array_each_with_len(0 as **libc::c_char, 1, |e| { + str::raw::from_c_str(e); + }); + } + } + #[test] + #[should_fail] + #[ignore(cfg(windows))] + pub fn test_ptr_array_each_null_ptr() { + unsafe { + ptr::array_each(0 as **libc::c_char, |e| { + str::raw::from_c_str(e); + }); + } + } +} diff --git a/src/libcore/reflect.rs b/src/libcore/reflect.rs index f29447ef53e33..30c46cd3e35d1 100644 --- a/src/libcore/reflect.rs +++ b/src/libcore/reflect.rs @@ -26,7 +26,7 @@ use vec; * then build a MovePtrAdaptor wrapped around your struct. */ pub trait MovePtr { - fn move_ptr(&self, adjustment: fn(*c_void) -> *c_void); + fn move_ptr(&self, adjustment: &fn(*c_void) -> *c_void); fn push_ptr(&self); fn pop_ptr(&self); } diff --git a/src/libcore/repr.rs b/src/libcore/repr.rs index e9122754eb42a..ad85c5e5ceff4 100644 --- a/src/libcore/repr.rs +++ b/src/libcore/repr.rs @@ -159,7 +159,7 @@ pub fn ReprVisitor(ptr: *c_void, writer: @Writer) -> ReprVisitor { impl MovePtr for ReprVisitor { #[inline(always)] - fn move_ptr(&self, adjustment: fn(*c_void) -> *c_void) { + fn move_ptr(&self, adjustment: &fn(*c_void) -> *c_void) { self.ptr = adjustment(self.ptr); } fn push_ptr(&self) { @@ -175,7 +175,7 @@ pub impl ReprVisitor { // Various helpers for the TyVisitor impl #[inline(always)] - fn get(&self, f: fn(&T)) -> bool { + fn get(&self, f: &fn(&T)) -> bool { unsafe { f(transmute::<*c_void,&T>(copy self.ptr)); } diff --git a/src/libcore/result.rs b/src/libcore/result.rs index dd9b55e672580..e3fd279a99609 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -122,7 +122,7 @@ pub pure fn to_either(res: &Result) * } */ #[inline(always)] -pub pure fn chain(res: Result, op: fn(T) +pub pure fn chain(res: Result, op: &fn(T) -> Result) -> Result { match res { Ok(t) => op(t), @@ -141,7 +141,7 @@ pub pure fn chain(res: Result, op: fn(T) #[inline(always)] pub pure fn chain_err( res: Result, - op: fn(t: V) -> Result) + op: &fn(t: V) -> Result) -> Result { match res { Ok(t) => Ok(t), @@ -164,7 +164,7 @@ pub pure fn chain_err( * } */ #[inline(always)] -pub pure fn iter(res: &Result, f: fn(&T)) { +pub pure fn iter(res: &Result, f: &fn(&T)) { match *res { Ok(ref t) => f(t), Err(_) => () @@ -180,7 +180,7 @@ pub pure fn iter(res: &Result, f: fn(&T)) { * handling an error. */ #[inline(always)] -pub pure fn iter_err(res: &Result, f: fn(&E)) { +pub pure fn iter_err(res: &Result, f: &fn(&E)) { match *res { Ok(_) => (), Err(ref e) => f(e) @@ -202,7 +202,7 @@ pub pure fn iter_err(res: &Result, f: fn(&E)) { * } */ #[inline(always)] -pub pure fn map(res: &Result, op: fn(&T) -> U) +pub pure fn map(res: &Result, op: &fn(&T) -> U) -> Result { match *res { Ok(ref t) => Ok(op(t)), @@ -219,7 +219,7 @@ pub pure fn map(res: &Result, op: fn(&T) -> U) * successful result while handling an error. */ #[inline(always)] -pub pure fn map_err(res: &Result, op: fn(&E) -> F) +pub pure fn map_err(res: &Result, op: &fn(&E) -> F) -> Result { match *res { Ok(copy t) => Ok(t), @@ -238,10 +238,10 @@ pub impl Result { pure fn is_err(&self) -> bool { is_err(self) } #[inline(always)] - pure fn iter(&self, f: fn(&T)) { iter(self, f) } + pure fn iter(&self, f: &fn(&T)) { iter(self, f) } #[inline(always)] - pure fn iter_err(&self, f: fn(&E)) { iter_err(self, f) } + pure fn iter_err(&self, f: &fn(&E)) { iter_err(self, f) } #[inline(always)] pure fn unwrap(self) -> T { unwrap(self) } @@ -250,12 +250,12 @@ pub impl Result { pure fn unwrap_err(self) -> E { unwrap_err(self) } #[inline(always)] - pure fn chain(self, op: fn(T) -> Result) -> Result { + pure fn chain(self, op: &fn(T) -> Result) -> Result { chain(self, op) } #[inline(always)] - pure fn chain_err(self, op: fn(E) -> Result) -> Result { + pure fn chain_err(self, op: &fn(E) -> Result) -> Result { chain_err(self, op) } } @@ -265,7 +265,7 @@ pub impl Result { pure fn get(&self) -> T { get(self) } #[inline(always)] - pure fn map_err(&self, op: fn(&E) -> F) -> Result { + pure fn map_err(&self, op: &fn(&E) -> F) -> Result { map_err(self, op) } } @@ -275,7 +275,7 @@ pub impl Result { pure fn get_err(&self) -> E { get_err(self) } #[inline(always)] - pure fn map(&self, op: fn(&T) -> U) -> Result { + pure fn map(&self, op: &fn(&T) -> U) -> Result { map(self, op) } } @@ -299,7 +299,7 @@ pub impl Result { */ #[inline(always)] pub fn map_vec( - ts: &[T], op: fn(&T) -> Result) -> Result<~[V],U> { + ts: &[T], op: &fn(&T) -> Result) -> Result<~[V],U> { let mut vs: ~[V] = vec::with_capacity(vec::len(ts)); for vec::each(ts) |t| { @@ -313,7 +313,7 @@ pub fn map_vec( #[inline(always)] pub fn map_opt( - o_t: &Option, op: fn(&T) -> Result) -> Result,U> { + o_t: &Option, op: &fn(&T) -> Result) -> Result,U> { match *o_t { None => Ok(None), @@ -335,7 +335,7 @@ pub fn map_opt( */ #[inline(always)] pub fn map_vec2(ss: &[S], ts: &[T], - op: fn(&S,&T) -> Result) -> Result<~[V],U> { + op: &fn(&S,&T) -> Result) -> Result<~[V],U> { fail_unless!(vec::same_length(ss, ts)); let n = vec::len(ts); @@ -358,7 +358,7 @@ pub fn map_vec2(ss: &[S], ts: &[T], */ #[inline(always)] pub fn iter_vec2(ss: &[S], ts: &[T], - op: fn(&S,&T) -> Result<(),U>) -> Result<(),U> { + op: &fn(&S,&T) -> Result<(),U>) -> Result<(),U> { fail_unless!(vec::same_length(ss, ts)); let n = vec::len(ts); diff --git a/src/libcore/rt/context.rs b/src/libcore/rt/context.rs new file mode 100644 index 0000000000000..de96a7d17932b --- /dev/null +++ b/src/libcore/rt/context.rs @@ -0,0 +1,156 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use super::stack::StackSegment; +use libc::c_void; +use cast::{transmute, transmute_mut_unsafe, + transmute_region, transmute_mut_region}; + +// XXX: Registers is boxed so that it is 16-byte aligned, for storing +// SSE regs. It would be marginally better not to do this. In C++ we +// use an attribute on a struct. +pub struct Context(~Registers); + +pub impl Context { + static fn empty() -> Context { + Context(new_regs()) + } + + /// Create a new context that will resume execution by running ~fn() + /// # Safety Note + /// The `start` closure must remain valid for the life of the Task + static fn new(start: &~fn(), stack: &mut StackSegment) -> Context { + + // The C-ABI function that is the task entry point + extern fn task_start_wrapper(f: &~fn()) { (*f)() } + + let fp: *c_void = task_start_wrapper as *c_void; + let argp: *c_void = unsafe { transmute::<&~fn(), *c_void>(&*start) }; + let sp: *uint = stack.end(); + let sp: *mut uint = unsafe { transmute_mut_unsafe(sp) }; + + // Save and then immediately load the current context, + // which we will then modify to call the given function when restored + let mut regs = new_regs(); + unsafe { + swap_registers(transmute_mut_region(&mut *regs), + transmute_region(&*regs)) + }; + + initialize_call_frame(&mut *regs, fp, argp, sp); + + return Context(regs); + } + + static fn swap(out_context: &mut Context, in_context: &Context) { + let out_regs: &mut Registers = match out_context { + &Context(~ref mut r) => r + }; + let in_regs: &Registers = match in_context { + &Context(~ref r) => r + }; + + unsafe { swap_registers(out_regs, in_regs) }; + } +} + +extern { + fn swap_registers(out_regs: *mut Registers, in_regs: *Registers); +} + +// Definitions of these registers are in rt/arch/x86_64/regs.h +#[cfg(target_arch = "x86_64")] +type Registers = [uint * 22]; + +#[cfg(target_arch = "x86_64")] +fn new_regs() -> ~Registers { ~[0, .. 22] } + +#[cfg(target_arch = "x86_64")] +fn initialize_call_frame(regs: &mut Registers, + fptr: *c_void, arg: *c_void, sp: *mut uint) { + + // Redefinitions from regs.h + const RUSTRT_ARG0: uint = 3; + const RUSTRT_RSP: uint = 1; + const RUSTRT_IP: uint = 8; + const RUSTRT_RBP: uint = 2; + + let sp = align_down(sp); + let sp = mut_offset(sp, -1); + + // The final return address. 0 indicates the bottom of the stack + unsafe { *sp = 0; } + + rtdebug!("creating call frame"); + rtdebug!("fptr %x", fptr as uint); + rtdebug!("arg %x", arg as uint); + rtdebug!("sp %x", sp as uint); + + regs[RUSTRT_ARG0] = arg as uint; + regs[RUSTRT_RSP] = sp as uint; + regs[RUSTRT_IP] = fptr as uint; + + // Last base pointer on the stack should be 0 + regs[RUSTRT_RBP] = 0; +} + +#[cfg(target_arch = "x86")] +struct Registers { + eax: u32, ebx: u32, ecx: u32, edx: u32, + ebp: u32, esi: u32, edi: u32, esp: u32, + cs: u16, ds: u16, ss: u16, es: u16, fs: u16, gs: u16, + eflags: u32, eip: u32 +} + +#[cfg(target_arch = "x86")] +fn new_regs() -> ~Registers { + ~Registers { + eax: 0, ebx: 0, ecx: 0, edx: 0, + ebp: 0, esi: 0, edi: 0, esp: 0, + cs: 0, ds: 0, ss: 0, es: 0, fs: 0, gs: 0, + eflags: 0, eip: 0 + } +} + +#[cfg(target_arch = "x86")] +fn initialize_call_frame(regs: &mut Registers, + fptr: *c_void, arg: *c_void, sp: *mut uint) { + + let sp = align_down(sp); + let sp = mut_offset(sp, -4); // XXX: -4 words? Needs this be done at all? + + unsafe { *sp = arg as uint; } + let sp = mut_offset(sp, -1); + unsafe { *sp = 0; } // The final return address + + regs.esp = sp as u32; + regs.eip = fptr as u32; + + // Last base pointer on the stack is 0 + regs.ebp = 0; +} + +fn align_down(sp: *mut uint) -> *mut uint { + unsafe { + let sp = transmute::<*mut uint, uint>(sp); + let sp = sp & !(16 - 1); + transmute::(sp) + } +} + +// XXX: ptr::offset is positive ints only +#[inline(always)] +pub pure fn mut_offset(ptr: *mut T, count: int) -> *mut T { + use core::sys::size_of; + unsafe { + (ptr as int + count * (size_of::() as int)) as *mut T + } +} + diff --git a/src/libcore/rt/io.rs b/src/libcore/rt/io.rs new file mode 100644 index 0000000000000..3a94c01e0a419 --- /dev/null +++ b/src/libcore/rt/io.rs @@ -0,0 +1,45 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use option::*; +use result::*; + +// XXX: ~object doesn't work currently so these are some placeholder +// types to use instead +pub type EventLoopObject = super::uvio::UvEventLoop; +pub type IoFactoryObject = super::uvio::UvIoFactory; +pub type StreamObject = super::uvio::UvStream; +pub type TcpListenerObject = super::uvio::UvTcpListener; + +pub trait EventLoop { + fn run(&mut self); + fn callback(&mut self, ~fn()); + /// The asynchronous I/O services. Not all event loops may provide one + fn io(&mut self) -> Option<&self/mut IoFactoryObject>; +} + +pub trait IoFactory { + fn connect(&mut self, addr: IpAddr) -> Option<~StreamObject>; + fn bind(&mut self, addr: IpAddr) -> Option<~TcpListenerObject>; +} + +pub trait TcpListener { + fn listen(&mut self) -> Option<~StreamObject>; +} + +pub trait Stream { + fn read(&mut self, buf: &mut [u8]) -> Result; + fn write(&mut self, buf: &[u8]) -> Result<(), ()>; +} + +pub enum IpAddr { + Ipv4(u8, u8, u8, u8, u16), + Ipv6 +} diff --git a/src/libcore/rt/mod.rs b/src/libcore/rt/mod.rs new file mode 100644 index 0000000000000..772690c8dcdc6 --- /dev/null +++ b/src/libcore/rt/mod.rs @@ -0,0 +1,51 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// XXX: Missing some implementation for other architectures +#[cfg(target_os = "linux")]; +#[cfg(target_os = "mac")]; +#[cfg(target_os = "win32")]; + +// Some basic logging +macro_rules! rtdebug ( + ($( $arg:expr),+) => ( { + dumb_println(fmt!( $($arg),+ )); + + fn dumb_println(s: &str) { + use str::as_c_str; + use libc::c_char; + + extern { + fn printf(s: *c_char); + } + + do as_c_str(s.to_str() + "\n") |s| { + unsafe { printf(s); } + } + } + + } ) +) + +// An alternate version with no output, for turning off logging +macro_rules! rtdebug_ ( + ($( $arg:expr),+) => ( $(let _ = $arg)*; ) +) + +mod sched; +mod io; +mod uvio; +mod uv; +// FIXME #5248: The import in `sched` doesn't resolve unless this is pub! +pub mod thread_local_storage; +mod work_queue; +mod stack; +mod context; +mod thread; diff --git a/src/libcore/rt/sched.rs b/src/libcore/rt/sched.rs new file mode 100644 index 0000000000000..8f315452e5e5c --- /dev/null +++ b/src/libcore/rt/sched.rs @@ -0,0 +1,564 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use option::*; +use sys; +use cast::transmute; +use libc::c_void; +use ptr::mut_null; + +use super::work_queue::WorkQueue; +use super::stack::{StackPool, StackSegment}; +use super::io::{EventLoop, EventLoopObject}; +use super::context::Context; +use tls = super::thread_local_storage; + +#[cfg(test)] use super::uvio::UvEventLoop; +#[cfg(test)] use unstable::run_in_bare_thread; +#[cfg(test)] use int; + +/// The Scheduler is responsible for coordinating execution of Tasks +/// on a single thread. When the scheduler is running it is owned by +/// thread local storage and the running task is owned by the +/// scheduler. +pub struct Scheduler { + task_queue: WorkQueue<~Task>, + stack_pool: StackPool, + /// The event loop used to drive the scheduler and perform I/O + event_loop: ~EventLoopObject, + /// The scheduler's saved context. + /// Always valid when a task is executing, otherwise not + priv saved_context: Context, + /// The currently executing task + priv current_task: Option<~Task>, + /// A queue of jobs to perform immediately upon return from task + /// context to scheduler context. + /// XXX: This probably should be a single cleanup action and it + /// should run after a context switch, not on return from the + /// scheduler + priv cleanup_jobs: ~[CleanupJob] +} + +// XXX: Some hacks to put a &fn in Scheduler without borrowck +// complaining +type UnsafeTaskReceiver = sys::Closure; +trait HackAroundBorrowCk { + static fn from_fn(&fn(&mut Scheduler, ~Task)) -> Self; + fn to_fn(self) -> &fn(&mut Scheduler, ~Task); +} +impl HackAroundBorrowCk for UnsafeTaskReceiver { + static fn from_fn(f: &fn(&mut Scheduler, ~Task)) -> UnsafeTaskReceiver { + unsafe { transmute(f) } + } + fn to_fn(self) -> &fn(&mut Scheduler, ~Task) { + unsafe { transmute(self) } + } +} + +enum CleanupJob { + RescheduleTask(~Task), + RecycleTask(~Task), + GiveTask(~Task, UnsafeTaskReceiver) +} + +pub impl Scheduler { + + static fn new(event_loop: ~EventLoopObject) -> Scheduler { + Scheduler { + event_loop: event_loop, + task_queue: WorkQueue::new(), + stack_pool: StackPool::new(), + saved_context: Context::empty(), + current_task: None, + cleanup_jobs: ~[] + } + } + + // XXX: This may eventually need to be refactored so that + // the scheduler itself doesn't have to call event_loop.run. + // That will be important for embedding the runtime into external + // event loops. + fn run(~self) -> ~Scheduler { + fail_unless!(!self.in_task_context()); + + // Give ownership of the scheduler (self) to the thread + do self.install |scheduler| { + fn run_scheduler_once() { + do Scheduler::local |scheduler| { + if scheduler.resume_task_from_queue() { + // Ok, a task ran. Nice! We'll do it again later + scheduler.event_loop.callback(run_scheduler_once); + } + } + } + + scheduler.event_loop.callback(run_scheduler_once); + scheduler.event_loop.run(); + } + } + + fn install(~self, f: &fn(&mut Scheduler)) -> ~Scheduler { + let mut tlsched = ThreadLocalScheduler::new(); + tlsched.put_scheduler(self); + { + let sched = tlsched.get_scheduler(); + f(sched); + } + return tlsched.take_scheduler(); + } + + static fn local(f: &fn(&mut Scheduler)) { + let mut tlsched = ThreadLocalScheduler::new(); + f(tlsched.get_scheduler()); + } + + // * Scheduler-context operations + + fn resume_task_from_queue(&mut self) -> bool { + fail_unless!(!self.in_task_context()); + + let mut self = self; + match self.task_queue.pop_front() { + Some(task) => { + self.resume_task_immediately(task); + return true; + } + None => { + rtdebug!("no tasks in queue"); + return false; + } + } + } + + fn resume_task_immediately(&mut self, task: ~Task) { + fail_unless!(!self.in_task_context()); + + rtdebug!("scheduling a task"); + + // Store the task in the scheduler so it can be grabbed later + self.current_task = Some(task); + self.swap_in_task(); + // The running task should have passed ownership elsewhere + fail_unless!(self.current_task.is_none()); + + // Running tasks may have asked us to do some cleanup + self.run_cleanup_jobs(); + } + + + // * Task-context operations + + /// Called by a running task to end execution, after which it will + /// be recycled by the scheduler for reuse in a new task. + fn terminate_current_task(&mut self) { + fail_unless!(self.in_task_context()); + + rtdebug!("ending running task"); + + let dead_task = self.current_task.swap_unwrap(); + self.enqueue_cleanup_job(RecycleTask(dead_task)); + let dead_task = self.task_from_last_cleanup_job(); + self.swap_out_task(dead_task); + } + + /// Block a running task, context switch to the scheduler, then pass the + /// blocked task to a closure. + /// + /// # Safety note + /// + /// The closure here is a *stack* closure that lives in the + /// running task. It gets transmuted to the scheduler's lifetime + /// and called while the task is blocked. + fn block_running_task_and_then(&mut self, f: &fn(&mut Scheduler, ~Task)) { + fail_unless!(self.in_task_context()); + + rtdebug!("blocking task"); + + let blocked_task = self.current_task.swap_unwrap(); + let f_fake_region = unsafe { + transmute::<&fn(&mut Scheduler, ~Task), + &fn(&mut Scheduler, ~Task)>(f) + }; + let f_opaque = HackAroundBorrowCk::from_fn(f_fake_region); + self.enqueue_cleanup_job(GiveTask(blocked_task, f_opaque)); + let blocked_task = self.task_from_last_cleanup_job(); + + self.swap_out_task(blocked_task); + } + + /// Switch directly to another task, without going through the scheduler. + /// You would want to think hard about doing this, e.g. if there are + /// pending I/O events it would be a bad idea. + fn resume_task_from_running_task_direct(&mut self, next_task: ~Task) { + fail_unless!(self.in_task_context()); + + rtdebug!("switching tasks"); + + let old_running_task = self.current_task.swap_unwrap(); + self.enqueue_cleanup_job(RescheduleTask(old_running_task)); + let old_running_task = self.task_from_last_cleanup_job(); + + self.current_task = Some(next_task); + self.swap_in_task_from_running_task(old_running_task); + } + + + // * Context switching + + // NB: When switching to a task callers are expected to first set + // self.running_task. When switching away from a task likewise move + // out of the self.running_task + + priv fn swap_in_task(&mut self) { + // Take pointers to both the task and scheduler's saved registers. + let running_task: &~Task = self.current_task.get_ref(); + let task_context = &running_task.saved_context; + let scheduler_context = &mut self.saved_context; + + // Context switch to the task, restoring it's registers + // and saving the scheduler's + Context::swap(scheduler_context, task_context); + } + + priv fn swap_out_task(&mut self, running_task: &mut Task) { + let task_context = &mut running_task.saved_context; + let scheduler_context = &self.saved_context; + Context::swap(task_context, scheduler_context); + } + + priv fn swap_in_task_from_running_task(&mut self, + running_task: &mut Task) { + let running_task_context = &mut running_task.saved_context; + let next_context = &self.current_task.get_ref().saved_context; + Context::swap(running_task_context, next_context); + } + + + // * Other stuff + + fn in_task_context(&self) -> bool { self.current_task.is_some() } + + fn enqueue_cleanup_job(&mut self, job: CleanupJob) { + self.cleanup_jobs.unshift(job); + } + + fn run_cleanup_jobs(&mut self) { + fail_unless!(!self.in_task_context()); + rtdebug!("running cleanup jobs"); + + while !self.cleanup_jobs.is_empty() { + match self.cleanup_jobs.pop() { + RescheduleTask(task) => { + // NB: Pushing to the *front* of the queue + self.task_queue.push_front(task); + } + RecycleTask(task) => task.recycle(&mut self.stack_pool), + GiveTask(task, f) => (f.to_fn())(self, task) + } + } + } + + // XXX: Hack. This should return &self/mut but I don't know how to + // make the borrowcheck happy + fn task_from_last_cleanup_job(&mut self) -> &mut Task { + fail_unless!(!self.cleanup_jobs.is_empty()); + let last_job: &self/mut CleanupJob = &mut self.cleanup_jobs[0]; + let last_task: &self/Task = match last_job { + &RescheduleTask(~ref task) => task, + &RecycleTask(~ref task) => task, + &GiveTask(~ref task, _) => task, + }; + // XXX: Pattern matching mutable pointers above doesn't work + // because borrowck thinks the three patterns are conflicting + // borrows + return unsafe { transmute::<&Task, &mut Task>(last_task) }; + } +} + +const TASK_MIN_STACK_SIZE: uint = 10000000; // XXX: Too much stack + +pub struct Task { + /// The task entry point, saved here for later destruction + priv start: ~~fn(), + /// The segment of stack on which the task is currently running or, + /// if the task is blocked, on which the task will resume execution + priv current_stack_segment: StackSegment, + /// These are always valid when the task is not running, unless + /// the task is dead + priv saved_context: Context, +} + +impl Task { + static fn new(stack_pool: &mut StackPool, start: ~fn()) -> Task { + // XXX: Putting main into a ~ so it's a thin pointer and can + // be passed to the spawn function. Another unfortunate + // allocation + let start = ~Task::build_start_wrapper(start); + let mut stack = stack_pool.take_segment(TASK_MIN_STACK_SIZE); + // NB: Context holds a pointer to that ~fn + let initial_context = Context::new(&*start, &mut stack); + return Task { + start: start, + current_stack_segment: stack, + saved_context: initial_context, + }; + } + + static priv fn build_start_wrapper(start: ~fn()) -> ~fn() { + // XXX: The old code didn't have this extra allocation + let wrapper: ~fn() = || { + start(); + + let mut sched = ThreadLocalScheduler::new(); + let sched = sched.get_scheduler(); + sched.terminate_current_task(); + }; + return wrapper; + } + + /// Destroy the task and try to reuse its components + fn recycle(~self, stack_pool: &mut StackPool) { + match self { + ~Task {current_stack_segment, _} => { + stack_pool.give_segment(current_stack_segment); + } + } + } +} + +// NB: This is a type so we can use make use of the &self region. +struct ThreadLocalScheduler(tls::Key); + +impl ThreadLocalScheduler { + static fn new() -> ThreadLocalScheduler { + unsafe { + // NB: This assumes that the TLS key has been created prior. + // Currently done in rust_start. + let key: *mut c_void = rust_get_sched_tls_key(); + let key: &mut tls::Key = transmute(key); + ThreadLocalScheduler(*key) + } + } + + fn put_scheduler(&mut self, scheduler: ~Scheduler) { + unsafe { + let key = match self { &ThreadLocalScheduler(key) => key }; + let value: *mut c_void = + transmute::<~Scheduler, *mut c_void>(scheduler); + tls::set(key, value); + } + } + + fn get_scheduler(&mut self) -> &self/mut Scheduler { + unsafe { + let key = match self { &ThreadLocalScheduler(key) => key }; + let mut value: *mut c_void = tls::get(key); + fail_unless!(value.is_not_null()); + { + let value_ptr = &mut value; + let sched: &mut ~Scheduler = + transmute::<&mut *mut c_void, &mut ~Scheduler>(value_ptr); + let sched: &mut Scheduler = &mut **sched; + return sched; + } + } + } + + fn take_scheduler(&mut self) -> ~Scheduler { + unsafe { + let key = match self { &ThreadLocalScheduler(key) => key }; + let value: *mut c_void = tls::get(key); + fail_unless!(value.is_not_null()); + let sched = transmute(value); + tls::set(key, mut_null()); + return sched; + } + } +} + +extern { + fn rust_get_sched_tls_key() -> *mut c_void; +} + +#[test] +fn thread_local_scheduler_smoke_test() { + let scheduler = ~UvEventLoop::new_scheduler(); + let mut tls_scheduler = ThreadLocalScheduler::new(); + tls_scheduler.put_scheduler(scheduler); + { + let _scheduler = tls_scheduler.get_scheduler(); + } + let _scheduler = tls_scheduler.take_scheduler(); +} + +#[test] +fn thread_local_scheduler_two_instances() { + let scheduler = ~UvEventLoop::new_scheduler(); + let mut tls_scheduler = ThreadLocalScheduler::new(); + tls_scheduler.put_scheduler(scheduler); + { + + let _scheduler = tls_scheduler.get_scheduler(); + } + { + let scheduler = tls_scheduler.take_scheduler(); + tls_scheduler.put_scheduler(scheduler); + } + + let mut tls_scheduler = ThreadLocalScheduler::new(); + { + let _scheduler = tls_scheduler.get_scheduler(); + } + let _scheduler = tls_scheduler.take_scheduler(); +} + +#[test] +fn test_simple_scheduling() { + do run_in_bare_thread { + let mut task_ran = false; + let task_ran_ptr: *mut bool = &mut task_ran; + + let mut sched = ~UvEventLoop::new_scheduler(); + let task = ~do Task::new(&mut sched.stack_pool) { + unsafe { *task_ran_ptr = true; } + }; + sched.task_queue.push_back(task); + sched.run(); + fail_unless!(task_ran); + } +} + +#[test] +fn test_several_tasks() { + do run_in_bare_thread { + let total = 10; + let mut task_count = 0; + let task_count_ptr: *mut int = &mut task_count; + + let mut sched = ~UvEventLoop::new_scheduler(); + for int::range(0, total) |_| { + let task = ~do Task::new(&mut sched.stack_pool) { + unsafe { *task_count_ptr = *task_count_ptr + 1; } + }; + sched.task_queue.push_back(task); + } + sched.run(); + fail_unless!(task_count == total); + } +} + +#[test] +fn test_swap_tasks() { + do run_in_bare_thread { + let mut count = 0; + let count_ptr: *mut int = &mut count; + + let mut sched = ~UvEventLoop::new_scheduler(); + let task1 = ~do Task::new(&mut sched.stack_pool) { + unsafe { *count_ptr = *count_ptr + 1; } + do Scheduler::local |sched| { + let task2 = ~do Task::new(&mut sched.stack_pool) { + unsafe { *count_ptr = *count_ptr + 1; } + }; + // Context switch directly to the new task + sched.resume_task_from_running_task_direct(task2); + } + unsafe { *count_ptr = *count_ptr + 1; } + }; + sched.task_queue.push_back(task1); + sched.run(); + fail_unless!(count == 3); + } +} + +#[bench] #[test] #[ignore(reason = "long test")] +fn test_run_a_lot_of_tasks_queued() { + do run_in_bare_thread { + const MAX: int = 1000000; + let mut count = 0; + let count_ptr: *mut int = &mut count; + + let mut sched = ~UvEventLoop::new_scheduler(); + + let start_task = ~do Task::new(&mut sched.stack_pool) { + run_task(count_ptr); + }; + sched.task_queue.push_back(start_task); + sched.run(); + + fail_unless!(count == MAX); + + fn run_task(count_ptr: *mut int) { + do Scheduler::local |sched| { + let task = ~do Task::new(&mut sched.stack_pool) { + unsafe { + *count_ptr = *count_ptr + 1; + if *count_ptr != MAX { + run_task(count_ptr); + } + } + }; + sched.task_queue.push_back(task); + } + }; + } +} + +#[bench] #[test] #[ignore(reason = "too much stack allocation")] +fn test_run_a_lot_of_tasks_direct() { + do run_in_bare_thread { + const MAX: int = 100000; + let mut count = 0; + let count_ptr: *mut int = &mut count; + + let mut sched = ~UvEventLoop::new_scheduler(); + + let start_task = ~do Task::new(&mut sched.stack_pool) { + run_task(count_ptr); + }; + sched.task_queue.push_back(start_task); + sched.run(); + + fail_unless!(count == MAX); + + fn run_task(count_ptr: *mut int) { + do Scheduler::local |sched| { + let task = ~do Task::new(&mut sched.stack_pool) { + unsafe { + *count_ptr = *count_ptr + 1; + if *count_ptr != MAX { + run_task(count_ptr); + } + } + }; + // Context switch directly to the new task + sched.resume_task_from_running_task_direct(task); + } + }; + } +} + +#[test] +fn test_block_task() { + do run_in_bare_thread { + let mut sched = ~UvEventLoop::new_scheduler(); + let task = ~do Task::new(&mut sched.stack_pool) { + do Scheduler::local |sched| { + fail_unless!(sched.in_task_context()); + do sched.block_running_task_and_then() |sched, task| { + fail_unless!(!sched.in_task_context()); + sched.task_queue.push_back(task); + } + } + }; + sched.task_queue.push_back(task); + sched.run(); + } +} diff --git a/src/libcore/rt/stack.rs b/src/libcore/rt/stack.rs new file mode 100644 index 0000000000000..02c47218ed83f --- /dev/null +++ b/src/libcore/rt/stack.rs @@ -0,0 +1,49 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use vec; + +pub struct StackSegment { + buf: ~[u8] +} + +pub impl StackSegment { + static fn new(size: uint) -> StackSegment { + // Crate a block of uninitialized values + let mut stack = vec::with_capacity(size); + unsafe { + vec::raw::set_len(&mut stack, size); + } + + StackSegment { + buf: stack + } + } + + fn end(&self) -> *uint { + unsafe { + vec::raw::to_ptr(self.buf).offset(self.buf.len()) as *uint + } + } +} + +pub struct StackPool(()); + +impl StackPool { + + static fn new() -> StackPool { StackPool(()) } + + fn take_segment(&self, min_size: uint) -> StackSegment { + StackSegment::new(min_size) + } + + fn give_segment(&self, _stack: StackSegment) { + } +} diff --git a/src/libcore/rt/thread.rs b/src/libcore/rt/thread.rs new file mode 100644 index 0000000000000..cd46127451281 --- /dev/null +++ b/src/libcore/rt/thread.rs @@ -0,0 +1,44 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use libc; +use ops::Drop; + +#[allow(non_camel_case_types)] // runtime type +type raw_thread = libc::c_void; + +struct Thread { + main: ~fn(), + raw_thread: *raw_thread +} + +impl Thread { + static fn start(main: ~fn()) -> Thread { + fn substart(main: &fn()) -> *raw_thread { + unsafe { rust_raw_thread_start(main) } + } + let raw = substart(main); + Thread { + main: main, + raw_thread: raw + } + } +} + +impl Drop for Thread { + fn finalize(&self) { + unsafe { rust_raw_thread_join_delete(self.raw_thread) } + } +} + +extern { + pub unsafe fn rust_raw_thread_start(f: &fn()) -> *raw_thread; + pub unsafe fn rust_raw_thread_join_delete(thread: *raw_thread); +} diff --git a/src/libcore/rt/thread_local_storage.rs b/src/libcore/rt/thread_local_storage.rs new file mode 100644 index 0000000000000..58b5a54438606 --- /dev/null +++ b/src/libcore/rt/thread_local_storage.rs @@ -0,0 +1,91 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use libc::{c_void}; +#[cfg(unix)] +use libc::{c_uint, c_int}; +#[cfg(unix)] +use ptr::null; +#[cfg(windows)] +use libc::types::os::arch::extra::{DWORD, LPVOID, BOOL}; + +#[cfg(unix)] +pub type Key = pthread_key_t; + +#[cfg(unix)] +pub unsafe fn create(key: &mut Key) { + unsafe { fail_unless!(0 == pthread_key_create(key, null())); } +} + +#[cfg(unix)] +pub unsafe fn set(key: Key, value: *mut c_void) { + unsafe { fail_unless!(0 == pthread_setspecific(key, value)); } +} + +#[cfg(unix)] +pub unsafe fn get(key: Key) -> *mut c_void { + unsafe { pthread_getspecific(key) } +} + +#[cfg(unix)] +#[allow(non_camel_case_types)] // foreign type +type pthread_key_t = c_uint; + +#[cfg(unix)] +extern { + fn pthread_key_create(key: *mut pthread_key_t, dtor: *u8) -> c_int; + fn pthread_setspecific(key: pthread_key_t, value: *mut c_void) -> c_int; + fn pthread_getspecific(key: pthread_key_t) -> *mut c_void; +} + +#[cfg(windows)] +pub type Key = DWORD; + +#[cfg(windows)] +pub unsafe fn create(key: &mut Key) { + const TLS_OUT_OF_INDEXES: DWORD = 0xFFFFFFFF; + *key = unsafe { TlsAlloc() }; + fail_unless!(*key != TLS_OUT_OF_INDEXES); +} + +#[cfg(windows)] +pub unsafe fn set(key: Key, value: *mut c_void) { + unsafe { fail_unless!(0 != TlsSetValue(key, value)) } +} + +#[cfg(windows)] +pub unsafe fn get(key: Key) -> *mut c_void { + TlsGetValue(key) +} + +#[cfg(windows)] +#[abi = "stdcall"] +extern { + fn TlsAlloc() -> DWORD; + fn TlsSetValue(dwTlsIndex: DWORD, lpTlsvalue: LPVOID) -> BOOL; + fn TlsGetValue(dwTlsIndex: DWORD) -> LPVOID; +} + +#[test] +fn tls_smoke_test() { + use cast::transmute; + unsafe { + let mut key = 0; + let value = ~20; + create(&mut key); + set(key, transmute(value)); + let value: ~int = transmute(get(key)); + fail_unless!(value == ~20); + let value = ~30; + set(key, transmute(value)); + let value: ~int = transmute(get(key)); + fail_unless!(value == ~30); + } +} diff --git a/src/libcore/rt/uv.rs b/src/libcore/rt/uv.rs new file mode 100644 index 0000000000000..c947e4dde4c15 --- /dev/null +++ b/src/libcore/rt/uv.rs @@ -0,0 +1,919 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +/*! + +Bindings to libuv. + +UV types consist of the event loop (Loop), Watchers, Requests and +Callbacks. + +Watchers and Requests encapsulate pointers to uv *handles*, which have +subtyping relationships with each other. This subtyping is reflected +in the bindings with explicit or implicit coercions. For example, an +upcast from TcpWatcher to StreamWatcher is done with +`tcp_watcher.as_stream()`. In other cases a callback on a specific +type of watcher will be passed a watcher of a supertype. + +Currently all use of Request types (connect/write requests) are +encapsulated in the bindings and don't need to be dealt with by the +caller. + +# Safety note + +Due to the complex lifecycle of uv handles, as well as compiler bugs, +this module is not memory safe and requires explicit memory management, +via `close` and `delete` methods. + +*/ + +use option::*; +use str::raw::from_c_str; +use to_str::ToStr; +use vec; +use ptr; +use libc::{c_void, c_int, size_t, malloc, free, ssize_t}; +use cast::{transmute, transmute_mut_region}; +use ptr::null; +use sys::size_of; +use unstable::uvll; +use super::io::{IpAddr, Ipv4, Ipv6}; + +#[cfg(test)] use unstable::run_in_bare_thread; +#[cfg(test)] use super::thread::Thread; +#[cfg(test)] use cell::Cell; + +fn ip4_to_uv_ip4(addr: IpAddr) -> uvll::sockaddr_in { + match addr { + Ipv4(a, b, c, d, p) => { + unsafe { + uvll::ip4_addr(fmt!("%u.%u.%u.%u", + a as uint, + b as uint, + c as uint, + d as uint), p as int) + } + } + Ipv6 => fail!() + } +} + +/// A trait for callbacks to implement. Provides a little extra type safety +/// for generic, unsafe interop functions like `set_watcher_callback`. +trait Callback { } + +type NullCallback = ~fn(); +impl Callback for NullCallback { } + +/// A type that wraps a native handle +trait NativeHandle { + static pub fn from_native_handle(T) -> Self; + pub fn native_handle(&self) -> T; +} + +/// XXX: Loop(*handle) is buggy with destructors. Normal structs +/// with dtors may not be destructured, but tuple structs can, +/// but the results are not correct. +pub struct Loop { + handle: *uvll::uv_loop_t +} + +pub impl Loop { + static fn new() -> Loop { + let handle = unsafe { uvll::loop_new() }; + fail_unless!(handle.is_not_null()); + NativeHandle::from_native_handle(handle) + } + + fn run(&mut self) { + unsafe { uvll::run(self.native_handle()) }; + } + + fn close(&mut self) { + unsafe { uvll::loop_delete(self.native_handle()) }; + } +} + +impl NativeHandle<*uvll::uv_loop_t> for Loop { + static fn from_native_handle(handle: *uvll::uv_loop_t) -> Loop { + Loop { handle: handle } + } + fn native_handle(&self) -> *uvll::uv_loop_t { + self.handle + } +} + +/// The trait implemented by uv 'watchers' (handles). Watchers are +/// non-owning wrappers around the uv handles and are not completely +/// safe - there may be multiple instances for a single underlying +/// handle. Watchers are generally created, then `start`ed, `stop`ed +/// and `close`ed, but due to their complex life cycle may not be +/// entirely memory safe if used in unanticipated patterns. +trait Watcher { + fn event_loop(&self) -> Loop; +} + +pub struct IdleWatcher(*uvll::uv_idle_t); + +impl Watcher for IdleWatcher { + fn event_loop(&self) -> Loop { + loop_from_watcher(self) + } +} + +type IdleCallback = ~fn(IdleWatcher, Option); +impl Callback for IdleCallback { } + +pub impl IdleWatcher { + static fn new(loop_: &mut Loop) -> IdleWatcher { + unsafe { + let handle = uvll::idle_new(); + fail_unless!(handle.is_not_null()); + fail_unless!(0 == uvll::idle_init(loop_.native_handle(), handle)); + uvll::set_data_for_uv_handle(handle, null::<()>()); + NativeHandle::from_native_handle(handle) + } + } + + fn start(&mut self, cb: IdleCallback) { + + set_watcher_callback(self, cb); + unsafe { + fail_unless!(0 == uvll::idle_start(self.native_handle(), idle_cb)) + }; + + extern fn idle_cb(handle: *uvll::uv_idle_t, status: c_int) { + let idle_watcher: IdleWatcher = + NativeHandle::from_native_handle(handle); + let cb: &IdleCallback = + borrow_callback_from_watcher(&idle_watcher); + let status = status_to_maybe_uv_error(handle, status); + (*cb)(idle_watcher, status); + } + } + + fn stop(&mut self) { + unsafe { fail_unless!(0 == uvll::idle_stop(self.native_handle())); } + } + + fn close(self) { + unsafe { uvll::close(self.native_handle(), close_cb) }; + + extern fn close_cb(handle: *uvll::uv_idle_t) { + let mut idle_watcher = NativeHandle::from_native_handle(handle); + drop_watcher_callback::(&mut idle_watcher); + unsafe { uvll::idle_delete(handle) }; + } + } +} + +impl NativeHandle<*uvll::uv_idle_t> for IdleWatcher { + static fn from_native_handle(handle: *uvll::uv_idle_t) -> IdleWatcher { + IdleWatcher(handle) + } + fn native_handle(&self) -> *uvll::uv_idle_t { + match self { &IdleWatcher(ptr) => ptr } + } +} + +// uv_stream t is the parent class of uv_tcp_t, uv_pipe_t, uv_tty_t +// and uv_file_t +pub struct StreamWatcher(*uvll::uv_stream_t); + +impl Watcher for StreamWatcher { + fn event_loop(&self) -> Loop { + loop_from_watcher(self) + } +} + +type ReadCallback = ~fn(StreamWatcher, int, Buf, Option); +impl Callback for ReadCallback { } + +// XXX: The uv alloc callback also has a *uv_handle_t arg +pub type AllocCallback = ~fn(uint) -> Buf; +impl Callback for AllocCallback { } + +pub impl StreamWatcher { + + fn read_start(&mut self, alloc: AllocCallback, cb: ReadCallback) { + // XXX: Borrowchk problems + let data = get_watcher_data(unsafe { transmute_mut_region(self) }); + data.alloc_cb = Some(alloc); + data.read_cb = Some(cb); + + let handle = self.native_handle(); + unsafe { uvll::read_start(handle, alloc_cb, read_cb); } + + extern fn alloc_cb(stream: *uvll::uv_stream_t, + suggested_size: size_t) -> Buf { + let mut stream_watcher: StreamWatcher = + NativeHandle::from_native_handle(stream); + let data = get_watcher_data(&mut stream_watcher); + let alloc_cb = data.alloc_cb.get_ref(); + return (*alloc_cb)(suggested_size as uint); + } + + extern fn read_cb(stream: *uvll::uv_stream_t, + nread: ssize_t, ++buf: Buf) { + rtdebug!("buf addr: %x", buf.base as uint); + rtdebug!("buf len: %d", buf.len as int); + let mut stream_watcher: StreamWatcher = + NativeHandle::from_native_handle(stream); + let data = get_watcher_data(&mut stream_watcher); + let cb = data.read_cb.get_ref(); + let status = status_to_maybe_uv_error(stream, nread as c_int); + (*cb)(stream_watcher, nread as int, buf, status); + } + } + + fn read_stop(&mut self) { + // It would be nice to drop the alloc and read callbacks here, + // but read_stop may be called from inside one of them and we + // would end up freeing the in-use environment + let handle = self.native_handle(); + unsafe { uvll::read_stop(handle); } + } + + // XXX: Needs to take &[u8], not ~[u8] + fn write(&mut self, msg: ~[u8], cb: ConnectionCallback) { + // XXX: Borrowck + let data = get_watcher_data(unsafe { transmute_mut_region(self) }); + fail_unless!(data.write_cb.is_none()); + data.write_cb = Some(cb); + + let req = WriteRequest::new(); + let buf = vec_to_uv_buf(msg); + // XXX: Allocation + let bufs = ~[buf]; + unsafe { + fail_unless!(0 == uvll::write(req.native_handle(), + self.native_handle(), + &bufs, write_cb)); + } + // XXX: Freeing immediately after write. Is this ok? + let _v = vec_from_uv_buf(buf); + + extern fn write_cb(req: *uvll::uv_write_t, status: c_int) { + let write_request: WriteRequest = + NativeHandle::from_native_handle(req); + let mut stream_watcher = write_request.stream(); + write_request.delete(); + let cb = get_watcher_data(&mut stream_watcher) + .write_cb.swap_unwrap(); + let status = status_to_maybe_uv_error( + stream_watcher.native_handle(), status); + cb(stream_watcher, status); + } + } + + fn accept(&mut self, stream: StreamWatcher) { + let self_handle = self.native_handle() as *c_void; + let stream_handle = stream.native_handle() as *c_void; + unsafe { + fail_unless!(0 == uvll::accept(self_handle, stream_handle)); + } + } + + fn close(self, cb: NullCallback) { + { + let mut self = self; + let data = get_watcher_data(&mut self); + fail_unless!(data.close_cb.is_none()); + data.close_cb = Some(cb); + } + + unsafe { uvll::close(self.native_handle(), close_cb); } + + extern fn close_cb(handle: *uvll::uv_stream_t) { + let mut stream_watcher: StreamWatcher = + NativeHandle::from_native_handle(handle); + { + let mut data = get_watcher_data(&mut stream_watcher); + data.close_cb.swap_unwrap()(); + } + drop_watcher_data(&mut stream_watcher); + unsafe { free(handle as *c_void) } + } + } +} + +impl NativeHandle<*uvll::uv_stream_t> for StreamWatcher { + static fn from_native_handle( + handle: *uvll::uv_stream_t) -> StreamWatcher { + StreamWatcher(handle) + } + fn native_handle(&self) -> *uvll::uv_stream_t { + match self { &StreamWatcher(ptr) => ptr } + } +} + +pub struct TcpWatcher(*uvll::uv_tcp_t); + +impl Watcher for TcpWatcher { + fn event_loop(&self) -> Loop { + loop_from_watcher(self) + } +} + +type ConnectionCallback = ~fn(StreamWatcher, Option); +impl Callback for ConnectionCallback { } + +pub impl TcpWatcher { + static fn new(loop_: &mut Loop) -> TcpWatcher { + unsafe { + let size = size_of::() as size_t; + let handle = malloc(size) as *uvll::uv_tcp_t; + fail_unless!(handle.is_not_null()); + fail_unless!(0 == uvll::tcp_init(loop_.native_handle(), handle)); + let mut watcher = NativeHandle::from_native_handle(handle); + install_watcher_data(&mut watcher); + return watcher; + } + } + + fn bind(&mut self, address: IpAddr) { + match address { + Ipv4(*) => { + let addr = ip4_to_uv_ip4(address); + let result = unsafe { + uvll::tcp_bind(self.native_handle(), &addr) + }; + // XXX: bind is likely to fail. need real error handling + fail_unless!(result == 0); + } + _ => fail!() + } + } + + fn connect(&mut self, address: IpAddr, cb: ConnectionCallback) { + unsafe { + fail_unless!(get_watcher_data(self).connect_cb.is_none()); + get_watcher_data(self).connect_cb = Some(cb); + + let mut connect_watcher = ConnectRequest::new(); + let connect_handle = connect_watcher.native_handle(); + match address { + Ipv4(*) => { + let addr = ip4_to_uv_ip4(address); + rtdebug!("connect_t: %x", connect_handle as uint); + fail_unless!(0 == uvll::tcp_connect(connect_handle, + self.native_handle(), + &addr, connect_cb)); + } + _ => fail!() + } + + extern fn connect_cb(req: *uvll::uv_connect_t, status: c_int) { + rtdebug!("connect_t: %x", req as uint); + let connect_request: ConnectRequest = + NativeHandle::from_native_handle(req); + let mut stream_watcher = connect_request.stream(); + connect_request.delete(); + let cb: ConnectionCallback = { + let data = get_watcher_data(&mut stream_watcher); + data.connect_cb.swap_unwrap() + }; + let status = status_to_maybe_uv_error( + stream_watcher.native_handle(), status); + cb(stream_watcher, status); + } + } + } + + fn listen(&mut self, cb: ConnectionCallback) { + // XXX: Borrowck + let data = get_watcher_data(unsafe { transmute_mut_region(self) }); + fail_unless!(data.connect_cb.is_none()); + data.connect_cb = Some(cb); + + unsafe { + const BACKLOG: c_int = 128; // XXX should be configurable + // XXX: This can probably fail + fail_unless!(0 == uvll::listen(self.native_handle(), + BACKLOG, connection_cb)); + } + + extern fn connection_cb(handle: *uvll::uv_stream_t, status: c_int) { + rtdebug!("connection_cb"); + let mut stream_watcher: StreamWatcher = + NativeHandle::from_native_handle(handle); + let cb = get_watcher_data(&mut stream_watcher) + .connect_cb.swap_unwrap(); + let status = status_to_maybe_uv_error( + stream_watcher.native_handle(), status); + cb(stream_watcher, status); + } + } + + fn as_stream(&self) -> StreamWatcher { + NativeHandle::from_native_handle( + self.native_handle() as *uvll::uv_stream_t) + } +} + +impl NativeHandle<*uvll::uv_tcp_t> for TcpWatcher { + static fn from_native_handle(handle: *uvll::uv_tcp_t) -> TcpWatcher { + TcpWatcher(handle) + } + fn native_handle(&self) -> *uvll::uv_tcp_t { + match self { &TcpWatcher(ptr) => ptr } + } +} + +trait Request { } + +type ConnectCallback = ~fn(ConnectRequest, Option); +impl Callback for ConnectCallback { } + +// uv_connect_t is a subclass of uv_req_t +struct ConnectRequest(*uvll::uv_connect_t); + +impl Request for ConnectRequest { } + +impl ConnectRequest { + + static fn new() -> ConnectRequest { + let connect_handle = unsafe { + malloc(size_of::() as size_t) + }; + fail_unless!(connect_handle.is_not_null()); + let connect_handle = connect_handle as *uvll::uv_connect_t; + ConnectRequest(connect_handle) + } + + fn stream(&self) -> StreamWatcher { + unsafe { + let stream_handle = + uvll::get_stream_handle_from_connect_req( + self.native_handle()); + NativeHandle::from_native_handle(stream_handle) + } + } + + fn delete(self) { + unsafe { free(self.native_handle() as *c_void) } + } +} + +impl NativeHandle<*uvll::uv_connect_t> for ConnectRequest { + static fn from_native_handle( + handle: *uvll:: uv_connect_t) -> ConnectRequest { + ConnectRequest(handle) + } + fn native_handle(&self) -> *uvll::uv_connect_t { + match self { &ConnectRequest(ptr) => ptr } + } +} + +pub struct WriteRequest(*uvll::uv_write_t); + +impl Request for WriteRequest { } + +impl WriteRequest { + + static fn new() -> WriteRequest { + let write_handle = unsafe { + malloc(size_of::() as size_t) + }; + fail_unless!(write_handle.is_not_null()); + let write_handle = write_handle as *uvll::uv_write_t; + WriteRequest(write_handle) + } + + fn stream(&self) -> StreamWatcher { + unsafe { + let stream_handle = + uvll::get_stream_handle_from_write_req(self.native_handle()); + NativeHandle::from_native_handle(stream_handle) + } + } + + fn delete(self) { + unsafe { free(self.native_handle() as *c_void) } + } +} + +impl NativeHandle<*uvll::uv_write_t> for WriteRequest { + static fn from_native_handle(handle: *uvll:: uv_write_t) -> WriteRequest { + WriteRequest(handle) + } + fn native_handle(&self) -> *uvll::uv_write_t { + match self { &WriteRequest(ptr) => ptr } + } +} + +// XXX: Need to define the error constants like EOF so they can be +// compared to the UvError type + +struct UvError(uvll::uv_err_t); + +impl UvError { + + pure fn name(&self) -> ~str { + unsafe { + let inner = match self { &UvError(ref a) => a }; + let name_str = uvll::err_name(inner); + fail_unless!(name_str.is_not_null()); + from_c_str(name_str) + } + } + + pure fn desc(&self) -> ~str { + unsafe { + let inner = match self { &UvError(ref a) => a }; + let desc_str = uvll::strerror(inner); + fail_unless!(desc_str.is_not_null()); + from_c_str(desc_str) + } + } +} + +impl ToStr for UvError { + pure fn to_str(&self) -> ~str { + fmt!("%s: %s", self.name(), self.desc()) + } +} + +#[test] +fn error_smoke_test() { + let err = uvll::uv_err_t { code: 1, sys_errno_: 1 }; + let err: UvError = UvError(err); + fail_unless!(err.to_str() == ~"EOF: end of file"); +} + + +/// Given a uv handle, convert a callback status to a UvError +// XXX: Follow the pattern below by parameterizing over T: Watcher, not T +fn status_to_maybe_uv_error(handle: *T, status: c_int) -> Option { + if status != -1 { + None + } else { + unsafe { + rtdebug!("handle: %x", handle as uint); + let loop_ = uvll::get_loop_for_uv_handle(handle); + rtdebug!("loop: %x", loop_ as uint); + let err = uvll::last_error(loop_); + Some(UvError(err)) + } + } +} + +/// Get the uv event loop from a Watcher +pub fn loop_from_watcher>( + watcher: &W) -> Loop { + + let handle = watcher.native_handle(); + let loop_ = unsafe { uvll::get_loop_for_uv_handle(handle) }; + NativeHandle::from_native_handle(loop_) +} + +/// Set the custom data on a handle to a callback Note: This is only +/// suitable for watchers that make just one type of callback. For +/// others use WatcherData +fn set_watcher_callback, CB: Callback>( + watcher: &mut W, cb: CB) { + + drop_watcher_callback::(watcher); + // XXX: Boxing the callback so it fits into a + // pointer. Unfortunate extra allocation + let boxed_cb = ~cb; + let data = unsafe { transmute::<~CB, *c_void>(boxed_cb) }; + unsafe { uvll::set_data_for_uv_handle(watcher.native_handle(), data) }; +} + +/// Delete a callback from a handle's custom data +fn drop_watcher_callback, CB: Callback>( + watcher: &mut W) { + + unsafe { + let handle = watcher.native_handle(); + let handle_data: *c_void = uvll::get_data_for_uv_handle(handle); + if handle_data.is_not_null() { + // Take ownership of the callback and drop it + let _cb = transmute::<*c_void, ~CB>(handle_data); + // Make sure the pointer is zeroed + uvll::set_data_for_uv_handle( + watcher.native_handle(), null::<()>()); + } + } +} + +/// Take a pointer to the callback installed as custom data +fn borrow_callback_from_watcher, + CB: Callback>(watcher: &W) -> &CB { + + unsafe { + let handle = watcher.native_handle(); + let handle_data: *c_void = uvll::get_data_for_uv_handle(handle); + fail_unless!(handle_data.is_not_null()); + let cb = transmute::<&*c_void, &~CB>(&handle_data); + return &**cb; + } +} + +/// Take ownership of the callback installed as custom data +fn take_callback_from_watcher, CB: Callback>( + watcher: &mut W) -> CB { + + unsafe { + let handle = watcher.native_handle(); + let handle_data: *c_void = uvll::get_data_for_uv_handle(handle); + fail_unless!(handle_data.is_not_null()); + uvll::set_data_for_uv_handle(handle, null::<()>()); + let cb: ~CB = transmute::<*c_void, ~CB>(handle_data); + let cb = match cb { ~cb => cb }; + return cb; + } +} + +/// Callbacks used by StreamWatchers, set as custom data on the foreign handle +struct WatcherData { + read_cb: Option, + write_cb: Option, + connect_cb: Option, + close_cb: Option, + alloc_cb: Option +} + +fn install_watcher_data>(watcher: &mut W) { + unsafe { + let data = ~WatcherData { + read_cb: None, + write_cb: None, + connect_cb: None, + close_cb: None, + alloc_cb: None + }; + let data = transmute::<~WatcherData, *c_void>(data); + uvll::set_data_for_uv_handle(watcher.native_handle(), data); + } +} + +fn get_watcher_data>( + watcher: &r/mut W) -> &r/mut WatcherData { + + unsafe { + let data = uvll::get_data_for_uv_handle(watcher.native_handle()); + let data = transmute::<&*c_void, &mut ~WatcherData>(&data); + return &mut **data; + } +} + +fn drop_watcher_data>(watcher: &mut W) { + unsafe { + let data = uvll::get_data_for_uv_handle(watcher.native_handle()); + let _data = transmute::<*c_void, ~WatcherData>(data); + uvll::set_data_for_uv_handle(watcher.native_handle(), null::<()>()); + } +} + +#[test] +fn test_slice_to_uv_buf() { + let slice = [0, .. 20]; + let buf = slice_to_uv_buf(slice); + + fail_unless!(buf.len == 20); + + unsafe { + let base = transmute::<*u8, *mut u8>(buf.base); + (*base) = 1; + (*ptr::mut_offset(base, 1)) = 2; + } + + fail_unless!(slice[0] == 1); + fail_unless!(slice[1] == 2); +} + +/// The uv buffer type +pub type Buf = uvll::uv_buf_t; + +/// Borrow a slice to a Buf +pub fn slice_to_uv_buf(v: &[u8]) -> Buf { + let data = unsafe { vec::raw::to_ptr(v) }; + unsafe { uvll::buf_init(data, v.len()) } +} + +// XXX: Do these conversions without copying + +/// Transmute an owned vector to a Buf +fn vec_to_uv_buf(v: ~[u8]) -> Buf { + let data = unsafe { malloc(v.len() as size_t) } as *u8; + fail_unless!(data.is_not_null()); + do vec::as_imm_buf(v) |b, l| { + let data = data as *mut u8; + unsafe { ptr::copy_memory(data, b, l) } + } + let buf = unsafe { uvll::buf_init(data, v.len()) }; + return buf; +} + +/// Transmute a Buf that was once a ~[u8] back to ~[u8] +fn vec_from_uv_buf(buf: Buf) -> Option<~[u8]> { + if !(buf.len == 0 && buf.base.is_null()) { + let v = unsafe { vec::from_buf(buf.base, buf.len as uint) }; + unsafe { free(buf.base as *c_void) }; + return Some(v); + } else { + // No buffer + return None; + } +} + +#[test] +fn loop_smoke_test() { + do run_in_bare_thread { + let mut loop_ = Loop::new(); + loop_.run(); + loop_.close(); + } +} + +#[test] +#[ignore(reason = "valgrind - loop destroyed before watcher?")] +fn idle_new_then_close() { + do run_in_bare_thread { + let mut loop_ = Loop::new(); + let mut idle_watcher = { IdleWatcher::new(&mut loop_) }; + idle_watcher.close(); + } +} + +#[test] +fn idle_smoke_test() { + do run_in_bare_thread { + let mut loop_ = Loop::new(); + let mut idle_watcher = { IdleWatcher::new(&mut loop_) }; + let mut count = 10; + let count_ptr: *mut int = &mut count; + do idle_watcher.start |idle_watcher, status| { + let mut idle_watcher = idle_watcher; + fail_unless!(status.is_none()); + if unsafe { *count_ptr == 10 } { + idle_watcher.stop(); + idle_watcher.close(); + } else { + unsafe { *count_ptr = *count_ptr + 1; } + } + } + loop_.run(); + loop_.close(); + fail_unless!(count == 10); + } +} + +#[test] +fn idle_start_stop_start() { + do run_in_bare_thread { + let mut loop_ = Loop::new(); + let mut idle_watcher = { IdleWatcher::new(&mut loop_) }; + do idle_watcher.start |idle_watcher, status| { + let mut idle_watcher = idle_watcher; + fail_unless!(status.is_none()); + idle_watcher.stop(); + do idle_watcher.start |idle_watcher, status| { + fail_unless!(status.is_none()); + let mut idle_watcher = idle_watcher; + idle_watcher.stop(); + idle_watcher.close(); + } + } + loop_.run(); + loop_.close(); + } +} + +#[test] +#[ignore(reason = "ffi struct issues")] +fn connect_close() { + do run_in_bare_thread() { + let mut loop_ = Loop::new(); + let mut tcp_watcher = { TcpWatcher::new(&mut loop_) }; + // Connect to a port where nobody is listening + let addr = Ipv4(127, 0, 0, 1, 2923); + do tcp_watcher.connect(addr) |stream_watcher, status| { + rtdebug!("tcp_watcher.connect!"); + fail_unless!(status.is_some()); + fail_unless!(status.get().name() == ~"ECONNREFUSED"); + stream_watcher.close(||()); + } + loop_.run(); + loop_.close(); + } +} + +#[test] +#[ignore(reason = "need a server to connect to")] +fn connect_read() { + do run_in_bare_thread() { + let mut loop_ = Loop::new(); + let mut tcp_watcher = { TcpWatcher::new(&mut loop_) }; + let addr = Ipv4(127, 0, 0, 1, 2924); + do tcp_watcher.connect(addr) |stream_watcher, status| { + let mut stream_watcher = stream_watcher; + rtdebug!("tcp_watcher.connect!"); + fail_unless!(status.is_none()); + let alloc: AllocCallback = |size| { + vec_to_uv_buf(vec::from_elem(size, 0)) + }; + do stream_watcher.read_start(alloc) + |stream_watcher, nread, buf, status| { + + let buf = vec_from_uv_buf(buf); + rtdebug!("read cb!"); + if status.is_none() { + let bytes = buf.unwrap(); + rtdebug!("%s", bytes.slice(0, nread as uint).to_str()); + } else { + rtdebug!("status after read: %s", status.get().to_str()); + rtdebug!("closing"); + stream_watcher.close(||()); + } + } + } + loop_.run(); + loop_.close(); + } +} + +#[test] +#[ignore(reason = "ffi struct issues")] +fn listen() { + do run_in_bare_thread() { + const MAX: int = 10; + let mut loop_ = Loop::new(); + let mut server_tcp_watcher = { TcpWatcher::new(&mut loop_) }; + let addr = Ipv4(127, 0, 0, 1, 2925); + server_tcp_watcher.bind(addr); + let loop_ = loop_; + rtdebug!("listening"); + do server_tcp_watcher.listen |server_stream_watcher, status| { + rtdebug!("listened!"); + fail_unless!(status.is_none()); + let mut server_stream_watcher = server_stream_watcher; + let mut loop_ = loop_; + let mut client_tcp_watcher = TcpWatcher::new(&mut loop_); + let mut client_tcp_watcher = client_tcp_watcher.as_stream(); + server_stream_watcher.accept(client_tcp_watcher); + let count_cell = Cell(0); + let server_stream_watcher = server_stream_watcher; + rtdebug!("starting read"); + let alloc: AllocCallback = |size| { + vec_to_uv_buf(vec::from_elem(size, 0)) + }; + do client_tcp_watcher.read_start(alloc) + |stream_watcher, nread, buf, status| { + + rtdebug!("i'm reading!"); + let buf = vec_from_uv_buf(buf); + let mut count = count_cell.take(); + if status.is_none() { + rtdebug!("got %d bytes", nread); + let buf = buf.unwrap(); + for buf.view(0, nread as uint).each |byte| { + fail_unless!(*byte == count as u8); + rtdebug!("%u", *byte as uint); + count += 1; + } + } else { + fail_unless!(count == MAX); + do stream_watcher.close { + server_stream_watcher.close(||()); + } + } + count_cell.put_back(count); + } + } + + let _client_thread = do Thread::start { + rtdebug!("starting client thread"); + let mut loop_ = Loop::new(); + let mut tcp_watcher = { TcpWatcher::new(&mut loop_) }; + do tcp_watcher.connect(addr) |stream_watcher, status| { + rtdebug!("connecting"); + fail_unless!(status.is_none()); + let mut stream_watcher = stream_watcher; + let msg = ~[0, 1, 2, 3, 4, 5, 6 ,7 ,8, 9]; + do stream_watcher.write(msg) |stream_watcher, status| { + rtdebug!("writing"); + fail_unless!(status.is_none()); + stream_watcher.close(||()); + } + } + loop_.run(); + loop_.close(); + }; + + let mut loop_ = loop_; + loop_.run(); + loop_.close(); + } +} diff --git a/src/libcore/rt/uvio.rs b/src/libcore/rt/uvio.rs new file mode 100644 index 0000000000000..f7275652e7f39 --- /dev/null +++ b/src/libcore/rt/uvio.rs @@ -0,0 +1,475 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use option::*; +use result::*; + +use super::uv::*; +use super::io::*; +use ops::Drop; +use cell::{Cell, empty_cell}; +use cast::transmute; +use super::StreamObject; +use super::sched::Scheduler; +use super::IoFactoryObject; + +#[cfg(test)] use super::sched::Task; +#[cfg(test)] use unstable::run_in_bare_thread; +#[cfg(test)] use uint; + +pub struct UvEventLoop { + uvio: UvIoFactory +} + +pub impl UvEventLoop { + static fn new() -> UvEventLoop { + UvEventLoop { + uvio: UvIoFactory(Loop::new()) + } + } + + /// A convenience constructor + static fn new_scheduler() -> Scheduler { + Scheduler::new(~UvEventLoop::new()) + } +} + +impl Drop for UvEventLoop { + fn finalize(&self) { + // XXX: Need mutable finalizer + let self = unsafe { + transmute::<&UvEventLoop, &mut UvEventLoop>(self) + }; + let mut uv_loop = self.uvio.uv_loop(); + uv_loop.close(); + } +} + +impl EventLoop for UvEventLoop { + + fn run(&mut self) { + self.uvio.uv_loop().run(); + } + + fn callback(&mut self, f: ~fn()) { + let mut idle_watcher = IdleWatcher::new(self.uvio.uv_loop()); + do idle_watcher.start |idle_watcher, status| { + fail_unless!(status.is_none()); + let mut idle_watcher = idle_watcher; + idle_watcher.stop(); + idle_watcher.close(); + f(); + } + } + + fn io(&mut self) -> Option<&self/mut IoFactoryObject> { + Some(&mut self.uvio) + } +} + +#[test] +fn test_callback_run_once() { + do run_in_bare_thread { + let mut event_loop = UvEventLoop::new(); + let mut count = 0; + let count_ptr: *mut int = &mut count; + do event_loop.callback { + unsafe { *count_ptr += 1 } + } + event_loop.run(); + fail_unless!(count == 1); + } +} + +pub struct UvIoFactory(Loop); + +pub impl UvIoFactory { + fn uv_loop(&mut self) -> &self/mut Loop { + match self { &UvIoFactory(ref mut ptr) => ptr } + } +} + +impl IoFactory for UvIoFactory { + // Connect to an address and return a new stream + // NB: This blocks the task waiting on the connection. + // It would probably be better to return a future + fn connect(&mut self, addr: IpAddr) -> Option<~StreamObject> { + // Create a cell in the task to hold the result. We will fill + // the cell before resuming the task. + let result_cell = empty_cell(); + let result_cell_ptr: *Cell> = &result_cell; + + do Scheduler::local |scheduler| { + fail_unless!(scheduler.in_task_context()); + + // Block this task and take ownership, switch to scheduler context + do scheduler.block_running_task_and_then |scheduler, task| { + + rtdebug!("connect: entered scheduler context"); + fail_unless!(!scheduler.in_task_context()); + let mut tcp_watcher = TcpWatcher::new(self.uv_loop()); + let task_cell = Cell(task); + + // Wait for a connection + do tcp_watcher.connect(addr) |stream_watcher, status| { + rtdebug!("connect: in connect callback"); + let maybe_stream = if status.is_none() { + rtdebug!("status is none"); + Some(~UvStream(stream_watcher)) + } else { + rtdebug!("status is some"); + stream_watcher.close(||()); + None + }; + + // Store the stream in the task's stack + unsafe { (*result_cell_ptr).put_back(maybe_stream); } + + // Context switch + do Scheduler::local |scheduler| { + scheduler.resume_task_immediately(task_cell.take()); + } + } + } + } + + fail_unless!(!result_cell.is_empty()); + return result_cell.take(); + } + + fn bind(&mut self, addr: IpAddr) -> Option<~TcpListenerObject> { + let mut watcher = TcpWatcher::new(self.uv_loop()); + watcher.bind(addr); + return Some(~UvTcpListener(watcher)); + } +} + +pub struct UvTcpListener(TcpWatcher); + +impl UvTcpListener { + fn watcher(&self) -> TcpWatcher { + match self { &UvTcpListener(w) => w } + } + + fn close(&self) { + // XXX: Need to wait until close finishes before returning + self.watcher().as_stream().close(||()); + } +} + +impl Drop for UvTcpListener { + fn finalize(&self) { + // XXX: Again, this never gets called. Use .close() instead + //self.watcher().as_stream().close(||()); + } +} + +impl TcpListener for UvTcpListener { + + fn listen(&mut self) -> Option<~StreamObject> { + rtdebug!("entering listen"); + let result_cell = empty_cell(); + let result_cell_ptr: *Cell> = &result_cell; + + let server_tcp_watcher = self.watcher(); + + do Scheduler::local |scheduler| { + fail_unless!(scheduler.in_task_context()); + + do scheduler.block_running_task_and_then |_, task| { + let task_cell = Cell(task); + let mut server_tcp_watcher = server_tcp_watcher; + do server_tcp_watcher.listen |server_stream_watcher, status| { + let maybe_stream = if status.is_none() { + let mut server_stream_watcher = server_stream_watcher; + let mut loop_ = + loop_from_watcher(&server_stream_watcher); + let mut client_tcp_watcher = + TcpWatcher::new(&mut loop_); + let mut client_tcp_watcher = + client_tcp_watcher.as_stream(); + // XXX: Need's to be surfaced in interface + server_stream_watcher.accept(client_tcp_watcher); + Some(~UvStream::new(client_tcp_watcher)) + } else { + None + }; + + unsafe { (*result_cell_ptr).put_back(maybe_stream); } + + rtdebug!("resuming task from listen"); + // Context switch + do Scheduler::local |scheduler| { + scheduler.resume_task_immediately(task_cell.take()); + } + } + } + } + + fail_unless!(!result_cell.is_empty()); + return result_cell.take(); + } +} + +pub struct UvStream(StreamWatcher); + +impl UvStream { + static fn new(watcher: StreamWatcher) -> UvStream { + UvStream(watcher) + } + + fn watcher(&self) -> StreamWatcher { + match self { &UvStream(w) => w } + } + + // XXX: finalize isn't working for ~UvStream??? + fn close(&self) { + // XXX: Need to wait until this finishes before returning + self.watcher().close(||()); + } +} + +impl Drop for UvStream { + fn finalize(&self) { + rtdebug!("closing stream"); + //self.watcher().close(||()); + } +} + +impl Stream for UvStream { + fn read(&mut self, buf: &mut [u8]) -> Result { + let result_cell = empty_cell(); + let result_cell_ptr: *Cell> = &result_cell; + + do Scheduler::local |scheduler| { + fail_unless!(scheduler.in_task_context()); + let watcher = self.watcher(); + let buf_ptr: *&mut [u8] = &buf; + do scheduler.block_running_task_and_then |scheduler, task| { + rtdebug!("read: entered scheduler context"); + fail_unless!(!scheduler.in_task_context()); + let mut watcher = watcher; + let task_cell = Cell(task); + // XXX: We shouldn't reallocate these callbacks every + // call to read + let alloc: AllocCallback = |_| unsafe { + slice_to_uv_buf(*buf_ptr) + }; + do watcher.read_start(alloc) |watcher, nread, _buf, status| { + + // Stop reading so that no read callbacks are + // triggered before the user calls `read` again. + // XXX: Is there a performance impact to calling + // stop here? + let mut watcher = watcher; + watcher.read_stop(); + + let result = if status.is_none() { + fail_unless!(nread >= 0); + Ok(nread as uint) + } else { + Err(()) + }; + + unsafe { (*result_cell_ptr).put_back(result); } + + do Scheduler::local |scheduler| { + scheduler.resume_task_immediately(task_cell.take()); + } + } + } + } + + fail_unless!(!result_cell.is_empty()); + return result_cell.take(); + } + + fn write(&mut self, buf: &[u8]) -> Result<(), ()> { + let result_cell = empty_cell(); + let result_cell_ptr: *Cell> = &result_cell; + do Scheduler::local |scheduler| { + fail_unless!(scheduler.in_task_context()); + let watcher = self.watcher(); + let buf_ptr: *&[u8] = &buf; + do scheduler.block_running_task_and_then |_, task| { + let mut watcher = watcher; + let task_cell = Cell(task); + let buf = unsafe { &*buf_ptr }; + // XXX: OMGCOPIES + let buf = buf.to_vec(); + do watcher.write(buf) |_watcher, status| { + let result = if status.is_none() { + Ok(()) + } else { + Err(()) + }; + + unsafe { (*result_cell_ptr).put_back(result); } + + do Scheduler::local |scheduler| { + scheduler.resume_task_immediately(task_cell.take()); + } + } + } + } + + fail_unless!(!result_cell.is_empty()); + return result_cell.take(); + } +} + +#[test] +#[ignore(reason = "ffi struct issues")] +fn test_simple_io_no_connect() { + do run_in_bare_thread { + let mut sched = ~UvEventLoop::new_scheduler(); + let task = ~do Task::new(&mut sched.stack_pool) { + do Scheduler::local |sched| { + let io = sched.event_loop.io().unwrap(); + let addr = Ipv4(127, 0, 0, 1, 2926); + let maybe_chan = io.connect(addr); + fail_unless!(maybe_chan.is_none()); + } + }; + sched.task_queue.push_back(task); + sched.run(); + } +} + +#[test] +#[ignore(reason = "ffi struct issues")] +fn test_simple_tcp_server_and_client() { + do run_in_bare_thread { + let mut sched = ~UvEventLoop::new_scheduler(); + let addr = Ipv4(127, 0, 0, 1, 2929); + + let client_task = ~do Task::new(&mut sched.stack_pool) { + do Scheduler::local |sched| { + let io = sched.event_loop.io().unwrap(); + let mut stream = io.connect(addr).unwrap(); + stream.write([0, 1, 2, 3, 4, 5, 6, 7]); + stream.close(); + } + }; + + let server_task = ~do Task::new(&mut sched.stack_pool) { + do Scheduler::local |sched| { + let io = sched.event_loop.io().unwrap(); + let mut listener = io.bind(addr).unwrap(); + let mut stream = listener.listen().unwrap(); + let mut buf = [0, .. 2048]; + let nread = stream.read(buf).unwrap(); + fail_unless!(nread == 8); + for uint::range(0, nread) |i| { + rtdebug!("%u", buf[i] as uint); + fail_unless!(buf[i] == i as u8); + } + stream.close(); + listener.close(); + } + }; + + // Start the server first so it listens before the client connects + sched.task_queue.push_back(server_task); + sched.task_queue.push_back(client_task); + sched.run(); + } +} + +#[test] #[ignore(reason = "busted")] +fn test_read_and_block() { + do run_in_bare_thread { + let mut sched = ~UvEventLoop::new_scheduler(); + let addr = Ipv4(127, 0, 0, 1, 2930); + + let client_task = ~do Task::new(&mut sched.stack_pool) { + do Scheduler::local |sched| { + let io = sched.event_loop.io().unwrap(); + let mut stream = io.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]); + stream.close(); + } + }; + + let server_task = ~do Task::new(&mut sched.stack_pool) { + do Scheduler::local |sched| { + let io = sched.event_loop.io().unwrap(); + let mut listener = io.bind(addr).unwrap(); + let mut stream = listener.listen().unwrap(); + let mut buf = [0, .. 2048]; + + let expected = 32; + let mut current = 0; + let mut reads = 0; + + while current < expected { + let nread = stream.read(buf).unwrap(); + for uint::range(0, nread) |i| { + let val = buf[i] as uint; + fail_unless!(val == current % 8); + current += 1; + } + reads += 1; + + do Scheduler::local |scheduler| { + // Yield to the other task in hopes that it + // will trigger a read callback while we are + // not ready for it + do scheduler.block_running_task_and_then + |scheduler, task| { + scheduler.task_queue.push_back(task); + } + } + } + + // Make sure we had multiple reads + fail_unless!(reads > 1); + + stream.close(); + listener.close(); + } + }; + + // Start the server first so it listens before the client connects + sched.task_queue.push_back(server_task); + sched.task_queue.push_back(client_task); + sched.run(); + } +} + +#[test] #[ignore(reason = "needs server")] +fn test_read_read_read() { + do run_in_bare_thread { + let mut sched = ~UvEventLoop::new_scheduler(); + let addr = Ipv4(127, 0, 0, 1, 2931); + + let client_task = ~do Task::new(&mut sched.stack_pool) { + do Scheduler::local |sched| { + let io = sched.event_loop.io().unwrap(); + let mut stream = io.connect(addr).unwrap(); + let mut buf = [0, .. 2048]; + let mut total_bytes_read = 0; + while total_bytes_read < 500000000 { + let nread = stream.read(buf).unwrap(); + rtdebug!("read %u bytes", nread as uint); + total_bytes_read += nread; + } + rtdebug_!("read %u bytes total", total_bytes_read as uint); + stream.close(); + } + }; + + sched.task_queue.push_back(client_task); + sched.run(); + } +} diff --git a/src/libcore/rt/work_queue.rs b/src/libcore/rt/work_queue.rs new file mode 100644 index 0000000000000..1be2eb26e6292 --- /dev/null +++ b/src/libcore/rt/work_queue.rs @@ -0,0 +1,47 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use option::*; + +pub struct WorkQueue { + priv queue: ~[T] +} + +pub impl WorkQueue { + static fn new() -> WorkQueue { + WorkQueue { + queue: ~[] + } + } + + fn push_back(&mut self, value: T) { + self.queue.push(value) + } + + fn pop_back(&mut self) -> Option { + if !self.queue.is_empty() { + Some(self.queue.pop()) + } else { + None + } + } + + fn push_front(&mut self, value: T) { + self.queue.unshift(value) + } + + fn pop_front(&mut self) -> Option { + if !self.queue.is_empty() { + Some(self.queue.shift()) + } else { + None + } + } +} diff --git a/src/libcore/run.rs b/src/libcore/run.rs index bebcc909dc658..a9d96d891c944 100644 --- a/src/libcore/run.rs +++ b/src/libcore/run.rs @@ -102,7 +102,7 @@ pub fn spawn_process(prog: &str, args: &[~str], } fn with_argv(prog: &str, args: &[~str], - cb: fn(**libc::c_char) -> T) -> T { + cb: &fn(**libc::c_char) -> T) -> T { let mut argptrs = str::as_c_str(prog, |b| ~[b]); let mut tmps = ~[]; for vec::each(args) |arg| { @@ -116,7 +116,7 @@ fn with_argv(prog: &str, args: &[~str], #[cfg(unix)] fn with_envp(env: &Option<~[(~str,~str)]>, - cb: fn(*c_void) -> T) -> T { + cb: &fn(*c_void) -> T) -> T { // On posixy systems we can pass a char** for envp, which is // a null-terminated array of "k=v\n" strings. match *env { @@ -141,7 +141,7 @@ fn with_envp(env: &Option<~[(~str,~str)]>, #[cfg(windows)] fn with_envp(env: &Option<~[(~str,~str)]>, - cb: fn(*c_void) -> T) -> T { + cb: &fn(*c_void) -> T) -> T { // On win32 we pass an "environment block" which is not a char**, but // rather a concatenation of null-terminated k=v\0 sequences, with a final // \0 to terminate. @@ -165,7 +165,7 @@ fn with_envp(env: &Option<~[(~str,~str)]>, } fn with_dirp(d: &Option<~str>, - cb: fn(*libc::c_char) -> T) -> T { + cb: &fn(*libc::c_char) -> T) -> T { match *d { Some(ref dir) => str::as_c_str(*dir, cb), None => cb(ptr::null()) diff --git a/src/libcore/stackwalk.rs b/src/libcore/stackwalk.rs index 107e52b245e37..955e486649b99 100644 --- a/src/libcore/stackwalk.rs +++ b/src/libcore/stackwalk.rs @@ -24,7 +24,7 @@ pub fn Frame(fp: *Word) -> Frame { } } -pub fn walk_stack(visit: fn(Frame) -> bool) { +pub fn walk_stack(visit: &fn(Frame) -> bool) { debug!("beginning stack walk"); @@ -80,7 +80,7 @@ fn breakpoint() { } } -fn frame_address(f: fn(++x: *u8)) { +fn frame_address(f: &fn(++x: *u8)) { unsafe { rusti::frame_address(f) } diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 6a0673878e0e2..ae778cb7649b7 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -382,7 +382,7 @@ pub pure fn to_bytes(s: &str) -> ~[u8] { /// Work with the string as a byte slice, not including trailing null. #[inline(always)] -pub pure fn byte_slice(s: &str, f: fn(v: &[u8]) -> T) -> T { +pub pure fn byte_slice(s: &str, f: &fn(v: &[u8]) -> T) -> T { do as_buf(s) |p,n| { unsafe { vec::raw::buf_as_slice(p, n-1u, f) } } @@ -483,7 +483,7 @@ pure fn split_char_inner(s: &str, sep: char, count: uint, allow_empty: bool) /// Splits a string into substrings using a character function -pub pure fn split(s: &str, sepfn: fn(char) -> bool) -> ~[~str] { +pub pure fn split(s: &str, sepfn: &fn(char) -> bool) -> ~[~str] { split_inner(s, sepfn, len(s), true) } @@ -491,16 +491,19 @@ pub pure fn split(s: &str, sepfn: fn(char) -> bool) -> ~[~str] { * Splits a string into substrings using a character function, cutting at * most `count` times. */ -pub pure fn splitn(s: &str, sepfn: fn(char) -> bool, count: uint) -> ~[~str] { +pub pure fn splitn(s: &str, + sepfn: &fn(char) -> bool, + count: uint) + -> ~[~str] { split_inner(s, sepfn, count, true) } /// Like `split`, but omits empty strings from the returned vector -pub pure fn split_nonempty(s: &str, sepfn: fn(char) -> bool) -> ~[~str] { +pub pure fn split_nonempty(s: &str, sepfn: &fn(char) -> bool) -> ~[~str] { split_inner(s, sepfn, len(s), false) } -pure fn split_inner(s: &str, sepfn: fn(cc: char) -> bool, count: uint, +pure fn split_inner(s: &str, sepfn: &fn(cc: char) -> bool, count: uint, allow_empty: bool) -> ~[~str] { let l = len(s); let mut result = ~[], i = 0u, start = 0u, done = 0u; @@ -526,7 +529,7 @@ pure fn split_inner(s: &str, sepfn: fn(cc: char) -> bool, count: uint, } // See Issue #1932 for why this is a naive search -pure fn iter_matches(s: &a/str, sep: &b/str, f: fn(uint, uint)) { +pure fn iter_matches(s: &a/str, sep: &b/str, f: &fn(uint, uint)) { let sep_len = len(sep), l = len(s); fail_unless!(sep_len > 0u); let mut i = 0u, match_start = 0u, match_i = 0u; @@ -553,7 +556,7 @@ pure fn iter_matches(s: &a/str, sep: &b/str, f: fn(uint, uint)) { } } -pure fn iter_between_matches(s: &a/str, sep: &b/str, f: fn(uint, uint)) { +pure fn iter_between_matches(s: &a/str, sep: &b/str, f: &fn(uint, uint)) { let mut last_end = 0u; do iter_matches(s, sep) |from, to| { f(last_end, from); @@ -912,7 +915,7 @@ Section: Iterating through strings * Return true if a predicate matches all characters or if the string * contains no characters */ -pub pure fn all(s: &str, it: fn(char) -> bool) -> bool { +pub pure fn all(s: &str, it: &fn(char) -> bool) -> bool { all_between(s, 0u, len(s), it) } @@ -920,12 +923,12 @@ pub pure fn all(s: &str, it: fn(char) -> bool) -> bool { * Return true if a predicate matches any character (and false if it * matches none or there are no characters) */ -pub pure fn any(ss: &str, pred: fn(char) -> bool) -> bool { +pub pure fn any(ss: &str, pred: &fn(char) -> bool) -> bool { !all(ss, |cc| !pred(cc)) } /// Apply a function to each character -pub pure fn map(ss: &str, ff: fn(char) -> char) -> ~str { +pub pure fn map(ss: &str, ff: &fn(char) -> char) -> ~str { let mut result = ~""; unsafe { reserve(&mut result, len(ss)); @@ -937,7 +940,7 @@ pub pure fn map(ss: &str, ff: fn(char) -> char) -> ~str { } /// Iterate over the bytes in a string -pub pure fn bytes_each(ss: &str, it: fn(u8) -> bool) { +pub pure fn bytes_each(ss: &str, it: &fn(u8) -> bool) { let mut pos = 0u; let len = len(ss); @@ -949,13 +952,13 @@ pub pure fn bytes_each(ss: &str, it: fn(u8) -> bool) { /// Iterate over the bytes in a string #[inline(always)] -pub pure fn each(s: &str, it: fn(u8) -> bool) { +pub pure fn each(s: &str, it: &fn(u8) -> bool) { eachi(s, |_i, b| it(b) ) } /// Iterate over the bytes in a string, with indices #[inline(always)] -pub pure fn eachi(s: &str, it: fn(uint, u8) -> bool) { +pub pure fn eachi(s: &str, it: &fn(uint, u8) -> bool) { let mut i = 0u, l = len(s); while (i < l) { if !it(i, s[i]) { break; } @@ -965,13 +968,13 @@ pub pure fn eachi(s: &str, it: fn(uint, u8) -> bool) { /// Iterates over the chars in a string #[inline(always)] -pub pure fn each_char(s: &str, it: fn(char) -> bool) { +pub pure fn each_char(s: &str, it: &fn(char) -> bool) { each_chari(s, |_i, c| it(c)) } /// Iterates over the chars in a string, with indices #[inline(always)] -pub pure fn each_chari(s: &str, it: fn(uint, char) -> bool) { +pub pure fn each_chari(s: &str, it: &fn(uint, char) -> bool) { let mut pos = 0u, ch_pos = 0u; let len = len(s); while pos < len { @@ -983,7 +986,7 @@ pub pure fn each_chari(s: &str, it: fn(uint, char) -> bool) { } /// Iterate over the characters in a string -pub pure fn chars_each(s: &str, it: fn(char) -> bool) { +pub pure fn chars_each(s: &str, it: &fn(char) -> bool) { let mut pos = 0u; let len = len(s); while (pos < len) { @@ -994,7 +997,7 @@ pub pure fn chars_each(s: &str, it: fn(char) -> bool) { } /// Apply a function to each substring after splitting by character -pub pure fn split_char_each(ss: &str, cc: char, ff: fn(v: &str) -> bool) { +pub pure fn split_char_each(ss: &str, cc: char, ff: &fn(v: &str) -> bool) { vec::each(split_char(ss, cc), |s| ff(*s)) } @@ -1003,19 +1006,19 @@ pub pure fn split_char_each(ss: &str, cc: char, ff: fn(v: &str) -> bool) { * `count` times */ pub pure fn splitn_char_each(ss: &str, sep: char, count: uint, - ff: fn(v: &str) -> bool) { + ff: &fn(v: &str) -> bool) { vec::each(splitn_char(ss, sep, count), |s| ff(*s)) } /// Apply a function to each word -pub pure fn words_each(ss: &str, ff: fn(v: &str) -> bool) { +pub pure fn words_each(ss: &str, ff: &fn(v: &str) -> bool) { vec::each(words(ss), |s| ff(*s)) } /** * Apply a function to each line (by '\n') */ -pub pure fn lines_each(ss: &str, ff: fn(v: &str) -> bool) { +pub pure fn lines_each(ss: &str, ff: &fn(v: &str) -> bool) { vec::each(lines(ss), |s| ff(*s)) } @@ -1195,7 +1198,7 @@ pub pure fn rfind_char_between(s: &str, c: char, start: uint, end: uint) * An `option` containing the byte index of the first matching character * or `none` if there is no match */ -pub pure fn find(s: &str, f: fn(char) -> bool) -> Option { +pub pure fn find(s: &str, f: &fn(char) -> bool) -> Option { find_between(s, 0u, len(s), f) } @@ -1219,7 +1222,7 @@ pub pure fn find(s: &str, f: fn(char) -> bool) -> Option { * `start` must be less than or equal to `len(s)`. `start` must be the * index of a character boundary, as defined by `is_char_boundary`. */ -pub pure fn find_from(s: &str, start: uint, f: fn(char) +pub pure fn find_from(s: &str, start: uint, f: &fn(char) -> bool) -> Option { find_between(s, start, len(s), f) } @@ -1246,8 +1249,11 @@ pub pure fn find_from(s: &str, start: uint, f: fn(char) * or equal to `len(s)`. `start` must be the index of a character * boundary, as defined by `is_char_boundary`. */ -pub pure fn find_between(s: &str, start: uint, end: uint, f: fn(char) -> bool) - -> Option { +pub pure fn find_between(s: &str, + start: uint, + end: uint, + f: &fn(char) -> bool) + -> Option { fail_unless!(start <= end); fail_unless!(end <= len(s)); fail_unless!(is_char_boundary(s, start)); @@ -1274,7 +1280,7 @@ pub pure fn find_between(s: &str, start: uint, end: uint, f: fn(char) -> bool) * An option containing the byte index of the last matching character * or `none` if there is no match */ -pub pure fn rfind(s: &str, f: fn(char) -> bool) -> Option { +pub pure fn rfind(s: &str, f: &fn(char) -> bool) -> Option { rfind_between(s, len(s), 0u, f) } @@ -1298,7 +1304,7 @@ pub pure fn rfind(s: &str, f: fn(char) -> bool) -> Option { * `start` must be less than or equal to `len(s)', `start` must be the * index of a character boundary, as defined by `is_char_boundary` */ -pub pure fn rfind_from(s: &str, start: uint, f: fn(char) -> bool) +pub pure fn rfind_from(s: &str, start: uint, f: &fn(char) -> bool) -> Option { rfind_between(s, start, 0u, f) } @@ -1326,7 +1332,7 @@ pub pure fn rfind_from(s: &str, start: uint, f: fn(char) -> bool) * boundary, as defined by `is_char_boundary` */ pub pure fn rfind_between(s: &str, start: uint, end: uint, - f: fn(char) -> bool) + f: &fn(char) -> bool) -> Option { fail_unless!(start >= end); fail_unless!(start <= len(s)); @@ -1589,7 +1595,7 @@ pub pure fn to_utf16(s: &str) -> ~[u16] { u } -pub pure fn utf16_chars(v: &[u16], f: fn(char)) { +pub pure fn utf16_chars(v: &[u16], f: &fn(char)) { let len = vec::len(v); let mut i = 0u; while (i < len && v[i] != 0u16) { @@ -1815,7 +1821,7 @@ pure fn char_range_at_reverse(ss: &str, start: uint) -> CharRange { * that is if `it` returned `false` at any point. */ pub pure fn all_between(s: &str, start: uint, end: uint, - it: fn(char) -> bool) -> bool { + it: &fn(char) -> bool) -> bool { fail_unless!(is_char_boundary(s, start)); let mut i = start; while i < end { @@ -1848,7 +1854,7 @@ pub pure fn all_between(s: &str, start: uint, end: uint, * `true` if `it` returns `true` for any character */ pub pure fn any_between(s: &str, start: uint, end: uint, - it: fn(char) -> bool) -> bool { + it: &fn(char) -> bool) -> bool { !all_between(s, start, end, |c| !it(c)) } @@ -1886,7 +1892,7 @@ pub const nan_buf: [u8*3] = ['N' as u8, 'a' as u8, 'N' as u8]; * let i = str::as_bytes("Hello World") { |bytes| vec::len(bytes) }; * ~~~ */ -pub pure fn as_bytes(s: &const ~str, f: fn(&~[u8]) -> T) -> T { +pub pure fn as_bytes(s: &const ~str, f: &fn(&~[u8]) -> T) -> T { unsafe { let v: *~[u8] = cast::transmute(copy s); f(&*v) @@ -1921,7 +1927,7 @@ pub pure fn as_bytes_slice(s: &a/str) -> &a/[u8] { * let s = str::as_c_str("PATH", { |path| libc::getenv(path) }); * ~~~ */ -pub pure fn as_c_str(s: &str, f: fn(*libc::c_char) -> T) -> T { +pub pure fn as_c_str(s: &str, f: &fn(*libc::c_char) -> T) -> T { do as_buf(s) |buf, len| { // NB: len includes the trailing null. fail_unless!(len > 0); @@ -1943,7 +1949,7 @@ pub pure fn as_c_str(s: &str, f: fn(*libc::c_char) -> T) -> T { * to full strings, or suffixes of them. */ #[inline(always)] -pub pure fn as_buf(s: &str, f: fn(*u8, uint) -> T) -> T { +pub pure fn as_buf(s: &str, f: &fn(*u8, uint) -> T) -> T { unsafe { let v : *(*u8,uint) = ::cast::reinterpret_cast(&ptr::addr_of(&s)); let (buf,len) = *v; @@ -2088,7 +2094,7 @@ pub mod raw { /// Form a slice from a *u8 buffer of the given length without copying. pub unsafe fn buf_as_slice(buf: *u8, len: uint, - f: fn(v: &str) -> T) -> T { + f: &fn(v: &str) -> T) -> T { let v = (buf, len + 1); fail_unless!(is_utf8(::cast::reinterpret_cast(&v))); f(::cast::transmute(v)) @@ -2238,21 +2244,21 @@ pub mod traits { pub mod traits {} pub trait StrSlice { - pure fn all(&self, it: fn(char) -> bool) -> bool; - pure fn any(&self, it: fn(char) -> bool) -> bool; + pure fn all(&self, it: &fn(char) -> bool) -> bool; + pure fn any(&self, it: &fn(char) -> bool) -> bool; pure fn contains(&self, needle: &a/str) -> bool; pure fn contains_char(&self, needle: char) -> bool; - pure fn each(&self, it: fn(u8) -> bool); - pure fn eachi(&self, it: fn(uint, u8) -> bool); - pure fn each_char(&self, it: fn(char) -> bool); - pure fn each_chari(&self, it: fn(uint, char) -> bool); + pure fn each(&self, it: &fn(u8) -> bool); + pure fn eachi(&self, it: &fn(uint, u8) -> bool); + pure fn each_char(&self, it: &fn(char) -> bool); + pure fn each_chari(&self, it: &fn(uint, char) -> bool); pure fn ends_with(&self, needle: &str) -> bool; pure fn is_empty(&self) -> bool; pure fn is_whitespace(&self) -> bool; pure fn is_alphanumeric(&self) -> bool; pure fn len(&self) -> uint; pure fn slice(&self, begin: uint, end: uint) -> ~str; - pure fn split(&self, sepfn: fn(char) -> bool) -> ~[~str]; + pure fn split(&self, sepfn: &fn(char) -> bool) -> ~[~str]; pure fn split_char(&self, sep: char) -> ~[~str]; pure fn split_str(&self, sep: &a/str) -> ~[~str]; pure fn starts_with(&self, needle: &a/str) -> bool; @@ -2276,13 +2282,13 @@ impl StrSlice for &self/str { * contains no characters */ #[inline] - pure fn all(&self, it: fn(char) -> bool) -> bool { all(*self, it) } + pure fn all(&self, it: &fn(char) -> bool) -> bool { all(*self, it) } /** * Return true if a predicate matches any character (and false if it * matches none or there are no characters) */ #[inline] - pure fn any(&self, it: fn(char) -> bool) -> bool { any(*self, it) } + pure fn any(&self, it: &fn(char) -> bool) -> bool { any(*self, it) } /// Returns true if one string contains another #[inline] pure fn contains(&self, needle: &a/str) -> bool { @@ -2295,16 +2301,16 @@ impl StrSlice for &self/str { } /// Iterate over the bytes in a string #[inline] - pure fn each(&self, it: fn(u8) -> bool) { each(*self, it) } + pure fn each(&self, it: &fn(u8) -> bool) { each(*self, it) } /// Iterate over the bytes in a string, with indices #[inline] - pure fn eachi(&self, it: fn(uint, u8) -> bool) { eachi(*self, it) } + pure fn eachi(&self, it: &fn(uint, u8) -> bool) { eachi(*self, it) } /// Iterate over the chars in a string #[inline] - pure fn each_char(&self, it: fn(char) -> bool) { each_char(*self, it) } + pure fn each_char(&self, it: &fn(char) -> bool) { each_char(*self, it) } /// Iterate over the chars in a string, with indices #[inline] - pure fn each_chari(&self, it: fn(uint, char) -> bool) { + pure fn each_chari(&self, it: &fn(uint, char) -> bool) { each_chari(*self, it) } /// Returns true if one string ends with another @@ -2345,7 +2351,7 @@ impl StrSlice for &self/str { } /// Splits a string into substrings using a character function #[inline] - pure fn split(&self, sepfn: fn(char) -> bool) -> ~[~str] { + pure fn split(&self, sepfn: &fn(char) -> bool) -> ~[~str] { split(*self, sepfn) } /** diff --git a/src/libcore/sys.rs b/src/libcore/sys.rs index d4db61f4519c3..179a33ae43ea3 100644 --- a/src/libcore/sys.rs +++ b/src/libcore/sys.rs @@ -227,7 +227,7 @@ pub mod tests { pub fn synthesize_closure() { unsafe { let x = 10; - let f: fn(int) -> int = |y| x + y; + let f: &fn(int) -> int = |y| x + y; fail_unless!(f(20) == 30); @@ -241,7 +241,7 @@ pub mod tests { env: environment }; - let new_f: fn(int) -> int = cast::transmute(new_closure); + let new_f: &fn(int) -> int = cast::transmute(new_closure); fail_unless!(new_f(20) == 30); } } diff --git a/src/libcore/task/local_data.rs b/src/libcore/task/local_data.rs index 72c328d4613bc..690b3aedc5a49 100644 --- a/src/libcore/task/local_data.rs +++ b/src/libcore/task/local_data.rs @@ -79,7 +79,7 @@ pub unsafe fn local_data_set( */ pub unsafe fn local_data_modify( key: LocalDataKey, - modify_fn: fn(Option<@T>) -> Option<@T>) { + modify_fn: &fn(Option<@T>) -> Option<@T>) { local_modify(rt::rust_get_task(), key, modify_fn) } diff --git a/src/libcore/task/local_data_priv.rs b/src/libcore/task/local_data_priv.rs index f035916f59423..bb05520e1a363 100644 --- a/src/libcore/task/local_data_priv.rs +++ b/src/libcore/task/local_data_priv.rs @@ -176,7 +176,7 @@ pub unsafe fn local_set( pub unsafe fn local_modify( task: *rust_task, key: LocalDataKey, - modify_fn: fn(Option<@T>) -> Option<@T>) { + modify_fn: &fn(Option<@T>) -> Option<@T>) { // Could be more efficient by doing the lookup work, but this is easy. let newdata = modify_fn(local_pop(task, key)); diff --git a/src/libcore/task/mod.rs b/src/libcore/task/mod.rs index 065feaebb5169..31c44531efec0 100644 --- a/src/libcore/task/mod.rs +++ b/src/libcore/task/mod.rs @@ -295,7 +295,7 @@ pub impl TaskBuilder { * # Failure * Fails if a future_result was already set for this task. */ - fn future_result(&self, blk: fn(v: Port)) -> TaskBuilder { + fn future_result(&self, blk: &fn(v: Port)) -> TaskBuilder { // FIXME (#3725): Once linked failure and notification are // handled in the library, I can imagine implementing this by just // registering an arbitrary number of task::on_exit handlers and @@ -572,7 +572,7 @@ pub fn get_scheduler() -> Scheduler { * } * ~~~ */ -pub unsafe fn unkillable(f: fn() -> U) -> U { +pub unsafe fn unkillable(f: &fn() -> U) -> U { struct AllowFailure { t: *rust_task, drop { @@ -597,7 +597,7 @@ pub unsafe fn unkillable(f: fn() -> U) -> U { } /// The inverse of unkillable. Only ever to be used nested in unkillable(). -pub unsafe fn rekillable(f: fn() -> U) -> U { +pub unsafe fn rekillable(f: &fn() -> U) -> U { struct DisallowFailure { t: *rust_task, drop { @@ -625,7 +625,7 @@ pub unsafe fn rekillable(f: fn() -> U) -> U { * A stronger version of unkillable that also inhibits scheduling operations. * For use with exclusive ARCs, which use pthread mutexes directly. */ -pub unsafe fn atomically(f: fn() -> U) -> U { +pub unsafe fn atomically(f: &fn() -> U) -> U { struct DeferInterrupts { t: *rust_task, drop { diff --git a/src/libcore/task/spawn.rs b/src/libcore/task/spawn.rs index 7b7ec769fa9a7..a0db252544156 100644 --- a/src/libcore/task/spawn.rs +++ b/src/libcore/task/spawn.rs @@ -108,7 +108,7 @@ fn taskset_remove(tasks: &mut TaskSet, task: *rust_task) { let was_present = tasks.remove(&task); fail_unless!(was_present); } -pub fn taskset_each(tasks: &TaskSet, blk: fn(v: *rust_task) -> bool) { +pub fn taskset_each(tasks: &TaskSet, blk: &fn(v: *rust_task) -> bool) { tasks.each(|k| blk(*k)) } @@ -151,17 +151,17 @@ struct AncestorNode { mut ancestors: AncestorList, } -enum AncestorList = Option>; +struct AncestorList(Option>); // Accessors for taskgroup arcs and ancestor arcs that wrap the unsafety. #[inline(always)] -fn access_group(x: &TaskGroupArc, blk: fn(TaskGroupInner) -> U) -> U { +fn access_group(x: &TaskGroupArc, blk: &fn(TaskGroupInner) -> U) -> U { unsafe { x.with(blk) } } #[inline(always)] fn access_ancestors(x: &unstable::Exclusive, - blk: fn(x: &mut AncestorNode) -> U) -> U { + blk: &fn(x: &mut AncestorNode) -> U) -> U { unsafe { x.with(blk) } } @@ -175,7 +175,7 @@ fn access_ancestors(x: &unstable::Exclusive, // allocations. Once that bug is fixed, changing the sigil should suffice. fn each_ancestor(list: &mut AncestorList, bail_opt: Option<@fn(TaskGroupInner)>, - forward_blk: fn(TaskGroupInner) -> bool) + forward_blk: &fn(TaskGroupInner) -> bool) -> bool { // "Kickoff" call - there was no last generation. return !coalesce(list, bail_opt, forward_blk, uint::max_value); @@ -184,7 +184,7 @@ fn each_ancestor(list: &mut AncestorList, // whether or not unwinding is needed (i.e., !successful iteration). fn coalesce(list: &mut AncestorList, bail_opt: Option<@fn(TaskGroupInner)>, - forward_blk: fn(TaskGroupInner) -> bool, + forward_blk: &fn(TaskGroupInner) -> bool, last_generation: uint) -> bool { // Need to swap the list out to use it, to appease borrowck. let tmp_list = util::replace(&mut *list, AncestorList(None)); @@ -288,7 +288,7 @@ fn each_ancestor(list: &mut AncestorList, // Wrapper around exclusive::with that appeases borrowck. fn with_parent_tg(parent_group: &mut Option, - blk: fn(TaskGroupInner) -> U) -> U { + blk: &fn(TaskGroupInner) -> U) -> U { // If this trips, more likely the problem is 'blk' failed inside. let tmp_arc = option::swap_unwrap(&mut *parent_group); let result = do access_group(&tmp_arc) |tg_opt| { blk(tg_opt) }; diff --git a/src/libcore/trie.rs b/src/libcore/trie.rs index 395772df57179..7dc85cba297f1 100644 --- a/src/libcore/trie.rs +++ b/src/libcore/trie.rs @@ -32,7 +32,7 @@ pub struct TrieMap { impl BaseIter<(uint, &'self T)> for TrieMap { /// Visit all key-value pairs in order #[inline(always)] - pure fn each(&self, f: fn(&(uint, &self/T)) -> bool) { + pure fn each(&self, f: &fn(&(uint, &self/T)) -> bool) { self.root.each(f); } #[inline(always)] @@ -42,7 +42,7 @@ impl BaseIter<(uint, &'self T)> for TrieMap { impl ReverseIter<(uint, &'self T)> for TrieMap { /// Visit all key-value pairs in reverse order #[inline(always)] - pure fn each_reverse(&self, f: fn(&(uint, &self/T)) -> bool) { + pure fn each_reverse(&self, f: &fn(&(uint, &self/T)) -> bool) { self.root.each_reverse(f); } } @@ -75,13 +75,16 @@ impl Map for TrieMap { /// Visit all keys in order #[inline(always)] - pure fn each_key(&self, f: fn(&uint) -> bool) { + pure fn each_key(&self, f: &fn(&uint) -> bool) { self.each(|&(k, _)| f(&k)) } /// Visit all values in order #[inline(always)] - pure fn each_value(&self, f: fn(&T) -> bool) { self.each(|&(_, v)| f(v)) } + pure fn each_value(&self, + f: &fn(&T) -> bool) { + self.each(|&(_, v)| f(v)) + } /// Return the value corresponding to the key in the map #[inline(hint)] @@ -138,18 +141,18 @@ impl TrieMap { impl TrieMap { /// Visit all keys in reverse order #[inline(always)] - pure fn each_key_reverse(&self, f: fn(&uint) -> bool) { + pure fn each_key_reverse(&self, f: &fn(&uint) -> bool) { self.each_reverse(|&(k, _)| f(&k)) } /// Visit all values in reverse order #[inline(always)] - pure fn each_value_reverse(&self, f: fn(&T) -> bool) { + pure fn each_value_reverse(&self, f: &fn(&T) -> bool) { self.each_reverse(|&(_, v)| f(v)) } /// Iterate over the map and mutate the contained values - fn mutate_values(&mut self, f: fn(uint, &mut T) -> bool) { + fn mutate_values(&mut self, f: &fn(uint, &mut T) -> bool) { self.root.mutate_values(f); } } @@ -160,13 +163,13 @@ pub struct TrieSet { impl BaseIter for TrieSet { /// Visit all values in order - pure fn each(&self, f: fn(&uint) -> bool) { self.map.each_key(f) } + pure fn each(&self, f: &fn(&uint) -> bool) { self.map.each_key(f) } pure fn size_hint(&self) -> Option { Some(self.len()) } } impl ReverseIter for TrieSet { /// Visit all values in reverse order - pure fn each_reverse(&self, f: fn(&uint) -> bool) { + pure fn each_reverse(&self, f: &fn(&uint) -> bool) { self.map.each_key_reverse(f) } } @@ -223,7 +226,7 @@ impl TrieNode { } impl TrieNode { - pure fn each(&self, f: fn(&(uint, &self/T)) -> bool) -> bool { + pure fn each(&self, f: &fn(&(uint, &self/T)) -> bool) -> bool { for uint::range(0, self.children.len()) |idx| { match self.children[idx] { Internal(ref x) => if !x.each(f) { return false }, @@ -234,7 +237,7 @@ impl TrieNode { true } - pure fn each_reverse(&self, f: fn(&(uint, &self/T)) -> bool) -> bool { + pure fn each_reverse(&self, f: &fn(&(uint, &self/T)) -> bool) -> bool { for uint::range_rev(self.children.len(), 0) |idx| { match self.children[idx - 1] { Internal(ref x) => if !x.each_reverse(f) { return false }, @@ -245,7 +248,7 @@ impl TrieNode { true } - fn mutate_values(&mut self, f: fn(uint, &mut T) -> bool) -> bool { + fn mutate_values(&mut self, f: &fn(uint, &mut T) -> bool) -> bool { for vec::each_mut(self.children) |child| { match *child { Internal(ref mut x) => if !x.mutate_values(f) { diff --git a/src/libcore/unstable.rs b/src/libcore/unstable.rs index 96cd732d815d5..7936b18dbe20c 100644 --- a/src/libcore/unstable.rs +++ b/src/libcore/unstable.rs @@ -35,6 +35,8 @@ pub mod extfmt; #[path = "unstable/lang.rs"] #[cfg(notest)] pub mod lang; +#[path = "unstable/uvll.rs"] +pub mod uvll; mod rustrt { use unstable::{raw_thread, rust_little_lock}; @@ -61,7 +63,7 @@ for it to terminate. The executing thread has no access to a task pointer and will be using a normal large stack. */ -pub unsafe fn run_in_bare_thread(f: ~fn()) { +pub fn run_in_bare_thread(f: ~fn()) { let (port, chan) = comm::stream(); // FIXME #4525: Unfortunate that this creates an extra scheduler but it's // necessary since rust_raw_thread_join_delete is blocking @@ -80,22 +82,18 @@ pub unsafe fn run_in_bare_thread(f: ~fn()) { #[test] fn test_run_in_bare_thread() { - unsafe { - let i = 100; - do run_in_bare_thread { - fail_unless!(i == 100); - } + let i = 100; + do run_in_bare_thread { + fail_unless!(i == 100); } } #[test] fn test_run_in_bare_thread_exchange() { - unsafe { - // Does the exchange heap work without the runtime? - let i = ~100; - do run_in_bare_thread { - fail_unless!(i == ~100); - } + // Does the exchange heap work without the runtime? + let i = ~100; + do run_in_bare_thread { + fail_unless!(i == ~100); } } @@ -232,7 +230,7 @@ fn LittleLock() -> LittleLock { pub impl LittleLock { #[inline(always)] - unsafe fn lock(&self, f: fn() -> T) -> T { + unsafe fn lock(&self, f: &fn() -> T) -> T { struct Unlock { l: rust_little_lock, drop { @@ -284,7 +282,7 @@ pub impl Exclusive { // accessing the provided condition variable) are prohibited while inside // the exclusive. Supporting that is a work in progress. #[inline(always)] - unsafe fn with(&self, f: fn(x: &mut T) -> U) -> U { + unsafe fn with(&self, f: &fn(x: &mut T) -> U) -> U { unsafe { let rec = get_shared_mutable_state(&self.x); do (*rec).lock.lock { @@ -301,7 +299,7 @@ pub impl Exclusive { } #[inline(always)] - unsafe fn with_imm(&self, f: fn(x: &T) -> U) -> U { + unsafe fn with_imm(&self, f: &fn(x: &T) -> U) -> U { do self.with |x| { f(cast::transmute_immut(x)) } diff --git a/src/libcore/unstable/exchange_alloc.rs b/src/libcore/unstable/exchange_alloc.rs index a2815cebc51aa..3b4d86ba86b42 100644 --- a/src/libcore/unstable/exchange_alloc.rs +++ b/src/libcore/unstable/exchange_alloc.rs @@ -41,6 +41,17 @@ pub unsafe fn malloc(td: *TypeDesc, size: uint) -> *c_void { return transmute(box); } } +/** +Thin wrapper around libc::malloc, none of the box header +stuff in exchange_alloc::malloc +*/ +pub unsafe fn malloc_raw(size: uint) -> *c_void { + let p = c_malloc(size as size_t); + if p.is_null() { + fail!(~"Failure in malloc_raw: result ptr is null"); + } + p +} pub unsafe fn free(ptr: *c_void) { let exchange_count = &mut *rust_get_exchange_count_ptr(); @@ -49,6 +60,10 @@ pub unsafe fn free(ptr: *c_void) { fail_unless!(ptr.is_not_null()); c_free(ptr); } +///Thin wrapper around libc::free, as with exchange_alloc::malloc_raw +pub unsafe fn free_raw(ptr: *c_void) { + c_free(ptr); +} fn get_box_size(body_size: uint, body_align: uint) -> uint { let header_size = size_of::(); diff --git a/src/libstd/uv_ll.rs b/src/libcore/unstable/uvll.rs similarity index 86% rename from src/libstd/uv_ll.rs rename to src/libcore/unstable/uvll.rs index fa415e0875b3e..0aed2567a220f 100644 --- a/src/libstd/uv_ll.rs +++ b/src/libcore/unstable/uvll.rs @@ -32,14 +32,15 @@ #[allow(non_camel_case_types)]; // C types -use core::libc::size_t; -use core::libc; -use core::prelude::*; -use core::ptr::to_unsafe_ptr; -use core::ptr; -use core::str; -use core::vec; -use core::comm::{stream, Chan, SharedChan, Port}; +use libc::size_t; +use libc::c_void; +use prelude::*; +use ptr::to_unsafe_ptr; + +pub type uv_handle_t = c_void; +pub type uv_loop_t = c_void; +pub type uv_idle_t = c_void; +pub type uv_idle_cb = *u8; // libuv struct mappings pub struct uv_ip4_addr { @@ -355,7 +356,10 @@ pub struct uv_getaddrinfo_t { } pub mod uv_ll_struct_stubgen { - use uv_ll::{ + + use ptr; + + use super::{ uv_async_t, uv_connect_t, uv_getaddrinfo_t, @@ -369,15 +373,13 @@ pub mod uv_ll_struct_stubgen { #[cfg(target_os = "android")] #[cfg(target_os = "macos")] #[cfg(target_os = "freebsd")] - use uv_ll::{ + use super::{ uv_async_t_32bit_unix_riders, uv_tcp_t_32bit_unix_riders, uv_timer_t_32bit_unix_riders, uv_write_t_32bit_unix_riders, }; - use core::ptr; - pub fn gen_stub_uv_tcp_t() -> uv_tcp_t { return gen_stub_os(); #[cfg(target_os = "linux")] @@ -724,157 +726,157 @@ pub mod uv_ll_struct_stubgen { } } -pub mod rustrt { - use super::{addrinfo, sockaddr_in, sockaddr_in6, uv_async_t, uv_buf_t}; - use super::{uv_connect_t, uv_err_t, uv_getaddrinfo_t, uv_stream_t}; - use super::{uv_tcp_t, uv_timer_t, uv_write_t}; - - use core::libc; - - #[nolink] - pub extern { - // libuv public API - unsafe fn rust_uv_loop_new() -> *libc::c_void; - unsafe fn rust_uv_loop_delete(lp: *libc::c_void); - unsafe fn rust_uv_run(loop_handle: *libc::c_void); - unsafe fn rust_uv_close(handle: *libc::c_void, cb: *u8); - unsafe fn rust_uv_walk(loop_handle: *libc::c_void, cb: *u8, - arg: *libc::c_void); - unsafe fn rust_uv_async_send(handle: *uv_async_t); - unsafe fn rust_uv_async_init(loop_handle: *libc::c_void, - async_handle: *uv_async_t, - cb: *u8) -> libc::c_int; - unsafe fn rust_uv_tcp_init( - loop_handle: *libc::c_void, - handle_ptr: *uv_tcp_t) -> libc::c_int; - // FIXME ref #2604 .. ? - unsafe fn rust_uv_buf_init(out_buf: *uv_buf_t, base: *u8, - len: libc::size_t); - unsafe fn rust_uv_last_error(loop_handle: *libc::c_void) -> uv_err_t; - // FIXME ref #2064 - unsafe fn rust_uv_strerror(err: *uv_err_t) -> *libc::c_char; - // FIXME ref #2064 - unsafe fn rust_uv_err_name(err: *uv_err_t) -> *libc::c_char; - unsafe fn rust_uv_ip4_addr(ip: *u8, port: libc::c_int) - -> sockaddr_in; - unsafe fn rust_uv_ip6_addr(ip: *u8, port: libc::c_int) - -> sockaddr_in6; - unsafe fn rust_uv_ip4_name(src: *sockaddr_in, - dst: *u8, - size: libc::size_t) - -> libc::c_int; - unsafe fn rust_uv_ip6_name(src: *sockaddr_in6, - dst: *u8, - size: libc::size_t) - -> libc::c_int; - unsafe fn rust_uv_ip4_port(src: *sockaddr_in) -> libc::c_uint; - unsafe fn rust_uv_ip6_port(src: *sockaddr_in6) -> libc::c_uint; - // FIXME ref #2064 - unsafe fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t, - tcp_handle_ptr: *uv_tcp_t, - ++after_cb: *u8, - ++addr: *sockaddr_in) -> libc::c_int; - // FIXME ref #2064 - unsafe fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t, - ++addr: *sockaddr_in) -> libc::c_int; - // FIXME ref #2064 - unsafe fn rust_uv_tcp_connect6(connect_ptr: *uv_connect_t, - tcp_handle_ptr: *uv_tcp_t, - ++after_cb: *u8, - ++addr: *sockaddr_in6) -> libc::c_int; - // FIXME ref #2064 - unsafe fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t, - ++addr: *sockaddr_in6) -> libc::c_int; - unsafe fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t, - ++name: *sockaddr_in) - -> libc::c_int; - unsafe fn rust_uv_tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t, - ++name: *sockaddr_in6) - -> libc::c_int; - unsafe fn rust_uv_listen(stream: *libc::c_void, - backlog: libc::c_int, - cb: *u8) -> libc::c_int; - unsafe fn rust_uv_accept(server: *libc::c_void, client: *libc::c_void) - -> libc::c_int; - unsafe fn rust_uv_write(req: *libc::c_void, - stream: *libc::c_void, - ++buf_in: *uv_buf_t, - buf_cnt: libc::c_int, - cb: *u8) - -> libc::c_int; - unsafe fn rust_uv_read_start(stream: *libc::c_void, - on_alloc: *u8, - on_read: *u8) - -> libc::c_int; - unsafe fn rust_uv_read_stop(stream: *libc::c_void) -> libc::c_int; - unsafe fn rust_uv_timer_init(loop_handle: *libc::c_void, - timer_handle: *uv_timer_t) - -> libc::c_int; - unsafe fn rust_uv_timer_start( - timer_handle: *uv_timer_t, - cb: *u8, - timeout: libc::c_uint, - repeat: libc::c_uint) -> libc::c_int; - unsafe fn rust_uv_timer_stop(handle: *uv_timer_t) -> libc::c_int; - - unsafe fn rust_uv_getaddrinfo(loop_ptr: *libc::c_void, - handle: *uv_getaddrinfo_t, - cb: *u8, - node_name_ptr: *u8, - service_name_ptr: *u8, - // should probably only pass ptr::null() - hints: *addrinfo) - -> libc::c_int; - unsafe fn rust_uv_freeaddrinfo(res: *addrinfo); - - // data accessors/helpers for rust-mapped uv structs - unsafe fn rust_uv_helper_get_INADDR_NONE() -> u32; - unsafe fn rust_uv_is_ipv4_addrinfo(input: *addrinfo) -> bool; - unsafe fn rust_uv_is_ipv6_addrinfo(input: *addrinfo) -> bool; - unsafe fn rust_uv_get_next_addrinfo(input: *addrinfo) -> *addrinfo; - unsafe fn rust_uv_addrinfo_as_sockaddr_in(input: *addrinfo) - -> *sockaddr_in; - unsafe fn rust_uv_addrinfo_as_sockaddr_in6(input: *addrinfo) - -> *sockaddr_in6; - unsafe fn rust_uv_malloc_buf_base_of(sug_size: libc::size_t) -> *u8; - unsafe fn rust_uv_free_base_of_buf(++buf: uv_buf_t); - unsafe fn rust_uv_get_stream_handle_from_connect_req( - connect_req: *uv_connect_t) - -> *uv_stream_t; - unsafe fn rust_uv_get_stream_handle_from_write_req( - write_req: *uv_write_t) - -> *uv_stream_t; - unsafe fn rust_uv_get_loop_for_uv_handle(handle: *libc::c_void) - -> *libc::c_void; - unsafe fn rust_uv_get_data_for_uv_loop(loop_ptr: *libc::c_void) - -> *libc::c_void; - unsafe fn rust_uv_set_data_for_uv_loop(loop_ptr: *libc::c_void, - data: *libc::c_void); - unsafe fn rust_uv_get_data_for_uv_handle(handle: *libc::c_void) - -> *libc::c_void; - unsafe fn rust_uv_set_data_for_uv_handle(handle: *libc::c_void, - data: *libc::c_void); - unsafe fn rust_uv_get_data_for_req(req: *libc::c_void) - -> *libc::c_void; - unsafe fn rust_uv_set_data_for_req(req: *libc::c_void, +#[nolink] +extern mod rustrt { + + // libuv public API + unsafe fn rust_uv_loop_new() -> *libc::c_void; + unsafe fn rust_uv_loop_delete(lp: *libc::c_void); + unsafe fn rust_uv_run(loop_handle: *libc::c_void); + unsafe fn rust_uv_close(handle: *libc::c_void, cb: *u8); + unsafe fn rust_uv_walk(loop_handle: *libc::c_void, cb: *u8, + arg: *libc::c_void); + + unsafe fn rust_uv_idle_new() -> *uv_idle_t; + unsafe fn rust_uv_idle_delete(handle: *uv_idle_t); + unsafe fn rust_uv_idle_init(loop_handle: *uv_loop_t, + handle: *uv_idle_t) -> libc::c_int; + unsafe fn rust_uv_idle_start(handle: *uv_idle_t, + cb: uv_idle_cb) -> libc::c_int; + unsafe fn rust_uv_idle_stop(handle: *uv_idle_t) -> libc::c_int; + + unsafe fn rust_uv_async_send(handle: *uv_async_t); + unsafe fn rust_uv_async_init(loop_handle: *libc::c_void, + async_handle: *uv_async_t, + cb: *u8) -> libc::c_int; + unsafe fn rust_uv_tcp_init( + loop_handle: *libc::c_void, + handle_ptr: *uv_tcp_t) -> libc::c_int; + // FIXME ref #2604 .. ? + unsafe fn rust_uv_buf_init(out_buf: *uv_buf_t, base: *u8, + len: libc::size_t); + unsafe fn rust_uv_last_error(loop_handle: *libc::c_void) -> uv_err_t; + // FIXME ref #2064 + unsafe fn rust_uv_strerror(err: *uv_err_t) -> *libc::c_char; + // FIXME ref #2064 + unsafe fn rust_uv_err_name(err: *uv_err_t) -> *libc::c_char; + unsafe fn rust_uv_ip4_addr(ip: *u8, port: libc::c_int) + -> sockaddr_in; + unsafe fn rust_uv_ip6_addr(ip: *u8, port: libc::c_int) + -> sockaddr_in6; + unsafe fn rust_uv_ip4_name(src: *sockaddr_in, + dst: *u8, + size: libc::size_t) + -> libc::c_int; + unsafe fn rust_uv_ip6_name(src: *sockaddr_in6, + dst: *u8, + size: libc::size_t) + -> libc::c_int; + unsafe fn rust_uv_ip4_port(src: *sockaddr_in) -> libc::c_uint; + unsafe fn rust_uv_ip6_port(src: *sockaddr_in6) -> libc::c_uint; + // FIXME ref #2064 + unsafe fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t, + tcp_handle_ptr: *uv_tcp_t, + ++after_cb: *u8, + ++addr: *sockaddr_in) -> libc::c_int; + // FIXME ref #2064 + unsafe fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t, + ++addr: *sockaddr_in) -> libc::c_int; + // FIXME ref #2064 + unsafe fn rust_uv_tcp_connect6(connect_ptr: *uv_connect_t, + tcp_handle_ptr: *uv_tcp_t, + ++after_cb: *u8, + ++addr: *sockaddr_in6) -> libc::c_int; + // FIXME ref #2064 + unsafe fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t, + ++addr: *sockaddr_in6) -> libc::c_int; + unsafe fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t, + ++name: *sockaddr_in) -> libc::c_int; + unsafe fn rust_uv_tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t, + ++name: *sockaddr_in6) ->libc::c_int; + unsafe fn rust_uv_listen(stream: *libc::c_void, + backlog: libc::c_int, + cb: *u8) -> libc::c_int; + unsafe fn rust_uv_accept(server: *libc::c_void, client: *libc::c_void) + -> libc::c_int; + unsafe fn rust_uv_write(req: *libc::c_void, + stream: *libc::c_void, + ++buf_in: *uv_buf_t, + buf_cnt: libc::c_int, + cb: *u8) + -> libc::c_int; + unsafe fn rust_uv_read_start(stream: *libc::c_void, + on_alloc: *u8, + on_read: *u8) + -> libc::c_int; + unsafe fn rust_uv_read_stop(stream: *libc::c_void) -> libc::c_int; + unsafe fn rust_uv_timer_init(loop_handle: *libc::c_void, + timer_handle: *uv_timer_t) + -> libc::c_int; + unsafe fn rust_uv_timer_start( + timer_handle: *uv_timer_t, + cb: *u8, + timeout: libc::c_uint, + repeat: libc::c_uint) -> libc::c_int; + unsafe fn rust_uv_timer_stop(handle: *uv_timer_t) -> libc::c_int; + + unsafe fn rust_uv_getaddrinfo(loop_ptr: *libc::c_void, + handle: *uv_getaddrinfo_t, + cb: *u8, + node_name_ptr: *u8, + service_name_ptr: *u8, + // should probably only pass ptr::null() + hints: *addrinfo) + -> libc::c_int; + unsafe fn rust_uv_freeaddrinfo(res: *addrinfo); + + // data accessors/helpers for rust-mapped uv structs + unsafe fn rust_uv_helper_get_INADDR_NONE() -> u32; + unsafe fn rust_uv_is_ipv4_addrinfo(input: *addrinfo) -> bool; + unsafe fn rust_uv_is_ipv6_addrinfo(input: *addrinfo) -> bool; + unsafe fn rust_uv_get_next_addrinfo(input: *addrinfo) -> *addrinfo; + unsafe fn rust_uv_addrinfo_as_sockaddr_in(input: *addrinfo) + -> *sockaddr_in; + unsafe fn rust_uv_addrinfo_as_sockaddr_in6(input: *addrinfo) + -> *sockaddr_in6; + unsafe fn rust_uv_malloc_buf_base_of(sug_size: libc::size_t) -> *u8; + unsafe fn rust_uv_free_base_of_buf(++buf: uv_buf_t); + unsafe fn rust_uv_get_stream_handle_from_connect_req( + connect_req: *uv_connect_t) + -> *uv_stream_t; + unsafe fn rust_uv_get_stream_handle_from_write_req( + write_req: *uv_write_t) + -> *uv_stream_t; + unsafe fn rust_uv_get_loop_for_uv_handle(handle: *libc::c_void) + -> *libc::c_void; + unsafe fn rust_uv_get_data_for_uv_loop(loop_ptr: *libc::c_void) + -> *libc::c_void; + unsafe fn rust_uv_set_data_for_uv_loop(loop_ptr: *libc::c_void, data: *libc::c_void); - unsafe fn rust_uv_get_base_from_buf(++buf: uv_buf_t) -> *u8; - unsafe fn rust_uv_get_len_from_buf(++buf: uv_buf_t) -> libc::size_t; - - // sizeof testing helpers - unsafe fn rust_uv_helper_uv_tcp_t_size() -> libc::c_uint; - unsafe fn rust_uv_helper_uv_connect_t_size() -> libc::c_uint; - unsafe fn rust_uv_helper_uv_buf_t_size() -> libc::c_uint; - unsafe fn rust_uv_helper_uv_write_t_size() -> libc::c_uint; - unsafe fn rust_uv_helper_uv_err_t_size() -> libc::c_uint; - unsafe fn rust_uv_helper_sockaddr_in_size() -> libc::c_uint; - unsafe fn rust_uv_helper_sockaddr_in6_size() -> libc::c_uint; - unsafe fn rust_uv_helper_uv_async_t_size() -> libc::c_uint; - unsafe fn rust_uv_helper_uv_timer_t_size() -> libc::c_uint; - unsafe fn rust_uv_helper_uv_getaddrinfo_t_size() -> libc::c_uint; - unsafe fn rust_uv_helper_addrinfo_size() -> libc::c_uint; - unsafe fn rust_uv_helper_addr_in_size() -> libc::c_uint; - } + unsafe fn rust_uv_get_data_for_uv_handle(handle: *libc::c_void) + -> *libc::c_void; + unsafe fn rust_uv_set_data_for_uv_handle(handle: *libc::c_void, + data: *libc::c_void); + unsafe fn rust_uv_get_data_for_req(req: *libc::c_void) + -> *libc::c_void; + unsafe fn rust_uv_set_data_for_req(req: *libc::c_void, + data: *libc::c_void); + unsafe fn rust_uv_get_base_from_buf(++buf: uv_buf_t) -> *u8; + unsafe fn rust_uv_get_len_from_buf(++buf: uv_buf_t) -> libc::size_t; + + // sizeof testing helpers + unsafe fn rust_uv_helper_uv_tcp_t_size() -> libc::c_uint; + unsafe fn rust_uv_helper_uv_connect_t_size() -> libc::c_uint; + unsafe fn rust_uv_helper_uv_buf_t_size() -> libc::c_uint; + unsafe fn rust_uv_helper_uv_write_t_size() -> libc::c_uint; + unsafe fn rust_uv_helper_uv_err_t_size() -> libc::c_uint; + unsafe fn rust_uv_helper_sockaddr_in_size() -> libc::c_uint; + unsafe fn rust_uv_helper_sockaddr_in6_size() -> libc::c_uint; + unsafe fn rust_uv_helper_uv_async_t_size() -> libc::c_uint; + unsafe fn rust_uv_helper_uv_timer_t_size() -> libc::c_uint; + unsafe fn rust_uv_helper_uv_getaddrinfo_t_size() -> libc::c_uint; + unsafe fn rust_uv_helper_addrinfo_size() -> libc::c_uint; + unsafe fn rust_uv_helper_addr_in_size() -> libc::c_uint; } pub unsafe fn loop_new() -> *libc::c_void { @@ -897,6 +899,27 @@ pub unsafe fn walk(loop_handle: *libc::c_void, cb: *u8, arg: *libc::c_void) { rustrt::rust_uv_walk(loop_handle, cb, arg); } +pub unsafe fn idle_new() -> *uv_idle_t { + rustrt::rust_uv_idle_new() +} + +pub unsafe fn idle_delete(handle: *uv_idle_t) { + rustrt::rust_uv_idle_delete(handle) +} + +pub unsafe fn idle_init(loop_handle: *uv_loop_t, + handle: *uv_idle_t) -> libc::c_int { + rustrt::rust_uv_idle_init(loop_handle, handle) +} + +pub unsafe fn idle_start(handle: *uv_idle_t, cb: uv_idle_cb) -> libc::c_int { + rustrt::rust_uv_idle_start(handle, cb) +} + +pub unsafe fn idle_stop(handle: *uv_idle_t) -> libc::c_int { + rustrt::rust_uv_idle_stop(handle) +} + pub unsafe fn tcp_init(loop_handle: *libc::c_void, handle: *uv_tcp_t) -> libc::c_int { return rustrt::rust_uv_tcp_init(loop_handle, handle); @@ -1215,19 +1238,11 @@ pub unsafe fn addrinfo_as_sockaddr_in6(input: *addrinfo) -> *sockaddr_in6 { rustrt::rust_uv_addrinfo_as_sockaddr_in6(input) } -//#[cfg(test)] +#[cfg(test)] pub mod test { - use core::prelude::*; - - use uv_ll::*; - - use core::comm::{SharedChan, stream}; - use core::libc; - use core::ptr; - use core::str; - use core::sys; - use core::task; - use core::vec; + use prelude::*; + use super::*; + use comm::{SharedChan, stream, GenericChan, GenericPort}; enum tcp_read_data { tcp_read_eof, @@ -1473,7 +1488,7 @@ pub mod test { let client_data = get_data_for_uv_handle( client_stream_ptr as *libc::c_void) as *tcp_server_data; - let server_kill_msg = (*client_data).server_kill_msg; + let server_kill_msg = copy (*client_data).server_kill_msg; let write_req = (*client_data).server_write_req; if str::contains(request_str, server_kill_msg) { log(debug, ~"SERVER: client req contains kill_msg!"); @@ -1606,8 +1621,8 @@ pub mod test { fn impl_uv_tcp_server(server_ip: &str, server_port: int, - +kill_server_msg: ~str, - +server_resp_msg: ~str, + kill_server_msg: ~str, + server_resp_msg: ~str, server_chan: SharedChan<~str>, continue_chan: SharedChan) { unsafe { @@ -1725,10 +1740,12 @@ pub mod test { let (continue_port, continue_chan) = stream::(); let continue_chan = SharedChan(continue_chan); + let kill_server_msg_copy = copy kill_server_msg; + let server_resp_msg_copy = copy server_resp_msg; do task::spawn_sched(task::ManualThreads(1)) { impl_uv_tcp_server(bind_ip, port, - kill_server_msg, - server_resp_msg, + copy kill_server_msg_copy, + copy server_resp_msg_copy, server_chan.clone(), continue_chan.clone()); }; @@ -1738,9 +1755,10 @@ pub mod test { continue_port.recv(); log(debug, ~"received on continue port, set up tcp client"); + let kill_server_msg_copy = copy kill_server_msg; do task::spawn_sched(task::ManualThreads(1u)) { impl_uv_tcp_request(request_ip, port, - kill_server_msg, + kill_server_msg_copy, client_chan.clone()); }; @@ -1760,11 +1778,10 @@ pub mod test { pub mod tcp_and_server_client_test { #[cfg(target_arch="x86_64")] pub mod impl64 { - use uv_ll::test::*; #[test] pub fn test_uv_ll_tcp_server_and_request() { unsafe { - impl_uv_tcp_server_and_request(); + super::super::impl_uv_tcp_server_and_request(); } } } @@ -1772,12 +1789,11 @@ pub mod test { #[cfg(target_arch="arm")] #[cfg(target_arch="mips")] pub mod impl32 { - use uv_ll::test::*; #[test] #[ignore(cfg(target_os = "linux"))] pub fn test_uv_ll_tcp_server_and_request() { unsafe { - impl_uv_tcp_server_and_request(); + super::super::impl_uv_tcp_server_and_request(); } } } @@ -1804,7 +1820,7 @@ pub mod test { unsafe { struct_size_check_common::( ~"uv_tcp_t", - ::uv_ll::rustrt::rust_uv_helper_uv_tcp_t_size() + super::rustrt::rust_uv_helper_uv_tcp_t_size() ); } } @@ -1813,7 +1829,7 @@ pub mod test { unsafe { struct_size_check_common::( ~"uv_connect_t", - ::uv_ll::rustrt::rust_uv_helper_uv_connect_t_size() + super::rustrt::rust_uv_helper_uv_connect_t_size() ); } } @@ -1822,7 +1838,7 @@ pub mod test { unsafe { struct_size_check_common::( ~"uv_buf_t", - ::uv_ll::rustrt::rust_uv_helper_uv_buf_t_size() + super::rustrt::rust_uv_helper_uv_buf_t_size() ); } } @@ -1831,7 +1847,7 @@ pub mod test { unsafe { struct_size_check_common::( ~"uv_write_t", - ::uv_ll::rustrt::rust_uv_helper_uv_write_t_size() + super::rustrt::rust_uv_helper_uv_write_t_size() ); } } @@ -1841,7 +1857,7 @@ pub mod test { unsafe { struct_size_check_common::( ~"sockaddr_in", - ::uv_ll::rustrt::rust_uv_helper_sockaddr_in_size() + super::rustrt::rust_uv_helper_sockaddr_in_size() ); } } @@ -1849,7 +1865,7 @@ pub mod test { fn test_uv_ll_struct_size_sockaddr_in6() { unsafe { let foreign_handle_size = - ::uv_ll::rustrt::rust_uv_helper_sockaddr_in6_size(); + super::rustrt::rust_uv_helper_sockaddr_in6_size(); let rust_handle_size = sys::size_of::(); let output = fmt!("sockaddr_in6 -- foreign: %u rust: %u", foreign_handle_size as uint, rust_handle_size); @@ -1868,7 +1884,7 @@ pub mod test { fn test_uv_ll_struct_size_addr_in() { unsafe { let foreign_handle_size = - ::uv_ll::rustrt::rust_uv_helper_addr_in_size(); + super::rustrt::rust_uv_helper_addr_in_size(); let rust_handle_size = sys::size_of::(); let output = fmt!("addr_in -- foreign: %u rust: %u", foreign_handle_size as uint, rust_handle_size); @@ -1884,7 +1900,7 @@ pub mod test { unsafe { struct_size_check_common::( ~"uv_async_t", - ::uv_ll::rustrt::rust_uv_helper_uv_async_t_size() + super::rustrt::rust_uv_helper_uv_async_t_size() ); } } @@ -1894,7 +1910,7 @@ pub mod test { unsafe { struct_size_check_common::( ~"uv_timer_t", - ::uv_ll::rustrt::rust_uv_helper_uv_timer_t_size() + super::rustrt::rust_uv_helper_uv_timer_t_size() ); } } @@ -1905,7 +1921,7 @@ pub mod test { unsafe { struct_size_check_common::( ~"uv_getaddrinfo_t", - ::uv_ll::rustrt::rust_uv_helper_uv_getaddrinfo_t_size() + super::rustrt::rust_uv_helper_uv_getaddrinfo_t_size() ); } } @@ -1916,7 +1932,7 @@ pub mod test { unsafe { struct_size_check_common::( ~"addrinfo", - ::uv_ll::rustrt::rust_uv_helper_uv_timer_t_size() + super::rustrt::rust_uv_helper_uv_timer_t_size() ); } } diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 365de1ac3e2b9..68dca608a480d 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -53,7 +53,7 @@ pub pure fn is_empty(v: &[const T]) -> bool { /// Returns true if two vectors have the same length pub pure fn same_length(xs: &[const T], ys: &[const U]) -> bool { - len(xs) == len(ys) + xs.len() == ys.len() } /** @@ -136,7 +136,7 @@ pub pure fn from_fn(n_elts: uint, op: iter::InitOp) -> ~[T] { } } raw::set_len(&mut v, n_elts); - return v; + v } } @@ -158,7 +158,7 @@ pub pure fn from_slice(t: &[T]) -> ~[T] { pub pure fn with_capacity(capacity: uint) -> ~[T] { let mut vec = ~[]; unsafe { reserve(&mut vec, capacity); } - return vec; + vec } /** @@ -175,7 +175,7 @@ pub pure fn with_capacity(capacity: uint) -> ~[T] { */ #[inline(always)] pub pure fn build_sized(size: uint, - builder: fn(push: pure fn(v: A))) -> ~[A] { + builder: &fn(push: &pure fn(v: A))) -> ~[A] { let mut vec = with_capacity(size); builder(|x| unsafe { vec.push(x) }); vec @@ -192,7 +192,7 @@ pub pure fn build_sized(size: uint, * onto the vector being constructed. */ #[inline(always)] -pub pure fn build(builder: fn(push: pure fn(v: A))) -> ~[A] { +pub pure fn build(builder: &fn(push: &pure fn(v: A))) -> ~[A] { build_sized(4, builder) } @@ -210,7 +210,7 @@ pub pure fn build(builder: fn(push: pure fn(v: A))) -> ~[A] { */ #[inline(always)] pub pure fn build_sized_opt(size: Option, - builder: fn(push: pure fn(v: A))) -> ~[A] { + builder: &fn(push: &pure fn(v: A))) -> ~[A] { build_sized(size.get_or_default(4), builder) } @@ -257,8 +257,8 @@ pub pure fn last_opt(v: &r/[T]) -> Option<&r/T> { /// Return a slice that points into another slice. #[inline(always)] pub pure fn slice(v: &r/[T], start: uint, end: uint) -> &r/[T] { - fail_unless!((start <= end)); - fail_unless!((end <= len(v))); + fail_unless!(start <= end); + fail_unless!(end <= len(v)); do as_imm_buf(v) |p, _len| { unsafe { ::cast::reinterpret_cast( @@ -274,8 +274,8 @@ pub pure fn mut_slice(v: &r/mut [T], start: uint, end: uint) -> &r/mut [T] { - fail_unless!((start <= end)); - fail_unless!((end <= len(v))); + fail_unless!(start <= end); + fail_unless!(end <= v.len()); do as_mut_buf(v) |p, _len| { unsafe { ::cast::reinterpret_cast( @@ -291,8 +291,8 @@ pub pure fn const_slice(v: &r/[const T], start: uint, end: uint) -> &r/[const T] { - fail_unless!((start <= end)); - fail_unless!((end <= len(v))); + fail_unless!(start <= end); + fail_unless!(end <= len(v)); do as_const_buf(v) |p, _len| { unsafe { ::cast::reinterpret_cast( @@ -305,7 +305,7 @@ pub pure fn const_slice(v: &r/[const T], /// Copies /// Split the vector `v` by applying each element against the predicate `f`. -pub fn split(v: &[T], f: fn(t: &T) -> bool) -> ~[~[T]] { +pub fn split(v: &[T], f: &fn(t: &T) -> bool) -> ~[~[T]] { let ln = len(v); if (ln == 0u) { return ~[] } @@ -328,7 +328,7 @@ pub fn split(v: &[T], f: fn(t: &T) -> bool) -> ~[~[T]] { * Split the vector `v` by applying each element against the predicate `f` up * to `n` times. */ -pub fn splitn(v: &[T], n: uint, f: fn(t: &T) -> bool) -> ~[~[T]] { +pub fn splitn(v: &[T], n: uint, f: &fn(t: &T) -> bool) -> ~[~[T]] { let ln = len(v); if (ln == 0u) { return ~[] } @@ -354,7 +354,7 @@ pub fn splitn(v: &[T], n: uint, f: fn(t: &T) -> bool) -> ~[~[T]] { * Reverse split the vector `v` by applying each element against the predicate * `f`. */ -pub fn rsplit(v: &[T], f: fn(t: &T) -> bool) -> ~[~[T]] { +pub fn rsplit(v: &[T], f: &fn(t: &T) -> bool) -> ~[~[T]] { let ln = len(v); if (ln == 0) { return ~[] } @@ -371,14 +371,14 @@ pub fn rsplit(v: &[T], f: fn(t: &T) -> bool) -> ~[~[T]] { } result.push(slice(v, 0u, end).to_vec()); reverse(result); - return result; + result } /** * Reverse split the vector `v` by applying each element against the predicate * `f` up to `n times. */ -pub fn rsplitn(v: &[T], n: uint, f: fn(t: &T) -> bool) -> ~[~[T]] { +pub fn rsplitn(v: &[T], n: uint, f: &fn(t: &T) -> bool) -> ~[~[T]] { let ln = len(v); if (ln == 0u) { return ~[] } @@ -405,7 +405,7 @@ pub fn rsplitn(v: &[T], n: uint, f: fn(t: &T) -> bool) -> ~[~[T]] { * Partitions a vector into two new vectors: those that satisfies the * predicate, and those that do not. */ -pub fn partition(v: ~[T], f: fn(&T) -> bool) -> (~[T], ~[T]) { +pub fn partition(v: ~[T], f: &fn(&T) -> bool) -> (~[T], ~[T]) { let mut lefts = ~[]; let mut rights = ~[]; @@ -426,7 +426,7 @@ pub fn partition(v: ~[T], f: fn(&T) -> bool) -> (~[T], ~[T]) { * Partitions a vector into two new vectors: those that satisfies the * predicate, and those that do not. */ -pub pure fn partitioned(v: &[T], f: fn(&T) -> bool) -> (~[T], ~[T]) { +pub pure fn partitioned(v: &[T], f: &fn(&T) -> bool) -> (~[T], ~[T]) { let mut lefts = ~[]; let mut rights = ~[]; @@ -496,7 +496,7 @@ pub fn shift(v: &mut ~[T]) -> T { let vp = ptr::mut_offset(vp, next_ln - 1); *vp <-> work_elt; - return work_elt; + work_elt } } @@ -535,7 +535,7 @@ pub fn remove(v: &mut ~[T], i: uint) -> T { v.pop() } -pub fn consume(mut v: ~[T], f: fn(uint, v: T)) { +pub fn consume(mut v: ~[T], f: &fn(uint, v: T)) { unsafe { do as_mut_buf(v) |p, ln| { for uint::range(0, ln) |i| { @@ -584,7 +584,7 @@ pub fn swap_remove(v: &mut ~[T], index: uint) -> T { if index < ln - 1 { v[index] <-> v[ln - 1]; } - vec::pop(v) + v.pop() } /// Append an element to a vector @@ -650,7 +650,7 @@ pub fn push_all_move(v: &mut ~[T], mut rhs: ~[T]) { /// Shorten a vector, dropping excess elements. pub fn truncate(v: &mut ~[T], newlen: uint) { do as_mut_buf(*v) |p, oldlen| { - fail_unless!((newlen <= oldlen)); + fail_unless!(newlen <= oldlen); unsafe { // This loop is optimized out for non-drop types. for uint::range(newlen, oldlen) |i| { @@ -780,7 +780,7 @@ pub fn grow_set(v: &mut ~[T], index: uint, initval: &T, val: T) { // Functional utilities /// Apply a function to each element of a vector and return the results -pub pure fn map(v: &[T], f: fn(t: &T) -> U) -> ~[U] { +pub pure fn map(v: &[T], f: &fn(t: &T) -> U) -> ~[U] { let mut result = with_capacity(len(v)); for each(v) |elem| { unsafe { @@ -790,7 +790,7 @@ pub pure fn map(v: &[T], f: fn(t: &T) -> U) -> ~[U] { result } -pub fn map_consume(v: ~[T], f: fn(v: T) -> U) -> ~[U] { +pub fn map_consume(v: ~[T], f: &fn(v: T) -> U) -> ~[U] { let mut result = ~[]; do consume(v) |_i, x| { result.push(f(x)); @@ -799,7 +799,7 @@ pub fn map_consume(v: ~[T], f: fn(v: T) -> U) -> ~[U] { } /// Apply a function to each element of a vector and return the results -pub pure fn mapi(v: &[T], f: fn(uint, t: &T) -> U) -> ~[U] { +pub pure fn mapi(v: &[T], f: &fn(uint, t: &T) -> U) -> ~[U] { let mut i = 0; do map(v) |e| { i += 1; @@ -811,7 +811,7 @@ pub pure fn mapi(v: &[T], f: fn(uint, t: &T) -> U) -> ~[U] { * Apply a function to each element of a vector and return a concatenation * of each result vector */ -pub pure fn flat_map(v: &[T], f: fn(t: &T) -> ~[U]) -> ~[U] { +pub pure fn flat_map(v: &[T], f: &fn(t: &T) -> ~[U]) -> ~[U] { let mut result = ~[]; for each(v) |elem| { unsafe{ result.push_all_move(f(elem)); } } result @@ -819,7 +819,7 @@ pub pure fn flat_map(v: &[T], f: fn(t: &T) -> ~[U]) -> ~[U] { /// Apply a function to each pair of elements and return the results pub pure fn map2(v0: &[T], v1: &[U], - f: fn(t: &T, v: &U) -> V) -> ~[V] { + f: &fn(t: &T, v: &U) -> V) -> ~[V] { let v0_len = len(v0); if v0_len != len(v1) { fail!(); } let mut u: ~[V] = ~[]; @@ -833,7 +833,7 @@ pub pure fn map2(v0: &[T], v1: &[U], pub fn filter_map( v: ~[T], - f: fn(t: T) -> Option) -> ~[U] + f: &fn(t: T) -> Option) -> ~[U] { /*! * @@ -854,7 +854,7 @@ pub fn filter_map( pub pure fn filter_mapped( v: &[T], - f: fn(t: &T) -> Option) -> ~[U] + f: &fn(t: &T) -> Option) -> ~[U] { /*! * @@ -879,7 +879,7 @@ pub pure fn filter_mapped( * Apply function `f` to each element of `v` and return a vector containing * only those elements for which `f` returned true. */ -pub fn filter(v: ~[T], f: fn(t: &T) -> bool) -> ~[T] { +pub fn filter(v: ~[T], f: &fn(t: &T) -> bool) -> ~[T] { let mut result = ~[]; // FIXME (#4355 maybe): using v.consume here crashes // do v.consume |_, elem| { @@ -896,7 +896,7 @@ pub fn filter(v: ~[T], f: fn(t: &T) -> bool) -> ~[T] { * Apply function `f` to each element of `v` and return a vector containing * only those elements for which `f` returned true. */ -pub pure fn filtered(v: &[T], f: fn(t: &T) -> bool) -> ~[T] { +pub pure fn filtered(v: &[T], f: &fn(t: &T) -> bool) -> ~[T] { let mut result = ~[]; for each(v) |elem| { if f(elem) { unsafe { result.push(*elem); } } @@ -907,7 +907,7 @@ pub pure fn filtered(v: &[T], f: fn(t: &T) -> bool) -> ~[T] { /** * Like `filter()`, but in place. Preserves order of `v`. Linear time. */ -pub fn retain(v: &mut ~[T], f: pure fn(t: &T) -> bool) { +pub fn retain(v: &mut ~[T], f: &pure fn(t: &T) -> bool) { let len = v.len(); let mut deleted: uint = 0; @@ -963,7 +963,7 @@ pub pure fn connect(v: &[~[T]], sep: &T) -> ~[T] { * ~~~ * */ -pub pure fn foldl(z: T, v: &[U], p: fn(t: T, u: &U) -> T) -> T { +pub pure fn foldl(z: T, v: &[U], p: &fn(t: T, u: &U) -> T) -> T { let mut accum = z; let mut i = 0; let l = v.len(); @@ -973,7 +973,7 @@ pub pure fn foldl(z: T, v: &[U], p: fn(t: T, u: &U) -> T) -> T { accum = p(accum, &v[i]); i += 1; } - return accum; + accum } /** @@ -995,12 +995,12 @@ pub pure fn foldl(z: T, v: &[U], p: fn(t: T, u: &U) -> T) -> T { * ~~~ * */ -pub pure fn foldr(v: &[T], z: U, p: fn(t: &T, u: U) -> U) -> U { +pub pure fn foldr(v: &[T], z: U, p: &fn(t: &T, u: U) -> U) -> U { let mut accum = z; for rev_each(v) |elt| { accum = p(elt, accum); } - return accum; + accum } /** @@ -1008,9 +1008,9 @@ pub pure fn foldr(v: &[T], z: U, p: fn(t: &T, u: U) -> U) -> U { * * If the vector contains no elements then false is returned. */ -pub pure fn any(v: &[T], f: fn(t: &T) -> bool) -> bool { +pub pure fn any(v: &[T], f: &fn(t: &T) -> bool) -> bool { for each(v) |elem| { if f(elem) { return true; } } - return false; + false } /** @@ -1019,7 +1019,7 @@ pub pure fn any(v: &[T], f: fn(t: &T) -> bool) -> bool { * If the vectors contains no elements then false is returned. */ pub pure fn any2(v0: &[T], v1: &[U], - f: fn(a: &T, b: &U) -> bool) -> bool { + f: &fn(a: &T, b: &U) -> bool) -> bool { let v0_len = len(v0); let v1_len = len(v1); let mut i = 0u; @@ -1027,7 +1027,7 @@ pub pure fn any2(v0: &[T], v1: &[U], if f(&v0[i], &v1[i]) { return true; }; i += 1u; } - return false; + false } /** @@ -1035,9 +1035,9 @@ pub pure fn any2(v0: &[T], v1: &[U], * * If the vector contains no elements then true is returned. */ -pub pure fn all(v: &[T], f: fn(t: &T) -> bool) -> bool { +pub pure fn all(v: &[T], f: &fn(t: &T) -> bool) -> bool { for each(v) |elem| { if !f(elem) { return false; } } - return true; + true } /** @@ -1045,9 +1045,9 @@ pub pure fn all(v: &[T], f: fn(t: &T) -> bool) -> bool { * * If the vector contains no elements then true is returned. */ -pub pure fn alli(v: &[T], f: fn(uint, t: &T) -> bool) -> bool { +pub pure fn alli(v: &[T], f: &fn(uint, t: &T) -> bool) -> bool { for eachi(v) |i, elem| { if !f(i, elem) { return false; } } - return true; + true } /** @@ -1056,25 +1056,25 @@ pub pure fn alli(v: &[T], f: fn(uint, t: &T) -> bool) -> bool { * If the vectors are not the same size then false is returned. */ pub pure fn all2(v0: &[T], v1: &[U], - f: fn(t: &T, u: &U) -> bool) -> bool { + f: &fn(t: &T, u: &U) -> bool) -> bool { let v0_len = len(v0); if v0_len != len(v1) { return false; } let mut i = 0u; while i < v0_len { if !f(&v0[i], &v1[i]) { return false; }; i += 1u; } - return true; + true } /// Return true if a vector contains an element with the given value pub pure fn contains(v: &[T], x: &T) -> bool { for each(v) |elt| { if *x == *elt { return true; } } - return false; + false } /// Returns the number of elements that are equal to a given value pub pure fn count(v: &[T], x: &T) -> uint { let mut cnt = 0u; for each(v) |elt| { if *x == *elt { cnt += 1u; } } - return cnt; + cnt } /** @@ -1084,7 +1084,7 @@ pub pure fn count(v: &[T], x: &T) -> uint { * When function `f` returns true then an option containing the element * is returned. If `f` matches no elements then none is returned. */ -pub pure fn find(v: &[T], f: fn(t: &T) -> bool) -> Option { +pub pure fn find(v: &[T], f: &fn(t: &T) -> bool) -> Option { find_between(v, 0u, len(v), f) } @@ -1096,7 +1096,7 @@ pub pure fn find(v: &[T], f: fn(t: &T) -> bool) -> Option { * the element is returned. If `f` matches no elements then none is returned. */ pub pure fn find_between(v: &[T], start: uint, end: uint, - f: fn(t: &T) -> bool) -> Option { + f: &fn(t: &T) -> bool) -> Option { position_between(v, start, end, f).map(|i| v[*i]) } @@ -1107,7 +1107,7 @@ pub pure fn find_between(v: &[T], start: uint, end: uint, * `f` returns true then an option containing the element is returned. If `f` * matches no elements then none is returned. */ -pub pure fn rfind(v: &[T], f: fn(t: &T) -> bool) -> Option { +pub pure fn rfind(v: &[T], f: &fn(t: &T) -> bool) -> Option { rfind_between(v, 0u, len(v), f) } @@ -1119,7 +1119,7 @@ pub pure fn rfind(v: &[T], f: fn(t: &T) -> bool) -> Option { * the element is returned. If `f` matches no elements then none is return. */ pub pure fn rfind_between(v: &[T], start: uint, end: uint, - f: fn(t: &T) -> bool) -> Option { + f: &fn(t: &T) -> bool) -> Option { rposition_between(v, start, end, f).map(|i| v[*i]) } @@ -1135,7 +1135,7 @@ pub pure fn position_elem(v: &[T], x: &T) -> Option { * then an option containing the index is returned. If `f` matches no elements * then none is returned. */ -pub pure fn position(v: &[T], f: fn(t: &T) -> bool) -> Option { +pub pure fn position(v: &[T], f: &fn(t: &T) -> bool) -> Option { position_between(v, 0u, len(v), f) } @@ -1147,12 +1147,12 @@ pub pure fn position(v: &[T], f: fn(t: &T) -> bool) -> Option { * the index is returned. If `f` matches no elements then none is returned. */ pub pure fn position_between(v: &[T], start: uint, end: uint, - f: fn(t: &T) -> bool) -> Option { + f: &fn(t: &T) -> bool) -> Option { fail_unless!(start <= end); fail_unless!(end <= len(v)); let mut i = start; while i < end { if f(&v[i]) { return Some::(i); } i += 1u; } - return None; + None } /// Find the last index containing a matching value @@ -1167,7 +1167,7 @@ pure fn rposition_elem(v: &[T], x: &T) -> Option { * `f` returns true then an option containing the index is returned. If `f` * matches no elements then none is returned. */ -pub pure fn rposition(v: &[T], f: fn(t: &T) -> bool) -> Option { +pub pure fn rposition(v: &[T], f: &fn(t: &T) -> bool) -> Option { rposition_between(v, 0u, len(v), f) } @@ -1180,7 +1180,7 @@ pub pure fn rposition(v: &[T], f: fn(t: &T) -> bool) -> Option { * returned. */ pub pure fn rposition_between(v: &[T], start: uint, end: uint, - f: fn(t: &T) -> bool) -> Option { + f: &fn(t: &T) -> bool) -> Option { fail_unless!(start <= end); fail_unless!(end <= len(v)); let mut i = end; @@ -1188,7 +1188,7 @@ pub pure fn rposition_between(v: &[T], start: uint, end: uint, if f(&v[i - 1u]) { return Some::(i - 1u); } i -= 1u; } - return None; + None } // FIXME: if issue #586 gets implemented, could have a postcondition @@ -1207,7 +1207,7 @@ pure fn unzip_slice(v: &[(T, U)]) -> (~[T], ~[U]) { us.push(u); } } - return (ts, us); + (ts, us) } /** @@ -1334,7 +1334,7 @@ pub pure fn reversed(v: &[const T]) -> ~[T] { * ~~~ */ #[inline(always)] -pub pure fn each(v: &r/[T], f: fn(&r/T) -> bool) { +pub pure fn each(v: &r/[T], f: &fn(&r/T) -> bool) { // ^^^^ // NB---this CANNOT be &[const T]! The reason // is that you are passing it to `f()` using @@ -1358,7 +1358,7 @@ pub pure fn each(v: &r/[T], f: fn(&r/T) -> bool) { /// a vector with mutable contents and you would like /// to mutate the contents as you iterate. #[inline(always)] -pub fn each_mut(v: &mut [T], f: fn(elem: &mut T) -> bool) { +pub fn each_mut(v: &mut [T], f: &fn(elem: &mut T) -> bool) { let mut i = 0; let n = v.len(); while i < n { @@ -1372,7 +1372,7 @@ pub fn each_mut(v: &mut [T], f: fn(elem: &mut T) -> bool) { /// Like `each()`, but for the case where you have a vector that *may or may /// not* have mutable contents. #[inline(always)] -pub pure fn each_const(v: &[const T], f: fn(elem: &const T) -> bool) { +pub pure fn each_const(v: &[const T], f: &fn(elem: &const T) -> bool) { let mut i = 0; let n = v.len(); while i < n { @@ -1389,7 +1389,7 @@ pub pure fn each_const(v: &[const T], f: fn(elem: &const T) -> bool) { * Return true to continue, false to break. */ #[inline(always)] -pub pure fn eachi(v: &r/[T], f: fn(uint, v: &r/T) -> bool) { +pub pure fn eachi(v: &r/[T], f: &fn(uint, v: &r/T) -> bool) { let mut i = 0; for each(v) |p| { if !f(i, p) { return; } @@ -1403,7 +1403,7 @@ pub pure fn eachi(v: &r/[T], f: fn(uint, v: &r/T) -> bool) { * Return true to continue, false to break. */ #[inline(always)] -pub pure fn rev_each(v: &r/[T], blk: fn(v: &r/T) -> bool) { +pub pure fn rev_each(v: &r/[T], blk: &fn(v: &r/T) -> bool) { rev_eachi(v, |_i, v| blk(v)) } @@ -1413,7 +1413,7 @@ pub pure fn rev_each(v: &r/[T], blk: fn(v: &r/T) -> bool) { * Return true to continue, false to break. */ #[inline(always)] -pub pure fn rev_eachi(v: &r/[T], blk: fn(i: uint, v: &r/T) -> bool) { +pub pure fn rev_eachi(v: &r/[T], blk: &fn(i: uint, v: &r/T) -> bool) { let mut i = v.len(); while i > 0 { i -= 1; @@ -1431,7 +1431,7 @@ pub pure fn rev_eachi(v: &r/[T], blk: fn(i: uint, v: &r/T) -> bool) { * Both vectors must have the same length */ #[inline] -pub pure fn each2(v1: &[U], v2: &[T], f: fn(u: &U, t: &T) -> bool) { +pub pure fn each2(v1: &[U], v2: &[T], f: &fn(u: &U, t: &T) -> bool) { fail_unless!(len(v1) == len(v2)); for uint::range(0u, len(v1)) |i| { if !f(&v1[i], &v2[i]) { @@ -1450,7 +1450,7 @@ pub pure fn each2(v1: &[U], v2: &[T], f: fn(u: &U, t: &T) -> bool) { * The total number of permutations produced is `len(v)!`. If `v` contains * repeated elements, then some permutations are repeated. */ -pub pure fn each_permutation(v: &[T], put: fn(ts: &[T]) -> bool) { +pub pure fn each_permutation(v: &[T], put: &fn(ts: &[T]) -> bool) { let ln = len(v); if ln <= 1 { put(v); @@ -1478,7 +1478,7 @@ pub pure fn windowed(nn: uint, xx: &[TT]) -> ~[~[TT]] { let mut ww = ~[]; fail_unless!(1u <= nn); for vec::eachi (xx) |ii, _x| { - let len = vec::len(xx); + let len = xx.len(); if ii+nn <= len { unsafe { ww.push(slice(xx, ii, ii+nn).to_vec()); @@ -1497,7 +1497,7 @@ pub pure fn windowed(nn: uint, xx: &[TT]) -> ~[~[TT]] { #[inline(always)] pub pure fn as_imm_buf(s: &[T], /* NB---this CANNOT be const, see below */ - f: fn(*T, uint) -> U) -> U { + f: &fn(*T, uint) -> U) -> U { // NB---Do not change the type of s to `&[const T]`. This is // unsound. The reason is that we are going to create immutable pointers @@ -1516,7 +1516,7 @@ pub pure fn as_imm_buf(s: &[T], /// Similar to `as_imm_buf` but passing a `*const T` #[inline(always)] pub pure fn as_const_buf(s: &[const T], - f: fn(*const T, uint) -> U) -> U { + f: &fn(*const T, uint) -> U) -> U { unsafe { let v : *(*const T,uint) = @@ -1529,7 +1529,7 @@ pub pure fn as_const_buf(s: &[const T], /// Similar to `as_imm_buf` but passing a `*mut T` #[inline(always)] pub pure fn as_mut_buf(s: &mut [T], - f: fn(*mut T, uint) -> U) -> U { + f: &fn(*mut T, uint) -> U) -> U { unsafe { let v : *(*mut T,uint) = @@ -1551,7 +1551,7 @@ pure fn eq(a: &[T], b: &[T]) -> bool { i += 1; } - return true; + true } #[cfg(notest)] @@ -1631,7 +1631,7 @@ pure fn lt(a: &[T], b: &[T]) -> bool { i += 1; } - return a_len < b_len; + a_len < b_len } pure fn le(a: &[T], b: &[T]) -> bool { !lt(b, a) } @@ -1721,13 +1721,13 @@ pub trait ImmutableVector { pure fn initn(&self, n: uint) -> &self/[T]; pure fn last(&self) -> &self/T; pure fn last_opt(&self) -> Option<&self/T>; - pure fn foldr(&self, z: U, p: fn(t: &T, u: U) -> U) -> U; - pure fn map(&self, f: fn(t: &T) -> U) -> ~[U]; - pure fn mapi(&self, f: fn(uint, t: &T) -> U) -> ~[U]; - fn map_r(&self, f: fn(x: &T) -> U) -> ~[U]; - pure fn alli(&self, f: fn(uint, t: &T) -> bool) -> bool; - pure fn flat_map(&self, f: fn(t: &T) -> ~[U]) -> ~[U]; - pure fn filter_mapped(&self, f: fn(t: &T) -> Option) -> ~[U]; + pure fn foldr(&self, z: U, p: &fn(t: &T, u: U) -> U) -> U; + pure fn map(&self, f: &fn(t: &T) -> U) -> ~[U]; + pure fn mapi(&self, f: &fn(uint, t: &T) -> U) -> ~[U]; + fn map_r(&self, f: &fn(x: &T) -> U) -> ~[U]; + pure fn alli(&self, f: &fn(uint, t: &T) -> bool) -> bool; + pure fn flat_map(&self, f: &fn(t: &T) -> ~[U]) -> ~[U]; + pure fn filter_mapped(&self, f: &fn(t: &T) -> Option) -> ~[U]; } /// Extension methods for vectors @@ -1772,24 +1772,24 @@ impl ImmutableVector for &self/[T] { /// Reduce a vector from right to left #[inline] - pure fn foldr(&self, z: U, p: fn(t: &T, u: U) -> U) -> U { + pure fn foldr(&self, z: U, p: &fn(t: &T, u: U) -> U) -> U { foldr(*self, z, p) } /// Apply a function to each element of a vector and return the results #[inline] - pure fn map(&self, f: fn(t: &T) -> U) -> ~[U] { map(*self, f) } + pure fn map(&self, f: &fn(t: &T) -> U) -> ~[U] { map(*self, f) } /** * Apply a function to the index and value of each element in the vector * and return the results */ - pure fn mapi(&self, f: fn(uint, t: &T) -> U) -> ~[U] { + pure fn mapi(&self, f: &fn(uint, t: &T) -> U) -> ~[U] { mapi(*self, f) } #[inline] - fn map_r(&self, f: fn(x: &T) -> U) -> ~[U] { + fn map_r(&self, f: &fn(x: &T) -> U) -> ~[U] { let mut r = ~[]; let mut i = 0; while i < self.len() { @@ -1804,7 +1804,7 @@ impl ImmutableVector for &self/[T] { * * If the vector is empty, true is returned. */ - pure fn alli(&self, f: fn(uint, t: &T) -> bool) -> bool { + pure fn alli(&self, f: &fn(uint, t: &T) -> bool) -> bool { alli(*self, f) } /** @@ -1812,7 +1812,7 @@ impl ImmutableVector for &self/[T] { * of each result vector */ #[inline] - pure fn flat_map(&self, f: fn(t: &T) -> ~[U]) -> ~[U] { + pure fn flat_map(&self, f: &fn(t: &T) -> ~[U]) -> ~[U] { flat_map(*self, f) } /** @@ -1822,15 +1822,15 @@ impl ImmutableVector for &self/[T] { * the resulting vector. */ #[inline] - pure fn filter_mapped(&self, f: fn(t: &T) -> Option) -> ~[U] { + pure fn filter_mapped(&self, f: &fn(t: &T) -> Option) -> ~[U] { filter_mapped(*self, f) } } pub trait ImmutableEqVector { - pure fn position(&self, f: fn(t: &T) -> bool) -> Option; + pure fn position(&self, f: &fn(t: &T) -> bool) -> Option; pure fn position_elem(&self, t: &T) -> Option; - pure fn rposition(&self, f: fn(t: &T) -> bool) -> Option; + pure fn rposition(&self, f: &fn(t: &T) -> bool) -> Option; pure fn rposition_elem(&self, t: &T) -> Option; } @@ -1843,7 +1843,7 @@ impl ImmutableEqVector for &self/[T] { * elements then none is returned. */ #[inline] - pure fn position(&self, f: fn(t: &T) -> bool) -> Option { + pure fn position(&self, f: &fn(t: &T) -> bool) -> Option { position(*self, f) } @@ -1861,7 +1861,7 @@ impl ImmutableEqVector for &self/[T] { * returned. If `f` matches no elements then none is returned. */ #[inline] - pure fn rposition(&self, f: fn(t: &T) -> bool) -> Option { + pure fn rposition(&self, f: &fn(t: &T) -> bool) -> Option { rposition(*self, f) } @@ -1873,9 +1873,9 @@ impl ImmutableEqVector for &self/[T] { } pub trait ImmutableCopyableVector { - pure fn filtered(&self, f: fn(&T) -> bool) -> ~[T]; - pure fn rfind(&self, f: fn(t: &T) -> bool) -> Option; - pure fn partitioned(&self, f: fn(&T) -> bool) -> (~[T], ~[T]); + pure fn filtered(&self, f: &fn(&T) -> bool) -> ~[T]; + pure fn rfind(&self, f: &fn(t: &T) -> bool) -> Option; + pure fn partitioned(&self, f: &fn(&T) -> bool) -> (~[T], ~[T]); } /// Extension methods for vectors @@ -1888,7 +1888,7 @@ impl ImmutableCopyableVector for &self/[T] { * containing only those elements for which `f` returned true. */ #[inline] - pure fn filtered(&self, f: fn(t: &T) -> bool) -> ~[T] { + pure fn filtered(&self, f: &fn(t: &T) -> bool) -> ~[T] { filtered(*self, f) } @@ -1900,7 +1900,7 @@ impl ImmutableCopyableVector for &self/[T] { * returned. If `f` matches no elements then none is returned. */ #[inline] - pure fn rfind(&self, f: fn(t: &T) -> bool) -> Option { + pure fn rfind(&self, f: &fn(t: &T) -> bool) -> Option { rfind(*self, f) } @@ -1909,7 +1909,7 @@ impl ImmutableCopyableVector for &self/[T] { * those that do not. */ #[inline] - pure fn partitioned(&self, f: fn(&T) -> bool) -> (~[T], ~[T]) { + pure fn partitioned(&self, f: &fn(&T) -> bool) -> (~[T], ~[T]) { partitioned(*self, f) } } @@ -1924,10 +1924,10 @@ pub trait OwnedVector { fn remove(&mut self, i: uint) -> T; fn swap_remove(&mut self, index: uint) -> T; fn truncate(&mut self, newlen: uint); - fn retain(&mut self, f: pure fn(t: &T) -> bool); - fn consume(self, f: fn(uint, v: T)); - fn filter(self, f: fn(t: &T) -> bool) -> ~[T]; - fn partition(self, f: pure fn(&T) -> bool) -> (~[T], ~[T]); + fn retain(&mut self, f: &pure fn(t: &T) -> bool); + fn consume(self, f: &fn(uint, v: T)); + fn filter(self, f: &fn(t: &T) -> bool) -> ~[T]; + fn partition(self, f: &pure fn(&T) -> bool) -> (~[T], ~[T]); fn grow_fn(&mut self, n: uint, op: iter::InitOp); } @@ -1978,17 +1978,17 @@ impl OwnedVector for ~[T] { } #[inline] - fn retain(&mut self, f: pure fn(t: &T) -> bool) { + fn retain(&mut self, f: &pure fn(t: &T) -> bool) { retain(self, f); } #[inline] - fn consume(self, f: fn(uint, v: T)) { + fn consume(self, f: &fn(uint, v: T)) { consume(self, f) } #[inline] - fn filter(self, f: fn(&T) -> bool) -> ~[T] { + fn filter(self, f: &fn(&T) -> bool) -> ~[T] { filter(self, f) } @@ -1997,7 +1997,7 @@ impl OwnedVector for ~[T] { * those that do not. */ #[inline] - fn partition(self, f: fn(&T) -> bool) -> (~[T], ~[T]) { + fn partition(self, f: &fn(&T) -> bool) -> (~[T], ~[T]) { partition(self, f) } @@ -2114,21 +2114,21 @@ pub mod raw { #[inline(always)] pub unsafe fn to_ptr(v: &[T]) -> *T { let repr: **SliceRepr = ::cast::transmute(&v); - return ::cast::reinterpret_cast(&addr_of(&((**repr).data))); + ::cast::reinterpret_cast(&addr_of(&((**repr).data))) } /** see `to_ptr()` */ #[inline(always)] pub unsafe fn to_const_ptr(v: &[const T]) -> *const T { let repr: **SliceRepr = ::cast::transmute(&v); - return ::cast::reinterpret_cast(&addr_of(&((**repr).data))); + ::cast::reinterpret_cast(&addr_of(&((**repr).data))) } /** see `to_ptr()` */ #[inline(always)] pub unsafe fn to_mut_ptr(v: &mut [T]) -> *mut T { let repr: **SliceRepr = ::cast::transmute(&v); - return ::cast::reinterpret_cast(&addr_of(&((**repr).data))); + ::cast::reinterpret_cast(&addr_of(&((**repr).data))) } /** @@ -2138,13 +2138,27 @@ pub mod raw { #[inline(always)] pub unsafe fn buf_as_slice(p: *T, len: uint, - f: fn(v: &[T]) -> U) -> U { + f: &fn(v: &[T]) -> U) -> U { let pair = (p, len * sys::nonzero_size_of::()); let v : *(&blk/[T]) = ::cast::reinterpret_cast(&addr_of(&pair)); f(*v) } + /** + * Form a slice from a pointer and length (as a number of units, + * not bytes). + */ + #[inline(always)] + pub unsafe fn mut_buf_as_slice(p: *mut T, + len: uint, + f: &fn(v: &mut [T]) -> U) -> U { + let pair = (p, len * sys::nonzero_size_of::()); + let v : *(&blk/mut [T]) = + ::cast::reinterpret_cast(&addr_of(&pair)); + f(*v) + } + /** * Unchecked vector indexing. */ @@ -2165,7 +2179,7 @@ pub mod raw { let mut box2 = None; box2 <-> box; intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i)), - option::unwrap(box2)); + box2.unwrap()); } } @@ -2210,14 +2224,13 @@ pub mod raw { pub mod bytes { use libc; use uint; - use vec::len; use vec::raw; use vec; /// Bytewise string comparison pub pure fn memcmp(a: &~[u8], b: &~[u8]) -> int { - let a_len = len(*a); - let b_len = len(*b); + let a_len = a.len(); + let b_len = b.len(); let n = uint::min(a_len, b_len) as libc::size_t; let r = unsafe { libc::memcmp(raw::to_ptr(*a) as *libc::c_void, @@ -2268,68 +2281,52 @@ pub mod bytes { // ___________________________________________________________________________ // ITERATION TRAIT METHODS -// -// This cannot be used with iter-trait.rs because of the region pointer -// required in the slice. impl iter::BaseIter for &self/[A] { - pub pure fn each(&self, blk: fn(v: &A) -> bool) { - // FIXME(#2263)---should be able to call each(self, blk) - for each(*self) |e| { - if (!blk(e)) { - return; - } - } + #[inline(always)] + pub pure fn each(&self, blk: &fn(v: &'self A) -> bool) { + each(*self, blk) } - pure fn size_hint(&self) -> Option { Some(len(*self)) } + #[inline(always)] + pure fn size_hint(&self) -> Option { Some(self.len()) } } // FIXME(#4148): This should be redundant impl iter::BaseIter for ~[A] { - pub pure fn each(&self, blk: fn(v: &A) -> bool) { - // FIXME(#2263)---should be able to call each(self, blk) - for each(*self) |e| { - if (!blk(e)) { - return; - } - } - } - pure fn size_hint(&self) -> Option { Some(len(*self)) } + #[inline(always)] + pure fn each(&self, blk: &fn(v: &'self A) -> bool) { each(*self, blk) } + #[inline(always)] + pure fn size_hint(&self) -> Option { Some(self.len()) } } // FIXME(#4148): This should be redundant impl iter::BaseIter for @[A] { - pub pure fn each(&self, blk: fn(v: &A) -> bool) { - // FIXME(#2263)---should be able to call each(self, blk) - for each(*self) |e| { - if (!blk(e)) { - return; - } - } - } - pure fn size_hint(&self) -> Option { Some(len(*self)) } + #[inline(always)] + pure fn each(&self, blk: &fn(v: &'self A) -> bool) { each(*self, blk) } + #[inline(always)] + pure fn size_hint(&self) -> Option { Some(self.len()) } } impl iter::ExtendedIter for &self/[A] { - pub pure fn eachi(&self, blk: fn(uint, v: &A) -> bool) { + pub pure fn eachi(&self, blk: &fn(uint, v: &A) -> bool) { iter::eachi(self, blk) } - pub pure fn all(&self, blk: fn(&A) -> bool) -> bool { + pub pure fn all(&self, blk: &fn(&A) -> bool) -> bool { iter::all(self, blk) } - pub pure fn any(&self, blk: fn(&A) -> bool) -> bool { + pub pure fn any(&self, blk: &fn(&A) -> bool) -> bool { iter::any(self, blk) } - pub pure fn foldl(&self, b0: B, blk: fn(&B, &A) -> B) -> B { + pub pure fn foldl(&self, b0: B, blk: &fn(&B, &A) -> B) -> B { iter::foldl(self, b0, blk) } - pub pure fn position(&self, f: fn(&A) -> bool) -> Option { + pub pure fn position(&self, f: &fn(&A) -> bool) -> Option { iter::position(self, f) } - pure fn map_to_vec(&self, op: fn(&A) -> B) -> ~[B] { + pure fn map_to_vec(&self, op: &fn(&A) -> B) -> ~[B] { iter::map_to_vec(self, op) } - pure fn flat_map_to_vec>(&self, op: fn(&A) -> IB) + pure fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) -> ~[B] { iter::flat_map_to_vec(self, op) } @@ -2337,25 +2334,25 @@ impl iter::ExtendedIter for &self/[A] { // FIXME(#4148): This should be redundant impl iter::ExtendedIter for ~[A] { - pub pure fn eachi(&self, blk: fn(uint, v: &A) -> bool) { + pub pure fn eachi(&self, blk: &fn(uint, v: &A) -> bool) { iter::eachi(self, blk) } - pub pure fn all(&self, blk: fn(&A) -> bool) -> bool { + pub pure fn all(&self, blk: &fn(&A) -> bool) -> bool { iter::all(self, blk) } - pub pure fn any(&self, blk: fn(&A) -> bool) -> bool { + pub pure fn any(&self, blk: &fn(&A) -> bool) -> bool { iter::any(self, blk) } - pub pure fn foldl(&self, b0: B, blk: fn(&B, &A) -> B) -> B { + pub pure fn foldl(&self, b0: B, blk: &fn(&B, &A) -> B) -> B { iter::foldl(self, b0, blk) } - pub pure fn position(&self, f: fn(&A) -> bool) -> Option { + pub pure fn position(&self, f: &fn(&A) -> bool) -> Option { iter::position(self, f) } - pure fn map_to_vec(&self, op: fn(&A) -> B) -> ~[B] { + pure fn map_to_vec(&self, op: &fn(&A) -> B) -> ~[B] { iter::map_to_vec(self, op) } - pure fn flat_map_to_vec>(&self, op: fn(&A) -> IB) + pure fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) -> ~[B] { iter::flat_map_to_vec(self, op) } @@ -2363,25 +2360,25 @@ impl iter::ExtendedIter for ~[A] { // FIXME(#4148): This should be redundant impl iter::ExtendedIter for @[A] { - pub pure fn eachi(&self, blk: fn(uint, v: &A) -> bool) { + pub pure fn eachi(&self, blk: &fn(uint, v: &A) -> bool) { iter::eachi(self, blk) } - pub pure fn all(&self, blk: fn(&A) -> bool) -> bool { + pub pure fn all(&self, blk: &fn(&A) -> bool) -> bool { iter::all(self, blk) } - pub pure fn any(&self, blk: fn(&A) -> bool) -> bool { + pub pure fn any(&self, blk: &fn(&A) -> bool) -> bool { iter::any(self, blk) } - pub pure fn foldl(&self, b0: B, blk: fn(&B, &A) -> B) -> B { + pub pure fn foldl(&self, b0: B, blk: &fn(&B, &A) -> B) -> B { iter::foldl(self, b0, blk) } - pub pure fn position(&self, f: fn(&A) -> bool) -> Option { + pub pure fn position(&self, f: &fn(&A) -> bool) -> Option { iter::position(self, f) } - pure fn map_to_vec(&self, op: fn(&A) -> B) -> ~[B] { + pure fn map_to_vec(&self, op: &fn(&A) -> B) -> ~[B] { iter::map_to_vec(self, op) } - pure fn flat_map_to_vec>(&self, op: fn(&A) -> IB) + pure fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) -> ~[B] { iter::flat_map_to_vec(self, op) } @@ -2405,33 +2402,33 @@ impl iter::EqIter for @[A] { } impl iter::CopyableIter for &self/[A] { - pure fn filter_to_vec(&self, pred: fn(&A) -> bool) -> ~[A] { + pure fn filter_to_vec(&self, pred: &fn(&A) -> bool) -> ~[A] { iter::filter_to_vec(self, pred) } pure fn to_vec(&self) -> ~[A] { iter::to_vec(self) } - pub pure fn find(&self, f: fn(&A) -> bool) -> Option { + pub pure fn find(&self, f: &fn(&A) -> bool) -> Option { iter::find(self, f) } } // FIXME(#4148): This should be redundant impl iter::CopyableIter for ~[A] { - pure fn filter_to_vec(&self, pred: fn(&A) -> bool) -> ~[A] { + pure fn filter_to_vec(&self, pred: &fn(&A) -> bool) -> ~[A] { iter::filter_to_vec(self, pred) } pure fn to_vec(&self) -> ~[A] { iter::to_vec(self) } - pub pure fn find(&self, f: fn(&A) -> bool) -> Option { + pub pure fn find(&self, f: &fn(&A) -> bool) -> Option { iter::find(self, f) } } // FIXME(#4148): This should be redundant impl iter::CopyableIter for @[A] { - pure fn filter_to_vec(&self, pred: fn(&A) -> bool) -> ~[A] { + pure fn filter_to_vec(&self, pred: &fn(&A) -> bool) -> ~[A] { iter::filter_to_vec(self, pred) } pure fn to_vec(&self) -> ~[A] { iter::to_vec(self) } - pub pure fn find(&self, f: fn(&A) -> bool) -> Option { + pub pure fn find(&self, f: &fn(&A) -> bool) -> Option { iter::find(self, f) } } @@ -2454,7 +2451,7 @@ impl iter::CopyableOrderedIter for @[A] { } impl iter::CopyableNonstrictIter for &self/[A] { - pure fn each_val(&const self, f: fn(A) -> bool) { + pure fn each_val(&const self, f: &fn(A) -> bool) { let mut i = 0; while i < self.len() { if !f(copy self[i]) { break; } @@ -2465,7 +2462,7 @@ impl iter::CopyableNonstrictIter for &self/[A] { // FIXME(#4148): This should be redundant impl iter::CopyableNonstrictIter for ~[A] { - pure fn each_val(&const self, f: fn(A) -> bool) { + pure fn each_val(&const self, f: &fn(A) -> bool) { let mut i = 0; while i < self.len() { if !f(copy self[i]) { break; } @@ -2476,7 +2473,7 @@ impl iter::CopyableNonstrictIter for ~[A] { // FIXME(#4148): This should be redundant impl iter::CopyableNonstrictIter for @[A] { - pure fn each_val(&const self, f: fn(A) -> bool) { + pure fn each_val(&const self, f: &fn(A) -> bool) { let mut i = 0; while i < self.len() { if !f(copy self[i]) { break; } @@ -2495,25 +2492,25 @@ mod tests { use vec::*; use cmp::*; - fn square(n: uint) -> uint { return n * n; } + fn square(n: uint) -> uint { n * n } - fn square_ref(n: &uint) -> uint { return square(*n); } + fn square_ref(n: &uint) -> uint { square(*n) } - pure fn is_three(n: &uint) -> bool { return *n == 3u; } + pure fn is_three(n: &uint) -> bool { *n == 3u } - pure fn is_odd(n: &uint) -> bool { return *n % 2u == 1u; } + pure fn is_odd(n: &uint) -> bool { *n % 2u == 1u } - pure fn is_equal(x: &uint, y:&uint) -> bool { return *x == *y; } + pure fn is_equal(x: &uint, y:&uint) -> bool { *x == *y } fn square_if_odd_r(n: &uint) -> Option { - return if *n % 2u == 1u { Some(*n * *n) } else { None }; + if *n % 2u == 1u { Some(*n * *n) } else { None } } fn square_if_odd_v(n: uint) -> Option { - return if n % 2u == 1u { Some(n * n) } else { None }; + if n % 2u == 1u { Some(n * n) } else { None } } - fn add(x: uint, y: &uint) -> uint { return x + *y; } + fn add(x: uint, y: &uint) -> uint { x + *y } #[test] fn test_unsafe_ptrs() { @@ -2522,21 +2519,21 @@ mod tests { let a = ~[1, 2, 3]; let mut ptr = raw::to_ptr(a); let b = from_buf(ptr, 3u); - fail_unless!((len(b) == 3u)); - fail_unless!((b[0] == 1)); - fail_unless!((b[1] == 2)); - fail_unless!((b[2] == 3)); + fail_unless!(b.len() == 3u); + fail_unless!(b[0] == 1); + fail_unless!(b[1] == 2); + fail_unless!(b[2] == 3); // Test on-heap copy-from-buf. let c = ~[1, 2, 3, 4, 5]; ptr = raw::to_ptr(c); let d = from_buf(ptr, 5u); - fail_unless!((len(d) == 5u)); - fail_unless!((d[0] == 1)); - fail_unless!((d[1] == 2)); - fail_unless!((d[2] == 3)); - fail_unless!((d[3] == 4)); - fail_unless!((d[4] == 5)); + fail_unless!(d.len() == 5u); + fail_unless!(d[0] == 1); + fail_unless!(d[1] == 2); + fail_unless!(d[2] == 3); + fail_unless!(d[3] == 4); + fail_unless!(d[4] == 5); } } @@ -2544,43 +2541,43 @@ mod tests { fn test_from_fn() { // Test on-stack from_fn. let mut v = from_fn(3u, square); - fail_unless!((len(v) == 3u)); - fail_unless!((v[0] == 0u)); - fail_unless!((v[1] == 1u)); - fail_unless!((v[2] == 4u)); + fail_unless!(v.len() == 3u); + fail_unless!(v[0] == 0u); + fail_unless!(v[1] == 1u); + fail_unless!(v[2] == 4u); // Test on-heap from_fn. v = from_fn(5u, square); - fail_unless!((len(v) == 5u)); - fail_unless!((v[0] == 0u)); - fail_unless!((v[1] == 1u)); - fail_unless!((v[2] == 4u)); - fail_unless!((v[3] == 9u)); - fail_unless!((v[4] == 16u)); + fail_unless!(v.len() == 5u); + fail_unless!(v[0] == 0u); + fail_unless!(v[1] == 1u); + fail_unless!(v[2] == 4u); + fail_unless!(v[3] == 9u); + fail_unless!(v[4] == 16u); } #[test] fn test_from_elem() { // Test on-stack from_elem. let mut v = from_elem(2u, 10u); - fail_unless!((len(v) == 2u)); - fail_unless!((v[0] == 10u)); - fail_unless!((v[1] == 10u)); + fail_unless!(v.len() == 2u); + fail_unless!(v[0] == 10u); + fail_unless!(v[1] == 10u); // Test on-heap from_elem. v = from_elem(6u, 20u); - fail_unless!((v[0] == 20u)); - fail_unless!((v[1] == 20u)); - fail_unless!((v[2] == 20u)); - fail_unless!((v[3] == 20u)); - fail_unless!((v[4] == 20u)); - fail_unless!((v[5] == 20u)); + fail_unless!(v[0] == 20u); + fail_unless!(v[1] == 20u); + fail_unless!(v[2] == 20u); + fail_unless!(v[3] == 20u); + fail_unless!(v[4] == 20u); + fail_unless!(v[5] == 20u); } #[test] fn test_is_empty() { - fail_unless!((is_empty::(~[]))); - fail_unless!((!is_empty(~[0]))); + fail_unless!(is_empty::(~[])); + fail_unless!(!is_empty(~[0])); } #[test] @@ -2589,10 +2586,10 @@ mod tests { let v0 : &[Z] = &[]; let v1 : &[Z] = &[[]]; let v2 : &[Z] = &[[], []]; - fail_unless!((sys::size_of::() == 0)); - fail_unless!((len(v0) == 0)); - fail_unless!((len(v1) == 1)); - fail_unless!((len(v2) == 2)); + fail_unless!(sys::size_of::() == 0); + fail_unless!(v0.len() == 0); + fail_unless!(v1.len() == 1); + fail_unless!(v2.len() == 2); } #[test] @@ -2695,6 +2692,7 @@ mod tests { #[test] #[should_fail] + #[ignore(cfg(windows))] fn test_last_empty() { let a: ~[int] = ~[]; a.last(); @@ -2714,36 +2712,36 @@ mod tests { fn test_slice() { // Test fixed length vector. let vec_fixed = [1, 2, 3, 4]; - let v_a = slice(vec_fixed, 1u, len(vec_fixed)).to_vec(); - fail_unless!((len(v_a) == 3u)); - fail_unless!((v_a[0] == 2)); - fail_unless!((v_a[1] == 3)); - fail_unless!((v_a[2] == 4)); + let v_a = slice(vec_fixed, 1u, vec_fixed.len()).to_vec(); + fail_unless!(v_a.len() == 3u); + fail_unless!(v_a[0] == 2); + fail_unless!(v_a[1] == 3); + fail_unless!(v_a[2] == 4); // Test on stack. let vec_stack = &[1, 2, 3]; let v_b = slice(vec_stack, 1u, 3u).to_vec(); - fail_unless!((len(v_b) == 2u)); - fail_unless!((v_b[0] == 2)); - fail_unless!((v_b[1] == 3)); + fail_unless!(v_b.len() == 2u); + fail_unless!(v_b[0] == 2); + fail_unless!(v_b[1] == 3); // Test on managed heap. let vec_managed = @[1, 2, 3, 4, 5]; let v_c = slice(vec_managed, 0u, 3u).to_vec(); - fail_unless!((len(v_c) == 3u)); - fail_unless!((v_c[0] == 1)); - fail_unless!((v_c[1] == 2)); - fail_unless!((v_c[2] == 3)); + fail_unless!(v_c.len() == 3u); + fail_unless!(v_c[0] == 1); + fail_unless!(v_c[1] == 2); + fail_unless!(v_c[2] == 3); // Test on exchange heap. let vec_unique = ~[1, 2, 3, 4, 5, 6]; let v_d = slice(vec_unique, 1u, 6u).to_vec(); - fail_unless!((len(v_d) == 5u)); - fail_unless!((v_d[0] == 2)); - fail_unless!((v_d[1] == 3)); - fail_unless!((v_d[2] == 4)); - fail_unless!((v_d[3] == 5)); - fail_unless!((v_d[4] == 6)); + fail_unless!(v_d.len() == 5u); + fail_unless!(v_d[0] == 2); + fail_unless!(v_d[1] == 3); + fail_unless!(v_d[2] == 4); + fail_unless!(v_d[3] == 5); + fail_unless!(v_d[4] == 6); } #[test] @@ -2751,27 +2749,27 @@ mod tests { // Test on-heap pop. let mut v = ~[1, 2, 3, 4, 5]; let e = v.pop(); - fail_unless!((len(v) == 4u)); - fail_unless!((v[0] == 1)); - fail_unless!((v[1] == 2)); - fail_unless!((v[2] == 3)); - fail_unless!((v[3] == 4)); - fail_unless!((e == 5)); + fail_unless!(v.len() == 4u); + fail_unless!(v[0] == 1); + fail_unless!(v[1] == 2); + fail_unless!(v[2] == 3); + fail_unless!(v[3] == 4); + fail_unless!(e == 5); } #[test] fn test_swap_remove() { let mut v = ~[1, 2, 3, 4, 5]; let mut e = v.swap_remove(0); - fail_unless!((len(v) == 4)); + fail_unless!(v.len() == 4); fail_unless!(e == 1); - fail_unless!((v[0] == 5)); + fail_unless!(v[0] == 5); e = v.swap_remove(3); - fail_unless!((len(v) == 3)); + fail_unless!(v.len() == 3); fail_unless!(e == 4); - fail_unless!((v[0] == 5)); - fail_unless!((v[1] == 2)); - fail_unless!((v[2] == 3)); + fail_unless!(v[0] == 5); + fail_unless!(v[1] == 2); + fail_unless!(v[2] == 3); } #[test] @@ -2780,11 +2778,11 @@ mod tests { let mut v = ~[::unstable::exclusive(()), ::unstable::exclusive(()), ::unstable::exclusive(())]; let mut _e = v.swap_remove(0); - fail_unless!((len(v) == 2)); + fail_unless!(v.len() == 2); _e = v.swap_remove(1); - fail_unless!((len(v) == 1)); + fail_unless!(v.len() == 1); _e = v.swap_remove(0); - fail_unless!((len(v) == 0)); + fail_unless!(v.len() == 0); } #[test] @@ -2792,14 +2790,14 @@ mod tests { // Test on-stack push(). let mut v = ~[]; v.push(1); - fail_unless!((len(v) == 1u)); - fail_unless!((v[0] == 1)); + fail_unless!(v.len() == 1u); + fail_unless!(v[0] == 1); // Test on-heap push(). v.push(2); - fail_unless!((len(v) == 2u)); - fail_unless!((v[0] == 1)); - fail_unless!((v[1] == 2)); + fail_unless!(v.len() == 2u); + fail_unless!(v[0] == 1); + fail_unless!(v[1] == 2); } #[test] @@ -2807,48 +2805,48 @@ mod tests { // Test on-stack grow(). let mut v = ~[]; v.grow(2u, &1); - fail_unless!((len(v) == 2u)); - fail_unless!((v[0] == 1)); - fail_unless!((v[1] == 1)); + fail_unless!(v.len() == 2u); + fail_unless!(v[0] == 1); + fail_unless!(v[1] == 1); // Test on-heap grow(). v.grow(3u, &2); - fail_unless!((len(v) == 5u)); - fail_unless!((v[0] == 1)); - fail_unless!((v[1] == 1)); - fail_unless!((v[2] == 2)); - fail_unless!((v[3] == 2)); - fail_unless!((v[4] == 2)); + fail_unless!(v.len() == 5u); + fail_unless!(v[0] == 1); + fail_unless!(v[1] == 1); + fail_unless!(v[2] == 2); + fail_unless!(v[3] == 2); + fail_unless!(v[4] == 2); } #[test] fn test_grow_fn() { let mut v = ~[]; v.grow_fn(3u, square); - fail_unless!((len(v) == 3u)); - fail_unless!((v[0] == 0u)); - fail_unless!((v[1] == 1u)); - fail_unless!((v[2] == 4u)); + fail_unless!(v.len() == 3u); + fail_unless!(v[0] == 0u); + fail_unless!(v[1] == 1u); + fail_unless!(v[2] == 4u); } #[test] fn test_grow_set() { let mut v = ~[1, 2, 3]; v.grow_set(4u, &4, 5); - fail_unless!((len(v) == 5u)); - fail_unless!((v[0] == 1)); - fail_unless!((v[1] == 2)); - fail_unless!((v[2] == 3)); - fail_unless!((v[3] == 4)); - fail_unless!((v[4] == 5)); + fail_unless!(v.len() == 5u); + fail_unless!(v[0] == 1); + fail_unless!(v[1] == 2); + fail_unless!(v[2] == 3); + fail_unless!(v[3] == 4); + fail_unless!(v[4] == 5); } #[test] fn test_truncate() { let mut v = ~[@6,@5,@4]; v.truncate(1); - fail_unless!((v.len() == 1)); - fail_unless!((*(v[0]) == 6)); + fail_unless!(v.len() == 1); + fail_unless!(*(v[0]) == 6); // If the unsafe block didn't drop things properly, we blow up here. } @@ -2856,7 +2854,7 @@ mod tests { fn test_clear() { let mut v = ~[@6,@5,@4]; v.clear(); - fail_unless!((v.len() == 0)); + fail_unless!(v.len() == 0); // If the unsafe block didn't drop things properly, we blow up here. } @@ -2865,7 +2863,7 @@ mod tests { fn case(a: ~[uint], b: ~[uint]) { let mut v = a; v.dedup(); - fail_unless!((v == b)); + fail_unless!(v == b); } case(~[], ~[]); case(~[1], ~[1]); @@ -2910,31 +2908,31 @@ mod tests { // Test on-stack map. let mut v = ~[1u, 2u, 3u]; let mut w = map(v, square_ref); - fail_unless!((len(w) == 3u)); - fail_unless!((w[0] == 1u)); - fail_unless!((w[1] == 4u)); - fail_unless!((w[2] == 9u)); + fail_unless!(w.len() == 3u); + fail_unless!(w[0] == 1u); + fail_unless!(w[1] == 4u); + fail_unless!(w[2] == 9u); // Test on-heap map. v = ~[1u, 2u, 3u, 4u, 5u]; w = map(v, square_ref); - fail_unless!((len(w) == 5u)); - fail_unless!((w[0] == 1u)); - fail_unless!((w[1] == 4u)); - fail_unless!((w[2] == 9u)); - fail_unless!((w[3] == 16u)); - fail_unless!((w[4] == 25u)); + fail_unless!(w.len() == 5u); + fail_unless!(w[0] == 1u); + fail_unless!(w[1] == 4u); + fail_unless!(w[2] == 9u); + fail_unless!(w[3] == 16u); + fail_unless!(w[4] == 25u); } #[test] fn test_map2() { - fn times(x: &int, y: &int) -> int { return *x * *y; } + fn times(x: &int, y: &int) -> int { *x * *y } let f = times; let v0 = ~[1, 2, 3, 4, 5]; let v1 = ~[5, 4, 3, 2, 1]; let u = map2::(v0, v1, f); let mut i = 0; - while i < 5 { fail_unless!((v0[i] * v1[i] == u[i])); i += 1; } + while i < 5 { fail_unless!(v0[i] * v1[i] == u[i]); i += 1; } } #[test] @@ -2942,26 +2940,26 @@ mod tests { // Test on-stack filter-map. let mut v = ~[1u, 2u, 3u]; let mut w = filter_mapped(v, square_if_odd_r); - fail_unless!((len(w) == 2u)); - fail_unless!((w[0] == 1u)); - fail_unless!((w[1] == 9u)); + fail_unless!(w.len() == 2u); + fail_unless!(w[0] == 1u); + fail_unless!(w[1] == 9u); // Test on-heap filter-map. v = ~[1u, 2u, 3u, 4u, 5u]; w = filter_mapped(v, square_if_odd_r); - fail_unless!((len(w) == 3u)); - fail_unless!((w[0] == 1u)); - fail_unless!((w[1] == 9u)); - fail_unless!((w[2] == 25u)); + fail_unless!(w.len() == 3u); + fail_unless!(w[0] == 1u); + fail_unless!(w[1] == 9u); + fail_unless!(w[2] == 25u); fn halve(i: &int) -> Option { if *i % 2 == 0 { - return option::Some::(*i / 2); + Some::(*i / 2) } else { - return option::None::; + None:: } } - fn halve_for_sure(i: &int) -> int { return *i / 2; } + fn halve_for_sure(i: &int) -> int { *i / 2 } let all_even: ~[int] = ~[0, 2, 8, 6]; let all_odd1: ~[int] = ~[1, 7, 3]; let all_odd2: ~[int] = ~[]; @@ -2969,9 +2967,9 @@ mod tests { let mix_dest: ~[int] = ~[1, 3, 0, 0]; fail_unless!(filter_mapped(all_even, halve) == map(all_even, halve_for_sure)); - fail_unless!((filter_mapped(all_odd1, halve) == ~[])); - fail_unless!((filter_mapped(all_odd2, halve) == ~[])); - fail_unless!((filter_mapped(mix, halve) == mix_dest)); + fail_unless!(filter_mapped(all_odd1, halve) == ~[]); + fail_unless!(filter_mapped(all_odd2, halve) == ~[]); + fail_unless!(filter_mapped(mix, halve) == mix_dest); } #[test] @@ -2979,26 +2977,26 @@ mod tests { // Test on-stack filter-map. let mut v = ~[1u, 2u, 3u]; let mut w = filter_map(v, square_if_odd_v); - fail_unless!((len(w) == 2u)); - fail_unless!((w[0] == 1u)); - fail_unless!((w[1] == 9u)); + fail_unless!(w.len() == 2u); + fail_unless!(w[0] == 1u); + fail_unless!(w[1] == 9u); // Test on-heap filter-map. v = ~[1u, 2u, 3u, 4u, 5u]; w = filter_map(v, square_if_odd_v); - fail_unless!((len(w) == 3u)); - fail_unless!((w[0] == 1u)); - fail_unless!((w[1] == 9u)); - fail_unless!((w[2] == 25u)); + fail_unless!(w.len() == 3u); + fail_unless!(w[0] == 1u); + fail_unless!(w[1] == 9u); + fail_unless!(w[2] == 25u); fn halve(i: int) -> Option { if i % 2 == 0 { - return option::Some::(i / 2); + Some::(i / 2) } else { - return option::None::; + None:: } } - fn halve_for_sure(i: &int) -> int { return *i / 2; } + fn halve_for_sure(i: &int) -> int { *i / 2 } let all_even: ~[int] = ~[0, 2, 8, 6]; let all_even0: ~[int] = copy all_even; let all_odd1: ~[int] = ~[1, 7, 3]; @@ -3007,9 +3005,9 @@ mod tests { let mix_dest: ~[int] = ~[1, 3, 0, 0]; fail_unless!(filter_map(all_even, halve) == map(all_even0, halve_for_sure)); - fail_unless!((filter_map(all_odd1, halve) == ~[])); - fail_unless!((filter_map(all_odd2, halve) == ~[])); - fail_unless!((filter_map(mix, halve) == mix_dest)); + fail_unless!(filter_map(all_odd1, halve) == ~[]); + fail_unless!(filter_map(all_odd2, halve) == ~[]); + fail_unless!(filter_map(mix, halve) == mix_dest); } #[test] @@ -3030,12 +3028,12 @@ mod tests { // Test on-stack fold. let mut v = ~[1u, 2u, 3u]; let mut sum = foldl(0u, v, add); - fail_unless!((sum == 6u)); + fail_unless!(sum == 6u); // Test on-heap fold. v = ~[1u, 2u, 3u, 4u, 5u]; sum = foldl(0u, v, add); - fail_unless!((sum == 15u)); + fail_unless!(sum == 15u); } #[test] @@ -3137,29 +3135,29 @@ mod tests { #[test] fn test_any_and_all() { - fail_unless!((any(~[1u, 2u, 3u], is_three))); - fail_unless!((!any(~[0u, 1u, 2u], is_three))); - fail_unless!((any(~[1u, 2u, 3u, 4u, 5u], is_three))); - fail_unless!((!any(~[1u, 2u, 4u, 5u, 6u], is_three))); + fail_unless!(any(~[1u, 2u, 3u], is_three)); + fail_unless!(!any(~[0u, 1u, 2u], is_three)); + fail_unless!(any(~[1u, 2u, 3u, 4u, 5u], is_three)); + fail_unless!(!any(~[1u, 2u, 4u, 5u, 6u], is_three)); - fail_unless!((all(~[3u, 3u, 3u], is_three))); - fail_unless!((!all(~[3u, 3u, 2u], is_three))); - fail_unless!((all(~[3u, 3u, 3u, 3u, 3u], is_three))); - fail_unless!((!all(~[3u, 3u, 0u, 1u, 2u], is_three))); + fail_unless!(all(~[3u, 3u, 3u], is_three)); + fail_unless!(!all(~[3u, 3u, 2u], is_three)); + fail_unless!(all(~[3u, 3u, 3u, 3u, 3u], is_three)); + fail_unless!(!all(~[3u, 3u, 0u, 1u, 2u], is_three)); } #[test] fn test_any2_and_all2() { - fail_unless!((any2(~[2u, 4u, 6u], ~[2u, 4u, 6u], is_equal))); - fail_unless!((any2(~[1u, 2u, 3u], ~[4u, 5u, 3u], is_equal))); - fail_unless!((!any2(~[1u, 2u, 3u], ~[4u, 5u, 6u], is_equal))); - fail_unless!((any2(~[2u, 4u, 6u], ~[2u, 4u], is_equal))); + fail_unless!(any2(~[2u, 4u, 6u], ~[2u, 4u, 6u], is_equal)); + fail_unless!(any2(~[1u, 2u, 3u], ~[4u, 5u, 3u], is_equal)); + fail_unless!(!any2(~[1u, 2u, 3u], ~[4u, 5u, 6u], is_equal)); + fail_unless!(any2(~[2u, 4u, 6u], ~[2u, 4u], is_equal)); - fail_unless!((all2(~[2u, 4u, 6u], ~[2u, 4u, 6u], is_equal))); - fail_unless!((!all2(~[1u, 2u, 3u], ~[4u, 5u, 3u], is_equal))); - fail_unless!((!all2(~[1u, 2u, 3u], ~[4u, 5u, 6u], is_equal))); - fail_unless!((!all2(~[2u, 4u, 6u], ~[2u, 4u], is_equal))); + fail_unless!(all2(~[2u, 4u, 6u], ~[2u, 4u, 6u], is_equal)); + fail_unless!(!all2(~[1u, 2u, 3u], ~[4u, 5u, 3u], is_equal)); + fail_unless!(!all2(~[1u, 2u, 3u], ~[4u, 5u, 6u], is_equal)); + fail_unless!(!all2(~[2u, 4u, 6u], ~[2u, 4u], is_equal)); } #[test] @@ -3169,15 +3167,15 @@ mod tests { let z1 = zip(v1, v2); - fail_unless!(((1, 4) == z1[0])); - fail_unless!(((2, 5) == z1[1])); - fail_unless!(((3, 6) == z1[2])); + fail_unless!((1, 4) == z1[0]); + fail_unless!((2, 5) == z1[1]); + fail_unless!((3, 6) == z1[2]); let (left, right) = unzip(z1); - fail_unless!(((1, 4) == (left[0], right[0]))); - fail_unless!(((2, 5) == (left[1], right[1]))); - fail_unless!(((3, 6) == (left[2], right[2]))); + fail_unless!((1, 4) == (left[0], right[0])); + fail_unless!((2, 5) == (left[1], right[1])); + fail_unless!((3, 6) == (left[2], right[2])); } #[test] @@ -3193,8 +3191,8 @@ mod tests { #[test] fn test_position() { - fn less_than_three(i: &int) -> bool { return *i < 3; } - fn is_eighteen(i: &int) -> bool { return *i == 18; } + fn less_than_three(i: &int) -> bool { *i < 3 } + fn is_eighteen(i: &int) -> bool { *i == 18 } fail_unless!(position(~[], less_than_three).is_none()); @@ -3354,20 +3352,20 @@ mod tests { #[test] fn reverse_and_reversed() { let mut v: ~[int] = ~[10, 20]; - fail_unless!((v[0] == 10)); - fail_unless!((v[1] == 20)); + fail_unless!(v[0] == 10); + fail_unless!(v[1] == 20); reverse(v); - fail_unless!((v[0] == 20)); - fail_unless!((v[1] == 10)); + fail_unless!(v[0] == 20); + fail_unless!(v[1] == 10); let v2 = reversed::(~[10, 20]); - fail_unless!((v2[0] == 20)); - fail_unless!((v2[1] == 10)); + fail_unless!(v2[0] == 20); + fail_unless!(v2[1] == 10); v[0] = 30; - fail_unless!((v2[0] == 20)); + fail_unless!(v2[0] == 20); // Make sure they work with 0-length vectors too. let v4 = reversed::(~[]); - fail_unless!((v4 == ~[])); + fail_unless!(v4 == ~[]); let mut v3: ~[int] = ~[]; reverse::(v3); } @@ -3375,8 +3373,8 @@ mod tests { #[test] fn reversed_mut() { let mut v2 = reversed::(~[10, 20]); - fail_unless!((v2[0] == 20)); - fail_unless!((v2[1] == 10)); + fail_unless!(v2[0] == 20); + fail_unless!(v2[1] == 10); } #[test] @@ -3548,9 +3546,9 @@ mod tests { fn test_view() { let v = ~[1, 2, 3, 4, 5]; let v = v.view(1u, 3u); - fail_unless!((len(v) == 2u)); - fail_unless!((v[0] == 2)); - fail_unless!((v[1] == 3)); + fail_unless!(v.len() == 2u); + fail_unless!(v[0] == 2); + fail_unless!(v[1] == 3); } diff --git a/src/libfuzzer/fuzzer.rc b/src/libfuzzer/fuzzer.rc index 19afbc4b2b7ff..90ada832327f4 100644 --- a/src/libfuzzer/fuzzer.rc +++ b/src/libfuzzer/fuzzer.rc @@ -25,6 +25,7 @@ #[allow(non_camel_case_types)]; #[allow(deprecated_mode)]; #[allow(deprecated_pattern)]; +#[deny(deprecated_self)]; extern mod core(vers = "0.6"); extern mod std(vers = "0.6"); @@ -246,7 +247,7 @@ pub fn replace_ty_in_crate(crate: ast::crate, i: uint, newty: ast::Ty, *crate2 } -pub fn under(n: uint, it: fn(uint)) { +pub fn under(n: uint, it: &fn(uint)) { let mut i: uint = 0u; while i < n { it(i); i += 1u; } } diff --git a/src/librust/rust.rc b/src/librust/rust.rc index 023383b3dccc8..082861e0ae01f 100644 --- a/src/librust/rust.rc +++ b/src/librust/rust.rc @@ -12,6 +12,8 @@ // XXX: Make commands run and test emit proper file endings on winds // XXX: Make run only accept source that emits an executable +#[deny(deprecated_self)]; + #[link(name = "rust", vers = "0.6", uuid = "4a24da33-5cc8-4037-9352-2cbe9bd9d27c", diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index eaac7dd1a0b54..1437a3af7ddb6 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -153,7 +153,7 @@ pub mod jit { code: entry, env: ptr::null() }; - let func: fn(++argv: ~[~str]) = cast::transmute(closure); + let func: &fn(++argv: ~[~str]) = cast::transmute(closure); func(~[/*bad*/copy sess.opts.binary]); } @@ -818,7 +818,11 @@ pub fn link_binary(sess: Session, do cstore::iter_crate_data(cstore) |crate_num, _| { let link_args = csearch::get_link_args_for_crate(cstore, crate_num); do vec::consume(link_args) |_, link_arg| { - cc_args.push(link_arg); + // Linker arguments that don't begin with - are likely file names, + // so they should not be necessary. + if link_arg.starts_with("-") { + cc_args.push(link_arg); + } } } diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index e7e29ec6c72d5..2b61c9480457d 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -164,7 +164,7 @@ pub fn parse_input(sess: Session, +cfg: ast::crate_cfg, input: input) } } -pub fn time(do_it: bool, what: ~str, thunk: fn() -> T) -> T { +pub fn time(do_it: bool, what: ~str, thunk: &fn() -> T) -> T { if !do_it { return thunk(); } let start = std::time::precise_time_s(); let rv = thunk(); diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index 52426401d7927..d2d0ceff6331d 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -306,7 +306,7 @@ pub fn basic_options() -> @options { // Seems out of place, but it uses session, so I'm putting it here pub fn expect(sess: Session, opt: Option, - msg: fn() -> ~str) + msg: &fn() -> ~str) -> T { diagnostic::expect(sess.diagnostic(), opt, msg) } diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index 00cb977b50c83..47ee477210b78 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -155,7 +155,7 @@ pub fn get_static_methods_if_impl(cstore: @mut cstore::CStore, pub fn get_item_attrs(cstore: @mut cstore::CStore, def_id: ast::def_id, - f: fn(~[@ast::meta_item])) { + f: &fn(~[@ast::meta_item])) { let cdata = cstore::get_crate_data(cstore, def_id.crate); decoder::get_item_attrs(cdata, def_id.node, f) } diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index 2f82d99420c1a..0909a4437369d 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -88,7 +88,7 @@ pub fn have_crate_data(cstore: @mut CStore, cnum: ast::crate_num) -> bool { } pub fn iter_crate_data(cstore: @mut CStore, - i: fn(ast::crate_num, @crate_metadata)) { + i: &fn(ast::crate_num, @crate_metadata)) { let metas = cstore.metas; for metas.each |&k, &v| { i(k, v); diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 4fe708d1020cd..2643012d30ae2 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -48,7 +48,7 @@ type cmd = @crate_metadata; // what crate that's in and give us a def_id that makes sense for the current // build. -fn lookup_hash(d: ebml::Doc, eq_fn: fn(x:&[u8]) -> bool, hash: uint) -> +fn lookup_hash(d: ebml::Doc, eq_fn: &fn(x:&[u8]) -> bool, hash: uint) -> Option { let index = reader::get_doc(d, tag_index); let table = reader::get_doc(index, tag_index_table); @@ -193,7 +193,7 @@ fn item_def_id(d: ebml::Doc, cdata: cmd) -> ast::def_id { |d| parse_def_id(d))); } -fn each_reexport(d: ebml::Doc, f: fn(ebml::Doc) -> bool) { +fn each_reexport(d: ebml::Doc, f: &fn(ebml::Doc) -> bool) { for reader::tagged_docs(d, tag_items_data_item_reexport) |reexport_doc| { if !f(reexport_doc) { return; @@ -451,7 +451,7 @@ pub fn each_lang_item(cdata: cmd, f: &fn(ast::node_id, uint) -> bool) { /// Iterates over all the paths in the given crate. pub fn each_path(intr: @ident_interner, cdata: cmd, get_crate_data: GetCrateDataCb, - f: fn(&str, def_like) -> bool) { + f: &fn(&str, def_like) -> bool) { let root = reader::Doc(cdata.data); let items = reader::get_doc(root, tag_items); let items_data = reader::get_doc(items, tag_items_data); @@ -855,7 +855,7 @@ pub fn get_static_methods_if_impl(intr: @ident_interner, pub fn get_item_attrs(cdata: cmd, node_id: ast::node_id, - f: fn(~[@ast::meta_item])) { + f: &fn(~[@ast::meta_item])) { let item = lookup_item(node_id, cdata.data); for reader::tagged_docs(item, tag_attributes) |attributes| { @@ -1093,7 +1093,7 @@ pub fn get_crate_vers(data: @~[u8]) -> @~str { fn iter_crate_items(intr: @ident_interner, cdata: cmd, get_crate_data: GetCrateDataCb, - proc: fn(path: &str, ast::def_id)) { + proc: &fn(path: &str, ast::def_id)) { for each_path(intr, cdata, get_crate_data) |path_string, def_like| { match def_like { dl_impl(*) | dl_field => {} diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 414aa035b5497..fc42ac2ffedb9 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -1054,7 +1054,7 @@ fn create_index(index: ~[entry]) -> } fn encode_index(ebml_w: writer::Encoder, buckets: ~[@~[entry]], - write_fn: fn(io::Writer, T)) { + write_fn: &fn(io::Writer, T)) { let writer = ebml_w.writer; ebml_w.start_tag(tag_index); let mut bucket_locs: ~[uint] = ~[]; diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 08b9facf48613..63b14cc51be1c 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -217,7 +217,7 @@ fn parse_region(st: @mut PState) -> ty::Region { } } -fn parse_opt(st: @mut PState, f: fn() -> T) -> Option { +fn parse_opt(st: @mut PState, f: &fn() -> T) -> Option { match next(st) { 'n' => None, 's' => Some(f()), diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index caad6335ce512..b9cb0b1d4b5a3 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -122,7 +122,7 @@ fn enc_mt(w: io::Writer, cx: @ctxt, mt: ty::mt) { enc_ty(w, cx, mt.ty); } -fn enc_opt(w: io::Writer, t: Option, enc_f: fn(T)) { +fn enc_opt(w: io::Writer, t: Option, enc_f: &fn(T)) { match &t { &None => w.write_char('n'), &Some(ref v) => { diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 6f0bfbb197fac..c1a8f79b9b131 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -721,12 +721,12 @@ impl vtable_decoder_helpers for reader::Decoder { // Encoding and decoding the side tables trait get_ty_str_ctxt { - fn ty_str_ctxt() -> @tyencode::ctxt; + fn ty_str_ctxt(@self) -> @tyencode::ctxt; } -impl get_ty_str_ctxt for @e::EncodeContext { +impl get_ty_str_ctxt for e::EncodeContext { // IMPLICIT SELF WARNING: fix this! - fn ty_str_ctxt() -> @tyencode::ctxt { + fn ty_str_ctxt(@self) -> @tyencode::ctxt { @tyencode::ctxt {diag: self.tcx.sess.diagnostic(), ds: e::def_to_str, tcx: self.tcx, @@ -795,12 +795,12 @@ impl ebml_writer_helpers for writer::Encoder { } trait write_tag_and_id { - fn tag(&self, tag_id: c::astencode_tag, f: fn()); + fn tag(&self, tag_id: c::astencode_tag, f: &fn()); fn id(&self, id: ast::node_id); } impl write_tag_and_id for writer::Encoder { - fn tag(&self, tag_id: c::astencode_tag, f: fn()) { + fn tag(&self, tag_id: c::astencode_tag, f: &fn()) { do self.wr_tag(tag_id as uint) { f() } } diff --git a/src/librustc/middle/borrowck/gather_loans.rs b/src/librustc/middle/borrowck/gather_loans.rs index 94c266ab44fcb..6e998864def57 100644 --- a/src/librustc/middle/borrowck/gather_loans.rs +++ b/src/librustc/middle/borrowck/gather_loans.rs @@ -617,17 +617,17 @@ pub impl GatherLoanCtxt { } } - ast::pat_vec(_, Some(tail_pat)) => { - // The `tail_pat` here creates a slice into the + ast::pat_vec(_, Some(slice_pat), _) => { + // The `slice_pat` here creates a slice into the // original vector. This is effectively a borrow of // the elements of the vector being matched. - let tail_ty = self.tcx().ty(tail_pat); - let (tail_mutbl, tail_r) = - self.vec_slice_info(tail_pat, tail_ty); + let slice_ty = self.tcx().ty(slice_pat); + let (slice_mutbl, slice_r) = + self.vec_slice_info(slice_pat, slice_ty); let mcx = self.bccx.mc_ctxt(); - let cmt_index = mcx.cat_index(tail_pat, cmt); - self.guarantee_valid(cmt_index, tail_mutbl, tail_r); + let cmt_index = mcx.cat_index(slice_pat, cmt); + self.guarantee_valid(cmt_index, slice_mutbl, slice_r); } _ => {} @@ -637,7 +637,7 @@ pub impl GatherLoanCtxt { fn vec_slice_info(@mut self, pat: @ast::pat, - tail_ty: ty::t) -> (ast::mutability, ty::Region) { + slice_ty: ty::t) -> (ast::mutability, ty::Region) { /*! * * In a pattern like [a, b, ..c], normally `c` has slice type, @@ -646,9 +646,9 @@ pub impl GatherLoanCtxt { * to recurse through rptrs. */ - match ty::get(tail_ty).sty { - ty::ty_evec(tail_mt, ty::vstore_slice(tail_r)) => { - (tail_mt.mutbl, tail_r) + match ty::get(slice_ty).sty { + ty::ty_evec(slice_mt, ty::vstore_slice(slice_r)) => { + (slice_mt.mutbl, slice_r) } ty::ty_rptr(_, ref mt) => { @@ -658,7 +658,7 @@ pub impl GatherLoanCtxt { _ => { self.tcx().sess.span_bug( pat.span, - fmt!("Type of tail pattern is not a slice")); + fmt!("Type of slice pattern is not a slice")); } } } diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs index 5462ec87014e2..3e63707162417 100644 --- a/src/librustc/middle/borrowck/mod.rs +++ b/src/librustc/middle/borrowck/mod.rs @@ -510,7 +510,7 @@ pub impl BorrowckCtxt { method_map: self.method_map} } - fn cat_pattern(&self, cmt: cmt, pat: @ast::pat, op: fn(cmt, @ast::pat)) { + fn cat_pattern(&self, cmt: cmt, pat: @ast::pat, op: &fn(cmt, @ast::pat)) { let mc = self.mc_ctxt(); mc.cat_pattern(cmt, pat, op); } diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index a60b0332b8fb4..a7fb1506d181b 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -244,7 +244,9 @@ pub fn is_useful(cx: @MatchCheckCtxt, m: &matrix, v: &[@pat]) -> useful { ty::ty_unboxed_vec(*) | ty::ty_evec(*) => { let max_len = do m.foldr(0) |r, max_len| { match /*bad*/copy r[0].node { - pat_vec(elems, _) => uint::max(elems.len(), max_len), + pat_vec(before, _, after) => { + uint::max(before.len() + after.len(), max_len) + } _ => max_len } }; @@ -322,10 +324,10 @@ pub fn pat_ctor_id(cx: @MatchCheckCtxt, p: @pat) -> Option { pat_box(_) | pat_uniq(_) | pat_tup(_) | pat_region(*) => { Some(single) } - pat_vec(elems, tail) => { - match tail { + pat_vec(before, slice, after) => { + match slice { Some(_) => None, - None => Some(vec(elems.len())) + None => Some(vec(before.len() + after.len())) } } } @@ -393,22 +395,22 @@ pub fn missing_ctor(cx: @MatchCheckCtxt, } ty::ty_unboxed_vec(*) | ty::ty_evec(*) => { - // Find the lengths and tails of all vector patterns. + // Find the lengths and slices of all vector patterns. let vec_pat_lens = do m.filter_mapped |r| { match r[0].node { - pat_vec(ref elems, ref tail) => { - Some((elems.len(), tail.is_some())) + pat_vec(ref before, ref slice, ref after) => { + Some((before.len() + after.len(), slice.is_some())) } _ => None } }; // Sort them by length such that for patterns of the same length, - // those with a destructured tail come first. + // those with a destructured slice come first. let mut sorted_vec_lens = sort::merge_sort(vec_pat_lens, - |&(len1, tail1), &(len2, tail2)| { + |&(len1, slice1), &(len2, slice2)| { if len1 == len2 { - tail1 > tail2 + slice1 > slice2 } else { len1 <= len2 } @@ -416,24 +418,24 @@ pub fn missing_ctor(cx: @MatchCheckCtxt, ); vec::dedup(&mut sorted_vec_lens); - let mut found_tail = false; + let mut found_slice = false; let mut next = 0; let mut missing = None; - for sorted_vec_lens.each |&(length, tail)| { + for sorted_vec_lens.each |&(length, slice)| { if length != next { missing = Some(next); break; } - if tail { - found_tail = true; + if slice { + found_slice = true; break; } next += 1; } // We found patterns of all lengths within <0, next), yet there was no - // pattern with a tail - therefore, we report vec(next) as missing. - if !found_tail { + // pattern with a slice - therefore, we report vec(next) as missing. + if !found_slice { missing = Some(next); } match missing { @@ -621,19 +623,25 @@ pub fn specialize(cx: @MatchCheckCtxt, compare_const_vals(c_hi, v_hi) <= 0; if match_ { Some(vec::from_slice(r.tail())) } else { None } } - pat_vec(elems, tail) => { + pat_vec(before, slice, after) => { match ctor_id { vec(_) => { - let num_elements = elems.len(); - if num_elements < arity && tail.is_some() { + let num_elements = before.len() + after.len(); + if num_elements < arity && slice.is_some() { Some(vec::append( - vec::append(elems, vec::from_elem( - arity - num_elements, wild() - )), - vec::from_slice(r.tail()) + vec::concat(&[ + before, + vec::from_elem( + arity - num_elements, wild()), + after + ]), + r.tail() )) } else if num_elements == arity { - Some(vec::append(elems, r.tail())) + Some(vec::append( + vec::append(before, after), + r.tail() + )) } else { None } diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index 84de194915ad0..48d136ce65f36 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -95,7 +95,7 @@ type check_fn = @fn(Context, @freevar_entry); // Yields the appropriate function to check the kind of closed over // variables. `id` is the node_id for some expression that creates the // closure. -fn with_appropriate_checker(cx: Context, id: node_id, b: fn(check_fn)) { +fn with_appropriate_checker(cx: Context, id: node_id, b: &fn(check_fn)) { fn check_for_uniq(cx: Context, fv: @freevar_entry) { // all captured data must be owned, regardless of whether it is // moved in or copied in. diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 2bd08f109812f..93f0557028eae 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -77,6 +77,7 @@ pub enum lint { default_methods, deprecated_self, deprecated_mutable_fields, + deprecated_drop, managed_heap_memory, owned_heap_memory, @@ -251,6 +252,13 @@ pub fn get_lint_dict() -> LintDict { default: deny }), + (@~"deprecated_drop", + @LintSpec { + lint: deprecated_drop, + desc: "deprecated \"drop\" notation for the destructor", + default: deny + }), + /* FIXME(#3266)--make liveness warnings lintable (@~"unused_variable", @LintSpec { @@ -342,7 +350,7 @@ pub impl Context { * current lint context, call the provided function, then reset the * lints in effect to their previous state. */ - fn with_lint_attrs(&self, attrs: ~[ast::attribute], f: fn(Context)) { + fn with_lint_attrs(&self, attrs: ~[ast::attribute], f: &fn(Context)) { let mut new_ctxt = *self; let mut triples = ~[]; @@ -483,6 +491,7 @@ fn check_item(i: @ast::item, cx: ty::ctxt) { check_item_default_methods(cx, i); check_item_deprecated_self(cx, i); check_item_deprecated_mutable_fields(cx, i); + check_item_deprecated_drop(cx, i); } // Take a visitor, and modify it so that it will not proceed past subitems. @@ -720,6 +729,26 @@ fn check_item_deprecated_mutable_fields(cx: ty::ctxt, item: @ast::item) { } } +fn check_item_deprecated_drop(cx: ty::ctxt, item: @ast::item) { + match item.node { + ast::item_struct(struct_def, _) => { + match struct_def.dtor { + None => {} + Some(ref dtor) => { + cx.sess.span_lint(deprecated_drop, + item.id, + item.id, + dtor.span, + ~"`drop` notation for destructors is \ + deprecated; implement the `Drop` \ + trait instead"); + } + } + } + _ => {} + } +} + fn check_item_ctypes(cx: ty::ctxt, it: @ast::item) { fn check_foreign_fn(cx: ty::ctxt, fn_id: ast::node_id, diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index f0c06ceca989c..0c17b371694c4 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -137,8 +137,8 @@ use syntax::{visit, ast_util}; // if it detects an outstanding loan (that is, the addr is taken). pub type last_use_map = HashMap; -enum Variable = uint; -enum LiveNode = uint; +struct Variable(uint); +struct LiveNode(uint); impl cmp::Eq for Variable { pure fn eq(&self, other: &Variable) -> bool { *(*self) == *(*other) } @@ -735,7 +735,7 @@ pub impl Liveness { } } - fn pat_bindings(&self, pat: @pat, f: fn(LiveNode, Variable, span)) { + fn pat_bindings(&self, pat: @pat, f: &fn(LiveNode, Variable, span)) { let def_map = self.tcx.def_map; do pat_util::pat_bindings(def_map, pat) |_bm, p_id, sp, _n| { let ln = self.live_node(p_id, sp); @@ -745,7 +745,7 @@ pub impl Liveness { } fn arm_pats_bindings(&self, - pats: &[@pat], f: fn(LiveNode, Variable, span)) { + pats: &[@pat], f: &fn(LiveNode, Variable, span)) { // only consider the first pattern; any later patterns must have // the same bindings, and we also consider the first pattern to be // the "authoratative" set of ids @@ -809,15 +809,14 @@ pub impl Liveness { self.assigned_on_entry(copy self.successors[*ln], var) } - fn indices(&self, ln: LiveNode, op: fn(uint)) { + fn indices(&self, ln: LiveNode, op: &fn(uint)) { let node_base_idx = self.idx(ln, Variable(0)); for uint::range(0, self.ir.num_vars) |var_idx| { op(node_base_idx + var_idx) } } - fn indices2(ln: LiveNode, succ_ln: LiveNode, - op: fn(uint, uint)) { + fn indices2(&self, ln: LiveNode, succ_ln: LiveNode, op: &fn(uint, uint)) { let node_base_idx = self.idx(ln, Variable(0u)); let succ_base_idx = self.idx(succ_ln, Variable(0u)); for uint::range(0u, self.ir.num_vars) |var_idx| { @@ -827,7 +826,7 @@ pub impl Liveness { fn write_vars(&self, wr: io::Writer, ln: LiveNode, - test: fn(uint) -> LiveNode) { + test: &fn(uint) -> LiveNode) { let node_base_idx = self.idx(ln, Variable(0)); for uint::range(0, self.ir.num_vars) |var_idx| { let idx = node_base_idx + var_idx; @@ -1510,7 +1509,7 @@ pub impl Liveness { fn with_loop_nodes(&self, loop_node_id: node_id, break_ln: LiveNode, cont_ln: LiveNode, - f: fn() -> R) -> R { + f: &fn() -> R) -> R { debug!("with_loop_nodes: %d %u", loop_node_id, *break_ln); self.loop_scope.push(loop_node_id); self.break_ln.insert(loop_node_id, break_ln); diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 00cab7961cada..9e0ecb5a21859 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -856,7 +856,7 @@ pub impl mem_categorization_ctxt { fn cat_pattern(&self, cmt: cmt, pat: @ast::pat, - op: fn(cmt, @ast::pat)) + op: &fn(cmt, @ast::pat)) { // Here, `cmt` is the categorization for the value being // matched and pat is the pattern it is being matched against. @@ -963,16 +963,19 @@ pub impl mem_categorization_ctxt { self.cat_pattern(subcmt, subpat, op); } - ast::pat_vec(ref pats, opt_tail_pat) => { - for pats.each |pat| { + ast::pat_vec(ref before, slice, ref after) => { + for before.each |pat| { let elt_cmt = self.cat_index(*pat, cmt); self.cat_pattern(elt_cmt, *pat, op); } - - for opt_tail_pat.each |tail_pat| { - let tail_ty = self.tcx.ty(*tail_pat); - let tail_cmt = self.cat_rvalue(*tail_pat, tail_ty); - self.cat_pattern(tail_cmt, *tail_pat, op); + for slice.each |slice_pat| { + let slice_ty = self.tcx.ty(*slice_pat); + let slice_cmt = self.cat_rvalue(*slice_pat, slice_ty); + self.cat_pattern(slice_cmt, *slice_pat, op); + } + for after.each |pat| { + let elt_cmt = self.cat_index(*pat, cmt); + self.cat_pattern(elt_cmt, *pat, op); } } diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs index 77ad7df531978..4522977a4ab12 100644 --- a/src/librustc/middle/pat_util.rs +++ b/src/librustc/middle/pat_util.rs @@ -72,7 +72,7 @@ pub fn pat_is_binding_or_wild(dm: resolve::DefMap, pat: @pat) -> bool { } pub fn pat_bindings(dm: resolve::DefMap, pat: @pat, - it: fn(binding_mode, node_id, span, @path)) { + it: &fn(binding_mode, node_id, span, @path)) { do walk_pat(pat) |p| { match p.node { pat_ident(binding_mode, pth, _) if pat_is_binding(dm, p) => { diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 12c08ffb43585..a96ed9b8fa6da 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -31,6 +31,7 @@ use std::oldmap::HashMap; use syntax::ast_map; use syntax::codemap::span; use syntax::print::pprust; +use syntax::parse::token::special_idents; use syntax::{ast, visit}; pub type parent = Option; @@ -546,29 +547,20 @@ pub impl DetermineRpCtxt { // with &self type, &self is also bound. We detect those last two // cases via flags (anon_implies_rp and self_implies_rp) that are // true when the anon or self region implies RP. - fn region_is_relevant(&self, r: @ast::region) -> bool { - match r.node { - ast::re_static => false, - ast::re_anon => self.anon_implies_rp, - ast::re_self => self.self_implies_rp, - ast::re_named(_) => false - } - } - - // For named types like Foo, if there is no explicit region - // parameter, then we will add the anonymous region, so there is - // a dependency if the anonymous region implies rp. - // - // If the region is explicitly specified, then we follows the - // normal rules. - fn opt_region_is_relevant(&self, - opt_r: Option<@ast::region>) - -> bool { - debug!("opt_region_is_relevant: %? (anon_implies_rp=%b)", - opt_r, self.anon_implies_rp); - match opt_r { - None => self.anon_implies_rp, - Some(r) => self.region_is_relevant(r) + fn region_is_relevant(&self, r: Option<@ast::Lifetime>) -> bool { + match r { + None => { + self.anon_implies_rp + } + Some(ref l) if l.ident == special_idents::static => { + false + } + Some(ref l) if l.ident == special_idents::self_ => { + self.self_implies_rp + } + Some(_) => { + false + } } } @@ -672,8 +664,8 @@ pub fn determine_rp_in_ty(ty: @ast::Ty, debug!("referenced fn type: %s", pprust::ty_to_str(ty, sess.intr())); match f.region { - Some(r) => { - if cx.region_is_relevant(r) { + Some(_) => { + if cx.region_is_relevant(f.region) { cx.add_rp(cx.item_id, cx.add_variance(rv_contravariant)) } @@ -699,7 +691,7 @@ pub fn determine_rp_in_ty(ty: @ast::Ty, match cx.def_map.find(&id) { Some(ast::def_ty(did)) | Some(ast::def_struct(did)) => { if did.crate == ast::local_crate { - if cx.opt_region_is_relevant(path.rp) { + if cx.region_is_relevant(path.rp) { cx.add_dep(did.node); } } else { @@ -709,7 +701,7 @@ pub fn determine_rp_in_ty(ty: @ast::Ty, Some(variance) => { debug!("reference to external, rp'd type %s", pprust::ty_to_str(ty, sess.intr())); - if cx.opt_region_is_relevant(path.rp) { + if cx.region_is_relevant(path.rp) { cx.add_rp(cx.item_id, cx.add_variance(variance)) } } diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 391990eed95de..7ac559161af4f 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -592,7 +592,7 @@ pub impl NameBindings { } /// Returns the module node if applicable. - fn get_module_if_available() -> Option<@mut Module> { + fn get_module_if_available(&self) -> Option<@mut Module> { match self.type_def { Some(ref type_def) => (*type_def).module_def, None => None @@ -613,14 +613,14 @@ pub impl NameBindings { } } - fn defined_in_namespace(namespace: Namespace) -> bool { + fn defined_in_namespace(&self, namespace: Namespace) -> bool { match namespace { TypeNS => return self.type_def.is_some(), ValueNS => return self.value_def.is_some() } } - fn defined_in_public_namespace(namespace: Namespace) -> bool { + fn defined_in_public_namespace(&self, namespace: Namespace) -> bool { match namespace { TypeNS => match self.type_def { Some(def) => def.privacy != Private, @@ -633,7 +633,7 @@ pub impl NameBindings { } } - fn def_for_namespace(namespace: Namespace) -> Option { + fn def_for_namespace(&self, namespace: Namespace) -> Option { match namespace { TypeNS => { match self.type_def { @@ -666,7 +666,7 @@ pub impl NameBindings { } } - fn privacy_for_namespace(namespace: Namespace) -> Option { + fn privacy_for_namespace(&self, namespace: Namespace) -> Option { match namespace { TypeNS => { match self.type_def { @@ -683,7 +683,7 @@ pub impl NameBindings { } } - fn span_for_namespace(namespace: Namespace) -> Option { + fn span_for_namespace(&self, namespace: Namespace) -> Option { if self.defined_in_namespace(namespace) { match namespace { TypeNS => self.type_span, @@ -3241,7 +3241,7 @@ pub impl Resolver { // generate a fake "implementation scope" containing all the // implementations thus found, for compatibility with old resolve pass. - fn with_scope(@mut self, name: Option, f: fn()) { + fn with_scope(@mut self, name: Option, f: &fn()) { let orig_module = self.current_module; // Move down in the graph. @@ -3661,7 +3661,7 @@ pub impl Resolver { fn with_type_parameter_rib(@mut self, type_parameters: TypeParameters, - f: fn()) { + f: &fn()) { match type_parameters { HasTypeParameters(generics, node_id, initial_index, rib_kind) => { @@ -3702,13 +3702,13 @@ pub impl Resolver { } } - fn with_label_rib(@mut self, f: fn()) { + fn with_label_rib(@mut self, f: &fn()) { self.label_ribs.push(@Rib(NormalRibKind)); f(); self.label_ribs.pop(); } - fn with_constant_rib(@mut self, f: fn()) { + fn with_constant_rib(@mut self, f: &fn()) { self.value_ribs.push(@Rib(ConstantItemRibKind)); f(); self.value_ribs.pop(); diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index 8411064c57aef..d4a7c104500ba 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -190,7 +190,7 @@ pub enum Opt { var(/* disr val */int, @adt::Repr), range(@ast::expr, @ast::expr), vec_len_eq(uint), - vec_len_ge(uint) + vec_len_ge(uint, /* slice */uint) } pub fn opt_eq(tcx: ty::ctxt, a: &Opt, b: &Opt) -> bool { @@ -235,7 +235,7 @@ pub fn opt_eq(tcx: ty::ctxt, a: &Opt, b: &Opt) -> bool { } (&var(a, _), &var(b, _)) => a == b, (&vec_len_eq(a), &vec_len_eq(b)) => a == b, - (&vec_len_ge(a), &vec_len_ge(b)) => a == b, + (&vec_len_ge(a, _), &vec_len_ge(b, _)) => a == b, _ => false } } @@ -273,7 +273,7 @@ pub fn trans_opt(bcx: block, o: &Opt) -> opt_result { vec_len_eq(n) => { return single_result(rslt(bcx, C_int(ccx, n as int))); } - vec_len_ge(n) => { + vec_len_ge(n, _) => { return lower_bound(rslt(bcx, C_int(ccx, n as int))); } } @@ -565,18 +565,22 @@ pub fn enter_opt(bcx: block, m: &[@Match/&r], opt: &Opt, col: uint, None } } - ast::pat_vec(elems, tail) => { - match tail { + ast::pat_vec(before, slice, after) => { + match slice { Some(_) => { - if opt_eq(tcx, &vec_len_ge(elems.len()), opt) { - Some(vec::append_one(elems, tail.get())) + let n = before.len() + after.len(); + let i = before.len(); + if opt_eq(tcx, &vec_len_ge(n, i), opt) { + Some(vec::concat( + &[before, ~[slice.get()], after])) } else { None } } None => { - if opt_eq(tcx, &vec_len_eq(elems.len()), opt) { - Some(copy elems) + let n = before.len(); + if opt_eq(tcx, &vec_len_eq(n), opt) { + Some(copy before) } else { None } @@ -807,10 +811,11 @@ pub fn get_options(bcx: block, m: &[@Match], col: uint) -> ~[Opt] { ast::pat_range(l1, l2) => { add_to_set(ccx.tcx, &mut found, range(l1, l2)); } - ast::pat_vec(elems, tail) => { - let opt = match tail { - None => vec_len_eq(elems.len()), - Some(_) => vec_len_ge(elems.len()) + ast::pat_vec(before, slice, after) => { + let opt = match slice { + None => vec_len_eq(before.len()), + Some(_) => vec_len_ge(before.len() + after.len(), + before.len()) }; add_to_set(ccx.tcx, &mut found, opt); } @@ -841,8 +846,9 @@ pub fn extract_variant_args(bcx: block, pub fn extract_vec_elems(bcx: block, pat_id: ast::node_id, elem_count: uint, - tail: bool, - val: ValueRef) + slice: Option, + val: ValueRef, + count: ValueRef) -> ExtractedBlock { let _icx = bcx.insn_ctxt("match::extract_vec_elems"); let vt = tvec::vec_types(bcx, node_id_type(bcx, pat_id)); @@ -850,26 +856,39 @@ pub fn extract_vec_elems(bcx: block, let (base, len) = tvec::get_base_and_len(bcx, unboxed, vt.vec_ty); let mut elems = do vec::from_fn(elem_count) |i| { - GEPi(bcx, base, ~[i]) + match slice { + None => GEPi(bcx, base, ~[i]), + Some(n) if i < n => GEPi(bcx, base, ~[i]), + Some(n) if i > n => { + InBoundsGEP(bcx, base, ~[ + Sub(bcx, count, + C_int(bcx.ccx(), (elem_count - i) as int))]) + } + _ => unsafe { llvm::LLVMGetUndef(vt.llunit_ty) } + } }; - if tail { - let tail_offset = Mul(bcx, vt.llunit_size, - C_int(bcx.ccx(), elem_count as int) + if slice.is_some() { + let n = slice.get(); + let slice_offset = Mul(bcx, vt.llunit_size, + C_int(bcx.ccx(), n as int) + ); + let slice_begin = tvec::pointer_add(bcx, base, slice_offset); + let slice_len_offset = Mul(bcx, vt.llunit_size, + C_int(bcx.ccx(), (elem_count - 1u) as int) ); - let tail_begin = tvec::pointer_add(bcx, base, tail_offset); - let tail_len = Sub(bcx, len, tail_offset); - let tail_ty = ty::mk_evec(bcx.tcx(), + let slice_len = Sub(bcx, len, slice_len_offset); + let slice_ty = ty::mk_evec(bcx.tcx(), ty::mt {ty: vt.unit_ty, mutbl: ast::m_imm}, ty::vstore_slice(ty::re_static) ); - let scratch = scratch_datum(bcx, tail_ty, false); - Store(bcx, tail_begin, + let scratch = scratch_datum(bcx, slice_ty, false); + Store(bcx, slice_begin, GEPi(bcx, scratch.val, [0u, abi::slice_elt_base]) ); - Store(bcx, tail_len, + Store(bcx, slice_len, GEPi(bcx, scratch.val, [0u, abi::slice_elt_len]) ); - elems.push(scratch.val); + elems[n] = scratch.val; scratch.add_clean(bcx); } @@ -1367,7 +1386,7 @@ pub fn compile_submatch(bcx: block, test_val = Load(bcx, val); kind = compare; }, - vec_len_eq(_) | vec_len_ge(_) => { + vec_len_eq(*) | vec_len_ge(*) => { let vt = tvec::vec_types(bcx, node_id_type(bcx, pat_id)); let unboxed = load_if_immediate(bcx, val, vt.vec_ty); let (_, len) = tvec::get_base_and_len( @@ -1511,12 +1530,17 @@ pub fn compile_submatch(bcx: block, unpacked = argvals; opt_cx = new_bcx; } - vec_len_eq(n) | vec_len_ge(n) => { - let tail = match *opt { - vec_len_ge(_) => true, - _ => false + vec_len_eq(n) | vec_len_ge(n, _) => { + let n = match *opt { + vec_len_ge(*) => n + 1u, + _ => n + }; + let slice = match *opt { + vec_len_ge(_, i) => Some(i), + _ => None }; - let args = extract_vec_elems(opt_cx, pat_id, n, tail, val); + let args = extract_vec_elems(opt_cx, pat_id, n, slice, + val, test_val); size = args.vals.len(); unpacked = /*bad*/copy args.vals; opt_cx = args.bcx; diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index e39de62cd297c..66a32335020ac 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -71,18 +71,16 @@ use util::ppaux::ty_to_str; /// Representations. pub enum Repr { - /** - * `Unit` exists only so that an enum with a single C-like variant - * can occupy no space, for ABI compatibility with rustc from - * before (and during) the creation of this module. It may not be - * worth keeping around; `CEnum` and `Univariant` cover it - * overwise. - */ - Unit(int), /// C-like enums; basically an int. CEnum(int, int), // discriminant range - /// Single-case variants, and structs/tuples/records. - Univariant(Struct, Destructor), + /** + * Single-case variants, and structs/tuples/records. + * + * Structs with destructors need a dynamic destroyedness flag to + * avoid running the destructor too many times; this is included + * in the `Struct` if present. + */ + Univariant(Struct, bool), /** * General-case enums: discriminant as int, followed by fields. * The fields start immediately after the discriminant, meaning @@ -92,18 +90,6 @@ pub enum Repr { General(~[Struct]) } -/** - * Structs without destructors have historically had an extra layer of - * LLVM-struct to make accessing them work the same as structs with - * destructors. This could probably be flattened to a boolean now - * that this module exists. - */ -enum Destructor { - StructWithDtor, - StructWithoutDtor, - NonStruct -} - /// For structs, and struct-like parts of anything fancier. struct Struct { size: u64, @@ -129,14 +115,17 @@ pub fn represent_type(cx: @CrateContext, t: ty::t) -> @Repr { } let repr = @match ty::get(t).sty { ty::ty_tup(ref elems) => { - Univariant(mk_struct(cx, *elems), NonStruct) + Univariant(mk_struct(cx, *elems), false) } ty::ty_struct(def_id, ref substs) => { let fields = ty::lookup_struct_fields(cx.tcx, def_id); - let dt = ty::ty_dtor(cx.tcx, def_id).is_present(); - Univariant(mk_struct(cx, fields.map(|field| { + let ftys = do fields.map |field| { ty::lookup_field_type(cx.tcx, def_id, field.id, substs) - })), if dt { StructWithDtor } else { StructWithoutDtor }) + }; + let dtor = ty::ty_dtor(cx.tcx, def_id).is_present(); + let ftys = + if dtor { ftys + [ty::mk_bool(cx.tcx)] } else { ftys }; + Univariant(mk_struct(cx, ftys), dtor) } ty::ty_enum(def_id, ref substs) => { struct Case { discr: int, tys: ~[ty::t] }; @@ -149,18 +138,15 @@ pub fn represent_type(cx: @CrateContext, t: ty::t) -> @Repr { }; if cases.len() == 0 { // Uninhabitable; represent as unit - Unit(0) - } else if cases.len() == 1 && cases[0].tys.len() == 0 { - // `()`-like; see comment on definition of `Unit`. - Unit(cases[0].discr) - } else if cases.len() == 1 { - // Equivalent to a struct/tuple/newtype. - fail_unless!(cases[0].discr == 0); - Univariant(mk_struct(cx, cases[0].tys), NonStruct) + Univariant(mk_struct(cx, ~[]), false) } else if cases.all(|c| c.tys.len() == 0) { // All bodies empty -> intlike let discrs = cases.map(|c| c.discr); CEnum(discrs.min(), discrs.max()) + } else if cases.len() == 1 { + // Equivalent to a struct/tuple/newtype. + fail_unless!(cases[0].discr == 0); + Univariant(mk_struct(cx, cases[0].tys), false) } else { // The general case. Since there's at least one // non-empty body, explicit discriminants should have @@ -204,18 +190,12 @@ pub fn sizing_fields_of(cx: @CrateContext, r: &Repr) -> ~[TypeRef] { fn generic_fields_of(cx: @CrateContext, r: &Repr, sizing: bool) -> ~[TypeRef] { match *r { - Unit(*) => ~[], CEnum(*) => ~[T_enum_discrim(cx)], - Univariant(ref st, dt) => { - let f = if sizing { + Univariant(ref st, _dtor) => { + if sizing { st.fields.map(|&ty| type_of::sizing_type_of(cx, ty)) } else { st.fields.map(|&ty| type_of::type_of(cx, ty)) - }; - match dt { - NonStruct => f, - StructWithoutDtor => ~[T_struct(f)], - StructWithDtor => ~[T_struct(f), T_i8()] } } General(ref sts) => { @@ -237,7 +217,7 @@ pub fn trans_switch(bcx: block, r: &Repr, scrutinee: ValueRef) CEnum(*) | General(*) => { (_match::switch, Some(trans_get_discr(bcx, r, scrutinee))) } - Unit(*) | Univariant(*) => { + Univariant(*) => { (_match::single, None) } } @@ -247,7 +227,6 @@ pub fn trans_switch(bcx: block, r: &Repr, scrutinee: ValueRef) pub fn trans_get_discr(bcx: block, r: &Repr, scrutinee: ValueRef) -> ValueRef { match *r { - Unit(the_disc) => C_int(bcx.ccx(), the_disc), CEnum(min, max) => load_discr(bcx, scrutinee, min, max), Univariant(*) => C_int(bcx.ccx(), 0), General(ref cases) => load_discr(bcx, scrutinee, 0, @@ -285,7 +264,7 @@ pub fn trans_case(bcx: block, r: &Repr, discr: int) -> _match::opt_result { CEnum(*) => { _match::single_result(rslt(bcx, C_int(bcx.ccx(), discr))) } - Unit(*) | Univariant(*)=> { + Univariant(*)=> { bcx.ccx().sess.bug(~"no cases for univariants or structs") } General(*) => { @@ -301,16 +280,14 @@ pub fn trans_case(bcx: block, r: &Repr, discr: int) -> _match::opt_result { */ pub fn trans_start_init(bcx: block, r: &Repr, val: ValueRef, discr: int) { match *r { - Unit(the_discr) => { - fail_unless!(discr == the_discr); - } CEnum(min, max) => { fail_unless!(min <= discr && discr <= max); Store(bcx, C_int(bcx.ccx(), discr), GEPi(bcx, val, [0, 0])) } - Univariant(_, StructWithDtor) => { + Univariant(ref st, true) => { fail_unless!(discr == 0); - Store(bcx, C_u8(1), GEPi(bcx, val, [0, 1])) + Store(bcx, C_bool(true), + GEPi(bcx, val, [0, st.fields.len() - 1])) } Univariant(*) => { fail_unless!(discr == 0); @@ -327,8 +304,11 @@ pub fn trans_start_init(bcx: block, r: &Repr, val: ValueRef, discr: int) { */ pub fn num_args(r: &Repr, discr: int) -> uint { match *r { - Unit(*) | CEnum(*) => 0, - Univariant(ref st, _) => { fail_unless!(discr == 0); st.fields.len() } + CEnum(*) => 0, + Univariant(ref st, dtor) => { + fail_unless!(discr == 0); + st.fields.len() - (if dtor { 1 } else { 0 }) + } General(ref cases) => cases[discr as uint].fields.len() } } @@ -340,15 +320,11 @@ pub fn trans_field_ptr(bcx: block, r: &Repr, val: ValueRef, discr: int, // decide to do some kind of cdr-coding-like non-unique repr // someday), it will need to return a possibly-new bcx as well. match *r { - Unit(*) | CEnum(*) => { + CEnum(*) => { bcx.ccx().sess.bug(~"element access in C-like enum") } - Univariant(ref st, dt) => { + Univariant(ref st, _dtor) => { fail_unless!(discr == 0); - let val = match dt { - NonStruct => val, - StructWithDtor | StructWithoutDtor => GEPi(bcx, val, [0, 0]) - }; struct_field_ptr(bcx, st, val, ix, false) } General(ref cases) => { @@ -376,7 +352,7 @@ fn struct_field_ptr(bcx: block, st: &Struct, val: ValueRef, ix: uint, /// Access the struct drop flag, if present. pub fn trans_drop_flag_ptr(bcx: block, r: &Repr, val: ValueRef) -> ValueRef { match *r { - Univariant(_, StructWithDtor) => GEPi(bcx, val, [0, 1]), + Univariant(ref st, true) => GEPi(bcx, val, [0, st.fields.len() - 1]), _ => bcx.ccx().sess.bug(~"tried to get drop flag of non-droppable \ type") } @@ -407,23 +383,14 @@ pub fn trans_drop_flag_ptr(bcx: block, r: &Repr, val: ValueRef) -> ValueRef { pub fn trans_const(ccx: @CrateContext, r: &Repr, discr: int, vals: &[ValueRef]) -> ValueRef { match *r { - Unit(*) => { - C_struct(~[]) - } CEnum(min, max) => { fail_unless!(vals.len() == 0); fail_unless!(min <= discr && discr <= max); C_int(ccx, discr) } - Univariant(ref st, dt) => { + Univariant(ref st, _dro) => { fail_unless!(discr == 0); - let s = C_struct(build_const_struct(ccx, st, vals)); - match dt { - NonStruct => s, - // The actual destructor flag doesn't need to be present. - // But add an extra struct layer for compatibility. - StructWithDtor | StructWithoutDtor => C_struct(~[s]) - } + C_struct(build_const_struct(ccx, st, vals)) } General(ref cases) => { let case = &cases[discr as uint]; @@ -489,7 +456,6 @@ fn roundup(x: u64, a: u64) -> u64 { ((x + (a - 1)) / a) * a } pub fn const_get_discrim(ccx: @CrateContext, r: &Repr, val: ValueRef) -> int { match *r { - Unit(discr) => discr, CEnum(*) => const_to_int(val) as int, Univariant(*) => 0, General(*) => const_to_int(const_get_elt(ccx, val, [0])) as int, @@ -506,11 +472,9 @@ pub fn const_get_discrim(ccx: @CrateContext, r: &Repr, val: ValueRef) pub fn const_get_field(ccx: @CrateContext, r: &Repr, val: ValueRef, _discr: int, ix: uint) -> ValueRef { match *r { - Unit(*) | CEnum(*) => ccx.sess.bug(~"element access in C-like enum \ + CEnum(*) => ccx.sess.bug(~"element access in C-like enum \ const"), - Univariant(_, NonStruct) => const_struct_field(ccx, val, ix), - Univariant(*) => const_struct_field(ccx, const_get_elt(ccx, val, - [0]), ix), + Univariant(*) => const_struct_field(ccx, val, ix), General(*) => const_struct_field(ccx, const_get_elt(ccx, val, [1, 0]), ix) } @@ -542,8 +506,7 @@ fn const_struct_field(ccx: @CrateContext, val: ValueRef, ix: uint) /// Is it safe to bitcast a value to the one field of its one variant? pub fn is_newtypeish(r: &Repr) -> bool { match *r { - Univariant(ref st, StructWithoutDtor) - | Univariant(ref st, NonStruct) => st.fields.len() == 1, + Univariant(ref st, false) => st.fields.len() == 1, _ => false } } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 7af1fcc7e779b..d4ed0004c8f9b 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -728,8 +728,8 @@ pub fn cast_shift_const_rhs(op: ast::binop, pub fn cast_shift_rhs(op: ast::binop, lhs: ValueRef, rhs: ValueRef, - trunc: fn(ValueRef, TypeRef) -> ValueRef, - zext: fn(ValueRef, TypeRef) -> ValueRef) + trunc: &fn(ValueRef, TypeRef) -> ValueRef, + zext: &fn(ValueRef, TypeRef) -> ValueRef) -> ValueRef { // Shifts may have any size int on the rhs unsafe { @@ -863,7 +863,7 @@ pub fn have_cached_lpad(bcx: block) -> bool { return res; } -pub fn in_lpad_scope_cx(bcx: block, f: fn(+si: &mut scope_info)) { +pub fn in_lpad_scope_cx(bcx: block, f: &fn(+si: &mut scope_info)) { let mut bcx = bcx; loop { { @@ -1326,7 +1326,7 @@ pub fn leave_block(bcx: block, out_of: block) -> block { pub fn with_scope(bcx: block, opt_node_info: Option, +name: ~str, - f: fn(block) -> block) -> block { + f: &fn(block) -> block) -> block { let _icx = bcx.insn_ctxt("with_scope"); debug!("with_scope(bcx=%s, opt_node_info=%?, name=%s)", @@ -1341,7 +1341,7 @@ pub fn with_scope(bcx: block, pub fn with_scope_result(bcx: block, opt_node_info: Option, +name: ~str, - f: fn(block) -> Result) -> Result { + f: &fn(block) -> Result) -> Result { let _icx = bcx.insn_ctxt("with_scope_result"); let scope_cx = scope_block(bcx, opt_node_info, name); Br(bcx, scope_cx.llbb); @@ -1350,7 +1350,7 @@ pub fn with_scope_result(bcx: block, } pub fn with_scope_datumblock(bcx: block, opt_node_info: Option, - +name: ~str, f: fn(block) -> datum::DatumBlock) + +name: ~str, f: &fn(block) -> datum::DatumBlock) -> datum::DatumBlock { use middle::trans::datum::DatumBlock; @@ -1361,7 +1361,7 @@ pub fn with_scope_datumblock(bcx: block, opt_node_info: Option, DatumBlock {bcx: leave_block(bcx, scope_cx), datum: datum} } -pub fn block_locals(b: &ast::blk, it: fn(@ast::local)) { +pub fn block_locals(b: &ast::blk, it: &fn(@ast::local)) { for vec::each(b.node.stmts) |s| { match s.node { ast::stmt_decl(d, _) => { @@ -1401,7 +1401,7 @@ pub fn alloc_local(cx: block, local: @ast::local) -> block { } -pub fn with_cond(bcx: block, val: ValueRef, f: fn(block) -> block) -> block { +pub fn with_cond(bcx: block, val: ValueRef, f: &fn(block) -> block) -> block { let _icx = bcx.insn_ctxt("with_cond"); let next_cx = base::sub_block(bcx, ~"next"); let cond_cx = base::sub_block(bcx, ~"cond"); @@ -1742,8 +1742,8 @@ pub fn trans_closure(ccx: @CrateContext, param_substs: Option<@param_substs>, id: ast::node_id, impl_id: Option, - maybe_load_env: fn(fn_ctxt), - finish: fn(block)) { + maybe_load_env: &fn(fn_ctxt), + finish: &fn(block)) { ccx.stats.n_closures += 1; let _icx = ccx.insn_ctxt("trans_closure"); set_uwtable(llfndecl); diff --git a/src/librustc/middle/trans/cabi.rs b/src/librustc/middle/trans/cabi.rs index 1d7314f751870..7e159ef606242 100644 --- a/src/librustc/middle/trans/cabi.rs +++ b/src/librustc/middle/trans/cabi.rs @@ -37,7 +37,7 @@ pub struct FnType { } pub impl FnType { - fn decl_fn(&self, decl: fn(fnty: TypeRef) -> ValueRef) -> ValueRef { + fn decl_fn(&self, decl: &fn(fnty: TypeRef) -> ValueRef) -> ValueRef { let atys = vec::map(self.arg_tys, |t| t.ty); let rty = self.ret_ty.ty; let fnty = T_fn(atys, rty); diff --git a/src/librustc/middle/trans/cabi_x86_64.rs b/src/librustc/middle/trans/cabi_x86_64.rs index 54b10e2ad5c62..d5877ec563123 100644 --- a/src/librustc/middle/trans/cabi_x86_64.rs +++ b/src/librustc/middle/trans/cabi_x86_64.rs @@ -346,7 +346,7 @@ fn x86_64_tys(atys: &[TypeRef], } fn x86_64_ty(ty: TypeRef, - is_mem_cls: fn(cls: &[x86_64_reg_class]) -> bool, + is_mem_cls: &fn(cls: &[x86_64_reg_class]) -> bool, attr: Attribute) -> (LLVMType, Option) { let mut cast = false; let mut ty_attr = option::None; diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index d4ff0d74a47b7..9e38252dc9a8a 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -438,7 +438,7 @@ pub fn trans_call_inner( call_info: Option, fn_expr_ty: ty::t, ret_ty: ty::t, - get_callee: fn(block) -> Callee, + get_callee: &fn(block) -> Callee, args: CallArgs, dest: expr::Dest, autoref_arg: AutorefArg) -> block { diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs index 556c15c446d2f..11d3e1552028f 100644 --- a/src/librustc/middle/trans/datum.rs +++ b/src/librustc/middle/trans/datum.rs @@ -515,7 +515,7 @@ pub impl Datum { fn get_element(&self, bcx: block, ty: ty::t, source: DatumCleanup, - gep: fn(ValueRef) -> ValueRef) -> Datum { + gep: &fn(ValueRef) -> ValueRef) -> Datum { let base_val = self.to_ref_llval(bcx); Datum { val: gep(base_val), diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 02b68afff4a82..af54d4734314c 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -190,7 +190,7 @@ fn md_from_metadata(val: debug_metadata) -> T { fn cached_metadata(cache: metadata_cache, mdtag: int, - eq_fn: fn(md: T) -> bool) + eq_fn: &fn(md: T) -> bool) -> Option { unsafe { if cache.contains_key(&mdtag) { diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index b7942fa66dbbd..e38b0be7bccba 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -1135,7 +1135,7 @@ pub fn trans_local_var(bcx: block, def: ast::def) -> Datum { pub fn with_field_tys(tcx: ty::ctxt, ty: ty::t, node_id_opt: Option, - op: fn(int, (&[ty::field])) -> R) -> R { + op: &fn(int, (&[ty::field])) -> R) -> R { match ty::get(ty).sty { ty::ty_struct(did, ref substs) => { op(0, struct_mutable_fields(tcx, did, substs)) diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 978b1ed16d841..b4ef87491a8a3 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -582,18 +582,20 @@ pub enum param_bound { } #[deriving_eq] -pub enum TyVid = uint; +pub struct TyVid(uint); #[deriving_eq] -pub enum IntVid = uint; +pub struct IntVid(uint); #[deriving_eq] -pub enum FloatVid = uint; +pub struct FloatVid(uint); #[deriving_eq] #[auto_encode] #[auto_decode] -pub enum RegionVid = uint; +pub struct RegionVid { + id: uint +} #[deriving_eq] pub enum InferTy { @@ -687,11 +689,11 @@ impl ToStr for FloatVid { } impl Vid for RegionVid { - pure fn to_uint(&self) -> uint { **self } + pure fn to_uint(&self) -> uint { self.id } } impl ToStr for RegionVid { - pure fn to_str(&self) -> ~str { fmt!("%?", self) } + pure fn to_str(&self) -> ~str { fmt!("%?", self.id) } } impl ToStr for FnSig { @@ -1138,11 +1140,11 @@ pub fn encl_region(cx: ctxt, id: ast::node_id) -> ty::Region { } } -pub fn walk_ty(ty: t, f: fn(t)) { +pub fn walk_ty(ty: t, f: &fn(t)) { maybe_walk_ty(ty, |t| { f(t); true }); } -pub fn maybe_walk_ty(ty: t, f: fn(t) -> bool) { +pub fn maybe_walk_ty(ty: t, f: &fn(t) -> bool) { if !f(ty) { return; } match /*bad*/copy get(ty).sty { ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) | @@ -1170,11 +1172,11 @@ pub fn maybe_walk_ty(ty: t, f: fn(t) -> bool) { } } -pub fn fold_sty_to_ty(tcx: ty::ctxt, sty: &sty, foldop: fn(t) -> t) -> t { +pub fn fold_sty_to_ty(tcx: ty::ctxt, sty: &sty, foldop: &fn(t) -> t) -> t { mk_t(tcx, fold_sty(sty, foldop)) } -pub fn fold_sig(sig: &FnSig, fldop: fn(t) -> t) -> FnSig { +pub fn fold_sig(sig: &FnSig, fldop: &fn(t) -> t) -> FnSig { let args = do sig.inputs.map |arg| { arg { mode: arg.mode, ty: fldop(arg.ty) } }; @@ -1185,8 +1187,8 @@ pub fn fold_sig(sig: &FnSig, fldop: fn(t) -> t) -> FnSig { } } -fn fold_sty(sty: &sty, fldop: fn(t) -> t) -> sty { - fn fold_substs(substs: &substs, fldop: fn(t) -> t) -> substs { +fn fold_sty(sty: &sty, fldop: &fn(t) -> t) -> sty { + fn fold_substs(substs: &substs, fldop: &fn(t) -> t) -> substs { substs {self_r: substs.self_r, self_ty: substs.self_ty.map(|t| fldop(*t)), tps: substs.tps.map(|t| fldop(*t))} @@ -1241,7 +1243,7 @@ fn fold_sty(sty: &sty, fldop: fn(t) -> t) -> sty { } // Folds types from the bottom up. -pub fn fold_ty(cx: ctxt, t0: t, fldop: fn(t) -> t) -> t { +pub fn fold_ty(cx: ctxt, t0: t, fldop: &fn(t) -> t) -> t { let sty = fold_sty(&get(t0).sty, |t| fold_ty(cx, fldop(t), fldop)); fldop(mk_t(cx, sty)) } @@ -1249,8 +1251,8 @@ pub fn fold_ty(cx: ctxt, t0: t, fldop: fn(t) -> t) -> t { pub fn walk_regions_and_ty( cx: ctxt, ty: t, - walkr: fn(r: Region), - walkt: fn(t: t) -> bool) { + walkr: &fn(r: Region), + walkt: &fn(t: t) -> bool) { if (walkt(ty)) { fold_regions_and_ty( @@ -1264,14 +1266,14 @@ pub fn walk_regions_and_ty( pub fn fold_regions_and_ty( cx: ctxt, ty: t, - fldr: fn(r: Region) -> Region, - fldfnt: fn(t: t) -> t, - fldt: fn(t: t) -> t) -> t { + fldr: &fn(r: Region) -> Region, + fldfnt: &fn(t: t) -> t, + fldt: &fn(t: t) -> t) -> t { fn fold_substs( substs: &substs, - fldr: fn(r: Region) -> Region, - fldt: fn(t: t) -> t) + fldr: &fn(r: Region) -> Region, + fldt: &fn(t: t) -> t) -> substs { substs { self_r: substs.self_r.map(|r| fldr(*r)), @@ -1325,9 +1327,9 @@ pub fn fold_regions_and_ty( pub fn fold_regions( cx: ctxt, ty: t, - fldr: fn(r: Region, in_fn: bool) -> Region) -> t { + fldr: &fn(r: Region, in_fn: bool) -> Region) -> t { fn do_fold(cx: ctxt, ty: t, in_fn: bool, - fldr: fn(Region, bool) -> Region) -> t { + fldr: &fn(Region, bool) -> Region) -> t { debug!("do_fold(ty=%s, in_fn=%b)", ty_to_str(cx, ty), in_fn); if !type_has_regions(ty) { return ty; } fold_regions_and_ty( @@ -2274,7 +2276,7 @@ pub fn is_instantiable(cx: ctxt, r_ty: t) -> bool { pub fn type_structurally_contains(cx: ctxt, ty: t, - test: fn(x: &sty) -> bool) + test: &fn(x: &sty) -> bool) -> bool { let sty = &get(ty).sty; debug!("type_structurally_contains: %s", @@ -4008,7 +4010,7 @@ pub fn struct_fields(cx: ctxt, fn struct_item_fields(cx:ctxt, did: ast::def_id, substs: &substs, - frob_mutability: fn(struct_mutability) -> mutability) + frob_mutability: &fn(struct_mutability) -> mutability) -> ~[field] { do lookup_struct_fields(cx, did).map |f| { // consider all instance vars mut, because the diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 0b6c07832f634..6c27decc28345 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -36,7 +36,7 @@ * scopes and (b) the default region may change. To understand case (a), * consider something like: * - * type foo = { x: &a.int, y: fn(&a.int) } + * type foo = { x: &a.int, y: &fn(&a.int) } * * The type of `x` is an error because there is no region `a` in scope. * In the type of `y`, however, region `a` is considered a bound region @@ -65,7 +65,8 @@ use core::result; use core::vec; use syntax::ast; use syntax::codemap::span; -use syntax::print::pprust::{region_to_str, path_to_str}; +use syntax::print::pprust::{lifetime_to_str, path_to_str}; +use syntax::parse::token::special_idents; use util::common::indenter; pub trait AstConv { @@ -79,7 +80,7 @@ pub trait AstConv { pub fn get_region_reporting_err( tcx: ty::ctxt, span: span, - a_r: Option<@ast::region>, + a_r: Option<@ast::Lifetime>, res: Result) -> ty::Region { match res { @@ -87,13 +88,8 @@ pub fn get_region_reporting_err( result::Err(ref e) => { let descr = match a_r { None => ~"anonymous lifetime", - Some(a) if a.node == ast::re_anon => { - ~"anonymous lifetime" - } - Some(a) => { - fmt!("lifetime %s", - region_to_str(a, tcx.sess.intr())) - } + Some(a) => fmt!("lifetime %s", + lifetime_to_str(a, tcx.sess.intr())) }; tcx.sess.span_err( span, @@ -105,19 +101,28 @@ pub fn get_region_reporting_err( } pub fn ast_region_to_region( - self: &AC, - rscope: &RS, - span: span, - a_r: @ast::region) - -> ty::Region { - let res = match a_r.node { - ast::re_static => Ok(ty::re_static), - ast::re_anon => rscope.anon_region(span), - ast::re_self => rscope.self_region(span), - ast::re_named(id) => rscope.named_region(span, id) + self: &AC, + rscope: &RS, + default_span: span, + opt_lifetime: Option<@ast::Lifetime>) -> ty::Region +{ + let (span, res) = match opt_lifetime { + None => { + (default_span, rscope.anon_region(default_span)) + } + Some(ref lifetime) if lifetime.ident == special_idents::static => { + (lifetime.span, Ok(ty::re_static)) + } + Some(ref lifetime) if lifetime.ident == special_idents::self_ => { + (lifetime.span, rscope.self_region(lifetime.span)) + } + Some(ref lifetime) => { + (lifetime.span, rscope.named_region(lifetime.span, + lifetime.ident)) + } }; - get_region_reporting_err(self.tcx(), span, Some(a_r), res) + get_region_reporting_err(self.tcx(), span, opt_lifetime, res) } pub fn ast_path_to_substs_and_ty( @@ -156,8 +161,8 @@ pub fn ast_path_to_substs_and_ty( let r = get_region_reporting_err(self.tcx(), path.span, None, res); Some(r) } - (Some(_), Some(r)) => { - Some(ast_region_to_region(self, rscope, path.span, r)) + (Some(_), Some(_)) => { + Some(ast_region_to_region(self, rscope, path.span, path.rp)) } }; @@ -219,7 +224,7 @@ pub fn ast_ty_to_ty( rscope: &RS, a_seq_ty: ast::mt, vst: ty::vstore, - constr: fn(ty::mt) -> ty::t) -> ty::t + constr: &fn(ty::mt) -> ty::t) -> ty::t { let tcx = self.tcx(); @@ -504,7 +509,7 @@ pub fn ty_of_closure( sigil: ast::Sigil, purity: ast::purity, onceness: ast::Onceness, - opt_region: Option<@ast::region>, + opt_lifetime: Option<@ast::Lifetime>, decl: &ast::fn_decl, expected_tys: Option, span: span) @@ -514,9 +519,9 @@ pub fn ty_of_closure( // resolve the function bound region in the original region // scope `rscope`, not the scope of the function parameters - let bound_region = match opt_region { - Some(region) => { - ast_region_to_region(self, rscope, span, region) + let bound_region = match opt_lifetime { + Some(_) => { + ast_region_to_region(self, rscope, span, opt_lifetime) } None => { match sigil { @@ -526,9 +531,8 @@ pub fn ty_of_closure( ty::re_static } ast::BorrowedSigil => { - // &fn() defaults to an anonymous region: - let r_result = rscope.anon_region(span); - get_region_reporting_err(self.tcx(), span, None, r_result) + // &fn() defaults as normal for an omitted lifetime: + ast_region_to_region(self, rscope, span, opt_lifetime) } } } diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs index 1da4cbe7c91cc..4b7def26fd559 100644 --- a/src/librustc/middle/typeck/check/_match.rs +++ b/src/librustc/middle/typeck/check/_match.rs @@ -509,7 +509,7 @@ pub fn check_pat(pcx: pat_ctxt, pat: @ast::pat, expected: ty::t) { } } } - ast::pat_vec(elts, tail) => { + ast::pat_vec(before, slice, after) => { let default_region_var = fcx.infcx().next_region_var_with_lb( pat.span, pcx.block_region @@ -538,21 +538,23 @@ pub fn check_pat(pcx: pat_ctxt, pat: @ast::pat, expected: ty::t) { ); } }; - for elts.each |elt| { + for before.each |elt| { check_pat(pcx, *elt, elt_type.ty); } - fcx.write_ty(pat.id, expected); - - match tail { - Some(tail_pat) => { + match slice { + Some(slice_pat) => { let slice_ty = ty::mk_evec(tcx, ty::mt {ty: elt_type.ty, mutbl: elt_type.mutbl}, ty::vstore_slice(region_var) ); - check_pat(pcx, tail_pat, slice_ty); + check_pat(pcx, slice_pat, slice_ty); } None => () } + for after.each |elt| { + check_pat(pcx, *elt, elt_type.ty); + } + fcx.write_ty(pat.id, expected); } } } diff --git a/src/librustc/middle/typeck/check/demand.rs b/src/librustc/middle/typeck/check/demand.rs index a3fac8b4e1cde..1bb71c156c3dc 100644 --- a/src/librustc/middle/typeck/check/demand.rs +++ b/src/librustc/middle/typeck/check/demand.rs @@ -33,7 +33,7 @@ pub fn subtype(fcx: @mut FnCtxt, sp: span, expected: ty::t, actual: ty::t) { pub fn suptype_with_fn(fcx: @mut FnCtxt, sp: span, b_is_expected: bool, ty_a: ty::t, ty_b: ty::t, - handle_err: fn(span, ty::t, ty::t, &ty::type_err)) { + handle_err: &fn(span, ty::t, ty::t, &ty::type_err)) { // n.b.: order of actual, expected is reversed match infer::mk_subty(fcx.infcx(), b_is_expected, sp, ty_b, ty_a) { diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index 0bcbb3012cf10..d6060c1ae316d 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -105,17 +105,24 @@ use syntax::ast::{m_const, m_mutbl, m_imm}; use syntax::ast; use syntax::ast_map; +#[deriving_eq] +pub enum CheckTraitsFlag { + CheckTraitsOnly, + CheckTraitsAndInherentMethods, +} + pub fn lookup( fcx: @mut FnCtxt, // In a call `a.b::(...)`: - expr: @ast::expr, // The expression `a.b`. - self_expr: @ast::expr, // The expression `a`. - callee_id: node_id, // Where to store the type of `a.b` - m_name: ast::ident, // The ident `b`. - self_ty: ty::t, // The type of `a`. - supplied_tps: &[ty::t], // The list of types X, Y, ... . - deref_args: check::DerefArgs) // Whether we autopointer first. + expr: @ast::expr, // The expression `a.b`. + self_expr: @ast::expr, // The expression `a`. + callee_id: node_id, // Where to store the type of `a.b` + m_name: ast::ident, // The ident `b`. + self_ty: ty::t, // The type of `a`. + supplied_tps: &[ty::t], // The list of types X, Y, ... . + deref_args: check::DerefArgs, // Whether we autopointer first. + check_traits: CheckTraitsFlag) // Whether we check traits only. -> Option { let lcx = LookupContext { @@ -129,6 +136,7 @@ pub fn lookup( inherent_candidates: @mut ~[], extension_candidates: @mut ~[], deref_args: deref_args, + check_traits: check_traits, }; let mme = lcx.do_lookup(self_ty); debug!("method lookup for %s yielded %?", @@ -147,6 +155,7 @@ pub struct LookupContext { inherent_candidates: @mut ~[Candidate], extension_candidates: @mut ~[Candidate], deref_args: check::DerefArgs, + check_traits: CheckTraitsFlag, } /** @@ -235,7 +244,8 @@ pub impl LookupContext/&self { self.search_for_autosliced_method(self_ty, autoderefs) } - fn deref(ty: ty::t, enum_dids: &mut ~[ast::def_id]) -> Option { + fn deref(&self, ty: ty::t, enum_dids: &mut ~[ast::def_id]) + -> Option { match ty::get(ty).sty { ty_enum(did, _) => { // Watch out for newtype'd enums like "enum t = @T". @@ -298,7 +308,9 @@ pub impl LookupContext/&self { self_ty, self_did, &substs); } ty_enum(did, _) | ty_struct(did, _) => { - self.push_inherent_impl_candidates_for_type(did); + if self.check_traits == CheckTraitsAndInherentMethods { + self.push_inherent_impl_candidates_for_type(did); + } } _ => { /* No inherent methods in these types */ } } @@ -599,7 +611,7 @@ pub impl LookupContext/&self { } } - fn push_inherent_impl_candidates_for_type(did: def_id) { + fn push_inherent_impl_candidates_for_type(&self, did: def_id) { let opt_impl_infos = self.fcx.ccx.coherence_info.inherent_methods.find(&did); for opt_impl_infos.each |impl_infos| { diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 6efa62c55cc24..6617fa3b27c91 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -89,7 +89,8 @@ use middle::typeck::astconv::{AstConv, ast_path_to_ty}; use middle::typeck::astconv::{ast_region_to_region, ast_ty_to_ty}; use middle::typeck::astconv; use middle::typeck::check::_match::pat_ctxt; -use middle::typeck::check::method::TransformTypeNormally; +use middle::typeck::check::method::{CheckTraitsAndInherentMethods}; +use middle::typeck::check::method::{CheckTraitsOnly, TransformTypeNormally}; use middle::typeck::check::regionmanip::replace_bound_regions_in_fn_sig; use middle::typeck::check::vtable::{LocationInfo, VtableContext}; use middle::typeck::CrateCtxt; @@ -162,7 +163,17 @@ pub struct inherited { adjustments: HashMap } -pub enum FnKind { ForLoop, DoBlock, Vanilla } +pub enum FnKind { + // This is a for-closure. The ty::t is the return type of the + // enclosing function. + ForLoop(ty::t), + + // A do-closure. + DoBlock, + + // A normal closure or fn item. + Vanilla +} pub struct FnCtxt { // var_bindings, locals and next_var_id are shared @@ -250,8 +261,14 @@ pub fn check_bare_fn(ccx: @mut CrateCtxt, let fty = ty::node_id_to_type(ccx.tcx, id); match ty::get(fty).sty { ty::ty_bare_fn(ref fn_ty) => { - check_fn(ccx, self_info, fn_ty.purity, None, - &fn_ty.sig, decl, body, Vanilla, None) + let fcx = + check_fn(ccx, self_info, fn_ty.purity, + &fn_ty.sig, decl, body, Vanilla, + @Nil, blank_inherited(ccx));; + + vtable::resolve_in_block(fcx, body); + regionck::regionck_fn(fcx, body); + writeback::resolve_type_vars_in_fn(fcx, decl, body, self_info); } _ => ccx.tcx.sess.impossible_case(body.span, "check_bare_fn: function type expected") @@ -261,16 +278,26 @@ pub fn check_bare_fn(ccx: @mut CrateCtxt, pub fn check_fn(ccx: @mut CrateCtxt, +self_info: Option, purity: ast::purity, - sigil: Option, fn_sig: &ty::FnSig, decl: &ast::fn_decl, body: &ast::blk, fn_kind: FnKind, - old_fcx: Option<@mut FnCtxt>) { + inherited_isr: isr_alist, + inherited: @inherited) -> @mut FnCtxt +{ + /*! + * + * Helper used by check_bare_fn and check_expr_fn. Does the + * grungy work of checking a function body and returns the + * function context used for that purpose, since in the case of a + * fn item there is still a bit more to do. + * + * - ... + * - inherited_isr: regions in scope from the enclosing fn (if any) + * - inherited: other fields inherited from the enclosing fn (if any) + */ + let tcx = ccx.tcx; - let indirect_ret = match fn_kind { - ForLoop => true, _ => false - }; // ______________________________________________________________________ // First, we have to replace any bound regions in the fn and self @@ -278,9 +305,7 @@ pub fn check_fn(ccx: @mut CrateCtxt, // the node_id of the body block. let (isr, self_info, fn_sig) = { - let old_isr = option::map_default(&old_fcx, @Nil, - |fcx| fcx.in_scope_regions); - replace_bound_regions_in_fn_sig(tcx, old_isr, self_info, fn_sig, + replace_bound_regions_in_fn_sig(tcx, inherited_isr, self_info, fn_sig, |br| ty::re_free(body.node.id, br)) }; @@ -296,23 +321,13 @@ pub fn check_fn(ccx: @mut CrateCtxt, // Create the function context. This is either derived from scratch or, // in the case of function expressions, based on the outer context. let fcx: @mut FnCtxt = { - let (purity, inherited) = match old_fcx { - None => (purity, blank_inherited(ccx)), - Some(fcx) => { - (ty::determine_inherited_purity(fcx.purity, purity, - sigil.get()), - fcx.inh) - } + // In a for-loop, you have an 'indirect return' because return + // does not return out of the directly enclosing fn + let indirect_ret_ty = match fn_kind { + ForLoop(t) => Some(t), + DoBlock | Vanilla => None }; - let indirect_ret_ty = if indirect_ret { - let ofcx = old_fcx.get(); - match ofcx.indirect_ret_ty { - Some(t) => Some(t), - None => Some(ofcx.ret_ty) - } - } else { None }; - @mut FnCtxt { self_info: self_info, ret_ty: ret_ty, @@ -370,15 +385,7 @@ pub fn check_fn(ccx: @mut CrateCtxt, fcx.write_ty(input.id, *arg); } - // If we don't have any enclosing function scope, it is time to - // force any remaining type vars to be resolved. - // If we have an enclosing function scope, our type variables will be - // resolved when the enclosing scope finishes up. - if old_fcx.is_none() { - vtable::resolve_in_block(fcx, body); - regionck::regionck_fn(fcx, body); - writeback::resolve_type_vars_in_fn(fcx, decl, body, self_info); - } + return fcx; fn gather_locals(fcx: @mut FnCtxt, decl: &ast::fn_decl, @@ -903,7 +910,7 @@ pub impl FnCtxt { a: ty::t, err: &ty::type_err) { match self.fn_kind { - ForLoop if !ty::type_is_bool(e) && !ty::type_is_nil(a) => + ForLoop(_) if !ty::type_is_bool(e) && !ty::type_is_nil(a) => self.tcx().sess.span_err(sp, fmt!("A for-loop body must \ return (), but it returns %s here. \ Perhaps you meant to write a `do`-block?", @@ -1136,7 +1143,7 @@ pub fn break_here() { pub fn check_expr_with_unifier(fcx: @mut FnCtxt, expr: @ast::expr, expected: Option, - unifier: fn()) -> bool { + unifier: &fn()) -> bool { debug!(">> typechecking %s", fcx.expr_to_str(expr)); // A generic function to factor out common logic from call and @@ -1365,7 +1372,8 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, method_name, expr_t, tps, - DontDerefArgs) { + DontDerefArgs, + CheckTraitsAndInherentMethods) { Some(ref entry) => { let method_map = fcx.ccx.method_map; method_map.insert(expr.id, (*entry)); @@ -1447,9 +1455,15 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, +args: ~[@ast::expr], +deref_args: DerefArgs) -> Option<(ty::t, bool)> { - match method::lookup(fcx, op_ex, self_ex, - op_ex.callee_id, opname, self_t, ~[], - deref_args) { + match method::lookup(fcx, + op_ex, + self_ex, + op_ex.callee_id, + opname, + self_t, + ~[], + deref_args, + CheckTraitsOnly) { Some(ref origin) => { let method_ty = fcx.node_ty(op_ex.callee_id); let method_map = fcx.ccx.method_map; @@ -1596,7 +1610,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, // returns `none`. fn unpack_expected(fcx: @mut FnCtxt, expected: Option, - unpack: fn(&ty::sty) -> Option) + unpack: &fn(&ty::sty) -> Option) -> Option { match expected { Some(t) => { @@ -1667,10 +1681,15 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, fcx.write_ty(expr.id, fty); + let inherited_purity = + ty::determine_inherited_purity(fcx.purity, purity, + fn_ty.sigil); + // We inherit the same self info as the enclosing scope, // since the function we're checking might capture `self` - check_fn(fcx.ccx, fcx.self_info, fn_ty.purity, Some(fn_ty.sigil), - &fn_ty.sig, decl, body, fn_kind, Some(fcx)); + check_fn(fcx.ccx, fcx.self_info, inherited_purity, + &fn_ty.sig, decl, body, fn_kind, + fcx.in_scope_regions, fcx.inh); } @@ -1721,7 +1740,8 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, field, expr_t, tps, - DontDerefArgs) { + DontDerefArgs, + CheckTraitsAndInherentMethods) { Some(ref entry) => { let method_map = fcx.ccx.method_map; method_map.insert(expr.id, (*entry)); @@ -2080,7 +2100,13 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, // derived errors. If we passed in ForLoop in the // error case, we'd potentially emit a spurious error // message because of the indirect_ret_ty. - let fn_kind = if err_happened {Vanilla} else {ForLoop}; + let fn_kind = if err_happened { + Vanilla + } else { + let indirect_ret_ty = + fcx.indirect_ret_ty.get_or_default(fcx.ret_ty); + ForLoop(indirect_ret_ty) + }; check_expr_fn(fcx, loop_body, None, decl, body, fn_kind, Some(inner_ty)); demand::suptype(fcx, loop_body.span, @@ -2950,19 +2976,19 @@ pub fn instantiate_path(fcx: @mut FnCtxt, // determine the region bound, using the value given by the user // (if any) and otherwise using a fresh region variable let self_r = match pth.rp { - Some(r) => { + Some(_) => { // user supplied a lifetime parameter... match tpt.region_param { - None => { + None => { // ...but the type is not lifetime parameterized! fcx.ccx.tcx.sess.span_err (span, ~"this item is not region-parameterized"); None } - Some(_) => { - Some(ast_region_to_region(fcx, fcx, span, r)) + Some(_) => { // ...and the type is lifetime parameterized, ok. + Some(ast_region_to_region(fcx, fcx, span, pth.rp)) } } } - None => { + None => { // no lifetime parameter supplied, insert default fcx.region_var_if_parameterized( tpt.region_param, span, region_lb) } diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs index 818a444a4f38c..55d027549e30c 100644 --- a/src/librustc/middle/typeck/check/regionck.rs +++ b/src/librustc/middle/typeck/check/regionck.rs @@ -896,7 +896,7 @@ pub mod guarantor { } ast::pat_lit(*) => {} ast::pat_range(*) => {} - ast::pat_vec(ref ps, ref opt_tail_pat) => { + ast::pat_vec(ref before, ref slice, ref after) => { let vec_ty = rcx.resolve_node_type(pat.id); if !ty::type_contains_err(vec_ty) { let vstore = ty::ty_vstore(vec_ty); @@ -906,11 +906,11 @@ pub mod guarantor { ty::vstore_box => None }; - link_ref_bindings_in_pats(rcx, ps, guarantor1); - - for opt_tail_pat.each |p| { - link_ref_bindings_in_pat(rcx, *p, guarantor); + link_ref_bindings_in_pats(rcx, before, guarantor1); + for slice.each |&p| { + link_ref_bindings_in_pat(rcx, p, guarantor); } + link_ref_bindings_in_pats(rcx, after, guarantor1); } } } diff --git a/src/librustc/middle/typeck/check/regionmanip.rs b/src/librustc/middle/typeck/check/regionmanip.rs index a5c64e7c8736b..98f49e48c0849 100644 --- a/src/librustc/middle/typeck/check/regionmanip.rs +++ b/src/librustc/middle/typeck/check/regionmanip.rs @@ -30,7 +30,7 @@ pub fn replace_bound_regions_in_fn_sig( isr: isr_alist, self_info: Option, fn_sig: &ty::FnSig, - mapf: fn(ty::bound_region) -> ty::Region) -> + mapf: &fn(ty::bound_region) -> ty::Region) -> (isr_alist, Option, ty::FnSig) { // Take self_info apart; the self_ty part is the only one we want // to update here. @@ -96,7 +96,7 @@ pub fn replace_bound_regions_in_fn_sig( tcx: ty::ctxt, isr: isr_alist, tys: ~[ty::t], - to_r: fn(ty::bound_region) -> ty::Region) -> isr_alist { + to_r: &fn(ty::bound_region) -> ty::Region) -> isr_alist { // Takes `isr` (described above), `to_r` (described above), // and `r`, a region. If `r` is anything other than a bound @@ -106,7 +106,7 @@ pub fn replace_bound_regions_in_fn_sig( // updated isr_alist that now contains a mapping from `r` to // the result of calling `to_r` on it. fn append_isr(isr: isr_alist, - to_r: fn(ty::bound_region) -> ty::Region, + to_r: &fn(ty::bound_region) -> ty::Region, r: ty::Region) -> isr_alist { match r { ty::re_free(_, _) | ty::re_static | ty::re_scope(_) | diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index 3e45323807212..00352ba29582a 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -191,15 +191,14 @@ pub struct CoherenceChecker { } pub impl CoherenceChecker { - // IMPLICIT SELF WARNING: fix this! - fn check_coherence(crate: @crate) { + fn check_coherence(self, crate: @crate) { // Check implementations and traits. This populates the tables // containing the inherent methods and extension methods. It also // builds up the trait inheritance table. visit_crate(*crate, (), mk_simple_visitor(@SimpleVisitor { visit_item: |item| { - debug!("(checking coherence) item '%s'", - *self.crate_context.tcx.sess.str_of(item.ident)); +// debug!("(checking coherence) item '%s'", +// self.crate_context.tcx.sess.str_of(item.ident)); match item.node { item_impl(_, opt_trait, _, _) => { @@ -617,8 +616,7 @@ pub impl CoherenceChecker { } // Privileged scope checking - // IMPLICIT SELF WARNING: fix this! - fn check_privileged_scopes(crate: @crate) { + fn check_privileged_scopes(self, crate: @crate) { visit_crate(*crate, (), mk_vt(@Visitor { visit_item: |item, _context, visitor| { match /*bad*/copy item.node { diff --git a/src/librustc/middle/typeck/infer/coercion.rs b/src/librustc/middle/typeck/infer/coercion.rs index 2390e73f16f9a..91c987acc6aa7 100644 --- a/src/librustc/middle/typeck/infer/coercion.rs +++ b/src/librustc/middle/typeck/infer/coercion.rs @@ -84,7 +84,7 @@ use syntax::ast; // Note: Coerce is not actually a combiner, in that it does not // conform to the same interface, though it performs a similar // function. -pub enum Coerce = CombineFields; +pub struct Coerce(CombineFields); pub impl Coerce { fn tys(&self, a: ty::t, b: ty::t) -> CoerceResult { diff --git a/src/librustc/middle/typeck/infer/glb.rs b/src/librustc/middle/typeck/infer/glb.rs index dd9bf9cac64bf..bba35f02b0c1e 100644 --- a/src/librustc/middle/typeck/infer/glb.rs +++ b/src/librustc/middle/typeck/infer/glb.rs @@ -29,7 +29,7 @@ use util::ppaux::mt_to_str; use std::list; -pub enum Glb = CombineFields; // "greatest lower bound" (common subtype) +pub struct Glb(CombineFields); // "greatest lower bound" (common subtype) impl Combine for Glb { fn infcx(&self) -> @mut InferCtxt { self.infcx } @@ -228,7 +228,7 @@ impl Combine for Glb { // NB---I do not believe this algorithm computes // (necessarily) the GLB. As written it can // spuriously fail. In particular, if there is a case - // like: fn(fn(&a)) and fn(fn(&b)), where a and b are + // like: &fn(fn(&a)) and fn(fn(&b)), where a and b are // free, it will return fn(&c) where c = GLB(a,b). If // however this GLB is not defined, then the result is // an error, even though something like diff --git a/src/librustc/middle/typeck/infer/lub.rs b/src/librustc/middle/typeck/infer/lub.rs index 83cbd4c745c0c..3a12fb31a1a6f 100644 --- a/src/librustc/middle/typeck/infer/lub.rs +++ b/src/librustc/middle/typeck/infer/lub.rs @@ -29,7 +29,7 @@ use syntax::ast::{pure_fn, ret_style, return_val, unsafe_fn}; use syntax::ast::{Onceness, purity}; use syntax::codemap::span; -pub enum Lub = CombineFields; // least-upper-bound: common supertype +pub struct Lub(CombineFields); // least-upper-bound: common supertype pub impl Lub { fn bot_ty(&self, b: ty::t) -> cres { Ok(b) } diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs index 9cb6c473d586b..f68a0db63870b 100644 --- a/src/librustc/middle/typeck/infer/mod.rs +++ b/src/librustc/middle/typeck/infer/mod.rs @@ -481,12 +481,12 @@ fn resolve_borrowings(cx: @mut InferCtxt) { */ trait then { - fn then(&self, f: fn() -> Result) + fn then(&self, f: &fn() -> Result) -> Result; } impl then for ures { - fn then(&self, f: fn() -> Result) + fn then(&self, f: &fn() -> Result) -> Result { self.chain(|_i| f()) } @@ -506,11 +506,11 @@ impl ToUres for cres { } trait CresCompare { - fn compare(&self, t: T, f: fn() -> ty::type_err) -> cres; + fn compare(&self, t: T, f: &fn() -> ty::type_err) -> cres; } impl CresCompare for cres { - fn compare(&self, t: T, f: fn() -> ty::type_err) -> cres { + fn compare(&self, t: T, f: &fn() -> ty::type_err) -> cres { do self.chain |s| { if s == t { *self @@ -584,7 +584,7 @@ pub impl @mut InferCtxt { } /// Execute `f` and commit the bindings if successful - fn commit(f: fn() -> Result) -> Result { + fn commit(&self, f: &fn() -> Result) -> Result { fail_unless!(!self.in_snapshot()); debug!("commit()"); @@ -599,7 +599,7 @@ pub impl @mut InferCtxt { } /// Execute `f`, unroll bindings on failure - fn try(f: fn() -> Result) -> Result { + fn try(&self, f: &fn() -> Result) -> Result { debug!("try()"); do indent { let snapshot = self.start_snapshot(); @@ -613,7 +613,7 @@ pub impl @mut InferCtxt { } /// Execute `f` then unroll any bindings it creates - fn probe(f: fn() -> Result) -> Result { + fn probe(&self, f: &fn() -> Result) -> Result { debug!("probe()"); do indent { let snapshot = self.start_snapshot(); @@ -706,7 +706,7 @@ pub impl @mut InferCtxt { } } - fn type_error_message(&self, sp: span, mk_msg: fn(~str) -> ~str, + fn type_error_message(&self, sp: span, mk_msg: &fn(~str) -> ~str, actual_ty: ty::t, err: Option<&ty::type_err>) { let actual_ty = self.resolve_type_vars_if_possible(actual_ty); diff --git a/src/librustc/middle/typeck/infer/region_inference.rs b/src/librustc/middle/typeck/infer/region_inference.rs index 35c901c7528de..33e953b6218d9 100644 --- a/src/librustc/middle/typeck/infer/region_inference.rs +++ b/src/librustc/middle/typeck/infer/region_inference.rs @@ -153,7 +153,7 @@ The problem we are addressing is that there is a kind of subtyping between functions with bound region parameters. Consider, for example, whether the following relation holds: - fn(&a/int) <: fn(&b/int)? (Yes, a => b) + fn(&a/int) <: &fn(&b/int)? (Yes, a => b) The answer is that of course it does. These two types are basically the same, except that in one we used the name `a` and one we used @@ -170,7 +170,7 @@ Now let's consider two more function types. Here, we assume that the `self` lifetime is defined somewhere outside and hence is not a lifetime parameter bound by the function type (it "appears free"): - fn(&a/int) <: fn(&self/int)? (Yes, a => self) + fn(&a/int) <: &fn(&self/int)? (Yes, a => self) This subtyping relation does in fact hold. To see why, you have to consider what subtyping means. One way to look at `T1 <: T2` is to @@ -187,7 +187,7 @@ to the same thing: a function that accepts pointers with any lifetime So, what if we reverse the order of the two function types, like this: - fn(&self/int) <: fn(&a/int)? (No) + fn(&self/int) <: &fn(&a/int)? (No) Does the subtyping relationship still hold? The answer of course is no. In this case, the function accepts *only the lifetime `&self`*, @@ -196,8 +196,8 @@ accepted any lifetime. What about these two examples: - fn(&a/int, &b/int) <: fn(&a/int, &a/int)? (Yes) - fn(&a/int, &a/int) <: fn(&a/int, &b/int)? (No) + fn(&a/int, &b/int) <: &fn(&a/int, &a/int)? (Yes) + fn(&a/int, &a/int) <: &fn(&a/int, &b/int)? (No) Here, it is true that functions which take two pointers with any two lifetimes can be treated as if they only accepted two pointers with @@ -221,12 +221,12 @@ Let's walk through some examples and see how this algorithm plays out. We'll start with the first example, which was: - 1. fn(&a/T) <: fn(&b/T)? Yes: a -> b + 1. fn(&a/T) <: &fn(&b/T)? Yes: a -> b After steps 1 and 2 of the algorithm we will have replaced the types like so: - 1. fn(&A/T) <: fn(&x/T)? + 1. fn(&A/T) <: &fn(&x/T)? Here the upper case `&A` indicates a *region variable*, that is, a region whose value is being inferred by the system. I also replaced @@ -255,12 +255,12 @@ So far we have encountered no error, so the subtype check succeeds. Now let's look first at the third example, which was: - 3. fn(&self/T) <: fn(&b/T)? No! + 3. fn(&self/T) <: &fn(&b/T)? No! After steps 1 and 2 of the algorithm we will have replaced the types like so: - 3. fn(&self/T) <: fn(&x/T)? + 3. fn(&self/T) <: &fn(&x/T)? This looks pretty much the same as before, except that on the LHS `&self` was not bound, and hence was left as-is and not replaced with @@ -275,7 +275,7 @@ You may be wondering about that mysterious last step in the algorithm. So far it has not been relevant. The purpose of that last step is to catch something like *this*: - fn() -> fn(&a/T) <: fn() -> fn(&b/T)? No. + fn() -> fn(&a/T) <: &fn() -> fn(&b/T)? No. Here the function types are the same but for where the binding occurs. The subtype returns a function that expects a value in precisely one @@ -289,15 +289,15 @@ So let's step through what happens when we perform this subtype check. We first replace the bound regions in the subtype (the supertype has no bound regions). This gives us: - fn() -> fn(&A/T) <: fn() -> fn(&b/T)? + fn() -> fn(&A/T) <: &fn() -> fn(&b/T)? Now we compare the return types, which are covariant, and hence we have: - fn(&A/T) <: fn(&b/T)? + fn(&A/T) <: &fn(&b/T)? Here we skolemize the bound region in the supertype to yield: - fn(&A/T) <: fn(&x/T)? + fn(&A/T) <: &fn(&x/T)? And then proceed to compare the argument types: @@ -314,7 +314,7 @@ The difference between this example and the first one is that the variable `A` already existed at the point where the skolemization occurred. In the first example, you had two functions: - fn(&a/T) <: fn(&b/T) + fn(&a/T) <: &fn(&b/T) and hence `&A` and `&x` were created "together". In general, the intention of the skolemized names is that they are supposed to be @@ -700,7 +700,7 @@ pub impl RegionVarBindings { match undo_item { Snapshot => {} AddVar(vid) => { - fail_unless!(self.var_spans.len() == *vid + 1); + fail_unless!(self.var_spans.len() == vid.to_uint() + 1); self.var_spans.pop(); } AddConstraint(ref constraint) => { @@ -720,7 +720,7 @@ pub impl RegionVarBindings { fn new_region_var(&mut self, span: span) -> RegionVid { let id = self.num_vars(); self.var_spans.push(span); - let vid = RegionVid(id); + let vid = RegionVid { id: id }; if self.in_snapshot() { self.undo_log.push(AddVar(vid)); } @@ -863,15 +863,15 @@ pub impl RegionVarBindings { } fn resolve_var(&mut self, rid: RegionVid) -> ty::Region { - debug!("RegionVarBindings: resolve_var(%?=%u)", rid, *rid); + debug!("RegionVarBindings: resolve_var(%?=%u)", rid, rid.to_uint()); if self.values.is_empty() { self.tcx.sess.span_bug( - self.var_spans[*rid], + self.var_spans[rid.to_uint()], fmt!("Attempt to resolve region variable before values have \ been computed!")); } - let v = self.values.with_ref(|values| values[*rid]); + let v = self.values.with_ref(|values| values[rid.to_uint()]); match v { Value(r) => r, @@ -886,13 +886,13 @@ pub impl RegionVarBindings { // should ultimately have some bounds. self.tcx.sess.span_err( - self.var_spans[*rid], - fmt!("Unconstrained region variable #%u", *rid)); + self.var_spans[rid.to_uint()], + fmt!("Unconstrained region variable #%u", rid.to_uint())); // Touch of a hack: to suppress duplicate messages, // replace the NoValue entry with ErrorValue. let mut values = self.values.take(); - values[*rid] = ErrorValue; + values[rid.to_uint()] = ErrorValue; self.values.put_back(values); re_static } @@ -1049,7 +1049,7 @@ priv impl RegionVarBindings { (re_infer(ReVar(v_id)), _) | (_, re_infer(ReVar(v_id))) => { self.tcx.sess.span_bug( - self.var_spans[*v_id], + self.var_spans[v_id.to_uint()], fmt!("lub_concrete_regions invoked with \ non-concrete regions: %?, %?", a, b)); } @@ -1111,7 +1111,7 @@ priv impl RegionVarBindings { (re_infer(ReVar(v_id)), _) | (_, re_infer(ReVar(v_id))) => { self.tcx.sess.span_bug( - self.var_spans[*v_id], + self.var_spans[v_id.to_uint()], fmt!("glb_concrete_regions invoked with \ non-concrete regions: %?, %?", a, b)); } @@ -1275,8 +1275,8 @@ pub impl RegionVarBindings { edge_idx: uint) { let edge_dir = edge_dir as uint; graph.edges[edge_idx].next_edge[edge_dir] = - graph.nodes[*node_id].head_edge[edge_dir]; - graph.nodes[*node_id].head_edge[edge_dir] = + graph.nodes[node_id.to_uint()].head_edge[edge_dir]; + graph.nodes[node_id.to_uint()].head_edge[edge_dir] = edge_idx; } } @@ -1285,14 +1285,14 @@ pub impl RegionVarBindings { do iterate_until_fixed_point(~"Expansion", graph) |nodes, edge| { match edge.constraint { ConstrainRegSubVar(a_region, b_vid) => { - let b_node = &mut nodes[*b_vid]; + let b_node = &mut nodes[b_vid.to_uint()]; self.expand_node(a_region, b_vid, b_node) } ConstrainVarSubVar(a_vid, b_vid) => { - match nodes[*a_vid].value { + match nodes[a_vid.to_uint()].value { NoValue | ErrorValue => false, Value(a_region) => { - let b_node = &mut nodes[*b_vid]; + let b_node = &mut nodes[b_vid.to_uint()]; self.expand_node(a_region, b_vid, b_node) } } @@ -1349,16 +1349,16 @@ pub impl RegionVarBindings { false } ConstrainVarSubVar(a_vid, b_vid) => { - match nodes[*b_vid].value { + match nodes[b_vid.to_uint()].value { NoValue | ErrorValue => false, Value(b_region) => { - let a_node = &mut nodes[*a_vid]; + let a_node = &mut nodes[a_vid.to_uint()]; self.contract_node(a_vid, a_node, b_region) } } } ConstrainVarSubReg(a_vid, b_region) => { - let a_node = &mut nodes[*a_vid]; + let a_node = &mut nodes[a_vid.to_uint()]; self.contract_node(a_vid, a_node, b_region) } } @@ -1474,7 +1474,7 @@ pub impl RegionVarBindings { that is not used is not a problem, so if this rule starts to create problems we'll have to revisit this portion of the code and think hard about it. =) */ - let node_vid = RegionVid(idx); + let node_vid = RegionVid { id: idx }; match node.classification { Expanding => { self.report_error_for_expanding_node( @@ -1525,7 +1525,7 @@ pub impl RegionVarBindings { } self.tcx.sess.span_err( - self.var_spans[*node_idx], + self.var_spans[node_idx.to_uint()], fmt!("cannot infer an appropriate lifetime \ due to conflicting requirements")); @@ -1578,7 +1578,7 @@ pub impl RegionVarBindings { } self.tcx.sess.span_err( - self.var_spans[*node_idx], + self.var_spans[node_idx.to_uint()], fmt!("cannot infer an appropriate lifetime \ due to conflicting requirements")); @@ -1616,7 +1616,7 @@ pub impl RegionVarBindings { -> ~[SpannedRegion] { let set = HashMap(); let mut stack = ~[orig_node_idx]; - set.insert(*orig_node_idx, ()); + set.insert(orig_node_idx.to_uint(), ()); let mut result = ~[]; while !vec::is_empty(stack) { let node_idx = stack.pop(); @@ -1627,7 +1627,7 @@ pub impl RegionVarBindings { Incoming => from_vid, Outgoing => to_vid }; - if set.insert(*vid, ()) { + if set.insert(vid.to_uint(), ()) { stack.push(vid); } } @@ -1657,8 +1657,9 @@ pub impl RegionVarBindings { graph: &Graph, node_idx: RegionVid, dir: Direction, - op: fn(edge: &GraphEdge) -> bool) { - let mut edge_idx = graph.nodes[*node_idx].head_edge[dir as uint]; + op: &fn(edge: &GraphEdge) -> bool) { + let mut edge_idx = + graph.nodes[node_idx.to_uint()].head_edge[dir as uint]; while edge_idx != uint::max_value { let edge_ptr = &graph.edges[edge_idx]; if !op(edge_ptr) { diff --git a/src/librustc/middle/typeck/infer/sub.rs b/src/librustc/middle/typeck/infer/sub.rs index f209116696e10..b4d8905a93627 100644 --- a/src/librustc/middle/typeck/infer/sub.rs +++ b/src/librustc/middle/typeck/infer/sub.rs @@ -29,7 +29,7 @@ use syntax::ast::{Onceness, m_const, purity, ret_style}; use syntax::codemap::span; -pub enum Sub = CombineFields; // "subtype", "subregion" etc +pub struct Sub(CombineFields); // "subtype", "subregion" etc impl Combine for Sub { fn infcx(&self) -> @mut InferCtxt { self.infcx } diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs index 61f1ceeabaec5..abaf658a1a43e 100644 --- a/src/librustc/middle/typeck/mod.rs +++ b/src/librustc/middle/typeck/mod.rs @@ -225,7 +225,7 @@ pub fn require_same_types( span: span, t1: ty::t, t2: ty::t, - msg: fn() -> ~str) -> bool { + msg: &fn() -> ~str) -> bool { let l_tcx, l_infcx; match maybe_infcx { diff --git a/src/librustc/middle/typeck/rscope.rs b/src/librustc/middle/typeck/rscope.rs index f0fc173101f2f..f74a0960f6674 100644 --- a/src/librustc/middle/typeck/rscope.rs +++ b/src/librustc/middle/typeck/rscope.rs @@ -74,7 +74,8 @@ impl region_scope for MethodRscope { } } -pub enum type_rscope = Option; +pub struct type_rscope(Option); + impl type_rscope { priv fn replacement(&self) -> ty::Region { if self.is_some() { diff --git a/src/librustc/rustc.rc b/src/librustc/rustc.rc index 355ecaed7d7e0..296c94f3299cb 100644 --- a/src/librustc/rustc.rc +++ b/src/librustc/rustc.rc @@ -24,7 +24,7 @@ #[allow(non_camel_case_types)]; #[allow(deprecated_mode)]; #[warn(deprecated_pattern)]; -#[allow(deprecated_self)]; +#[deny(deprecated_self)]; #[no_core]; diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index d3ffd2deb8141..c7945f74f55a5 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -17,7 +17,7 @@ use syntax::visit; use core::str; use std::oldmap::HashMap; -pub fn indent(op: fn() -> R) -> R { +pub fn indent(op: &fn() -> R) -> R { // Use in conjunction with the log post-processor like `src/etc/indenter` // to make debug output more readable. debug!(">>"); diff --git a/src/librustdoc/extract.rs b/src/librustdoc/extract.rs index fc784722b256e..5e5c843da26da 100644 --- a/src/librustdoc/extract.rs +++ b/src/librustdoc/extract.rs @@ -322,8 +322,7 @@ fn structdoc_from_struct( fields: do struct_def.fields.map |field| { match field.node.kind { ast::named_field(ident, _, _) => to_str(ident), - ast::unnamed_field => fail!( - ~"what is an unnamed struct field?") + ast::unnamed_field => ~"(unnamed)", } }, sig: None diff --git a/src/librustdoc/rustdoc.rc b/src/librustdoc/rustdoc.rc index 9bd78e54b78be..f5cf98759b375 100644 --- a/src/librustdoc/rustdoc.rc +++ b/src/librustdoc/rustdoc.rc @@ -22,6 +22,7 @@ #[no_core]; #[allow(non_implicitly_copyable_typarams)]; +#[deny(deprecated_self)]; extern mod core(vers = "0.6"); extern mod std(vers = "0.6"); @@ -142,7 +143,7 @@ fn run(config: Config) { } } -pub fn time(what: ~str, f: fn() -> T) -> T { +pub fn time(what: ~str, f: &fn() -> T) -> T { let start = std::time::precise_time_s(); let rv = f(); let end = std::time::precise_time_s(); diff --git a/src/librusti/rusti.rc b/src/librusti/rusti.rc index 3e1b0c03bd702..0367a771ffbd1 100644 --- a/src/librusti/rusti.rc +++ b/src/librusti/rusti.rc @@ -22,6 +22,7 @@ #[allow(vecs_implicitly_copyable, non_implicitly_copyable_typarams)]; +#[deny(deprecated_self)]; extern mod core(vers = "0.6"); extern mod std(vers = "0.6"); @@ -58,7 +59,7 @@ enum CmdAction { /// A utility function that hands off a pretty printer to a callback. fn with_pp(intr: @token::ident_interner, - cb: fn(@pprust::ps, io::Writer)) -> ~str { + cb: &fn(@pprust::ps, io::Writer)) -> ~str { do io::with_str_writer |writer| { let pp = pprust::rust_printer(writer, intr); diff --git a/src/librustpkg/rustpkg.rc b/src/librustpkg/rustpkg.rc index 0f8463b0b3c93..5b9f3c3cd229e 100644 --- a/src/librustpkg/rustpkg.rc +++ b/src/librustpkg/rustpkg.rc @@ -20,6 +20,7 @@ #[no_core]; #[allow(vecs_implicitly_copyable, non_implicitly_copyable_typarams)]; +#[deny(deprecated_self)]; extern mod core(vers = "0.6"); extern mod std(vers = "0.6"); diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs index b63a0a92e6c15..7d2b8eccd6c0e 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -260,7 +260,7 @@ pub fn hash(data: ~str) -> ~str { hasher.result_str() } -pub fn temp_change_dir(dir: &Path, cb: fn() -> T) { +pub fn temp_change_dir(dir: &Path, cb: &fn() -> T) { let cwd = os::getcwd(); os::change_dir(dir); diff --git a/src/libstd/arc.rs b/src/libstd/arc.rs index e7503f0082c2e..d7d878fa192dd 100644 --- a/src/libstd/arc.rs +++ b/src/libstd/arc.rs @@ -176,7 +176,7 @@ pub impl MutexARC { * blocked on the mutex) will also fail immediately. */ #[inline(always)] - unsafe fn access(&self, blk: fn(x: &mut T) -> U) -> U { + unsafe fn access(&self, blk: &fn(x: &mut T) -> U) -> U { unsafe { let state = get_shared_mutable_state(&self.x); // Borrowck would complain about this if the function were @@ -301,7 +301,7 @@ pub impl RWARC { * poison the ARC, so subsequent readers and writers will both also fail. */ #[inline(always)] - fn write(&self, blk: fn(x: &mut T) -> U) -> U { + fn write(&self, blk: &fn(x: &mut T) -> U) -> U { unsafe { let state = get_shared_mutable_state(&self.x); do (*borrow_rwlock(state)).write { @@ -313,7 +313,7 @@ pub impl RWARC { } /// As write(), but with a condvar, as sync::rwlock.write_cond(). #[inline(always)] - fn write_cond(&self, blk: fn(x: &x/mut T, c: &c/Condvar) -> U) -> U { + fn write_cond(&self, blk: &fn(x: &x/mut T, c: &c/Condvar) -> U) -> U { unsafe { let state = get_shared_mutable_state(&self.x); do (*borrow_rwlock(state)).write_cond |cond| { @@ -335,7 +335,7 @@ pub impl RWARC { * Failing will unlock the ARC while unwinding. However, unlike all other * access modes, this will not poison the ARC. */ - fn read(&self, blk: fn(x: &T) -> U) -> U { + fn read(&self, blk: &fn(x: &T) -> U) -> U { let state = unsafe { get_shared_immutable_state(&self.x) }; do (&state.lock).read { check_poison(false, state.failed); @@ -360,14 +360,16 @@ pub impl RWARC { * } * ~~~ */ - fn write_downgrade(&self, blk: fn(v: RWWriteMode) -> U) -> U { + fn write_downgrade(&self, blk: &fn(v: RWWriteMode) -> U) -> U { unsafe { let state = get_shared_mutable_state(&self.x); do (*borrow_rwlock(state)).write_downgrade |write_mode| { check_poison(false, (*state).failed); - blk(RWWriteMode((&mut (*state).data, - write_mode, - PoisonOnFail(&mut (*state).failed)))) + blk(RWWriteMode { + data: &mut (*state).data, + token: write_mode, + poison: PoisonOnFail(&mut (*state).failed) + }) } } } @@ -376,7 +378,11 @@ pub impl RWARC { fn downgrade(&self, token: RWWriteMode/&a) -> RWReadMode/&a { // The rwlock should assert that the token belongs to us for us. let state = unsafe { get_shared_immutable_state(&self.x) }; - let RWWriteMode((data, t, _poison)) = token; + let RWWriteMode { + data: data, + token: t, + poison: _poison + } = token; // Let readers in let new_token = (&state.lock).downgrade(t); // Whatever region the input reference had, it will be safe to use @@ -386,7 +392,10 @@ pub impl RWARC { // Downgrade ensured the token belonged to us. Just a sanity check. fail_unless!(ptr::ref_eq(&state.data, new_data)); // Produce new token - RWReadMode((new_data, new_token)) + RWReadMode { + data: new_data, + token: new_token, + } } } @@ -398,19 +407,28 @@ fn borrow_rwlock(state: *const RWARCInner) -> *RWlock { unsafe { cast::transmute(&const (*state).lock) } } -// FIXME (#3154) ice with struct/& prevents these from being structs. - /// The "write permission" token used for RWARC.write_downgrade(). -pub enum RWWriteMode = - (&self/mut T, sync::RWlockWriteMode/&self, PoisonOnFail); +pub struct RWWriteMode<'self, T> { + data: &'self mut T, + token: sync::RWlockWriteMode<'self>, + poison: PoisonOnFail, +} + /// The "read permission" token used for RWARC.write_downgrade(). -pub enum RWReadMode = (&self/T, sync::RWlockReadMode/&self); +pub struct RWReadMode<'self, T> { + data: &'self T, + token: sync::RWlockReadMode<'self>, +} pub impl RWWriteMode/&self { /// Access the pre-downgrade RWARC in write mode. - fn write(&self, blk: fn(x: &mut T) -> U) -> U { + fn write(&self, blk: &fn(x: &mut T) -> U) -> U { match *self { - RWWriteMode((ref data, ref token, _)) => { + RWWriteMode { + data: ref data, + token: ref token, + poison: _ + } => { do token.write { blk(&mut **data) } @@ -418,9 +436,13 @@ pub impl RWWriteMode/&self { } } /// Access the pre-downgrade RWARC in write mode with a condvar. - fn write_cond(&self, blk: fn(x: &x/mut T, c: &c/Condvar) -> U) -> U { + fn write_cond(&self, blk: &fn(x: &x/mut T, c: &c/Condvar) -> U) -> U { match *self { - RWWriteMode((ref data, ref token, ref poison)) => { + RWWriteMode { + data: ref data, + token: ref token, + poison: ref poison + } => { do token.write_cond |cond| { unsafe { let cvar = Condvar { @@ -438,9 +460,12 @@ pub impl RWWriteMode/&self { pub impl RWReadMode/&self { /// Access the post-downgrade rwlock in read mode. - fn read(&self, blk: fn(x: &T) -> U) -> U { + fn read(&self, blk: &fn(x: &T) -> U) -> U { match *self { - RWReadMode((data, ref token)) => { + RWReadMode { + data: data, + token: ref token + } => { do token.read { blk(data) } } } diff --git a/src/libstd/arena.rs b/src/libstd/arena.rs index 9ed6d285ce687..695b3d01376c3 100644 --- a/src/libstd/arena.rs +++ b/src/libstd/arena.rs @@ -201,7 +201,7 @@ pub impl Arena { } #[inline(always)] - fn alloc_pod(&self, op: fn() -> T) -> &self/T { + fn alloc_pod(&self, op: &fn() -> T) -> &self/T { unsafe { let tydesc = sys::get_type_desc::(); let ptr = self.alloc_pod_inner((*tydesc).size, (*tydesc).align); @@ -246,7 +246,7 @@ pub impl Arena { } #[inline(always)] - fn alloc_nonpod(&self, op: fn() -> T) -> &self/T { + fn alloc_nonpod(&self, op: &fn() -> T) -> &self/T { unsafe { let tydesc = sys::get_type_desc::(); let (ty_ptr, ptr) = @@ -268,7 +268,7 @@ pub impl Arena { // The external interface #[inline(always)] - fn alloc(&self, op: fn() -> T) -> &self/T { + fn alloc(&self, op: &fn() -> T) -> &self/T { unsafe { if !rusti::needs_drop::() { self.alloc_pod(op) diff --git a/src/libstd/bitv.rs b/src/libstd/bitv.rs index 55ec29d2337ca..8dbdb83698c6f 100644 --- a/src/libstd/bitv.rs +++ b/src/libstd/bitv.rs @@ -33,7 +33,7 @@ pub impl SmallBitv { #[inline(always)] fn bits_op(&mut self, right_bits: uint, nbits: uint, - f: fn(uint, uint) -> uint) -> bool { + f: &fn(uint, uint) -> uint) -> bool { let mask = small_mask(nbits); let old_b: uint = self.bits; let new_b = f(old_b, right_bits); @@ -130,7 +130,7 @@ pub impl BigBitv { #[inline(always)] fn process(&mut self, b: &BigBitv, nbits: uint, - op: fn(uint, uint) -> uint) -> bool { + op: &fn(uint, uint) -> uint) -> bool { let len = b.storage.len(); fail_unless!((self.storage.len() == len)); let mut changed = false; @@ -148,7 +148,7 @@ pub impl BigBitv { } #[inline(always)] - fn each_storage(&mut self, op: fn(v: &mut uint) -> bool) { + fn each_storage(&mut self, op: &fn(v: &mut uint) -> bool) { for uint::range(0, self.storage.len()) |i| { let mut w = self.storage[i]; let b = op(&mut w); @@ -392,7 +392,7 @@ pub impl Bitv { } #[inline(always)] - fn each(&self, f: fn(bool) -> bool) { + fn each(&self, f: &fn(bool) -> bool) { let mut i = 0; while i < self.nbits { if !f(self.get(i)) { break; } @@ -493,7 +493,7 @@ pub impl Bitv { true } - fn ones(&self, f: fn(uint) -> bool) { + fn ones(&self, f: &fn(uint) -> bool) { for uint::range(0, self.nbits) |i| { if self.get(i) { if !f(i) { break } @@ -546,7 +546,7 @@ pub fn from_bools(bools: &[bool]) -> Bitv { * Create a bitv of the specified length where the value at each * index is f(index). */ -pub fn from_fn(len: uint, f: fn(index: uint) -> bool) -> Bitv { +pub fn from_fn(len: uint, f: &fn(index: uint) -> bool) -> Bitv { let mut bitv = Bitv::new(len, false); for uint::range(0, len) |i| { bitv.set(i, f(i)); @@ -561,7 +561,7 @@ impl ops::Index for Bitv { } #[inline(always)] -pure fn iterate_bits(base: uint, bits: uint, f: fn(uint) -> bool) -> bool { +pure fn iterate_bits(base: uint, bits: uint, f: &fn(uint) -> bool) -> bool { if bits == 0 { return true; } @@ -622,7 +622,7 @@ pub impl BitvSet { } #[inline(always)] - priv fn other_op(&mut self, other: &BitvSet, f: fn(uint, uint) -> uint) { + priv fn other_op(&mut self, other: &BitvSet, f: &fn(uint, uint) -> uint) { fn nbits(mut w: uint) -> uint { let mut bits = 0; for uint::bits.times { @@ -669,7 +669,7 @@ pub impl BitvSet { impl BaseIter for BitvSet { pure fn size_hint(&self) -> Option { Some(self.len()) } - pure fn each(&self, blk: fn(v: &uint) -> bool) { + pure fn each(&self, blk: &fn(v: &uint) -> bool) { for self.bitv.storage.eachi |i, &w| { if !iterate_bits(i * uint::bits, w, |b| blk(&b)) { return; @@ -778,7 +778,7 @@ impl Set for BitvSet { other.is_subset(self) } - pure fn difference(&self, other: &BitvSet, f: fn(&uint) -> bool) { + pure fn difference(&self, other: &BitvSet, f: &fn(&uint) -> bool) { for self.each_common(other) |i, w1, w2| { if !iterate_bits(i, w1 & !w2, |b| f(&b)) { return; @@ -791,7 +791,7 @@ impl Set for BitvSet { } pure fn symmetric_difference(&self, other: &BitvSet, - f: fn(&uint) -> bool) { + f: &fn(&uint) -> bool) { for self.each_common(other) |i, w1, w2| { if !iterate_bits(i, w1 ^ w2, |b| f(&b)) { return; @@ -802,7 +802,7 @@ impl Set for BitvSet { ); } - pure fn intersection(&self, other: &BitvSet, f: fn(&uint) -> bool) { + pure fn intersection(&self, other: &BitvSet, f: &fn(&uint) -> bool) { for self.each_common(other) |i, w1, w2| { if !iterate_bits(i, w1 & w2, |b| f(&b)) { return; @@ -810,7 +810,7 @@ impl Set for BitvSet { } } - pure fn union(&self, other: &BitvSet, f: fn(&uint) -> bool) { + pure fn union(&self, other: &BitvSet, f: &fn(&uint) -> bool) { for self.each_common(other) |i, w1, w2| { if !iterate_bits(i, w1 | w2, |b| f(&b)) { return; @@ -828,7 +828,7 @@ priv impl BitvSet { /// w1, w2) where the bit location is the number of bits offset so far, /// and w1/w2 are the words coming from the two vectors self, other. pure fn each_common(&self, other: &BitvSet, - f: fn(uint, uint, uint) -> bool) { + f: &fn(uint, uint, uint) -> bool) { let min = uint::min(self.bitv.storage.len(), other.bitv.storage.len()); for self.bitv.storage.view(0, min).eachi |i, &w| { @@ -846,7 +846,7 @@ priv impl BitvSet { /// is true if the word comes from 'self', and false if it comes from /// 'other'. pure fn each_outlier(&self, other: &BitvSet, - f: fn(bool, uint, uint) -> bool) { + f: &fn(bool, uint, uint) -> bool) { let len1 = self.bitv.storage.len(); let len2 = other.bitv.storage.len(); let min = uint::min(len1, len2); diff --git a/src/libstd/ebml.rs b/src/libstd/ebml.rs index 44461ae06fff4..a55d4bc97ec56 100644 --- a/src/libstd/ebml.rs +++ b/src/libstd/ebml.rs @@ -142,7 +142,7 @@ pub mod reader { } } - pub fn docs(d: Doc, it: fn(uint, Doc) -> bool) { + pub fn docs(d: Doc, it: &fn(uint, Doc) -> bool) { let mut pos = d.start; while pos < d.end { let elt_tag = vuint_at(*d.data, pos); @@ -155,7 +155,7 @@ pub mod reader { } } - pub fn tagged_docs(d: Doc, tg: uint, it: fn(Doc) -> bool) { + pub fn tagged_docs(d: Doc, tg: uint, it: &fn(Doc) -> bool) { let mut pos = d.start; while pos < d.end { let elt_tag = vuint_at(*d.data, pos); @@ -175,7 +175,7 @@ pub mod reader { vec::slice::(*d.data, d.start, d.end).to_vec() } - pub fn with_doc_data(d: Doc, f: fn(x: &[u8]) -> T) -> T { + pub fn with_doc_data(d: Doc, f: &fn(x: &[u8]) -> T) -> T { f(vec::slice(*d.data, d.start, d.end)) } @@ -255,7 +255,7 @@ pub mod reader { r_doc } - fn push_doc(&self, d: Doc, f: fn() -> T) -> T { + fn push_doc(&self, d: Doc, f: &fn() -> T) -> T { let old_parent = self.parent; let old_pos = self.pos; self.parent = d; @@ -274,7 +274,7 @@ pub mod reader { } pub impl Decoder { - fn read_opaque(&self, op: fn(Doc) -> R) -> R { + fn read_opaque(&self, op: &fn(Doc) -> R) -> R { do self.push_doc(self.next_doc(EsOpaque)) { op(copy self.parent) } @@ -321,23 +321,23 @@ pub mod reader { fn read_managed_str(&self) -> @str { fail!(~"read_managed_str()"); } // Compound types: - fn read_owned(&self, f: fn() -> T) -> T { + fn read_owned(&self, f: &fn() -> T) -> T { debug!("read_owned()"); f() } - fn read_managed(&self, f: fn() -> T) -> T { + fn read_managed(&self, f: &fn() -> T) -> T { debug!("read_managed()"); f() } - fn read_enum(&self, name: &str, f: fn() -> T) -> T { + fn read_enum(&self, name: &str, f: &fn() -> T) -> T { debug!("read_enum(%s)", name); self._check_label(name); self.push_doc(self.next_doc(EsEnum), f) } - fn read_enum_variant(&self, f: fn(uint) -> T) -> T { + fn read_enum_variant(&self, f: &fn(uint) -> T) -> T { debug!("read_enum_variant()"); let idx = self._next_uint(EsEnumVid); debug!(" idx=%u", idx); @@ -346,12 +346,12 @@ pub mod reader { } } - fn read_enum_variant_arg(&self, idx: uint, f: fn() -> T) -> T { + fn read_enum_variant_arg(&self, idx: uint, f: &fn() -> T) -> T { debug!("read_enum_variant_arg(idx=%u)", idx); f() } - fn read_owned_vec(&self, f: fn(uint) -> T) -> T { + fn read_owned_vec(&self, f: &fn(uint) -> T) -> T { debug!("read_owned_vec()"); do self.push_doc(self.next_doc(EsVec)) { let len = self._next_uint(EsVecLen); @@ -360,7 +360,7 @@ pub mod reader { } } - fn read_managed_vec(&self, f: fn(uint) -> T) -> T { + fn read_managed_vec(&self, f: &fn(uint) -> T) -> T { debug!("read_managed_vec()"); do self.push_doc(self.next_doc(EsVec)) { let len = self._next_uint(EsVecLen); @@ -369,33 +369,33 @@ pub mod reader { } } - fn read_vec_elt(&self, idx: uint, f: fn() -> T) -> T { + fn read_vec_elt(&self, idx: uint, f: &fn() -> T) -> T { debug!("read_vec_elt(idx=%u)", idx); self.push_doc(self.next_doc(EsVecElt), f) } - fn read_rec(&self, f: fn() -> T) -> T { + fn read_rec(&self, f: &fn() -> T) -> T { debug!("read_rec()"); f() } - fn read_struct(&self, name: &str, _len: uint, f: fn() -> T) -> T { + fn read_struct(&self, name: &str, _len: uint, f: &fn() -> T) -> T { debug!("read_struct(name=%s)", name); f() } - fn read_field(&self, name: &str, idx: uint, f: fn() -> T) -> T { + fn read_field(&self, name: &str, idx: uint, f: &fn() -> T) -> T { debug!("read_field(name=%s, idx=%u)", name, idx); self._check_label(name); f() } - fn read_tup(&self, len: uint, f: fn() -> T) -> T { + fn read_tup(&self, len: uint, f: &fn() -> T) -> T { debug!("read_tup(len=%u)", len); f() } - fn read_tup_elt(&self, idx: uint, f: fn() -> T) -> T { + fn read_tup_elt(&self, idx: uint, f: &fn() -> T) -> T { debug!("read_tup_elt(idx=%u)", idx); f() } @@ -469,7 +469,7 @@ pub mod writer { debug!("End tag (size = %u)", size); } - fn wr_tag(&self, tag_id: uint, blk: fn()) { + fn wr_tag(&self, tag_id: uint, blk: &fn()) { self.start_tag(tag_id); blk(); self.end_tag(); @@ -566,7 +566,7 @@ pub mod writer { } pub impl Encoder { - fn emit_opaque(&self, f: fn()) { + fn emit_opaque(&self, f: &fn()) { do self.wr_tag(EsOpaque as uint) { f() } @@ -623,49 +623,49 @@ pub mod writer { self.emit_borrowed_str(v) } - fn emit_borrowed(&self, f: fn()) { f() } - fn emit_owned(&self, f: fn()) { f() } - fn emit_managed(&self, f: fn()) { f() } + fn emit_borrowed(&self, f: &fn()) { f() } + fn emit_owned(&self, f: &fn()) { f() } + fn emit_managed(&self, f: &fn()) { f() } - fn emit_enum(&self, name: &str, f: fn()) { + fn emit_enum(&self, name: &str, f: &fn()) { self._emit_label(name); self.wr_tag(EsEnum as uint, f) } fn emit_enum_variant(&self, _v_name: &str, v_id: uint, _cnt: uint, - f: fn()) { + f: &fn()) { self._emit_tagged_uint(EsEnumVid, v_id); self.wr_tag(EsEnumBody as uint, f) } - fn emit_enum_variant_arg(&self, _idx: uint, f: fn()) { f() } + fn emit_enum_variant_arg(&self, _idx: uint, f: &fn()) { f() } - fn emit_borrowed_vec(&self, len: uint, f: fn()) { + fn emit_borrowed_vec(&self, len: uint, f: &fn()) { do self.wr_tag(EsVec as uint) { self._emit_tagged_uint(EsVecLen, len); f() } } - fn emit_owned_vec(&self, len: uint, f: fn()) { + fn emit_owned_vec(&self, len: uint, f: &fn()) { self.emit_borrowed_vec(len, f) } - fn emit_managed_vec(&self, len: uint, f: fn()) { + fn emit_managed_vec(&self, len: uint, f: &fn()) { self.emit_borrowed_vec(len, f) } - fn emit_vec_elt(&self, _idx: uint, f: fn()) { + fn emit_vec_elt(&self, _idx: uint, f: &fn()) { self.wr_tag(EsVecElt as uint, f) } - fn emit_rec(&self, f: fn()) { f() } - fn emit_struct(&self, _name: &str, _len: uint, f: fn()) { f() } - fn emit_field(&self, name: &str, _idx: uint, f: fn()) { + fn emit_rec(&self, f: &fn()) { f() } + fn emit_struct(&self, _name: &str, _len: uint, f: &fn()) { f() } + fn emit_field(&self, name: &str, _idx: uint, f: &fn()) { self._emit_label(name); f() } - fn emit_tup(&self, _len: uint, f: fn()) { f() } - fn emit_tup_elt(&self, _idx: uint, f: fn()) { f() } + fn emit_tup(&self, _len: uint, f: &fn()) { f() } + fn emit_tup_elt(&self, _idx: uint, f: &fn()) { f() } } } diff --git a/src/libstd/fun_treemap.rs b/src/libstd/fun_treemap.rs index 0729987958a06..735f86b34eca7 100644 --- a/src/libstd/fun_treemap.rs +++ b/src/libstd/fun_treemap.rs @@ -61,7 +61,7 @@ pub fn find(m: Treemap, k: K) -> Option { } /// Visit all pairs in the map in order. -pub fn traverse(m: Treemap, f: fn(&K, &V)) { +pub fn traverse(m: Treemap, f: &fn(&K, &V)) { match *m { Empty => (), /* diff --git a/src/libstd/getopts.rs b/src/libstd/getopts.rs index 2090a3728db52..eed00ccacffcc 100644 --- a/src/libstd/getopts.rs +++ b/src/libstd/getopts.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -29,8 +29,10 @@ * The following example shows simple command line parsing for an application * that requires an input file to be specified, accepts an optional output * file name following -o, and accepts both -h and --help as optional flags. - * extern mod std; - * use std::getopts::*; + * + * ``` + * extern mod std; + * use std::getopts::*; * * fn do_work(in: &str, out: Option<~str>) { * io::println(in); @@ -58,7 +60,7 @@ * ]; * let matches = match getopts(vec::tail(args), opts) { * result::Ok(m) => { m } - * result::Err(f) => { fail fail_str(f) } + * result::Err(f) => { fail!(fail_str(f)) } * }; * if opt_present(&matches, "h") || opt_present(&matches, "help") { * print_usage(program, opts); @@ -66,13 +68,14 @@ * } * let output = opt_maybe_str(&matches, "o"); * let input: &str = if !matches.free.is_empty() { - * matches.free[0] + * copy matches.free[0] * } else { * print_usage(program, opts); * return; * }; * do_work(input, output); * } + * ``` */ use core::cmp::Eq; diff --git a/src/libstd/json.rs b/src/libstd/json.rs index 9208d415971c6..8c6a870b98cd4 100644 --- a/src/libstd/json.rs +++ b/src/libstd/json.rs @@ -116,15 +116,15 @@ impl serialize::Encoder for Encoder { fn emit_owned_str(&self, v: &str) { self.emit_borrowed_str(v) } fn emit_managed_str(&self, v: &str) { self.emit_borrowed_str(v) } - fn emit_borrowed(&self, f: fn()) { f() } - fn emit_owned(&self, f: fn()) { f() } - fn emit_managed(&self, f: fn()) { f() } + fn emit_borrowed(&self, f: &fn()) { f() } + fn emit_owned(&self, f: &fn()) { f() } + fn emit_managed(&self, f: &fn()) { f() } - fn emit_enum(&self, _name: &str, f: fn()) { + fn emit_enum(&self, _name: &str, f: &fn()) { f() } - fn emit_enum_variant(&self, name: &str, _id: uint, _cnt: uint, f: fn()) { + fn emit_enum_variant(&self, name: &str, _id: uint, _cnt: uint, f: &fn()) { // encoding of enums is special-cased for Option. Specifically: // Some(34) => 34 // None => null @@ -160,49 +160,49 @@ impl serialize::Encoder for Encoder { } } - fn emit_enum_variant_arg(&self, idx: uint, f: fn()) { + fn emit_enum_variant_arg(&self, idx: uint, f: &fn()) { if (idx != 0) {self.wr.write_char(',');} f(); } - fn emit_borrowed_vec(&self, _len: uint, f: fn()) { + fn emit_borrowed_vec(&self, _len: uint, f: &fn()) { self.wr.write_char('['); f(); self.wr.write_char(']'); } - fn emit_owned_vec(&self, len: uint, f: fn()) { + fn emit_owned_vec(&self, len: uint, f: &fn()) { self.emit_borrowed_vec(len, f) } - fn emit_managed_vec(&self, len: uint, f: fn()) { + fn emit_managed_vec(&self, len: uint, f: &fn()) { self.emit_borrowed_vec(len, f) } - fn emit_vec_elt(&self, idx: uint, f: fn()) { + fn emit_vec_elt(&self, idx: uint, f: &fn()) { if idx != 0 { self.wr.write_char(','); } f() } - fn emit_rec(&self, f: fn()) { + fn emit_rec(&self, f: &fn()) { self.wr.write_char('{'); f(); self.wr.write_char('}'); } - fn emit_struct(&self, _name: &str, _len: uint, f: fn()) { + fn emit_struct(&self, _name: &str, _len: uint, f: &fn()) { self.wr.write_char('{'); f(); self.wr.write_char('}'); } - fn emit_field(&self, name: &str, idx: uint, f: fn()) { + fn emit_field(&self, name: &str, idx: uint, f: &fn()) { if idx != 0 { self.wr.write_char(','); } self.wr.write_str(escape_str(name)); self.wr.write_char(':'); f(); } - fn emit_tup(&self, len: uint, f: fn()) { + fn emit_tup(&self, len: uint, f: &fn()) { self.emit_borrowed_vec(len, f); } - fn emit_tup_elt(&self, idx: uint, f: fn()) { + fn emit_tup_elt(&self, idx: uint, f: &fn()) { self.emit_vec_elt(idx, f) } } @@ -251,39 +251,39 @@ impl serialize::Encoder for PrettyEncoder { fn emit_owned_str(&self, v: &str) { self.emit_borrowed_str(v) } fn emit_managed_str(&self, v: &str) { self.emit_borrowed_str(v) } - fn emit_borrowed(&self, f: fn()) { f() } - fn emit_owned(&self, f: fn()) { f() } - fn emit_managed(&self, f: fn()) { f() } + fn emit_borrowed(&self, f: &fn()) { f() } + fn emit_owned(&self, f: &fn()) { f() } + fn emit_managed(&self, f: &fn()) { f() } - fn emit_enum(&self, name: &str, f: fn()) { + fn emit_enum(&self, name: &str, f: &fn()) { if name != "option" { fail!(~"only supports option enum") } f() } - fn emit_enum_variant(&self, _name: &str, id: uint, _cnt: uint, f: fn()) { + fn emit_enum_variant(&self, _name: &str, id: uint, _cnt: uint, f: &fn()) { if id == 0 { self.emit_nil(); } else { f() } } - fn emit_enum_variant_arg(&self, _idx: uint, f: fn()) { + fn emit_enum_variant_arg(&self, _idx: uint, f: &fn()) { f() } - fn emit_borrowed_vec(&self, _len: uint, f: fn()) { + fn emit_borrowed_vec(&self, _len: uint, f: &fn()) { self.wr.write_char('['); self.indent += 2; f(); self.indent -= 2; self.wr.write_char(']'); } - fn emit_owned_vec(&self, len: uint, f: fn()) { + fn emit_owned_vec(&self, len: uint, f: &fn()) { self.emit_borrowed_vec(len, f) } - fn emit_managed_vec(&self, len: uint, f: fn()) { + fn emit_managed_vec(&self, len: uint, f: &fn()) { self.emit_borrowed_vec(len, f) } - fn emit_vec_elt(&self, idx: uint, f: fn()) { + fn emit_vec_elt(&self, idx: uint, f: &fn()) { if idx == 0 { self.wr.write_char('\n'); } else { @@ -293,17 +293,17 @@ impl serialize::Encoder for PrettyEncoder { f() } - fn emit_rec(&self, f: fn()) { + fn emit_rec(&self, f: &fn()) { self.wr.write_char('{'); self.indent += 2; f(); self.indent -= 2; self.wr.write_char('}'); } - fn emit_struct(&self, _name: &str, _len: uint, f: fn()) { + fn emit_struct(&self, _name: &str, _len: uint, f: &fn()) { self.emit_rec(f) } - fn emit_field(&self, name: &str, idx: uint, f: fn()) { + fn emit_field(&self, name: &str, idx: uint, f: &fn()) { if idx == 0 { self.wr.write_char('\n'); } else { @@ -314,10 +314,10 @@ impl serialize::Encoder for PrettyEncoder { self.wr.write_str(": "); f(); } - fn emit_tup(&self, sz: uint, f: fn()) { + fn emit_tup(&self, sz: uint, f: &fn()) { self.emit_borrowed_vec(sz, f); } - fn emit_tup_elt(&self, idx: uint, f: fn()) { + fn emit_tup_elt(&self, idx: uint, f: &fn()) { self.emit_vec_elt(idx, f) } } @@ -828,23 +828,23 @@ impl serialize::Decoder for Decoder/&self { } } - fn read_owned(&self, f: fn() -> T) -> T { + fn read_owned(&self, f: &fn() -> T) -> T { debug!("read_owned()"); f() } - fn read_managed(&self, f: fn() -> T) -> T { + fn read_managed(&self, f: &fn() -> T) -> T { debug!("read_managed()"); f() } - fn read_enum(&self, name: &str, f: fn() -> T) -> T { + fn read_enum(&self, name: &str, f: &fn() -> T) -> T { debug!("read_enum(%s)", name); if name != ~"option" { fail!(~"only supports the option enum") } f() } - fn read_enum_variant(&self, f: fn(uint) -> T) -> T { + fn read_enum_variant(&self, f: &fn(uint) -> T) -> T { debug!("read_enum_variant()"); let idx = match *self.peek() { Null => 0, @@ -853,13 +853,13 @@ impl serialize::Decoder for Decoder/&self { f(idx) } - fn read_enum_variant_arg(&self, idx: uint, f: fn() -> T) -> T { + fn read_enum_variant_arg(&self, idx: uint, f: &fn() -> T) -> T { debug!("read_enum_variant_arg(idx=%u)", idx); if idx != 0 { fail!(~"unknown index") } f() } - fn read_owned_vec(&self, f: fn(uint) -> T) -> T { + fn read_owned_vec(&self, f: &fn(uint) -> T) -> T { debug!("read_owned_vec()"); let len = match *self.peek() { List(ref list) => list.len(), @@ -870,7 +870,7 @@ impl serialize::Decoder for Decoder/&self { res } - fn read_managed_vec(&self, f: fn(uint) -> T) -> T { + fn read_managed_vec(&self, f: &fn(uint) -> T) -> T { debug!("read_owned_vec()"); let len = match *self.peek() { List(ref list) => list.len(), @@ -881,7 +881,7 @@ impl serialize::Decoder for Decoder/&self { res } - fn read_vec_elt(&self, idx: uint, f: fn() -> T) -> T { + fn read_vec_elt(&self, idx: uint, f: &fn() -> T) -> T { debug!("read_vec_elt(idx=%u)", idx); match *self.peek() { List(ref list) => { @@ -892,21 +892,21 @@ impl serialize::Decoder for Decoder/&self { } } - fn read_rec(&self, f: fn() -> T) -> T { + fn read_rec(&self, f: &fn() -> T) -> T { debug!("read_rec()"); let value = f(); self.pop(); value } - fn read_struct(&self, _name: &str, _len: uint, f: fn() -> T) -> T { + fn read_struct(&self, _name: &str, _len: uint, f: &fn() -> T) -> T { debug!("read_struct()"); let value = f(); self.pop(); value } - fn read_field(&self, name: &str, idx: uint, f: fn() -> T) -> T { + fn read_field(&self, name: &str, idx: uint, f: &fn() -> T) -> T { debug!("read_rec_field(%s, idx=%u)", name, idx); let top = self.peek(); match *top { @@ -929,14 +929,14 @@ impl serialize::Decoder for Decoder/&self { } } - fn read_tup(&self, len: uint, f: fn() -> T) -> T { + fn read_tup(&self, len: uint, f: &fn() -> T) -> T { debug!("read_tup(len=%u)", len); let value = f(); self.pop(); value } - fn read_tup_elt(&self, idx: uint, f: fn() -> T) -> T { + fn read_tup_elt(&self, idx: uint, f: &fn() -> T) -> T { debug!("read_tup_elt(idx=%u)", idx); match *self.peek() { List(ref list) => { diff --git a/src/libstd/list.rs b/src/libstd/list.rs index 5ab1722ae8399..3a0f299257e09 100644 --- a/src/libstd/list.rs +++ b/src/libstd/list.rs @@ -39,7 +39,7 @@ pub pure fn from_vec(v: &[T]) -> @List { * * z - The initial value * * f - The function to apply */ -pub fn foldl(z: T, ls: @List, f: fn(&T, &U) -> T) -> T { +pub fn foldl(z: T, ls: @List, f: &fn(&T, &U) -> T) -> T { let mut accum: T = z; do iter(ls) |elt| { accum = f(&accum, elt);} accum @@ -52,7 +52,7 @@ pub fn foldl(z: T, ls: @List, f: fn(&T, &U) -> T) -> T { * When function `f` returns true then an option containing the element * is returned. If `f` matches no elements then none is returned. */ -pub pure fn find(ls: @List, f: fn(&T) -> bool) -> Option { +pub pure fn find(ls: @List, f: &fn(&T) -> bool) -> Option { let mut ls = ls; loop { ls = match *ls { @@ -125,7 +125,7 @@ pure fn push(ll: &mut @list, vv: T) { */ /// Iterate over a list -pub pure fn iter(l: @List, f: fn(&T)) { +pub pure fn iter(l: @List, f: &fn(&T)) { let mut cur = l; loop { cur = match *cur { @@ -139,7 +139,7 @@ pub pure fn iter(l: @List, f: fn(&T)) { } /// Iterate over a list -pub pure fn each(l: @List, f: fn(&T) -> bool) { +pub pure fn each(l: @List, f: &fn(&T) -> bool) { let mut cur = l; loop { cur = match *cur { diff --git a/src/libstd/md4.rs b/src/libstd/md4.rs index eb4bd6fe23f47..df254543512b0 100644 --- a/src/libstd/md4.rs +++ b/src/libstd/md4.rs @@ -105,7 +105,7 @@ pub pure fn md4(msg: &[u8]) -> Quad { pub pure fn md4_str(msg: &[u8]) -> ~str { let Quad {a, b, c, d} = md4(msg); - pure fn app(a: u32, b: u32, c: u32, d: u32, f: fn(u32)) { + pure fn app(a: u32, b: u32, c: u32, d: u32, f: &fn(u32)) { f(a); f(b); f(c); f(d); } let mut result = ~""; diff --git a/src/libstd/net_ip.rs b/src/libstd/net_ip.rs index 8021162188f79..a5e689077738b 100644 --- a/src/libstd/net_ip.rs +++ b/src/libstd/net_ip.rs @@ -21,20 +21,20 @@ use core::vec; use iotask = uv::iotask::IoTask; use interact = uv::iotask::interact; -use sockaddr_in = uv::ll::sockaddr_in; -use sockaddr_in6 = uv::ll::sockaddr_in6; -use addrinfo = uv::ll::addrinfo; -use uv_getaddrinfo_t = uv::ll::uv_getaddrinfo_t; -use uv_ip4_name = uv::ll::ip4_name; -use uv_ip4_port = uv::ll::ip4_port; -use uv_ip6_name = uv::ll::ip6_name; -use uv_ip6_port = uv::ll::ip6_port; -use uv_getaddrinfo = uv::ll::getaddrinfo; -use uv_freeaddrinfo = uv::ll::freeaddrinfo; -use create_uv_getaddrinfo_t = uv::ll::getaddrinfo_t; -use set_data_for_req = uv::ll::set_data_for_req; -use get_data_for_req = uv::ll::get_data_for_req; -use ll = uv::ll; +use sockaddr_in = core::unstable::uvll::sockaddr_in; +use sockaddr_in6 = core::unstable::uvll::sockaddr_in6; +use addrinfo = core::unstable::uvll::addrinfo; +use uv_getaddrinfo_t = core::unstable::uvll::uv_getaddrinfo_t; +use uv_ip4_name = core::unstable::uvll::ip4_name; +use uv_ip4_port = core::unstable::uvll::ip4_port; +use uv_ip6_name = core::unstable::uvll::ip6_name; +use uv_ip6_port = core::unstable::uvll::ip6_port; +use uv_getaddrinfo = core::unstable::uvll::getaddrinfo; +use uv_freeaddrinfo = core::unstable::uvll::freeaddrinfo; +use create_uv_getaddrinfo_t = core::unstable::uvll::getaddrinfo_t; +use set_data_for_req = core::unstable::uvll::set_data_for_req; +use get_data_for_req = core::unstable::uvll::get_data_for_req; +use ll = core::unstable::uvll; /// An IP address pub enum IpAddr { diff --git a/src/libstd/oldmap.rs b/src/libstd/oldmap.rs index 0f6434f1b2ba5..18527cfece111 100644 --- a/src/libstd/oldmap.rs +++ b/src/libstd/oldmap.rs @@ -134,7 +134,7 @@ pub mod chained { } pub impl T { - pure fn each_entry(&self, blk: fn(@Entry) -> bool) { + pure fn each_entry(&self, blk: &fn(@Entry) -> bool) { // n.b. we can't use vec::iter() here because self.chains // is stored in a mutable location. let mut i = 0u, n = self.chains.len(); @@ -236,17 +236,17 @@ pub mod chained { } } - pure fn each(&self, blk: fn(key: &K, value: &V) -> bool) { + pure fn each(&self, blk: &fn(key: &K, value: &V) -> bool) { for self.each_entry |entry| { if !blk(&entry.key, &entry.value) { break; } } } - pure fn each_key(&self, blk: fn(key: &K) -> bool) { + pure fn each_key(&self, blk: &fn(key: &K) -> bool) { self.each(|k, _v| blk(k)) } - pure fn each_value(&self, blk: fn(value: &V) -> bool) { + pure fn each_value(&self, blk: &fn(value: &V) -> bool) { self.each(|_k, v| blk(v)) } } @@ -260,8 +260,8 @@ pub mod chained { } } - fn update_with_key(&self, key: K, newval: V, ff: fn(K, V, V) -> V) - -> bool { + fn update_with_key(&self, key: K, newval: V, ff: &fn(K, V, V) -> V) + -> bool { /* match self.find(key) { None => return self.insert(key, val), @@ -312,7 +312,7 @@ pub mod chained { } } - fn update(&self, key: K, newval: V, ff: fn(V, V) -> V) -> bool { + fn update(&self, key: K, newval: V, ff: &fn(V, V) -> V) -> bool { return self.update_with_key(key, newval, |_k, v, v1| ff(v,v1)); } diff --git a/src/libstd/prettyprint.rs b/src/libstd/prettyprint.rs index ed02ea87dac4a..d2d80eb7da803 100644 --- a/src/libstd/prettyprint.rs +++ b/src/libstd/prettyprint.rs @@ -98,87 +98,87 @@ impl serialize::Encoder for Serializer { self.wr.write_str(fmt!("@%?", v)); } - fn emit_borrowed(&self, f: fn()) { + fn emit_borrowed(&self, f: &fn()) { self.wr.write_str(~"&"); f(); } - fn emit_owned(&self, f: fn()) { + fn emit_owned(&self, f: &fn()) { self.wr.write_str(~"~"); f(); } - fn emit_managed(&self, f: fn()) { + fn emit_managed(&self, f: &fn()) { self.wr.write_str(~"@"); f(); } - fn emit_enum(&self, _name: &str, f: fn()) { + fn emit_enum(&self, _name: &str, f: &fn()) { f(); } fn emit_enum_variant(&self, v_name: &str, _v_id: uint, sz: uint, - f: fn()) { + f: &fn()) { self.wr.write_str(v_name); if sz > 0u { self.wr.write_str(~"("); } f(); if sz > 0u { self.wr.write_str(~")"); } } - fn emit_enum_variant_arg(&self, idx: uint, f: fn()) { + fn emit_enum_variant_arg(&self, idx: uint, f: &fn()) { if idx > 0u { self.wr.write_str(~", "); } f(); } - fn emit_borrowed_vec(&self, _len: uint, f: fn()) { + fn emit_borrowed_vec(&self, _len: uint, f: &fn()) { self.wr.write_str(~"&["); f(); self.wr.write_str(~"]"); } - fn emit_owned_vec(&self, _len: uint, f: fn()) { + fn emit_owned_vec(&self, _len: uint, f: &fn()) { self.wr.write_str(~"~["); f(); self.wr.write_str(~"]"); } - fn emit_managed_vec(&self, _len: uint, f: fn()) { + fn emit_managed_vec(&self, _len: uint, f: &fn()) { self.wr.write_str(~"@["); f(); self.wr.write_str(~"]"); } - fn emit_vec_elt(&self, idx: uint, f: fn()) { + fn emit_vec_elt(&self, idx: uint, f: &fn()) { if idx > 0u { self.wr.write_str(~", "); } f(); } - fn emit_rec(&self, f: fn()) { + fn emit_rec(&self, f: &fn()) { self.wr.write_str(~"{"); f(); self.wr.write_str(~"}"); } - fn emit_struct(&self, name: &str, _len: uint, f: fn()) { + fn emit_struct(&self, name: &str, _len: uint, f: &fn()) { self.wr.write_str(fmt!("%s {", name)); f(); self.wr.write_str(~"}"); } - fn emit_field(&self, name: &str, idx: uint, f: fn()) { + fn emit_field(&self, name: &str, idx: uint, f: &fn()) { if idx > 0u { self.wr.write_str(~", "); } self.wr.write_str(name); self.wr.write_str(~": "); f(); } - fn emit_tup(&self, _len: uint, f: fn()) { + fn emit_tup(&self, _len: uint, f: &fn()) { self.wr.write_str(~"("); f(); self.wr.write_str(~")"); } - fn emit_tup_elt(&self, idx: uint, f: fn()) { + fn emit_tup_elt(&self, idx: uint, f: &fn()) { if idx > 0u { self.wr.write_str(~", "); } f(); } diff --git a/src/libstd/priority_queue.rs b/src/libstd/priority_queue.rs index 676bc68e4e513..31f29ce23f2cd 100644 --- a/src/libstd/priority_queue.rs +++ b/src/libstd/priority_queue.rs @@ -31,7 +31,7 @@ impl BaseIter for PriorityQueue { /// Visit all values in the underlying vector. /// /// The values are **not** visited in order. - pure fn each(&self, f: fn(&T) -> bool) { self.data.each(f) } + pure fn each(&self, f: &fn(&T) -> bool) { self.data.each(f) } pure fn size_hint(&self) -> Option { self.data.size_hint() } } diff --git a/src/libstd/rl.rs b/src/libstd/rl.rs index b2b30c1057ef9..a8b25767ce595 100644 --- a/src/libstd/rl.rs +++ b/src/libstd/rl.rs @@ -68,7 +68,7 @@ pub unsafe fn read(prompt: ~str) -> Option<~str> { } } -pub type CompletionCb = @fn(~str, fn(~str)); +pub type CompletionCb<'self> = @fn(~str, &'self fn(~str)); fn complete_key(_v: @CompletionCb) {} diff --git a/src/libstd/rope.rs b/src/libstd/rope.rs index d511ac9744eb3..dd2f5b58fb96a 100644 --- a/src/libstd/rope.rs +++ b/src/libstd/rope.rs @@ -393,7 +393,7 @@ Section: Iterating * `true` If execution proceeded correctly, `false` if it was interrupted, * that is if `it` returned `false` at any point. */ -pub fn loop_chars(rope: Rope, it: fn(c: char) -> bool) -> bool { +pub fn loop_chars(rope: Rope, it: &fn(c: char) -> bool) -> bool { match (rope) { node::Empty => return true, node::Content(x) => return node::loop_chars(x, it) @@ -407,7 +407,7 @@ pub fn loop_chars(rope: Rope, it: fn(c: char) -> bool) -> bool { * * rope - A rope to traverse. It may be empty * * it - A block to execute with each consecutive character of the rope. */ -pub fn iter_chars(rope: Rope, it: fn(char)) { +pub fn iter_chars(rope: Rope, it: &fn(char)) { do loop_chars(rope) |x| { it(x); true @@ -436,7 +436,7 @@ pub fn iter_chars(rope: Rope, it: fn(char)) { * `true` If execution proceeded correctly, `false` if it was interrupted, * that is if `it` returned `false` at any point. */ -pub fn loop_leaves(rope: Rope, it: fn(node::Leaf) -> bool) -> bool{ +pub fn loop_leaves(rope: Rope, it: &fn(node::Leaf) -> bool) -> bool{ match (rope) { node::Empty => return true, node::Content(x) => return node::loop_leaves(x, it) @@ -1078,7 +1078,7 @@ pub mod node { return result; } - pub fn loop_chars(node: @Node, it: fn(c: char) -> bool) -> bool { + pub fn loop_chars(node: @Node, it: &fn(c: char) -> bool) -> bool { return loop_leaves(node,|leaf| { str::all_between(*leaf.content, leaf.byte_offset, @@ -1100,7 +1100,7 @@ pub mod node { * `true` If execution proceeded correctly, `false` if it was interrupted, * that is if `it` returned `false` at any point. */ - pub fn loop_leaves(node: @Node, it: fn(Leaf) -> bool) -> bool{ + pub fn loop_leaves(node: @Node, it: &fn(Leaf) -> bool) -> bool{ let mut current = node; loop { match (*current) { diff --git a/src/libstd/semver.rs b/src/libstd/semver.rs index bf4091e1e902d..7b8a06f1b93af 100644 --- a/src/libstd/semver.rs +++ b/src/libstd/semver.rs @@ -140,7 +140,7 @@ condition! { fn take_nonempty_prefix(rdr: io::Reader, ch: char, - pred: fn(char) -> bool) -> (~str, char) { + pred: &fn(char) -> bool) -> (~str, char) { let mut buf = ~""; let mut ch = ch; while pred(ch) { diff --git a/src/libstd/serialize.rs b/src/libstd/serialize.rs index 5bbd926ba6beb..0288155d29ebd 100644 --- a/src/libstd/serialize.rs +++ b/src/libstd/serialize.rs @@ -43,25 +43,25 @@ pub trait Encoder { fn emit_managed_str(&self, v: &str); // Compound types: - fn emit_borrowed(&self, f: fn()); - fn emit_owned(&self, f: fn()); - fn emit_managed(&self, f: fn()); + fn emit_borrowed(&self, f: &fn()); + fn emit_owned(&self, f: &fn()); + fn emit_managed(&self, f: &fn()); - fn emit_enum(&self, name: &str, f: fn()); - fn emit_enum_variant(&self, v_name: &str, v_id: uint, sz: uint, f: fn()); - fn emit_enum_variant_arg(&self, idx: uint, f: fn()); + fn emit_enum(&self, name: &str, f: &fn()); + fn emit_enum_variant(&self, v_name: &str, v_id: uint, sz: uint, f: &fn()); + fn emit_enum_variant_arg(&self, idx: uint, f: &fn()); - fn emit_borrowed_vec(&self, len: uint, f: fn()); - fn emit_owned_vec(&self, len: uint, f: fn()); - fn emit_managed_vec(&self, len: uint, f: fn()); - fn emit_vec_elt(&self, idx: uint, f: fn()); + fn emit_borrowed_vec(&self, len: uint, f: &fn()); + fn emit_owned_vec(&self, len: uint, f: &fn()); + fn emit_managed_vec(&self, len: uint, f: &fn()); + fn emit_vec_elt(&self, idx: uint, f: &fn()); - fn emit_rec(&self, f: fn()); - fn emit_struct(&self, name: &str, _len: uint, f: fn()); - fn emit_field(&self, f_name: &str, f_idx: uint, f: fn()); + fn emit_rec(&self, f: &fn()); + fn emit_struct(&self, name: &str, _len: uint, f: &fn()); + fn emit_field(&self, f_name: &str, f_idx: uint, f: &fn()); - fn emit_tup(&self, len: uint, f: fn()); - fn emit_tup_elt(&self, idx: uint, f: fn()); + fn emit_tup(&self, len: uint, f: &fn()); + fn emit_tup_elt(&self, idx: uint, f: &fn()); } pub trait Decoder { @@ -86,23 +86,23 @@ pub trait Decoder { fn read_managed_str(&self) -> @str; // Compound types: - fn read_enum(&self, name: &str, f: fn() -> T) -> T; - fn read_enum_variant(&self, f: fn(uint) -> T) -> T; - fn read_enum_variant_arg(&self, idx: uint, f: fn() -> T) -> T; + fn read_enum(&self, name: &str, f: &fn() -> T) -> T; + fn read_enum_variant(&self, f: &fn(uint) -> T) -> T; + fn read_enum_variant_arg(&self, idx: uint, f: &fn() -> T) -> T; - fn read_owned(&self, f: fn() -> T) -> T; - fn read_managed(&self, f: fn() -> T) -> T; + fn read_owned(&self, f: &fn() -> T) -> T; + fn read_managed(&self, f: &fn() -> T) -> T; - fn read_owned_vec(&self, f: fn(uint) -> T) -> T; - fn read_managed_vec(&self, f: fn(uint) -> T) -> T; - fn read_vec_elt(&self, idx: uint, f: fn() -> T) -> T; + fn read_owned_vec(&self, f: &fn(uint) -> T) -> T; + fn read_managed_vec(&self, f: &fn(uint) -> T) -> T; + fn read_vec_elt(&self, idx: uint, f: &fn() -> T) -> T; - fn read_rec(&self, f: fn() -> T) -> T; - fn read_struct(&self, name: &str, _len: uint, f: fn() -> T) -> T; - fn read_field(&self, name: &str, idx: uint, f: fn() -> T) -> T; + fn read_rec(&self, f: &fn() -> T) -> T; + fn read_struct(&self, name: &str, _len: uint, f: &fn() -> T) -> T; + fn read_field(&self, name: &str, idx: uint, f: &fn() -> T) -> T; - fn read_tup(&self, sz: uint, f: fn() -> T) -> T; - fn read_tup_elt(&self, idx: uint, f: fn() -> T) -> T; + fn read_tup(&self, sz: uint, f: &fn() -> T) -> T; + fn read_tup_elt(&self, idx: uint, f: &fn() -> T) -> T; } pub trait Encodable { @@ -547,11 +547,11 @@ impl< // In some cases, these should eventually be coded as traits. pub trait EncoderHelpers { - fn emit_from_vec(&self, v: &[T], f: fn(v: &T)); + fn emit_from_vec(&self, v: &[T], f: &fn(v: &T)); } impl EncoderHelpers for S { - fn emit_from_vec(&self, v: &[T], f: fn(v: &T)) { + fn emit_from_vec(&self, v: &[T], f: &fn(v: &T)) { do self.emit_owned_vec(v.len()) { for v.eachi |i, e| { do self.emit_vec_elt(i) { @@ -563,11 +563,11 @@ impl EncoderHelpers for S { } pub trait DecoderHelpers { - fn read_to_vec(&self, f: fn() -> T) -> ~[T]; + fn read_to_vec(&self, f: &fn() -> T) -> ~[T]; } impl DecoderHelpers for D { - fn read_to_vec(&self, f: fn() -> T) -> ~[T] { + fn read_to_vec(&self, f: &fn() -> T) -> ~[T] { do self.read_owned_vec |len| { do vec::from_fn(len) |i| { self.read_vec_elt(i, || f()) diff --git a/src/libstd/smallintmap.rs b/src/libstd/smallintmap.rs index 84600ac74eeb9..726e7c36abd1b 100644 --- a/src/libstd/smallintmap.rs +++ b/src/libstd/smallintmap.rs @@ -24,7 +24,7 @@ pub struct SmallIntMap { impl BaseIter<(uint, &self/V)> for SmallIntMap { /// Visit all key-value pairs in order - pure fn each(&self, it: fn(&(uint, &self/V)) -> bool) { + pure fn each(&self, it: &fn(&(uint, &self/V)) -> bool) { for uint::range(0, self.v.len()) |i| { match self.v[i] { Some(ref elt) => if !it(&(i, elt)) { break }, @@ -38,7 +38,7 @@ impl BaseIter<(uint, &self/V)> for SmallIntMap { impl ReverseIter<(uint, &self/V)> for SmallIntMap { /// Visit all key-value pairs in reverse order - pure fn each_reverse(&self, it: fn(&(uint, &self/V)) -> bool) { + pure fn each_reverse(&self, it: &fn(&(uint, &self/V)) -> bool) { for uint::range_rev(self.v.len(), 0) |i| { match self.v[i - 1] { Some(ref elt) => if !it(&(i - 1, elt)) { break }, @@ -76,12 +76,12 @@ impl Map for SmallIntMap { } /// Visit all keys in order - pure fn each_key(&self, blk: fn(key: &uint) -> bool) { + pure fn each_key(&self, blk: &fn(key: &uint) -> bool) { self.each(|&(k, _)| blk(&k)) } /// Visit all values in order - pure fn each_value(&self, blk: fn(value: &V) -> bool) { + pure fn each_value(&self, blk: &fn(value: &V) -> bool) { self.each(|&(_, v)| blk(v)) } @@ -133,7 +133,7 @@ pub impl SmallIntMap { pub impl SmallIntMap { fn update_with_key(&mut self, key: uint, val: V, - ff: fn(uint, V, V) -> V) -> bool { + ff: &fn(uint, V, V) -> V) -> bool { let new_val = match self.find(&key) { None => val, Some(orig) => ff(key, *orig, val) @@ -141,7 +141,7 @@ pub impl SmallIntMap { self.insert(key, new_val) } - fn update(&mut self, key: uint, newval: V, ff: fn(V, V) -> V) -> bool { + fn update(&mut self, key: uint, newval: V, ff: &fn(V, V) -> V) -> bool { self.update_with_key(key, newval, |_k, v, v1| ff(v,v1)) } } diff --git a/src/libstd/std.rc b/src/libstd/std.rc index a3b18e50df26a..85e914a60a140 100644 --- a/src/libstd/std.rc +++ b/src/libstd/std.rc @@ -36,6 +36,8 @@ not required in or otherwise suitable for the core library. extern mod core(vers = "0.6"); use core::*; +pub use uv_ll = core::unstable::uvll; + // General io and system-services modules pub mod net; @@ -45,7 +47,6 @@ pub mod net_url; // libuv modules pub mod uv; -pub mod uv_ll; pub mod uv_iotask; pub mod uv_global_loop; diff --git a/src/libstd/sync.rs b/src/libstd/sync.rs index d143c665d8310..2190475d943b6 100644 --- a/src/libstd/sync.rs +++ b/src/libstd/sync.rs @@ -79,8 +79,9 @@ struct SemInner { // a condition variable attached, others should. blocked: Q } + #[doc(hidden)] -enum Sem = Exclusive>; +struct Sem(Exclusive>); #[doc(hidden)] fn new_sem(count: int, q: Q) -> Sem { @@ -135,7 +136,7 @@ pub impl &self/Sem { // FIXME(#3154) move both copies of this into Sem, and unify the 2 structs #[doc(hidden)] pub impl &self/Sem<()> { - fn access(&self, blk: fn() -> U) -> U { + fn access(&self, blk: &fn() -> U) -> U { let mut release = None; unsafe { do task::unkillable { @@ -148,7 +149,7 @@ pub impl &self/Sem<()> { } #[doc(hidden)] pub impl &self/Sem<~[Waitqueue]> { - fn access(&self, blk: fn() -> U) -> U { + fn access(&self, blk: &fn() -> U) -> U { let mut release = None; unsafe { do task::unkillable { @@ -332,7 +333,7 @@ pub impl Condvar/&self { #[inline(always)] #[doc(hidden)] fn check_cvar_bounds(out_of_bounds: Option, id: uint, act: &str, - blk: fn() -> U) -> U { + blk: &fn() -> U) -> U { match out_of_bounds { Some(0) => fail!(fmt!("%s with illegal ID %u - this lock has no condvars!", @@ -347,7 +348,7 @@ fn check_cvar_bounds(out_of_bounds: Option, id: uint, act: &str, #[doc(hidden)] pub impl Sem<~[Waitqueue]> { // The only other place that condvars get built is rwlock_write_mode. - fn access_cond(&self, blk: fn(c: &Condvar) -> U) -> U { + fn access_cond(&self, blk: &fn(c: &Condvar) -> U) -> U { do self.access { blk(&Condvar { sem: self }) } } } @@ -385,7 +386,7 @@ pub impl Semaphore { fn release(&self) { (&self.sem).release() } /// Run a function with ownership of one of the semaphore's resources. - fn access(&self, blk: fn() -> U) -> U { (&self.sem).access(blk) } + fn access(&self, blk: &fn() -> U) -> U { (&self.sem).access(blk) } } /**************************************************************************** @@ -421,10 +422,10 @@ impl Clone for Mutex { pub impl Mutex { /// Run a function with ownership of the mutex. - fn lock(&self, blk: fn() -> U) -> U { (&self.sem).access(blk) } + fn lock(&self, blk: &fn() -> U) -> U { (&self.sem).access(blk) } /// Run a function with ownership of the mutex and a handle to a condvar. - fn lock_cond(&self, blk: fn(c: &Condvar) -> U) -> U { + fn lock_cond(&self, blk: &fn(c: &Condvar) -> U) -> U { (&self.sem).access_cond(blk) } } @@ -480,7 +481,7 @@ pub impl RWlock { * Run a function with the rwlock in read mode. Calls to 'read' from other * tasks may run concurrently with this one. */ - fn read(&self, blk: fn() -> U) -> U { + fn read(&self, blk: &fn() -> U) -> U { let mut release = None; unsafe { do task::unkillable { @@ -511,7 +512,7 @@ pub impl RWlock { * Run a function with the rwlock in write mode. No calls to 'read' or * 'write' from other tasks will run concurrently with this one. */ - fn write(&self, blk: fn() -> U) -> U { + fn write(&self, blk: &fn() -> U) -> U { unsafe { do task::unkillable { (&self.order_lock).acquire(); @@ -529,7 +530,7 @@ pub impl RWlock { * the waiting task is signalled. (Note: a writer that waited and then * was signalled might reacquire the lock before other waiting writers.) */ - fn write_cond(&self, blk: fn(c: &Condvar) -> U) -> U { + fn write_cond(&self, blk: &fn(c: &Condvar) -> U) -> U { // NB: You might think I should thread the order_lock into the cond // wait call, so that it gets waited on before access_lock gets // reacquired upon being woken up. However, (a) this would be not @@ -564,7 +565,7 @@ pub impl RWlock { * } * ~~~ */ - fn write_downgrade(&self, blk: fn(v: RWlockWriteMode) -> U) -> U { + fn write_downgrade(&self, blk: &fn(v: RWlockWriteMode) -> U) -> U { // Implementation slightly different from the slicker 'write's above. // The exit path is conditional on whether the caller downgrades. let mut _release = None; @@ -692,16 +693,16 @@ impl Drop for RWlockReadMode/&self { fn finalize(&self) {} } pub impl RWlockWriteMode/&self { /// Access the pre-downgrade rwlock in write mode. - fn write(&self, blk: fn() -> U) -> U { blk() } + fn write(&self, blk: &fn() -> U) -> U { blk() } /// Access the pre-downgrade rwlock in write mode with a condvar. - fn write_cond(&self, blk: fn(c: &Condvar) -> U) -> U { + fn write_cond(&self, blk: &fn(c: &Condvar) -> U) -> U { blk(&Condvar { sem: &self.lock.access_lock }) } } pub impl RWlockReadMode/&self { /// Access the post-downgrade rwlock in read mode. - fn read(&self, blk: fn() -> U) -> U { blk() } + fn read(&self, blk: &fn() -> U) -> U { blk() } } /**************************************************************************** @@ -1082,7 +1083,7 @@ mod tests { #[cfg(test)] pub enum RWlockMode { Read, Write, Downgrade, DowngradeRead } #[cfg(test)] - pub fn lock_rwlock_in_mode(x: &RWlock, mode: RWlockMode, blk: fn()) { + pub fn lock_rwlock_in_mode(x: &RWlock, mode: RWlockMode, blk: &fn()) { match mode { Read => x.read(blk), Write => x.write(blk), @@ -1239,7 +1240,7 @@ mod tests { dg1: bool, dg2: bool) { // Much like the mutex broadcast test. Downgrade-enabled. - fn lock_cond(x: &RWlock, downgrade: bool, blk: fn(c: &Condvar)) { + fn lock_cond(x: &RWlock, downgrade: bool, blk: &fn(c: &Condvar)) { if downgrade { do x.write_downgrade |mode| { (&mode).write_cond(blk) diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs index f06f64dde010b..72351aac33975 100644 --- a/src/libstd/treemap.rs +++ b/src/libstd/treemap.rs @@ -96,7 +96,7 @@ impl Ord for TreeMap { impl<'self, K: TotalOrd, V> BaseIter<(&'self K, &'self V)> for TreeMap { /// Visit all key-value pairs in order - pure fn each(&self, f: fn(&(&self/K, &self/V)) -> bool) { + pure fn each(&self, f: &fn(&(&self/K, &self/V)) -> bool) { each(&self.root, f) } pure fn size_hint(&self) -> Option { Some(self.len()) } @@ -107,7 +107,7 @@ impl<'self, K: TotalOrd, V> for TreeMap { /// Visit all key-value pairs in reverse order - pure fn each_reverse(&self, f: fn(&(&self/K, &self/V)) -> bool) { + pure fn each_reverse(&self, f: &fn(&(&self/K, &self/V)) -> bool) { each_reverse(&self.root, f); } } @@ -135,10 +135,12 @@ impl Map for TreeMap { } /// Visit all keys in order - pure fn each_key(&self, f: fn(&K) -> bool) { self.each(|&(k, _)| f(k)) } + pure fn each_key(&self, f: &fn(&K) -> bool) { self.each(|&(k, _)| f(k)) } /// Visit all values in order - pure fn each_value(&self, f: fn(&V) -> bool) { self.each(|&(_, v)| f(v)) } + pure fn each_value(&self, f: &fn(&V) -> bool) { + self.each(|&(_, v)| f(v)) + } /// Return the value corresponding to the key in the map pure fn find(&self, key: &K) -> Option<&self/V> { @@ -180,12 +182,12 @@ pub impl TreeMap { static pure fn new() -> TreeMap { TreeMap{root: None, length: 0} } /// Visit all keys in reverse order - pure fn each_key_reverse(&self, f: fn(&K) -> bool) { + pure fn each_key_reverse(&self, f: &fn(&K) -> bool) { self.each_reverse(|&(k, _)| f(k)) } /// Visit all values in reverse order - pure fn each_value_reverse(&self, f: fn(&V) -> bool) { + pure fn each_value_reverse(&self, f: &fn(&V) -> bool) { self.each_reverse(|&(_, v)| f(v)) } @@ -225,7 +227,7 @@ pub fn map_next(iter: &mut TreeMapIterator/&r) /// Advance the iterator through the map pub fn map_advance(iter: &mut TreeMapIterator/&r, - f: fn((&r/K, &r/V)) -> bool) { + f: &fn((&r/K, &r/V)) -> bool) { loop { match map_next(iter) { Some(x) => { @@ -242,13 +244,13 @@ pub struct TreeSet { impl BaseIter for TreeSet { /// Visit all values in order - pure fn each(&self, f: fn(&T) -> bool) { self.map.each_key(f) } + pure fn each(&self, f: &fn(&T) -> bool) { self.map.each_key(f) } pure fn size_hint(&self) -> Option { Some(self.len()) } } impl ReverseIter for TreeSet { /// Visit all values in reverse order - pure fn each_reverse(&self, f: fn(&T) -> bool) { + pure fn each_reverse(&self, f: &fn(&T) -> bool) { self.map.each_key_reverse(f) } } @@ -350,7 +352,7 @@ impl Set for TreeSet { } /// Visit the values (in-order) representing the difference - pure fn difference(&self, other: &TreeSet, f: fn(&T) -> bool) { + pure fn difference(&self, other: &TreeSet, f: &fn(&T) -> bool) { let mut x = self.iter(); let mut y = other.iter(); @@ -383,7 +385,7 @@ impl Set for TreeSet { /// Visit the values (in-order) representing the symmetric difference pure fn symmetric_difference(&self, other: &TreeSet, - f: fn(&T) -> bool) { + f: &fn(&T) -> bool) { let mut x = self.iter(); let mut y = other.iter(); @@ -422,7 +424,7 @@ impl Set for TreeSet { } /// Visit the values (in-order) representing the intersection - pure fn intersection(&self, other: &TreeSet, f: fn(&T) -> bool) { + pure fn intersection(&self, other: &TreeSet, f: &fn(&T) -> bool) { let mut x = self.iter(); let mut y = other.iter(); @@ -449,7 +451,7 @@ impl Set for TreeSet { } /// Visit the values (in-order) representing the union - pure fn union(&self, other: &TreeSet, f: fn(&T) -> bool) { + pure fn union(&self, other: &TreeSet, f: &fn(&T) -> bool) { let mut x = self.iter(); let mut y = other.iter(); @@ -508,7 +510,7 @@ pub fn set_next(iter: &mut TreeSetIterator/&r) -> Option<&r/T> { /// Advance the iterator through the set fn set_advance(iter: &mut TreeSetIterator/&r, - f: fn(&r/T) -> bool) { + f: &fn(&r/T) -> bool) { do map_advance(&mut iter.iter) |(k, _)| { f(k) } } @@ -530,7 +532,7 @@ pub impl TreeNode { } pure fn each(node: &r/Option<~TreeNode>, - f: fn(&(&r/K, &r/V)) -> bool) { + f: &fn(&(&r/K, &r/V)) -> bool) { for node.each |x| { each(&x.left, f); if f(&(&x.key, &x.value)) { each(&x.right, f) } @@ -538,7 +540,7 @@ pure fn each(node: &r/Option<~TreeNode>, } pure fn each_reverse(node: &r/Option<~TreeNode>, - f: fn(&(&r/K, &r/V)) -> bool) { + f: &fn(&(&r/K, &r/V)) -> bool) { for node.each |x| { each_reverse(&x.right, f); if f(&(&x.key, &x.value)) { each_reverse(&x.left, f) } diff --git a/src/libstd/uv.rs b/src/libstd/uv.rs index 1a4f8e8990646..aaddc9b6836f3 100644 --- a/src/libstd/uv.rs +++ b/src/libstd/uv.rs @@ -33,6 +33,6 @@ * facilities. */ -pub use ll = uv_ll; +pub use ll = core::unstable::uvll; pub use iotask = uv_iotask; pub use global_loop = uv_global_loop; diff --git a/src/libstd/workcache.rs b/src/libstd/workcache.rs index eac6e090f1f10..68a6f8effaa77 100644 --- a/src/libstd/workcache.rs +++ b/src/libstd/workcache.rs @@ -269,7 +269,7 @@ pub impl Context { Decodable>( // FIXME(#5121) @self, fn_name:&str, - blk: fn(@Mut)->Work) -> Work { + blk: &fn(@Mut)->Work) -> Work { let p = @Mut(Prep {ctxt: self, fn_name: fn_name.to_owned(), declared_inputs: LinearMap::new()}); diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index a6ccd69dd0655..27dba9c2b5ebc 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -116,7 +116,7 @@ pub struct path { span: span, global: bool, idents: ~[ident], - rp: Option<@region>, + rp: Option<@Lifetime>, types: ~[@Ty], } @@ -309,7 +309,9 @@ pub enum pat_ { pat_region(@pat), // borrowed pointer pattern pat_lit(@expr), pat_range(@expr, @expr), - pat_vec(~[@pat], Option<@pat>) + // [a, b, ..i, y, z] is represented as + // pat_vec(~[a, b], Some(i), ~[y, z]) + pat_vec(~[@pat], Option<@pat>, ~[@pat]) } #[auto_encode] @@ -374,10 +376,10 @@ impl ToStr for Sigil { #[deriving_eq] pub enum vstore { // FIXME (#3469): Change uint to @expr (actually only constant exprs) - vstore_fixed(Option), // [1,2,3,4] - vstore_uniq, // ~[1,2,3,4] - vstore_box, // @[1,2,3,4] - vstore_slice(@region) // &[1,2,3,4](foo)? + vstore_fixed(Option), // [1,2,3,4] + vstore_uniq, // ~[1,2,3,4] + vstore_box, // @[1,2,3,4] + vstore_slice(Option<@Lifetime>) // &'foo? [1,2,3,4] } #[auto_encode] @@ -857,24 +859,6 @@ pub enum prim_ty { ty_bool, } -#[auto_encode] -#[auto_decode] -#[deriving_eq] -pub struct region { - id: node_id, - node: region_, -} - -#[auto_encode] -#[auto_decode] -#[deriving_eq] -pub enum region_ { - re_anon, - re_static, - re_self, - re_named(ident) -} - #[auto_encode] #[auto_decode] #[deriving_eq] @@ -903,7 +887,7 @@ impl to_bytes::IterBytes for Onceness { #[deriving_eq] pub struct TyClosure { sigil: Sigil, - region: Option<@region>, + region: Option<@Lifetime>, purity: purity, onceness: Onceness, decl: fn_decl @@ -929,7 +913,7 @@ pub enum ty_ { ty_vec(mt), ty_fixed_length_vec(mt, uint), ty_ptr(mt), - ty_rptr(@region, mt), + ty_rptr(Option<@Lifetime>, mt), ty_closure(@TyClosure), ty_bare_fn(@TyBareFn), ty_tup(~[@Ty]), @@ -1102,16 +1086,11 @@ pub enum variant_kind { #[auto_encode] #[auto_decode] #[deriving_eq] -pub struct enum_def_ { +pub struct enum_def { variants: ~[variant], common: Option<@struct_def>, } -#[auto_encode] -#[auto_decode] -#[deriving_eq] -pub enum enum_def = enum_def_; - #[auto_encode] #[auto_decode] #[deriving_eq] diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index 3001fe8069c93..a7d5c0ce75fa0 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -423,7 +423,7 @@ pub fn node_id_to_str(map: map, id: node_id, itr: @ident_interner) -> ~str { } pub fn node_item_query(items: map, id: node_id, - query: fn(@item) -> Result, + query: &fn(@item) -> Result, +error_msg: ~str) -> Result { match items.find(&id) { Some(node_item(it, _)) => query(it), diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 686ae3900ff43..35b188a248fd4 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -516,7 +516,7 @@ pub pure fn is_item_impl(item: @ast::item) -> bool { } } -pub fn walk_pat(pat: @pat, it: fn(@pat)) { +pub fn walk_pat(pat: @pat, it: &fn(@pat)) { it(pat); match pat.node { pat_ident(_, _, Some(p)) => walk_pat(p, it), @@ -533,12 +533,15 @@ pub fn walk_pat(pat: @pat, it: fn(@pat)) { pat_box(s) | pat_uniq(s) | pat_region(s) => { walk_pat(s, it) } - pat_vec(ref elts, ref tail) => { - for elts.each |p| { + pat_vec(ref before, ref slice, ref after) => { + for before.each |p| { walk_pat(*p, it) } - for tail.each |tail| { - walk_pat(*tail, it) + for slice.each |p| { + walk_pat(*p, it) + } + for after.each |p| { + walk_pat(*p, it) } } pat_wild | pat_lit(_) | pat_range(_, _) | pat_ident(_, _, _) | diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 3397ca91c9624..0d6ece8ad92f1 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -35,11 +35,11 @@ pub trait Pos { } /// A byte offset -pub enum BytePos = uint; +pub struct BytePos(uint); /// A character offset. Because of multibyte utf8 characters, a byte offset /// is not equivalent to a character offset. The CodeMap will convert BytePos /// values to CharPos values as necessary. -pub enum CharPos = uint; +pub struct CharPos(uint); // XXX: Lots of boilerplate in these impls, but so far my attempts to fix // have been unsuccessful diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index 33e734fbd64cc..4e177fecec9e6 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -306,7 +306,7 @@ fn print_macro_backtrace(cm: @codemap::CodeMap, sp: span) { pub fn expect(diag: span_handler, opt: Option, - msg: fn() -> ~str) -> T { + msg: &fn() -> ~str) -> T { match opt { Some(ref t) => (*t), None => diag.handler().bug(msg()) diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs index 644afaff37c5c..c99d89776431a 100644 --- a/src/libsyntax/ext/auto_encode.rs +++ b/src/libsyntax/ext/auto_encode.rs @@ -432,7 +432,7 @@ fn mk_impl( ty_param: ast::TyParam, path: @ast::path, generics: &ast::Generics, - f: fn(@ast::Ty) -> @ast::method + f: &fn(@ast::Ty) -> @ast::method ) -> @ast::item { /*! * @@ -594,10 +594,7 @@ fn mk_ser_method( let ty_s = @ast::Ty { id: cx.next_id(), node: ast::ty_rptr( - @ast::region { - id: cx.next_id(), - node: ast::re_anon, - }, + None, ast::mt { ty: cx.ty_path(span, ~[cx.ident_of(~"__S")], ~[]), mutbl: ast::m_imm @@ -658,10 +655,7 @@ fn mk_deser_method( let ty_d = @ast::Ty { id: cx.next_id(), node: ast::ty_rptr( - @ast::region { - id: cx.next_id(), - node: ast::re_anon, - }, + None, ast::mt { ty: cx.ty_path(span, ~[cx.ident_of(~"__D")], ~[]), mutbl: ast::m_imm @@ -1262,51 +1256,51 @@ mod test { fn emit_owned_str(&self, +_v: &str) { self.add_unknown_to_log(); } fn emit_managed_str(&self, +_v: &str) { self.add_unknown_to_log(); } - fn emit_borrowed(&self, f: fn()) { self.add_unknown_to_log(); f() } - fn emit_owned(&self, f: fn()) { self.add_unknown_to_log(); f() } - fn emit_managed(&self, f: fn()) { self.add_unknown_to_log(); f() } + fn emit_borrowed(&self, f: &fn()) { self.add_unknown_to_log(); f() } + fn emit_owned(&self, f: &fn()) { self.add_unknown_to_log(); f() } + fn emit_managed(&self, f: &fn()) { self.add_unknown_to_log(); f() } - fn emit_enum(&self, name: &str, f: fn()) { + fn emit_enum(&self, name: &str, f: &fn()) { self.add_to_log(CallToEmitEnum(name.to_str())); f(); } fn emit_enum_variant(&self, name: &str, +id: uint, - +cnt: uint, f: fn()) { + +cnt: uint, f: &fn()) { self.add_to_log(CallToEmitEnumVariant (name.to_str(),id,cnt)); f(); } - fn emit_enum_variant_arg(&self, +idx: uint, f: fn()) { + fn emit_enum_variant_arg(&self, +idx: uint, f: &fn()) { self.add_to_log(CallToEmitEnumVariantArg (idx)); f(); } - fn emit_borrowed_vec(&self, +_len: uint, f: fn()) { + fn emit_borrowed_vec(&self, +_len: uint, f: &fn()) { self.add_unknown_to_log(); f(); } - fn emit_owned_vec(&self, +_len: uint, f: fn()) { + fn emit_owned_vec(&self, +_len: uint, f: &fn()) { self.add_unknown_to_log(); f(); } - fn emit_managed_vec(&self, +_len: uint, f: fn()) { + fn emit_managed_vec(&self, +_len: uint, f: &fn()) { self.add_unknown_to_log(); f(); } - fn emit_vec_elt(&self, +_idx: uint, f: fn()) { + fn emit_vec_elt(&self, +_idx: uint, f: &fn()) { self.add_unknown_to_log(); f(); } - fn emit_rec(&self, f: fn()) { + fn emit_rec(&self, f: &fn()) { self.add_unknown_to_log(); f(); } - fn emit_struct(&self, name: &str, +len: uint, f: fn()) { + fn emit_struct(&self, name: &str, +len: uint, f: &fn()) { self.add_to_log(CallToEmitStruct (name.to_str(),len)); f(); } - fn emit_field(&self, name: &str, +idx: uint, f: fn()) { + fn emit_field(&self, name: &str, +idx: uint, f: &fn()) { self.add_to_log(CallToEmitField (name.to_str(),idx)); f(); } - fn emit_tup(&self, +_len: uint, f: fn()) { + fn emit_tup(&self, +_len: uint, f: &fn()) { self.add_unknown_to_log(); f(); } - fn emit_tup_elt(&self, +_idx: uint, f: fn()) { + fn emit_tup_elt(&self, +_idx: uint, f: &fn()) { self.add_unknown_to_log(); f(); } } @@ -1333,16 +1327,4 @@ mod test { CallToEmitEnumVariantArg (1), CallToEmitUint (44)]); } - - pub enum BPos = uint; - - #[auto_encode] - pub struct HasPos { pos : BPos } - - #[test] fn encode_newtype_test () { - check_equal (to_call_log (HasPos {pos:BPos(48)}), - ~[CallToEmitStruct(~"HasPos",1), - CallToEmitField(~"pos",0), - CallToEmitUint(48)]); - } } diff --git a/src/libsyntax/ext/deriving.rs b/src/libsyntax/ext/deriving.rs index a1514bc3eabdb..efea962a0892d 100644 --- a/src/libsyntax/ext/deriving.rs +++ b/src/libsyntax/ext/deriving.rs @@ -19,7 +19,7 @@ use ast::{enum_variant_kind, expr, expr_match, ident, impure_fn, item, item_}; use ast::{item_enum, item_impl, item_struct, Generics}; use ast::{m_imm, meta_item, method}; use ast::{named_field, or, pat, pat_ident, pat_wild, public, pure_fn}; -use ast::{re_anon, stmt, struct_def, struct_variant_kind}; +use ast::{stmt, struct_def, struct_variant_kind}; use ast::{sty_by_ref, sty_region, tuple_variant_kind, ty_nil, TyParam}; use ast::{TyParamBound, ty_path, ty_rptr, unnamed_field, variant}; use ext::base::ext_ctxt; @@ -147,9 +147,8 @@ fn create_eq_method(cx: ext_ctxt, span, type_ident, generics); - let arg_region = @ast::region { id: cx.next_id(), node: re_anon }; let arg_type = ty_rptr( - arg_region, + None, ast::mt { ty: arg_path_type, mutbl: m_imm } ); let arg_type = @ast::Ty { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index f76f10f3de16c..e61e8a1a594ce 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -409,14 +409,38 @@ pub fn core_macros() -> ~str { ~"pub mod macros { macro_rules! ignore (($($x:tt)*) => (())) - macro_rules! error ( ($( $arg:expr ),+) => ( - log(::core::error, fmt!( $($arg),+ )) )) - macro_rules! warn ( ($( $arg:expr ),+) => ( - log(::core::warn, fmt!( $($arg),+ )) )) - macro_rules! info ( ($( $arg:expr ),+) => ( - log(::core::info, fmt!( $($arg),+ )) )) - macro_rules! debug ( ($( $arg:expr ),+) => ( - log(::core::debug, fmt!( $($arg),+ )) )) + macro_rules! error ( + ($arg:expr) => ( + log(::core::error, fmt!( \"%?\", $arg )) + ); + ($( $arg:expr ),+) => ( + log(::core::error, fmt!( $($arg),+ )) + ) + ) + macro_rules! warn ( + ($arg:expr) => ( + log(::core::warn, fmt!( \"%?\", $arg )) + ); + ($( $arg:expr ),+) => ( + log(::core::warn, fmt!( $($arg),+ )) + ) + ) + macro_rules! info ( + ($arg:expr) => ( + log(::core::info, fmt!( \"%?\", $arg )) + ); + ($( $arg:expr ),+) => ( + log(::core::info, fmt!( $($arg),+ )) + ) + ) + macro_rules! debug ( + ($arg:expr) => ( + log(::core::debug, fmt!( \"%?\", $arg )) + ); + ($( $arg:expr ),+) => ( + log(::core::debug, fmt!( $($arg),+ )) + ) + ) macro_rules! fail( ($msg: expr) => ( diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs index 001e1b0daf63f..fd8b2dbf72f81 100644 --- a/src/libsyntax/ext/pipes/pipec.rs +++ b/src/libsyntax/ext/pipes/pipec.rs @@ -238,9 +238,7 @@ impl to_type_decls for state { cx.item_enum_poly( name, self.span, - ast::enum_def(enum_def_ { - variants: items_msg, - common: None }), + ast::enum_def { variants: items_msg, common: None }, cx.strip_bounds(&self.generics) ) ] diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs index 329b3f59b1e33..dc9abd536d11f 100644 --- a/src/libsyntax/ext/pipes/proto.rs +++ b/src/libsyntax/ext/pipes/proto.rs @@ -104,7 +104,7 @@ pub impl state_ { /// Iterate over the states that can be reached in one message /// from this state. - fn reachable(&self, f: fn(state) -> bool) { + fn reachable(&self, f: &fn(state) -> bool) { for self.messages.each |m| { match *m { message(_, _, _, _, Some(next_state { state: ref id, _ })) => { diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index b8371c9e8d962..427760c920f6d 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -254,16 +254,14 @@ pub fn noop_fold_item_underscore(i: &item_, fld: @ast_fold) -> item_ { } item_enum(ref enum_definition, ref generics) => { item_enum( - ast::enum_def( - ast::enum_def_ { - variants: do enum_definition.variants.map |x| { - fld.fold_variant(x) - }, - common: do enum_definition.common.map |x| { - fold_struct_def(*x, fld) - } + ast::enum_def { + variants: do enum_definition.variants.map |x| { + fld.fold_variant(x) + }, + common: do enum_definition.common.map |x| { + fold_struct_def(*x, fld) } - ), + }, fold_generics(generics, fld)) } item_struct(ref struct_def, ref generics) => { @@ -416,10 +414,11 @@ pub fn noop_fold_pat(p: &pat_, fld: @ast_fold) -> pat_ { pat_range(e1, e2) => { pat_range(fld.fold_expr(e1), fld.fold_expr(e2)) }, - pat_vec(ref elts, ref tail) => { + pat_vec(ref before, ref slice, ref after) => { pat_vec( - elts.map(|x| fld.fold_pat(*x)), - tail.map(|tail| fld.fold_pat(*tail)) + before.map(|x| fld.fold_pat(*x)), + slice.map(|x| fld.fold_pat(*x)), + after.map(|x| fld.fold_pat(*x)) ) } } @@ -683,10 +682,7 @@ fn noop_fold_variant(v: &variant_, fld: @ast_fold) -> variant_ { fold_struct_def(*x, fld) }; kind = enum_variant_kind( - ast::enum_def(ast::enum_def_ { - variants: variants, - common: common - }) + ast::enum_def { variants: variants, common: common } ); } } diff --git a/src/libsyntax/opt_vec.rs b/src/libsyntax/opt_vec.rs index 16db384bb062c..ba0c7a71b7c17 100644 --- a/src/libsyntax/opt_vec.rs +++ b/src/libsyntax/opt_vec.rs @@ -122,7 +122,7 @@ impl Eq for OptVec { } impl BaseIter for OptVec { - pure fn each(&self, blk: fn(v: &A) -> bool) { + pure fn each(&self, blk: &fn(v: &A) -> bool) { match *self { Empty => {} Vec(ref v) => v.each(blk) @@ -136,31 +136,31 @@ impl BaseIter for OptVec { impl iter::ExtendedIter for OptVec { #[inline(always)] - pure fn eachi(&self, blk: fn(+v: uint, v: &A) -> bool) { + pure fn eachi(&self, blk: &fn(+v: uint, v: &A) -> bool) { iter::eachi(self, blk) } #[inline(always)] - pure fn all(&self, blk: fn(&A) -> bool) -> bool { + pure fn all(&self, blk: &fn(&A) -> bool) -> bool { iter::all(self, blk) } #[inline(always)] - pure fn any(&self, blk: fn(&A) -> bool) -> bool { + pure fn any(&self, blk: &fn(&A) -> bool) -> bool { iter::any(self, blk) } #[inline(always)] - pure fn foldl(&self, +b0: B, blk: fn(&B, &A) -> B) -> B { + pure fn foldl(&self, +b0: B, blk: &fn(&B, &A) -> B) -> B { iter::foldl(self, b0, blk) } #[inline(always)] - pure fn position(&self, f: fn(&A) -> bool) -> Option { + pure fn position(&self, f: &fn(&A) -> bool) -> Option { iter::position(self, f) } #[inline(always)] - pure fn map_to_vec(&self, op: fn(&A) -> B) -> ~[B] { + pure fn map_to_vec(&self, op: &fn(&A) -> B) -> ~[B] { iter::map_to_vec(self, op) } #[inline(always)] - pure fn flat_map_to_vec>(&self, op: fn(&A) -> IB) + pure fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) -> ~[B] { iter::flat_map_to_vec(self, op) } @@ -176,13 +176,13 @@ impl iter::EqIter for OptVec { impl iter::CopyableIter for OptVec { #[inline(always)] - pure fn filter_to_vec(&self, pred: fn(&A) -> bool) -> ~[A] { + pure fn filter_to_vec(&self, pred: &fn(&A) -> bool) -> ~[A] { iter::filter_to_vec(self, pred) } #[inline(always)] pure fn to_vec(&self) -> ~[A] { iter::to_vec(self) } #[inline(always)] - pure fn find(&self, f: fn(&A) -> bool) -> Option { + pure fn find(&self, f: &fn(&A) -> bool) -> Option { iter::find(self, f) } } diff --git a/src/libsyntax/parse/common.rs b/src/libsyntax/parse/common.rs index 7af2204fafd09..c7b9a769293d6 100644 --- a/src/libsyntax/parse/common.rs +++ b/src/libsyntax/parse/common.rs @@ -248,7 +248,7 @@ pub impl Parser { fn parse_seq_to_before_gt( &self, sep: Option, - f: fn(&Parser) -> T + f: &fn(&Parser) -> T ) -> OptVec { let mut first = true; let mut v = opt_vec::Empty; @@ -269,7 +269,7 @@ pub impl Parser { fn parse_seq_to_gt( &self, sep: Option, - f: fn(&Parser) -> T + f: &fn(&Parser) -> T ) -> OptVec { let v = self.parse_seq_to_before_gt(sep, f); self.expect_gt(); @@ -283,7 +283,7 @@ pub impl Parser { &self, ket: &token::Token, sep: SeqSep, - f: fn(&Parser) -> T + f: &fn(&Parser) -> T ) -> ~[T] { let val = self.parse_seq_to_before_end(ket, sep, f); self.bump(); @@ -297,7 +297,7 @@ pub impl Parser { &self, ket: &token::Token, sep: SeqSep, - f: fn(&Parser) -> T + f: &fn(&Parser) -> T ) -> ~[T] { let mut first: bool = true; let mut v: ~[T] = ~[]; @@ -323,7 +323,7 @@ pub impl Parser { bra: &token::Token, ket: &token::Token, sep: SeqSep, - f: fn(&Parser) -> T + f: &fn(&Parser) -> T ) -> ~[T] { self.expect(bra); let result = self.parse_seq_to_before_end(ket, sep, f); @@ -338,7 +338,7 @@ pub impl Parser { bra: &token::Token, ket: &token::Token, sep: SeqSep, - f: fn(&Parser) -> T + f: &fn(&Parser) -> T ) -> spanned<~[T]> { let lo = self.span.lo; self.expect(bra); diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index a1fc7230dd1f0..fd84f8670686b 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -173,7 +173,7 @@ pub fn parse_tts_from_source_str( } pub fn parse_from_source_str( - f: fn (Parser) -> T, + f: &fn (Parser) -> T, name: ~str, ss: codemap::FileSubstr, source: @~str, +cfg: ast::crate_cfg, diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index 6f2d2c554aa93..ef858a2d5ebd1 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -52,6 +52,9 @@ pub enum ObsoleteSyntax { ObsoleteRecordType, ObsoleteRecordPattern, ObsoleteAssertion, + ObsoletePostFnTySigil, + ObsoleteBareFnType, + ObsoleteNewtypeEnum, } impl to_bytes::IterBytes for ObsoleteSyntax { @@ -160,6 +163,19 @@ pub impl Parser { "assertion", "use `fail_unless!()` instead" ), + ObsoletePostFnTySigil => ( + "fn sigil in postfix position", + "Rather than `fn@`, `fn~`, or `fn&`, \ + write `@fn`, `~fn`, and `&fn` respectively" + ), + ObsoleteBareFnType => ( + "bare function type", + "use `&fn` or `extern fn` instead" + ), + ObsoleteNewtypeEnum => ( + "newtype enum", + "instead of `enum Foo = int`, write `struct Foo(int)`" + ), }; self.report(sp, kind, kind_str, desc); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 384cf4f0e9517..99c1c2cb1feec 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -14,7 +14,7 @@ use ast::{Sigil, BorrowedSigil, ManagedSigil, OwnedSigil, RustAbi}; use ast::{CallSugar, NoSugar, DoSugar, ForSugar}; use ast::{TyBareFn, TyClosure}; use ast::{RegionTyParamBound, TraitTyParamBound}; -use ast::{provided, public, pure_fn, purity, re_static}; +use ast::{provided, public, pure_fn, purity}; use ast::{_mod, add, arg, arm, attribute, bind_by_ref, bind_infer}; use ast::{bind_by_copy, bitand, bitor, bitxor, blk}; use ast::{blk_check_mode, box, by_copy, by_ref, by_val}; @@ -40,9 +40,9 @@ use ast::{lit_int_unsuffixed, lit_nil, lit_str, lit_uint, local, m_const}; use ast::{m_imm, m_mutbl, mac_, mac_invoc_tt, matcher, match_nonterminal}; use ast::{match_seq, match_tok, method, mode, module_ns, mt, mul, mutability}; use ast::{named_field, neg, node_id, noreturn, not, pat, pat_box, pat_enum}; -use ast::{pat_ident, pat_lit, pat_range, pat_region, pat_struct, pat_tup}; -use ast::{pat_uniq, pat_wild, path, private}; -use ast::{re_self, re_anon, re_named, region, rem, required}; +use ast::{pat_ident, pat_lit, pat_range, pat_region, pat_struct}; +use ast::{pat_tup, pat_uniq, pat_wild, path, private}; +use ast::{rem, required}; use ast::{ret_style, return_val, self_ty, shl, shr, stmt, stmt_decl}; use ast::{stmt_expr, stmt_semi, stmt_mac, struct_def, struct_field}; use ast::{struct_immutable, struct_mutable, struct_variant_kind, subtract}; @@ -76,7 +76,8 @@ use parse::obsolete::{ObsoleteUnsafeBlock, ObsoleteImplSyntax}; use parse::obsolete::{ObsoleteTraitBoundSeparator, ObsoleteMutOwnedPointer}; use parse::obsolete::{ObsoleteMutVector, ObsoleteTraitImplVisibility}; use parse::obsolete::{ObsoleteRecordType, ObsoleteRecordPattern}; -use parse::obsolete::{ObsoleteAssertion}; +use parse::obsolete::{ObsoleteAssertion, ObsoletePostFnTySigil}; +use parse::obsolete::{ObsoleteBareFnType, ObsoleteNewtypeEnum}; use parse::prec::{as_prec, token_to_binop}; use parse::token::{can_begin_expr, is_ident, is_ident_or_path}; use parse::token::{is_plain_ident, INTERPOLATED, special_idents}; @@ -363,12 +364,13 @@ pub impl Parser { }); } - fn parse_ty_closure(&self, pre_sigil: Option, - pre_region_name: Option) -> ty_ + fn parse_ty_closure(&self, + sigil: ast::Sigil, + region: Option<@ast::Lifetime>) -> ty_ { /* - (&|~|@) [r/] [pure|unsafe] [once] fn <'lt> (S) -> T + (&|~|@) ['r] [pure|unsafe] [once] fn <'lt> (S) -> T ^~~~~~^ ^~~^ ^~~~~~~~~~~~^ ^~~~~^ ^~~~^ ^~^ ^ | | | | | | | | | | | | | Return type @@ -388,13 +390,10 @@ pub impl Parser { let onceness = parse_onceness(self); self.expect_keyword(&~"fn"); - let sigil = match pre_sigil { None => BorrowedSigil, Some(p) => p }; - - let region = if pre_region_name.is_some() { - Some(self.region_from_name(pre_region_name)) - } else { - None - }; + if self.parse_fn_ty_sigil().is_some() { + self.obsolete(*self.span, + ObsoletePostFnTySigil); + } return ty_closure(@TyClosure { sigil: sigil, @@ -432,7 +431,7 @@ pub impl Parser { */ if self.eat(&token::LT) { let _lifetimes = self.parse_lifetimes(); - self.expect(&token::GT); + self.expect_gt(); } let inputs = self.parse_unspanned_seq( &token::LPAREN, @@ -575,38 +574,6 @@ pub impl Parser { } } - fn region_from_name(&self, s: Option) -> @region { - let r = match s { - Some(id) if id == special_idents::static => ast::re_static, - Some(id) if id == special_idents::self_ => re_self, - Some(id) => re_named(id), - None => re_anon - }; - - @ast::region { id: self.get_id(), node: r } - } - - // Parses something like "&x" - fn parse_region(&self) -> @region { - self.expect(&token::BINOP(token::AND)); - - match *self.token { - token::IDENT(sid, _) => { - self.bump(); - self.region_from_name(Some(sid)) - } - _ => { - self.region_from_name(None) - } - } - } - - fn region_from_lifetime(&self, l: &ast::Lifetime) -> @region { - // eventually `ast::region` should go away in favor of - // `ast::Lifetime`. For now we convert between them. - self.region_from_name(Some(l.ident)) - } - fn parse_ty(&self, colons_before_params: bool) -> @Ty { maybe_whole!(self, nt_ty); @@ -681,7 +648,9 @@ pub impl Parser { } else if self.eat_keyword(&~"extern") { self.parse_ty_bare_fn() } else if self.token_is_closure_keyword(© *self.token) { - self.parse_ty_closure(None, None) + let result = self.parse_ty_closure(ast::BorrowedSigil, None); + self.obsolete(*self.last_span, ObsoleteBareFnType); + result } else if *self.token == token::MOD_SEP || is_ident_or_path(&*self.token) { let path = self.parse_path_with_tps(colons_before_params); @@ -701,20 +670,20 @@ pub impl Parser { { // @'foo fn() or @foo/fn() or @fn() are parsed directly as fn types: match *self.token { - token::LIFETIME(rname) => { + token::LIFETIME(*) => { + let lifetime = @self.parse_lifetime(); self.bump(); - return self.parse_ty_closure(Some(sigil), Some(rname)); + return self.parse_ty_closure(sigil, Some(lifetime)); } - token::IDENT(rname, _) => { + token::IDENT(*) => { if self.look_ahead(1u) == token::BINOP(token::SLASH) && self.token_is_closure_keyword(&self.look_ahead(2u)) { - self.bump(); - self.bump(); - return self.parse_ty_closure(Some(sigil), Some(rname)); + let lifetime = @self.parse_lifetime(); + return self.parse_ty_closure(sigil, Some(lifetime)); } else if self.token_is_closure_keyword(© *self.token) { - return self.parse_ty_closure(Some(sigil), None); + return self.parse_ty_closure(sigil, None); } } _ => {} @@ -735,31 +704,14 @@ pub impl Parser { fn parse_borrowed_pointee(&self) -> ty_ { // look for `&'lt` or `&foo/` and interpret `foo` as the region name: - let rname = match *self.token { - token::LIFETIME(sid) => { - self.bump(); - Some(sid) - } - - token::IDENT(sid, _) => { - if self.look_ahead(1u) == token::BINOP(token::SLASH) { - self.bump(); self.bump(); - Some(sid) - } else { - None - } - } - - _ => { None } - }; + let opt_lifetime = self.parse_opt_lifetime(); if self.token_is_closure_keyword(© *self.token) { - return self.parse_ty_closure(Some(BorrowedSigil), rname); + return self.parse_ty_closure(BorrowedSigil, opt_lifetime); } - let r = self.region_from_name(rname); let mt = self.parse_mt(); - return ty_rptr(r, mt); + return ty_rptr(opt_lifetime, mt); } fn parse_arg_mode(&self) -> mode { @@ -939,19 +891,27 @@ pub impl Parser { return path; } - // Parse the region parameter, if any, which will + // Parse the (obsolete) trailing region parameter, if any, which will // be written "foo/&x" let rp_slash = { - // Hack: avoid parsing vstores like /@ and /~. This is painful - // because the notation for region bounds and the notation for - // vstores is... um... the same. I guess that's my fault. This - // is still not ideal as for &str we end up parsing more than we - // ought to and have to sort it out later. if *self.token == token::BINOP(token::SLASH) - && self.look_ahead(1u) == token::BINOP(token::AND) { - - self.expect(&token::BINOP(token::SLASH)); - Some(self.parse_region()) + && self.look_ahead(1u) == token::BINOP(token::AND) + { + self.bump(); self.bump(); + match *self.token { + token::IDENT(sid, _) => { + let span = copy self.span; + self.bump(); + Some(@ast::Lifetime { + id: self.get_id(), + span: *span, + ident: sid + }) + } + _ => { + self.fatal(fmt!("Expected a lifetime name")); + } + } } else { None } @@ -967,7 +927,7 @@ pub impl Parser { if v.len() == 0 { None } else if v.len() == 1 { - Some(self.region_from_lifetime(v.get(0))) + Some(@*v.get(0)) } else { self.fatal(fmt!("Expected at most one \ lifetime name (for now)")); @@ -981,16 +941,26 @@ pub impl Parser { .. copy *path } } - fn parse_opt_lifetime(&self) -> Option { + fn parse_opt_lifetime(&self) -> Option<@ast::Lifetime> { /*! * * Parses 0 or 1 lifetime. */ match *self.token { - token::LIFETIME(_) => { - Some(self.parse_lifetime()) + token::LIFETIME(*) => { + Some(@self.parse_lifetime()) } + + // Also accept the (obsolete) syntax `foo/` + token::IDENT(*) => { + if self.look_ahead(1u) == token::BINOP(token::SLASH) { + Some(@self.parse_lifetime()) + } else { + None + } + } + _ => { None } @@ -1005,13 +975,27 @@ pub impl Parser { match *self.token { token::LIFETIME(i) => { + let span = copy self.span; self.bump(); return ast::Lifetime { id: self.get_id(), - span: *self.span, + span: *span, ident: i }; } + + // Also accept the (obsolete) syntax `foo/` + token::IDENT(i, _) => { + let span = copy self.span; + self.bump(); + self.expect(&token::BINOP(token::SLASH)); + return ast::Lifetime { + id: self.get_id(), + span: *span, + ident: i + }; + } + _ => { self.fatal(fmt!("Expected a lifetime name")); } @@ -1041,6 +1025,7 @@ pub impl Parser { match *self.token { token::COMMA => { self.bump();} token::GT => { return res; } + token::BINOP(token::SHR) => { return res; } _ => { self.fatal(~"expected `,` or `>` after lifetime name"); } @@ -1846,7 +1831,7 @@ pub impl Parser { fn parse_sugary_call_expr(&self, keyword: ~str, sugar: CallSugar, - ctor: fn(+v: @expr) -> expr_) -> @expr { + ctor: &fn(+v: @expr) -> expr_) -> @expr { let lo = self.last_span; // Parse the callee `foo` in // for foo || { @@ -2041,23 +2026,28 @@ pub impl Parser { fn parse_pat_vec_elements( &self, refutable: bool - ) -> (~[@pat], Option<@pat>) { - let mut elements = ~[]; - let mut tail = None; + ) -> (~[@pat], Option<@pat>, ~[@pat]) { + let mut before = ~[]; + let mut slice = None; + let mut after = ~[]; let mut first = true; + let mut before_slice = true; while *self.token != token::RBRACKET { if first { first = false; } else { self.expect(&token::COMMA); } - let mut is_tail = false; - if *self.token == token::DOTDOT { - self.bump(); - is_tail = true; + let mut is_slice = false; + if before_slice { + if *self.token == token::DOTDOT { + self.bump(); + is_slice = true; + before_slice = false; + } } let subpat = self.parse_pat(refutable); - if is_tail { + if is_slice { match subpat { @ast::pat { node: pat_wild, _ } => (), @ast::pat { node: pat_ident(_, _, _), _ } => (), @@ -2065,13 +2055,17 @@ pub impl Parser { span, ~"expected an identifier or `_`" ) } - tail = Some(subpat); - break; + slice = Some(subpat); + } else { + if before_slice { + before.push(subpat); + } else { + after.push(subpat); + } } - - elements.push(subpat); } - return (elements, tail); + + (before, slice, after) } fn parse_pat_fields(&self, refutable: bool) -> (~[ast::field_pat], bool) { @@ -2225,10 +2219,11 @@ pub impl Parser { } token::LBRACKET => { self.bump(); - let (elements, tail) = self.parse_pat_vec_elements(refutable); + let (before, slice, after) = + self.parse_pat_vec_elements(refutable); hi = self.span.hi; self.expect(&token::RBRACKET); - pat = ast::pat_vec(elements, tail); + pat = ast::pat_vec(before, slice, after); } copy tok => { if !is_ident_or_path(&tok) @@ -2776,7 +2771,7 @@ pub impl Parser { (lifetimes, opt_vec::take_vec(result)) } - fn parse_fn_decl(&self, parse_arg_fn: fn(&Parser) -> arg_or_capture_item) + fn parse_fn_decl(&self, parse_arg_fn: &fn(&Parser) -> arg_or_capture_item) -> fn_decl { let args_or_capture_items: ~[arg_or_capture_item] = @@ -2820,10 +2815,10 @@ pub impl Parser { fn parse_fn_decl_with_self( &self, parse_arg_fn: - fn(&Parser) -> arg_or_capture_item + &fn(&Parser) -> arg_or_capture_item ) -> (self_ty, fn_decl) { fn maybe_parse_self_ty( - cnstr: fn(+v: mutability) -> ast::self_ty_, + cnstr: &fn(+v: mutability) -> ast::self_ty_, p: &Parser ) -> ast::self_ty_ { // We need to make sure it isn't a mode or a type @@ -3772,7 +3767,7 @@ pub impl Parser { enum"); } - enum_def(ast::enum_def_ { variants: variants, common: common_fields }) + ast::enum_def { variants: variants, common: common_fields } } fn parse_item_enum(&self) -> item_info { @@ -3795,12 +3790,12 @@ pub impl Parser { vis: public, }); + self.obsolete(*self.last_span, ObsoleteNewtypeEnum); + return ( id, item_enum( - enum_def( - ast::enum_def_ { variants: ~[variant], common: None } - ), + ast::enum_def { variants: ~[variant], common: None }, generics), None ); diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index c68341c20fa4c..49899fdeec415 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -146,8 +146,8 @@ pub fn expr_to_str(e: @ast::expr, intr: @ident_interner) -> ~str { to_str(e, print_expr, intr) } -pub fn region_to_str(e: @ast::region, intr: @ident_interner) -> ~str { - to_str(e, |s, e| print_region(s, ~"&", e, ~""), intr) +pub fn lifetime_to_str(e: &ast::Lifetime, intr: @ident_interner) -> ~str { + to_str(e, print_lifetime, intr) } pub fn tt_to_str(tt: ast::token_tree, intr: @ident_interner) -> ~str { @@ -314,8 +314,8 @@ pub fn commasep(s: @ps, b: breaks, elts: ~[IN], op: &fn(@ps, IN)) { } -pub fn commasep_cmnt(s: @ps, b: breaks, elts: ~[IN], op: fn(@ps, IN), - get_span: fn(IN) -> codemap::span) { +pub fn commasep_cmnt(s: @ps, b: breaks, elts: ~[IN], op: &fn(@ps, IN), + get_span: &fn(IN) -> codemap::span) { box(s, 0u, b); let len = vec::len::(elts); let mut i = 0u; @@ -355,23 +355,11 @@ pub fn print_foreign_mod(s: @ps, nmod: ast::foreign_mod, for nmod.items.each |item| { print_foreign_item(s, *item); } } -pub fn print_region(s: @ps, prefix: ~str, region: @ast::region, sep: ~str) { - word(s.s, prefix); - match region.node { - ast::re_anon => { - return; - } - ast::re_static => { - word_space(s, ~"static") - } - ast::re_self => { - word_space(s, ~"self") - } - ast::re_named(name) => { - print_ident(s, name); - } +pub fn print_opt_lifetime(s: @ps, lifetime: Option<@ast::Lifetime>) { + for lifetime.each |l| { + print_lifetime(s, *l); + nbsp(s); } - word(s.s, sep); } pub fn print_type(s: @ps, &&ty: @ast::Ty) { @@ -397,8 +385,9 @@ pub fn print_type_ex(s: @ps, &&ty: @ast::Ty, print_colons: bool) { word(s.s, ~"]"); } ast::ty_ptr(mt) => { word(s.s, ~"*"); print_mt(s, mt); } - ast::ty_rptr(region, mt) => { - print_region(s, ~"&", region, ~"/"); + ast::ty_rptr(lifetime, mt) => { + word(s.s, ~"&"); + print_opt_lifetime(s, lifetime); print_mt(s, mt); } ast::ty_tup(elts) => { @@ -623,36 +612,11 @@ pub fn print_item(s: @ps, &&item: @ast::item) { pub fn print_enum_def(s: @ps, enum_definition: ast::enum_def, generics: &ast::Generics, ident: ast::ident, span: codemap::span, visibility: ast::visibility) { - let mut newtype = - vec::len(enum_definition.variants) == 1u && - ident == enum_definition.variants[0].node.name; - if newtype { - match enum_definition.variants[0].node.kind { - ast::tuple_variant_kind(ref args) if args.len() == 1 => {} - _ => newtype = false - } - } - if newtype { - ibox(s, indent_unit); - word_space(s, visibility_qualified(visibility, ~"enum")); - } else { - head(s, visibility_qualified(visibility, ~"enum")); - } - + head(s, visibility_qualified(visibility, ~"enum")); print_ident(s, ident); print_generics(s, generics); space(s.s); - if newtype { - word_space(s, ~"="); - match /*bad*/ copy enum_definition.variants[0].node.kind { - ast::tuple_variant_kind(args) => print_type(s, args[0].ty), - _ => fail!(~"newtype syntax with struct?") - } - word(s.s, ~";"); - end(s); - } else { - print_variants(s, enum_definition.variants, span); - } + print_variants(s, enum_definition.variants, span); } pub fn print_variants(s: @ps, @@ -1048,7 +1012,10 @@ pub fn print_vstore(s: @ps, t: ast::vstore) { ast::vstore_fixed(None) => word(s.s, ~"_"), ast::vstore_uniq => word(s.s, ~"~"), ast::vstore_box => word(s.s, ~"@"), - ast::vstore_slice(r) => print_region(s, ~"&", r, ~"/") + ast::vstore_slice(r) => { + word(s.s, ~"&"); + print_opt_lifetime(s, r); + } } } @@ -1501,17 +1468,18 @@ pub fn print_path(s: @ps, &&path: @ast::path, colons_before_params: bool) { if path.rp.is_some() || !path.types.is_empty() { if colons_before_params { word(s.s, ~"::"); } - match path.rp { - None => { /* ok */ } - Some(r) => { - word(s.s, ~"/"); - print_region(s, ~"&", r, ~""); - } - } - - if !path.types.is_empty() { + if path.rp.is_some() || !path.types.is_empty() { word(s.s, ~"<"); + + for path.rp.each |r| { + print_lifetime(s, *r); + if !path.types.is_empty() { + word_space(s, ~","); + } + } + commasep(s, inconsistent, path.types, print_type); + word(s.s, ~">"); } } @@ -1616,13 +1584,19 @@ pub fn print_pat(s: @ps, &&pat: @ast::pat, refutable: bool) { word(s.s, ~".."); print_expr(s, end); } - ast::pat_vec(elts, tail) => { + ast::pat_vec(before, slice, after) => { word(s.s, ~"["); - commasep(s, inconsistent, elts, |s, p| print_pat(s, p, refutable)); - for tail.each |tail| { - if vec::len(elts) != 0u { word_space(s, ~","); } + do commasep(s, inconsistent, before) |s, p| { + print_pat(s, p, refutable); + } + for slice.each |&p| { + if !before.is_empty() { word_space(s, ~","); } word(s.s, ~".."); - print_pat(s, *tail, refutable); + print_pat(s, p, refutable); + if !after.is_empty() { word_space(s, ~","); } + } + do commasep(s, inconsistent, after) |s, p| { + print_pat(s, p, refutable); } word(s.s, ~"]"); } @@ -1749,7 +1723,7 @@ pub fn print_bounds(s: @ps, bounds: @OptVec) { } } -pub fn print_lifetime(s: @ps, lifetime: &ast::Lifetime) { +pub fn print_lifetime(s: @ps, &&lifetime: &ast::Lifetime) { word(s.s, ~"'"); print_ident(s, lifetime.ident); } @@ -1908,7 +1882,7 @@ pub fn print_arg(s: @ps, input: ast::arg) { pub fn print_ty_fn(s: @ps, opt_abi: Option, opt_sigil: Option, - opt_region: Option<@ast::region>, + opt_region: Option<@ast::Lifetime>, purity: ast::purity, onceness: ast::Onceness, decl: &ast::fn_decl, id: Option, @@ -1921,7 +1895,7 @@ pub fn print_ty_fn(s: @ps, print_self_ty_if_static(s, opt_self_ty); print_opt_abi(s, opt_abi); print_opt_sigil(s, opt_sigil); - for opt_region.each |r| { print_region(s, ~"", *r, ~"/"); } + print_opt_lifetime(s, opt_region); print_purity(s, purity); print_onceness(s, onceness); word(s.s, ~"fn"); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 6048256b90bfe..f04894729bd0c 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -287,11 +287,14 @@ pub fn visit_pat(p: @pat, e: E, v: vt) { (v.visit_expr)(e2, e, v); } pat_wild => (), - pat_vec(ref elts, ref tail) => { - for elts.each |elt| { + pat_vec(ref before, ref slice, ref after) => { + for before.each |elt| { + (v.visit_pat)(*elt, e, v); + } + for slice.each |elt| { (v.visit_pat)(*elt, e, v); } - for tail.each |tail| { + for after.each |tail| { (v.visit_pat)(*tail, e, v); } } diff --git a/src/libuv b/src/libuv index 218ab86721eef..576ab1db8ea03 160000 --- a/src/libuv +++ b/src/libuv @@ -1 +1 @@ -Subproject commit 218ab86721eefd7b7e97fa6d9f95a80a1fa8686c +Subproject commit 576ab1db8ea03889eb7b2274654afe7c5c867230 diff --git a/src/rt/arch/i386/_context.S b/src/rt/arch/i386/_context.S index a9e329f0bf358..d8b7281e72b75 100644 --- a/src/rt/arch/i386/_context.S +++ b/src/rt/arch/i386/_context.S @@ -15,9 +15,15 @@ getcontext. The registers_t variable is in (%esp) */ +#if defined(__APPLE__) || defined(_WIN32) +#define SWAP_REGISTERS _swap_registers +#else +#define SWAP_REGISTERS swap_registers +#endif + // swap_registers(registers_t *oregs, registers_t *regs) -.globl swap_registers -swap_registers: +.globl SWAP_REGISTERS +SWAP_REGISTERS: // save the old context movl 4(%esp), %eax movl %ebx, 4(%eax) diff --git a/src/rt/arch/i386/context.cpp b/src/rt/arch/i386/context.cpp index 50a15e8d86c82..94e6f0418d07c 100644 --- a/src/rt/arch/i386/context.cpp +++ b/src/rt/arch/i386/context.cpp @@ -13,8 +13,7 @@ #include "../../rust_globals.h" extern "C" uint32_t CDECL swap_registers(registers_t *oregs, - registers_t *regs) - asm ("swap_registers"); + registers_t *regs); context::context() { diff --git a/src/rt/arch/x86_64/_context.S b/src/rt/arch/x86_64/_context.S index 7fdc6114b0a6b..1f9ae1c83c565 100644 --- a/src/rt/arch/x86_64/_context.S +++ b/src/rt/arch/x86_64/_context.S @@ -49,9 +49,15 @@ First four arguments: anyhow. */ +#if defined(__APPLE__) || defined(_WIN32) +#define SWAP_REGISTERS _swap_registers +#else +#define SWAP_REGISTERS swap_registers +#endif + // swap_registers(registers_t *oregs, registers_t *regs) -.globl swap_registers -swap_registers: +.globl SWAP_REGISTERS +SWAP_REGISTERS: // n.b. when we enter, the return address is at the top of // the stack (i.e., 0(%RSP)) and the argument is in // RUSTRT_ARG0_S. We diff --git a/src/rt/arch/x86_64/context.cpp b/src/rt/arch/x86_64/context.cpp index b7f82b574680b..6a265dff76156 100644 --- a/src/rt/arch/x86_64/context.cpp +++ b/src/rt/arch/x86_64/context.cpp @@ -13,8 +13,7 @@ #include "../../rust_globals.h" extern "C" void CDECL swap_registers(registers_t *oregs, - registers_t *regs) -asm ("swap_registers"); + registers_t *regs); context::context() { diff --git a/src/rt/rust.cpp b/src/rt/rust.cpp index 803da32cbc8ac..d9ef6a52dbef6 100644 --- a/src/rt/rust.cpp +++ b/src/rt/rust.cpp @@ -21,6 +21,17 @@ void* global_crate_map = NULL; +#ifndef _WIN32 +pthread_key_t sched_key; +#else +DWORD sched_key; +#endif + +extern "C" void* +rust_get_sched_tls_key() { + return &sched_key; +} + /** The runtime entrypoint. The (C ABI) main function generated by rustc calls `rust_start`, providing the address of the Rust ABI main function, the @@ -30,6 +41,10 @@ void* global_crate_map = NULL; extern "C" CDECL int rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map) { +#ifndef _WIN32 + pthread_key_create(&sched_key, NULL); +#endif + // Load runtime configuration options from the environment. // FIXME #1497: Should provide a way to get these from the command // line as well. diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 1243d82460346..248f851e5b9f8 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -52,64 +52,18 @@ timegm(struct tm *tm) } #endif -extern "C" CDECL rust_str * -rust_getcwd() { - rust_task *task = rust_get_current_task(); - LOG(task, task, "rust_getcwd()"); - - char cbuf[BUF_BYTES]; - -#if defined(__WIN32__) - if (!_getcwd(cbuf, sizeof(cbuf))) { -#else - if (!getcwd(cbuf, sizeof(cbuf))) { -#endif - task->fail(); - return NULL; - } - - return make_str(task->kernel, cbuf, strlen(cbuf), "rust_str(getcwd)"); -} - #if defined(__WIN32__) -extern "C" CDECL rust_vec_box * +extern "C" CDECL char** rust_env_pairs() { - rust_task *task = rust_get_current_task(); - size_t envc = 0; - LPTCH ch = GetEnvironmentStringsA(); - LPTCH c; - for (c = ch; *c; c += strlen(c) + 1) { - ++envc; - } - c = ch; - rust_vec_box *v = (rust_vec_box *) - task->kernel->malloc(vec_size(envc), - "str vec interior"); - v->body.fill = v->body.alloc = sizeof(rust_vec*) * envc; - for (size_t i = 0; i < envc; ++i) { - size_t n = strlen(c); - rust_str *str = make_str(task->kernel, c, n, "str"); - ((rust_str**)&v->body.data)[i] = str; - c += n + 1; - } - if (ch) { - FreeEnvironmentStrings(ch); - } - return v; + return 0; } #else -extern "C" CDECL rust_vec_box * +extern "C" CDECL char** rust_env_pairs() { - rust_task *task = rust_get_current_task(); #ifdef __APPLE__ char **environ = *_NSGetEnviron(); #endif - char **e = environ; - size_t envc = 0; - while (*e) { - ++envc; ++e; - } - return make_str_vec(task->kernel, envc, environ); + return environ; } #endif @@ -293,49 +247,43 @@ debug_get_stk_seg() { return task->stk; } -extern "C" CDECL rust_vec_box* -rust_list_files(rust_str *path) { - rust_task *task = rust_get_current_task(); - array_list strings; +extern "C" CDECL char* #if defined(__WIN32__) - WIN32_FIND_DATA FindFileData; - HANDLE hFind = FindFirstFile((char*)path->body.data, &FindFileData); - if (hFind != INVALID_HANDLE_VALUE) { - do { - rust_str *str = make_str(task->kernel, FindFileData.cFileName, - strlen(FindFileData.cFileName), - "list_files_str"); - strings.push(str); - } while (FindNextFile(hFind, &FindFileData)); - FindClose(hFind); - } +rust_list_dir_val(WIN32_FIND_DATA* entry_ptr) { + return entry_ptr->cFileName; +} #else - DIR *dirp = opendir((char*)path->body.data); - if (dirp) { - struct dirent *dp; - while ((dp = readdir(dirp))) { - rust_vec_box *str = make_str(task->kernel, dp->d_name, - strlen(dp->d_name), - "list_files_str"); - strings.push(str); - } - closedir(dirp); - } +rust_list_dir_val(dirent* entry_ptr) { + return entry_ptr->d_name; +} #endif - rust_vec_box *vec = (rust_vec_box *) - task->kernel->malloc(vec_size(strings.size()), - "list_files_vec"); - size_t alloc_sz = sizeof(rust_vec*) * strings.size(); - vec->body.fill = vec->body.alloc = alloc_sz; - memcpy(&vec->body.data[0], strings.data(), alloc_sz); - return vec; +extern "C" CDECL size_t +#if defined(__WIN32__) +rust_list_dir_wfd_size() { + return sizeof(WIN32_FIND_DATAW); +} +#else +rust_list_dir_wfd_size() { + return 0; } +#endif -extern "C" CDECL rust_vec_box* -rust_list_files2(rust_str **path) { - return rust_list_files(*path); +extern "C" CDECL void* +#if defined(__WIN32__) +rust_list_dir_wfd_fp_buf(WIN32_FIND_DATAW* wfd) { + if(wfd == NULL) { + return 0; + } + else { + return wfd->cFileName; + } +} +#else +rust_list_dir_wfd_fp_buf(void* wfd) { + return 0; } +#endif extern "C" CDECL int rust_path_is_dir(char *path) { @@ -821,20 +769,20 @@ extern "C" CDECL void record_sp_limit(void *limit); class raw_thread: public rust_thread { public: - fn_env_pair *fn; + fn_env_pair fn; - raw_thread(fn_env_pair *fn) : fn(fn) { } + raw_thread(fn_env_pair fn) : fn(fn) { } virtual void run() { record_sp_limit(0); - fn->f(NULL, fn->env, NULL); + fn.f(NULL, fn.env, NULL); } }; extern "C" raw_thread* rust_raw_thread_start(fn_env_pair *fn) { assert(fn); - raw_thread *thread = new raw_thread(fn); + raw_thread *thread = new raw_thread(*fn); thread->start(); return thread; } diff --git a/src/rt/rust_util.h b/src/rt/rust_util.h index fbedb9bc6efb2..101d04c880475 100644 --- a/src/rt/rust_util.h +++ b/src/rt/rust_util.h @@ -79,38 +79,6 @@ inline void reserve_vec_exact(rust_vec_box** vpp, typedef rust_vec_box rust_str; -inline rust_str * -make_str(rust_kernel* kernel, const char* c, size_t strlen, - const char* name) { - size_t str_fill = strlen + 1; - size_t str_alloc = str_fill; - rust_str *str = (rust_str *) - kernel->malloc(vec_size(str_fill), name); - str->header.td = &str_body_tydesc; - str->body.fill = str_fill; - str->body.alloc = str_alloc; - memcpy(&str->body.data, c, strlen); - str->body.data[strlen] = '\0'; - return str; -} - -inline rust_vec_box * -make_str_vec(rust_kernel* kernel, size_t nstrs, char **strs) { - rust_vec_box *v = (rust_vec_box *) - kernel->malloc(vec_size(nstrs), - "str vec interior"); - // FIXME: should have a real td (Issue #2639) - v->header.td = NULL; - v->body.fill = v->body.alloc = sizeof(rust_vec_box*) * nstrs; - for (size_t i = 0; i < nstrs; ++i) { - rust_str *str = make_str(kernel, strs[i], - strlen(strs[i]), - "str"); - ((rust_str**)&v->body.data)[i] = str; - } - return v; -} - inline size_t get_box_size(size_t body_size, size_t body_align) { size_t header_size = sizeof(rust_opaque_box); // FIXME (#2699): This alignment calculation is suspicious. Is it right? diff --git a/src/rt/rust_uv.cpp b/src/rt/rust_uv.cpp index f08261c336dcd..5159434873733 100644 --- a/src/rt/rust_uv.cpp +++ b/src/rt/rust_uv.cpp @@ -376,16 +376,7 @@ current_kernel_malloc_alloc_cb(uv_handle_t* handle, extern "C" void rust_uv_buf_init(uv_buf_t* out_buf, char* base, size_t len) { - rust_task* task = rust_get_current_task(); - LOG(task, stdlib,"rust_uv_buf_init: base: %lu" \ - "len: %lu", - (unsigned long int)base, - (unsigned long int)len); *out_buf = uv_buf_init(base, len); - LOG(task, stdlib, "rust_uv_buf_init: after: " - "result->base: %" PRIxPTR " len: %" PRIxPTR, - (unsigned long int)(*out_buf).base, - (unsigned long int)(*out_buf).len); } extern "C" uv_loop_t* @@ -481,18 +472,11 @@ rust_uv_free_base_of_buf(uv_buf_t buf) { extern "C" struct sockaddr_in rust_uv_ip4_addr(const char* ip, int port) { - rust_task* task = rust_get_current_task(); - LOG(task, stdlib, "before creating addr_ptr.. ip %s" \ - " port %d\n", ip, port); struct sockaddr_in addr = uv_ip4_addr(ip, port); - LOG(task, stdlib, "after creating .. port: %d", addr.sin_port); return addr; } extern "C" struct sockaddr_in6 rust_uv_ip6_addr(const char* ip, int port) { - rust_task* task = rust_get_current_task(); - LOG(task, stdlib, "before creating addr_ptr.. ip %s" \ - " port %d\n", ip, port); return uv_ip6_addr(ip, port); } extern "C" int @@ -554,3 +538,28 @@ extern "C" sockaddr_in6* rust_uv_addrinfo_as_sockaddr_in6(addrinfo* input) { return (sockaddr_in6*)input->ai_addr; } + +extern "C" uv_idle_t* +rust_uv_idle_new() { + return new uv_idle_t; +} + +extern "C" void +rust_uv_idle_delete(uv_idle_t* handle) { + delete handle; +} + +extern "C" int +rust_uv_idle_init(uv_loop_t* loop, uv_idle_t* idle) { + return uv_idle_init(loop, idle); +} + +extern "C" int +rust_uv_idle_start(uv_idle_t* idle, uv_idle_cb cb) { + return uv_idle_start(idle, cb); +} + +extern "C" int +rust_uv_idle_stop(uv_idle_t* idle) { + return uv_idle_stop(idle); +} diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index fca10ac3ef49b..e27e0d5240503 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -29,12 +29,12 @@ rust_new_task_in_sched rust_num_threads rust_path_is_dir rust_path_exists -rust_getcwd rust_get_stdin rust_get_stdout rust_get_stderr -rust_list_files -rust_list_files2 +rust_list_dir_val +rust_list_dir_wfd_size +rust_list_dir_wfd_fp_buf rust_log_console_on rust_log_console_off rust_process_wait @@ -43,7 +43,6 @@ rust_sched_current_nonlazy_threads rust_sched_threads rust_set_exit_status rust_start -rust_getcwd rust_env_pairs rust_task_yield rust_task_is_unwinding @@ -141,6 +140,11 @@ rust_uv_current_kernel_malloc rust_uv_current_kernel_free rust_uv_getaddrinfo rust_uv_freeaddrinfo +rust_uv_idle_new +rust_uv_idle_delete +rust_uv_idle_init +rust_uv_idle_start +rust_uv_idle_stop rust_dbg_lock_create rust_dbg_lock_destroy rust_dbg_lock_lock @@ -188,3 +192,5 @@ rust_get_global_data_ptr rust_inc_kernel_live_count rust_dec_kernel_live_count rust_get_exchange_count_ptr +rust_get_sched_tls_key +swap_registers diff --git a/src/test/auxiliary/cci_impl_lib.rs b/src/test/auxiliary/cci_impl_lib.rs index ab744d60ac228..b7149be00cca9 100644 --- a/src/test/auxiliary/cci_impl_lib.rs +++ b/src/test/auxiliary/cci_impl_lib.rs @@ -11,12 +11,12 @@ #[link(name="cci_impl_lib", vers="0.0")]; trait uint_helpers { - fn to(v: uint, f: fn(uint)); + fn to(v: uint, f: &fn(uint)); } impl uint_helpers for uint { #[inline] - fn to(v: uint, f: fn(uint)) { + fn to(v: uint, f: &fn(uint)) { let mut i = self; while i < v { f(i); diff --git a/src/test/auxiliary/cci_iter_lib.rs b/src/test/auxiliary/cci_iter_lib.rs index 6e2c36578ff1c..107f0ac32a4bf 100644 --- a/src/test/auxiliary/cci_iter_lib.rs +++ b/src/test/auxiliary/cci_iter_lib.rs @@ -12,7 +12,7 @@ #[legacy_modes]; #[inline] -pub fn iter(v: ~[T], f: fn(T)) { +pub fn iter(v: ~[T], f: &fn(T)) { let mut i = 0u; let n = vec::len(v); while i < n { diff --git a/src/test/auxiliary/cci_no_inline_lib.rs b/src/test/auxiliary/cci_no_inline_lib.rs index 0b0492f13b8c5..407f62adb0251 100644 --- a/src/test/auxiliary/cci_no_inline_lib.rs +++ b/src/test/auxiliary/cci_no_inline_lib.rs @@ -11,7 +11,7 @@ #[link(name="cci_no_inline_lib", vers="0.0")]; // same as cci_iter_lib, more-or-less, but not marked inline -pub fn iter(v: ~[uint], f: fn(uint)) { +pub fn iter(v: ~[uint], f: &fn(uint)) { let mut i = 0u; let n = vec::len(v); while i < n { diff --git a/src/test/auxiliary/issue_2472_b.rs b/src/test/auxiliary/issue_2472_b.rs index e7a9295472554..1dd30edcc980b 100644 --- a/src/test/auxiliary/issue_2472_b.rs +++ b/src/test/auxiliary/issue_2472_b.rs @@ -9,13 +9,13 @@ // except according to those terms. -enum S = (); +pub struct S(()); pub impl S { fn foo() { } } -trait T { +pub trait T { fn bar(); } diff --git a/src/test/auxiliary/issue_3136_a.rs b/src/test/auxiliary/issue_3136_a.rs index 4de0b900dd3ea..c80457ef1e92c 100644 --- a/src/test/auxiliary/issue_3136_a.rs +++ b/src/test/auxiliary/issue_3136_a.rs @@ -11,7 +11,7 @@ trait x { fn use_x(); } -enum y = (); +struct y(()); impl x for y { fn use_x() { struct foo { //~ ERROR quux diff --git a/src/test/bench/core-map.rs b/src/test/bench/core-map.rs index a1896c660eb6f..c86d2fe4d9332 100644 --- a/src/test/bench/core-map.rs +++ b/src/test/bench/core-map.rs @@ -25,7 +25,7 @@ struct Results { } fn timed(result: &mut float, - op: fn()) { + op: &fn()) { let start = std::time::precise_time_s(); op(); let end = std::time::precise_time_s(); diff --git a/src/test/bench/core-set.rs b/src/test/bench/core-set.rs index ab441277c62a3..adfde66e57a01 100644 --- a/src/test/bench/core-set.rs +++ b/src/test/bench/core-set.rs @@ -24,7 +24,7 @@ struct Results { delete_strings: float } -fn timed(result: &mut float, op: fn()) { +fn timed(result: &mut float, op: &fn()) { let start = std::time::precise_time_s(); op(); let end = std::time::precise_time_s(); @@ -33,7 +33,7 @@ fn timed(result: &mut float, op: fn()) { pub impl Results { fn bench_int>(&mut self, rng: @rand::Rng, num_keys: uint, - rand_cap: uint, f: fn() -> T) { + rand_cap: uint, f: &fn() -> T) { { let mut set = f(); do timed(&mut self.sequential_ints) { @@ -71,7 +71,7 @@ pub impl Results { } fn bench_str>(&mut self, rng: @rand::Rng, num_keys: uint, - f: fn() -> T) { + f: &fn() -> T) { { let mut set = f(); do timed(&mut self.sequential_strings) { diff --git a/src/test/bench/core-std.rs b/src/test/bench/core-std.rs index e026e78ffb81d..e8fb86fda7889 100644 --- a/src/test/bench/core-std.rs +++ b/src/test/bench/core-std.rs @@ -34,7 +34,7 @@ fn main() { bench!(vec_push_all); } -fn maybe_run_test(argv: &[~str], name: ~str, test: fn()) { +fn maybe_run_test(argv: &[~str], name: ~str, test: &fn()) { let mut run_test = false; if os::getenv(~"RUST_BENCH").is_some() { run_test = true } diff --git a/src/test/bench/pingpong.rs b/src/test/bench/pingpong.rs index f95bc3fc35a18..731605e82bd1f 100644 --- a/src/test/bench/pingpong.rs +++ b/src/test/bench/pingpong.rs @@ -71,7 +71,7 @@ macro_rules! follow ( ) fn switch(+endp: core::pipes::RecvPacketBuffered, - f: fn(+v: Option) -> U) -> U { + f: &fn(+v: Option) -> U) -> U { f(core::pipes::try_recv(endp)) } @@ -131,7 +131,7 @@ fn unbounded(count: uint) { } } -fn timeit(f: fn()) -> float { +fn timeit(f: &fn()) -> float { let start = precise_time_s(); f(); let stop = precise_time_s(); diff --git a/src/test/bench/shootout-k-nucleotide-pipes.rs b/src/test/bench/shootout-k-nucleotide-pipes.rs index 35c6694ee0c74..fc980e3d6db53 100644 --- a/src/test/bench/shootout-k-nucleotide-pipes.rs +++ b/src/test/bench/shootout-k-nucleotide-pipes.rs @@ -85,7 +85,7 @@ fn update_freq(mm: HashMap<~[u8], uint>, key: &[u8]) { // i.e., for "hello" and windows of size four, // run it("hell") and it("ello"), then return "llo" fn windows_with_carry(bb: &[u8], nn: uint, - it: fn(window: &[u8])) -> ~[u8] { + it: &fn(window: &[u8])) -> ~[u8] { let mut ii = 0u; let len = vec::len(bb); diff --git a/src/test/compile-fail/access-mode-in-closures.rs b/src/test/compile-fail/access-mode-in-closures.rs index 24897608880ca..f6b9a82ec676c 100644 --- a/src/test/compile-fail/access-mode-in-closures.rs +++ b/src/test/compile-fail/access-mode-in-closures.rs @@ -9,7 +9,7 @@ // except according to those terms. -enum sty = ~[int]; +struct sty(~[int]); fn unpack(_unpack: &fn(v: &sty) -> ~[int]) {} diff --git a/src/test/compile-fail/alt-vec-invalid-2.rs b/src/test/compile-fail/alt-vec-invalid-2.rs deleted file mode 100644 index 4174120b291c6..0000000000000 --- a/src/test/compile-fail/alt-vec-invalid-2.rs +++ /dev/null @@ -1,6 +0,0 @@ -fn main() { - match ~[] { - [_, ..tail, _] => {}, //~ ERROR: expected `]` but found `,` - _ => () - } -} diff --git a/src/test/compile-fail/alt-vec-invalid.rs b/src/test/compile-fail/alt-vec-invalid.rs index b35731c2e4acd..2cf2d5b93b056 100644 --- a/src/test/compile-fail/alt-vec-invalid.rs +++ b/src/test/compile-fail/alt-vec-invalid.rs @@ -1,7 +1,7 @@ fn main() { let a = ~[]; match a { - [1, ..tail, ..tail] => {}, //~ ERROR: expected `]` but found `,` + [1, ..tail, ..tail] => {}, //~ ERROR: unexpected token: `..` _ => () } } diff --git a/src/test/compile-fail/arg-style-mismatch.rs b/src/test/compile-fail/arg-style-mismatch.rs index f07a2be1edf66..2efc16de8307f 100644 --- a/src/test/compile-fail/arg-style-mismatch.rs +++ b/src/test/compile-fail/arg-style-mismatch.rs @@ -11,5 +11,5 @@ // error-pattern: mismatched types fn f(&&_x: int) {} -fn g(_a: fn(+v: int)) {} +fn g(_a: &fn(+v: int)) {} fn main() { g(f); } diff --git a/src/test/compile-fail/bad-for-loop.rs b/src/test/compile-fail/bad-for-loop.rs index bda463031fae9..8835c577fa8fd 100644 --- a/src/test/compile-fail/bad-for-loop.rs +++ b/src/test/compile-fail/bad-for-loop.rs @@ -9,6 +9,6 @@ // except according to those terms. fn main() { - fn baz(_x: fn(y: int) -> int) {} + fn baz(_x: &fn(y: int) -> int) {} for baz |_e| { } //~ ERROR A `for` loop iterator should expect a closure that returns `bool` } diff --git a/src/test/compile-fail/block-coerce-no-2.rs b/src/test/compile-fail/block-coerce-no-2.rs index b2265f5e959a0..95ff995258fad 100644 --- a/src/test/compile-fail/block-coerce-no-2.rs +++ b/src/test/compile-fail/block-coerce-no-2.rs @@ -15,7 +15,7 @@ fn main() { fn f(f: extern fn(extern fn(extern fn()))) { } - fn g(f: extern fn(fn())) { + fn g(f: extern fn(&fn())) { } f(g); diff --git a/src/test/compile-fail/block-coerce-no.rs b/src/test/compile-fail/block-coerce-no.rs index af93b1891e840..980dc66b4af59 100644 --- a/src/test/compile-fail/block-coerce-no.rs +++ b/src/test/compile-fail/block-coerce-no.rs @@ -11,9 +11,9 @@ // Make sure that fn-to-block coercion isn't incorrectly lifted over // other tycons. -fn coerce(b: fn()) -> extern fn() { - fn lol(+f: extern fn(+v: fn()) -> extern fn(), - +g: fn()) -> extern fn() { return f(g); } +fn coerce(b: &fn()) -> extern fn() { + fn lol(+f: extern fn(+v: &fn()) -> extern fn(), + +g: &fn()) -> extern fn() { return f(g); } fn fn_id(+f: extern fn()) -> extern fn() { return f } return lol(fn_id, b); //~^ ERROR mismatched types diff --git a/src/test/compile-fail/borrowck-assign-comp-idx.rs b/src/test/compile-fail/borrowck-assign-comp-idx.rs index 9c175ed42b665..25b56abb5ba00 100644 --- a/src/test/compile-fail/borrowck-assign-comp-idx.rs +++ b/src/test/compile-fail/borrowck-assign-comp-idx.rs @@ -22,7 +22,7 @@ fn a() { p[0] = 5; //~ ERROR assigning to mutable vec content prohibited due to outstanding loan } -fn borrow(_x: &[int], _f: fn()) {} +fn borrow(_x: &[int], _f: &fn()) {} fn b() { // here we alias the mutable vector into an imm slice and try to diff --git a/src/test/compile-fail/borrowck-assign-to-enum.rs b/src/test/compile-fail/borrowck-assign-to-enum.rs index 25a320061d451..a35d88a76f393 100644 --- a/src/test/compile-fail/borrowck-assign-to-enum.rs +++ b/src/test/compile-fail/borrowck-assign-to-enum.rs @@ -8,9 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -enum foo = int; +struct foo(int); fn main() { let x = foo(3); - *x = 4; //~ ERROR assigning to enum content + *x = 4; //~ ERROR assigning to anonymous field } diff --git a/src/test/compile-fail/borrowck-autoref-3261.rs b/src/test/compile-fail/borrowck-autoref-3261.rs index 7873adbf21d8e..b874eac34b18c 100644 --- a/src/test/compile-fail/borrowck-autoref-3261.rs +++ b/src/test/compile-fail/borrowck-autoref-3261.rs @@ -8,9 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -enum X = Either<(uint,uint),extern fn()>; +struct X(Either<(uint,uint),extern fn()>); + pub impl &'self X { - fn with(blk: fn(x: &Either<(uint,uint),extern fn()>)) { + fn with(blk: &fn(x: &Either<(uint,uint),extern fn()>)) { blk(&**self) } } diff --git a/src/test/compile-fail/borrowck-insert-during-each.rs b/src/test/compile-fail/borrowck-insert-during-each.rs index 476a790b85ede..788c5397e35d0 100644 --- a/src/test/compile-fail/borrowck-insert-during-each.rs +++ b/src/test/compile-fail/borrowck-insert-during-each.rs @@ -15,7 +15,7 @@ struct Foo { } pub impl Foo { - fn foo(&mut self, fun: fn(&int)) { + fn foo(&mut self, fun: &fn(&int)) { for self.n.each |f| { fun(f); } diff --git a/src/test/compile-fail/borrowck-lend-flow.rs b/src/test/compile-fail/borrowck-lend-flow.rs index 6ec7dd7330526..ed6446a6311b8 100644 --- a/src/test/compile-fail/borrowck-lend-flow.rs +++ b/src/test/compile-fail/borrowck-lend-flow.rs @@ -94,7 +94,7 @@ fn loop_in_block() { } fn at_most_once_block() { - fn at_most_once(f: fn()) { f() } + fn at_most_once(f: &fn()) { f() } // Here, the borrow check has no way of knowing that the block is // executed at most once. diff --git a/src/test/compile-fail/borrowck-loan-blocks-move-cc.rs b/src/test/compile-fail/borrowck-loan-blocks-move-cc.rs index aca63308d874e..784fce1300f76 100644 --- a/src/test/compile-fail/borrowck-loan-blocks-move-cc.rs +++ b/src/test/compile-fail/borrowck-loan-blocks-move-cc.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn borrow(v: &int, f: fn(x: &int)) { +fn borrow(v: &int, f: &fn(x: &int)) { f(v); } diff --git a/src/test/compile-fail/borrowck-loan-blocks-mut-uniq.rs b/src/test/compile-fail/borrowck-loan-blocks-mut-uniq.rs index e56a179e7741e..332ec3fe697d0 100644 --- a/src/test/compile-fail/borrowck-loan-blocks-mut-uniq.rs +++ b/src/test/compile-fail/borrowck-loan-blocks-mut-uniq.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn borrow(v: &int, f: fn(x: &int)) { +fn borrow(v: &int, f: &fn(x: &int)) { f(v); } diff --git a/src/test/compile-fail/borrowck-loan-in-overloaded-op.rs b/src/test/compile-fail/borrowck-loan-in-overloaded-op.rs index 7b6484fd4aadb..ece9ae7e86199 100644 --- a/src/test/compile-fail/borrowck-loan-in-overloaded-op.rs +++ b/src/test/compile-fail/borrowck-loan-in-overloaded-op.rs @@ -10,7 +10,7 @@ // xfail-test #3387 -enum foo = ~uint; +struct foo(~uint); impl Add for foo { pure fn add(f: &foo) -> foo { diff --git a/src/test/compile-fail/borrowck-loan-rcvr.rs b/src/test/compile-fail/borrowck-loan-rcvr.rs index bd4428dc93064..85989bf9d2140 100644 --- a/src/test/compile-fail/borrowck-loan-rcvr.rs +++ b/src/test/compile-fail/borrowck-loan-rcvr.rs @@ -12,7 +12,7 @@ struct point { x: int, y: int } trait methods { fn impurem(); - fn blockm(f: fn()); + fn blockm(f: &fn()); pure fn purem(); } @@ -20,7 +20,7 @@ impl methods for point { fn impurem() { } - fn blockm(f: fn()) { f() } + fn blockm(f: &fn()) { f() } pure fn purem() { } diff --git a/src/test/compile-fail/borrowck-loan-vec-content.rs b/src/test/compile-fail/borrowck-loan-vec-content.rs index 8457fce255ea3..d27d690437aff 100644 --- a/src/test/compile-fail/borrowck-loan-vec-content.rs +++ b/src/test/compile-fail/borrowck-loan-vec-content.rs @@ -12,7 +12,7 @@ // (locally rooted) mutable, unique vector, and that we then prevent // modifications to the contents. -fn takes_imm_elt(_v: &int, f: fn()) { +fn takes_imm_elt(_v: &int, f: &fn()) { f(); } @@ -29,7 +29,7 @@ fn has_mut_vec_but_tries_to_change_it() { } } -fn takes_const_elt(_v: &const int, f: fn()) { +fn takes_const_elt(_v: &const int, f: &fn()) { f(); } diff --git a/src/test/compile-fail/borrowck-mut-deref-comp.rs b/src/test/compile-fail/borrowck-mut-deref-comp.rs index 3c67b6d5caf8d..540793d4135f2 100644 --- a/src/test/compile-fail/borrowck-mut-deref-comp.rs +++ b/src/test/compile-fail/borrowck-mut-deref-comp.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -enum foo = ~int; +struct foo(~int); fn borrow(x: @mut foo) { let _y = &***x; //~ ERROR illegal borrow unless pure diff --git a/src/test/compile-fail/borrowck-unary-move-2.rs b/src/test/compile-fail/borrowck-unary-move-2.rs index a25fc8327bd10..520772f1ceea9 100644 --- a/src/test/compile-fail/borrowck-unary-move-2.rs +++ b/src/test/compile-fail/borrowck-unary-move-2.rs @@ -24,9 +24,9 @@ fn noncopyable() -> noncopyable { } } -enum wrapper = noncopyable; +struct wrapper(noncopyable); fn main() { let x1 = wrapper(noncopyable()); - let _x2 = *x1; //~ ERROR moving out of enum content + let _x2 = *x1; //~ ERROR moving out of anonymous field } diff --git a/src/test/compile-fail/borrowck-vec-pattern-element-loan.rs b/src/test/compile-fail/borrowck-vec-pattern-element-loan.rs index cec81d8a6ef5b..c8a0dbedd5d95 100644 --- a/src/test/compile-fail/borrowck-vec-pattern-element-loan.rs +++ b/src/test/compile-fail/borrowck-vec-pattern-element-loan.rs @@ -1,15 +1,28 @@ fn a() -> &[int] { let vec = [1, 2, 3, 4]; let tail = match vec { //~ ERROR illegal borrow - [_a, ..tail] => tail, - _ => fail!(~"foo") + [_, ..tail] => tail, + _ => fail!(~"a") }; tail } -fn main() { - let tail = a(); - for tail.each |n| { - io::println(fmt!("%d", *n)); - } +fn b() -> &[int] { + let vec = [1, 2, 3, 4]; + let init = match vec { //~ ERROR illegal borrow + [..init, _] => init, + _ => fail!(~"b") + }; + init } + +fn c() -> &[int] { + let vec = [1, 2, 3, 4]; + let slice = match vec { //~ ERROR illegal borrow + [_, ..slice, _] => slice, + _ => fail!(~"c") + }; + slice +} + +fn main() {} diff --git a/src/test/compile-fail/closure-that-fails.rs b/src/test/compile-fail/closure-that-fails.rs index 66d4e601ec7b6..aad0e8bcbb6dd 100644 --- a/src/test/compile-fail/closure-that-fails.rs +++ b/src/test/compile-fail/closure-that-fails.rs @@ -1,4 +1,4 @@ -fn foo(f: fn() -> !) {} +fn foo(f: &fn() -> !) {} fn main() { // Type inference didn't use to be able to handle this: diff --git a/src/test/compile-fail/enum-in-scope.rs b/src/test/compile-fail/enum-in-scope.rs index 704001de95844..cccf66ef2d54e 100644 --- a/src/test/compile-fail/enum-in-scope.rs +++ b/src/test/compile-fail/enum-in-scope.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -enum hello = int; +struct hello(int); fn main() { let hello = 0; //~ERROR declaration of `hello` shadows diff --git a/src/test/compile-fail/extern-wrong-value-type.rs b/src/test/compile-fail/extern-wrong-value-type.rs index 2462451c88a00..4daa7f71adf28 100644 --- a/src/test/compile-fail/extern-wrong-value-type.rs +++ b/src/test/compile-fail/extern-wrong-value-type.rs @@ -13,5 +13,5 @@ extern fn f() { fn main() { // extern functions are *u8 types - let _x: fn() = f; //~ ERROR mismatched types: expected `&fn()` but found `*u8` + let _x: &fn() = f; //~ ERROR mismatched types: expected `&fn()` but found `*u8` } diff --git a/src/test/compile-fail/fn-variance-1.rs b/src/test/compile-fail/fn-variance-1.rs index 5550eb4902e17..c5c29bd3ecfe7 100644 --- a/src/test/compile-fail/fn-variance-1.rs +++ b/src/test/compile-fail/fn-variance-1.rs @@ -14,7 +14,7 @@ fn takes_mut(&&x: @mut int) { } fn takes_const(&&x: @const int) { } fn takes_imm(&&x: @int) { } -fn apply(t: T, f: fn(T)) { +fn apply(t: T, f: &fn(T)) { f(t) } diff --git a/src/test/compile-fail/immut-function-arguments.rs b/src/test/compile-fail/immut-function-arguments.rs index e557eaba83474..2084729372d1d 100644 --- a/src/test/compile-fail/immut-function-arguments.rs +++ b/src/test/compile-fail/immut-function-arguments.rs @@ -13,7 +13,7 @@ fn f(y: ~int) { } fn g() { - let _frob: fn(~int) = |q| { *q = 2; }; //~ ERROR assigning to dereference of immutable ~ pointer + let _frob: &fn(~int) = |q| { *q = 2; }; //~ ERROR assigning to dereference of immutable ~ pointer } diff --git a/src/test/compile-fail/issue-2063-resource.rs b/src/test/compile-fail/issue-2063-resource.rs index 137ce2d5030fe..db054d5aba700 100644 --- a/src/test/compile-fail/issue-2063-resource.rs +++ b/src/test/compile-fail/issue-2063-resource.rs @@ -16,7 +16,7 @@ struct t { //~ ERROR this type cannot be instantiated to_str: (), } -enum x = @t; //~ ERROR this type cannot be instantiated +struct x(@t); //~ ERROR this type cannot be instantiated fn main() { } diff --git a/src/test/compile-fail/issue-2063.rs b/src/test/compile-fail/issue-2063.rs index 8f344f4260664..0ebf0218efe6d 100644 --- a/src/test/compile-fail/issue-2063.rs +++ b/src/test/compile-fail/issue-2063.rs @@ -1,3 +1,5 @@ +// xfail-test + // Copyright 2012 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. @@ -11,7 +13,7 @@ // test that autoderef of a type like this does not // cause compiler to loop. Note that no instances // of such a type could ever be constructed. -enum t = @t; //~ ERROR this type cannot be instantiated +struct t(@t); //~ ERROR this type cannot be instantiated trait to_str_2 { fn to_str() -> ~str; diff --git a/src/test/compile-fail/issue-2149.rs b/src/test/compile-fail/issue-2149.rs index 0880cabb2abf9..361a20ad45133 100644 --- a/src/test/compile-fail/issue-2149.rs +++ b/src/test/compile-fail/issue-2149.rs @@ -9,11 +9,11 @@ // except according to those terms. trait vec_monad { - fn bind(f: fn(A) -> ~[B]); + fn bind(f: &fn(A) -> ~[B]); } impl vec_monad for ~[A] { - fn bind(f: fn(A) -> ~[B]) { + fn bind(f: &fn(A) -> ~[B]) { let mut r = fail!(); for self.each |elt| { r += f(*elt); } //~^ WARNING unreachable expression diff --git a/src/test/compile-fail/issue-2718-a.rs b/src/test/compile-fail/issue-2718-a.rs index 925350d9b8804..8afaf8995c291 100644 --- a/src/test/compile-fail/issue-2718-a.rs +++ b/src/test/compile-fail/issue-2718-a.rs @@ -1,3 +1,5 @@ +// xfail-test + // Copyright 2012 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. @@ -16,7 +18,7 @@ pub struct send_packet { mod pingpong { use send_packet; pub type ping = send_packet; - pub enum pong = send_packet; //~ ERROR illegal recursive enum type; wrap the inner value in a box to make it representable + pub struct pong(send_packet); //~ ERROR illegal recursive enum type; wrap the inner value in a box to make it representable } fn main() {} diff --git a/src/test/compile-fail/issue-2817-2.rs b/src/test/compile-fail/issue-2817-2.rs index 890b984e42ef2..6084552f0ed6d 100644 --- a/src/test/compile-fail/issue-2817-2.rs +++ b/src/test/compile-fail/issue-2817-2.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn not_bool(f: fn(int) -> ~str) {} +fn not_bool(f: &fn(int) -> ~str) {} fn main() { for uint::range(0, 100000) |_i| { //~ ERROR A for-loop body must return (), but diff --git a/src/test/compile-fail/issue-3080.rs b/src/test/compile-fail/issue-3080.rs index 530dadd7e9094..02df25d87d7fb 100644 --- a/src/test/compile-fail/issue-3080.rs +++ b/src/test/compile-fail/issue-3080.rs @@ -9,7 +9,7 @@ // except according to those terms. // xfail-test -enum x = (); +struct x(()); pub impl x { unsafe fn with() { } // This should fail } diff --git a/src/test/compile-fail/issue-3344.rs b/src/test/compile-fail/issue-3344.rs index 2d31867752ac5..df768860cba94 100644 --- a/src/test/compile-fail/issue-3344.rs +++ b/src/test/compile-fail/issue-3344.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -enum thing = uint; +struct thing(uint); impl cmp::Ord for thing { //~ ERROR missing method `gt` pure fn lt(&self, other: &thing) -> bool { **self < **other } pure fn le(&self, other: &thing) -> bool { **self < **other } diff --git a/src/test/compile-fail/issue-3953.rs b/src/test/compile-fail/issue-3953.rs index afd8cf892333f..bfc17c589db91 100644 --- a/src/test/compile-fail/issue-3953.rs +++ b/src/test/compile-fail/issue-3953.rs @@ -20,7 +20,7 @@ trait Hahaha: Eq + Eq + Eq + Eq + Eq + //~ ERROR Duplicate supertrait Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq {} -enum Lol = int; +struct Lol(int); impl Hahaha for Lol { } diff --git a/src/test/compile-fail/liveness-closure-require-ret.rs b/src/test/compile-fail/liveness-closure-require-ret.rs index 742afd6d30ea9..b1fc6a870d086 100644 --- a/src/test/compile-fail/liveness-closure-require-ret.rs +++ b/src/test/compile-fail/liveness-closure-require-ret.rs @@ -8,5 +8,5 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn force(f: fn() -> int) -> int { f() } +fn force(f: &fn() -> int) -> int { f() } fn main() { log(debug, force(|| {})); } //~ ERROR mismatched types diff --git a/src/test/compile-fail/liveness-use-after-send.rs b/src/test/compile-fail/liveness-use-after-send.rs index 95dd59eb27f73..c0de60fa58e3f 100644 --- a/src/test/compile-fail/liveness-use-after-send.rs +++ b/src/test/compile-fail/liveness-use-after-send.rs @@ -14,7 +14,7 @@ fn send(ch: _chan, -data: T) { fail!(); } -enum _chan = int; +struct _chan(int); // Tests that "log(debug, message);" is flagged as using // message after the send deinitializes it diff --git a/src/test/compile-fail/missing-do.rs b/src/test/compile-fail/missing-do.rs index fc4a4c11e7d27..974f30feb0651 100644 --- a/src/test/compile-fail/missing-do.rs +++ b/src/test/compile-fail/missing-do.rs @@ -10,7 +10,7 @@ // Regression test for issue #2783 -fn foo(f: fn()) { f() } +fn foo(f: &fn()) { f() } fn main() { ~"" || 42; //~ ERROR binary operation || cannot be applied to type `~str` diff --git a/src/test/compile-fail/mode-inference-fail.rs b/src/test/compile-fail/mode-inference-fail.rs index fd15321e1d02b..d9f6cf8b2d722 100644 --- a/src/test/compile-fail/mode-inference-fail.rs +++ b/src/test/compile-fail/mode-inference-fail.rs @@ -13,8 +13,8 @@ // In this test, the mode gets inferred to ++ due to the apply_int(), // but then we get a failure in the generic apply(). -fn apply(f: fn(A) -> A, a: A) -> A { f(a) } -fn apply_int(f: fn(int) -> int, a: int) -> int { f(a) } +fn apply(f: &fn(A) -> A, a: A) -> A { f(a) } +fn apply_int(f: &fn(int) -> int, a: int) -> int { f(a) } fn main() { let f = {|i| i}; diff --git a/src/test/compile-fail/pat-shadow-in-nested-binding.rs b/src/test/compile-fail/pat-shadow-in-nested-binding.rs index 3d2587551857a..4d89ec14d94b2 100644 --- a/src/test/compile-fail/pat-shadow-in-nested-binding.rs +++ b/src/test/compile-fail/pat-shadow-in-nested-binding.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -enum foo = uint; +struct foo(uint); fn main() { let (foo, _) = (2, 3); //~ ERROR declaration of `foo` shadows diff --git a/src/test/compile-fail/prim-with-args.rs b/src/test/compile-fail/prim-with-args.rs index be57f88fd0a98..40d5a44124177 100644 --- a/src/test/compile-fail/prim-with-args.rs +++ b/src/test/compile-fail/prim-with-args.rs @@ -23,17 +23,17 @@ let x: u64; //~ ERROR type parameters are not allowed on this type let x: float; //~ ERROR type parameters are not allowed on this type let x: char; //~ ERROR type parameters are not allowed on this type -let x: int/&; //~ ERROR region parameters are not allowed on this type -let x: i8/&; //~ ERROR region parameters are not allowed on this type -let x: i16/&; //~ ERROR region parameters are not allowed on this type -let x: i32/&; //~ ERROR region parameters are not allowed on this type -let x: i64/&; //~ ERROR region parameters are not allowed on this type -let x: uint/&; //~ ERROR region parameters are not allowed on this type -let x: u8/&; //~ ERROR region parameters are not allowed on this type -let x: u16/&; //~ ERROR region parameters are not allowed on this type -let x: u32/&; //~ ERROR region parameters are not allowed on this type -let x: u64/&; //~ ERROR region parameters are not allowed on this type -let x: float/&; //~ ERROR region parameters are not allowed on this type -let x: char/&; //~ ERROR region parameters are not allowed on this type +let x: int<'static>; //~ ERROR region parameters are not allowed on this type +let x: i8<'static>; //~ ERROR region parameters are not allowed on this type +let x: i16<'static>; //~ ERROR region parameters are not allowed on this type +let x: i32<'static>; //~ ERROR region parameters are not allowed on this type +let x: i64<'static>; //~ ERROR region parameters are not allowed on this type +let x: uint<'static>; //~ ERROR region parameters are not allowed on this type +let x: u8<'static>; //~ ERROR region parameters are not allowed on this type +let x: u16<'static>; //~ ERROR region parameters are not allowed on this type +let x: u32<'static>; //~ ERROR region parameters are not allowed on this type +let x: u64<'static>; //~ ERROR region parameters are not allowed on this type +let x: float<'static>; //~ ERROR region parameters are not allowed on this type +let x: char<'static>; //~ ERROR region parameters are not allowed on this type } diff --git a/src/test/compile-fail/pure-higher-order.rs b/src/test/compile-fail/pure-higher-order.rs index e5638e11ae918..6d262bc04e1e4 100644 --- a/src/test/compile-fail/pure-higher-order.rs +++ b/src/test/compile-fail/pure-higher-order.rs @@ -16,7 +16,7 @@ struct S<'self> { f: &'self fn(uint) } -pure fn range(from: uint, to: uint, f: fn(uint)) { +pure fn range(from: uint, to: uint, f: &fn(uint)) { let mut i = from; while i < to { f(i); // Note: legal to call argument, even if it is not pure. @@ -24,13 +24,13 @@ pure fn range(from: uint, to: uint, f: fn(uint)) { } } -pure fn range2(from: uint, to: uint, f: fn(uint)) { +pure fn range2(from: uint, to: uint, f: &fn(uint)) { do range(from, to) |i| { f(i*2u); } } -pure fn range3(from: uint, to: uint, f: fn(uint)) { +pure fn range3(from: uint, to: uint, f: &fn(uint)) { range(from, to, f) } diff --git a/src/test/compile-fail/purity-infer-fail.rs b/src/test/compile-fail/purity-infer-fail.rs index e5301c0693d52..3e5296530fa35 100644 --- a/src/test/compile-fail/purity-infer-fail.rs +++ b/src/test/compile-fail/purity-infer-fail.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn something(f: pure fn()) { f(); } +fn something(f: &pure fn()) { f(); } fn main() { let mut x = ~[]; diff --git a/src/test/compile-fail/qquote-1.rs b/src/test/compile-fail/qquote-1.rs index e4e61e438f938..eda207f711d68 100644 --- a/src/test/compile-fail/qquote-1.rs +++ b/src/test/compile-fail/qquote-1.rs @@ -62,7 +62,7 @@ fn main() { check_pp(expr3, pprust::print_expr, "2 - 23 + 7"); } -fn check_pp(expr: T, f: fn(pprust::ps, T), expect: str) { +fn check_pp(expr: T, f: &fn(pprust::ps, T), expect: str) { fail!(); } diff --git a/src/test/compile-fail/qquote-2.rs b/src/test/compile-fail/qquote-2.rs index abe62e15e1309..c669053400831 100644 --- a/src/test/compile-fail/qquote-2.rs +++ b/src/test/compile-fail/qquote-2.rs @@ -57,7 +57,7 @@ fn main() { check_pp(*stmt, pprust::print_stmt, ""); } -fn check_pp(expr: T, f: fn(pprust::ps, T), expect: str) { +fn check_pp(expr: T, f: &fn(pprust::ps, T), expect: str) { fail!(); } diff --git a/src/test/compile-fail/regions-bounds.rs b/src/test/compile-fail/regions-bounds.rs index c7a951c9c056d..35bef5a407a55 100644 --- a/src/test/compile-fail/regions-bounds.rs +++ b/src/test/compile-fail/regions-bounds.rs @@ -12,7 +12,7 @@ // nominal types (but not on other types) and that they are type // checked. -enum an_enum = &'self int; +struct an_enum(&'self int); trait a_trait { fn foo() -> &'self int; } diff --git a/src/test/compile-fail/regions-creating-enums.rs b/src/test/compile-fail/regions-creating-enums.rs index 27fcd2338fa51..88f2eefd36905 100644 --- a/src/test/compile-fail/regions-creating-enums.rs +++ b/src/test/compile-fail/regions-creating-enums.rs @@ -29,7 +29,7 @@ fn compute(x: &ast) -> uint { } } -fn map_nums(x: &ast, f: fn(uint) -> uint) -> &ast { +fn map_nums(x: &ast, f: &fn(uint) -> uint) -> &ast { match *x { num(x) => { return &num(f(x)); //~ ERROR illegal borrow diff --git a/src/test/compile-fail/regions-escape-bound-fn-2.rs b/src/test/compile-fail/regions-escape-bound-fn-2.rs index 147a1bfa36d54..9cee55643f89c 100644 --- a/src/test/compile-fail/regions-escape-bound-fn-2.rs +++ b/src/test/compile-fail/regions-escape-bound-fn-2.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn with_int(f: fn(x: &int)) { +fn with_int(f: &fn(x: &int)) { let x = 3; f(&x); } diff --git a/src/test/compile-fail/regions-escape-bound-fn.rs b/src/test/compile-fail/regions-escape-bound-fn.rs index 8cdfe69a2f3ba..c81ef77f497db 100644 --- a/src/test/compile-fail/regions-escape-bound-fn.rs +++ b/src/test/compile-fail/regions-escape-bound-fn.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn with_int(f: fn(x: &int)) { +fn with_int(f: &fn(x: &int)) { let x = 3; f(&x); } diff --git a/src/test/compile-fail/regions-escape-via-trait-or-not.rs b/src/test/compile-fail/regions-escape-via-trait-or-not.rs index 0a1e917c361af..767d7c9174dfa 100644 --- a/src/test/compile-fail/regions-escape-via-trait-or-not.rs +++ b/src/test/compile-fail/regions-escape-via-trait-or-not.rs @@ -18,7 +18,7 @@ impl deref for &'self int { } } -fn with(f: fn(x: &int) -> R) -> int { +fn with(f: &fn(x: &int) -> R) -> int { f(&3).get() } diff --git a/src/test/compile-fail/regions-fn-subtyping.rs b/src/test/compile-fail/regions-fn-subtyping.rs index 526a5de7fefe2..50674ac81fecf 100644 --- a/src/test/compile-fail/regions-fn-subtyping.rs +++ b/src/test/compile-fail/regions-fn-subtyping.rs @@ -17,41 +17,41 @@ fn test_fn(_x: &x/T, _y: &y/T, _z: &z/T) { // subtype::(of::()) will typecheck // iff T1 <: T2. - subtype::( - of::()); + subtype::<&fn(&a/T)>( + of::<&fn(&a/T)>()); - subtype::( - of::()); + subtype::<&fn(&a/T)>( + of::<&fn(&b/T)>()); - subtype::( - of::()); + subtype::<&fn(&b/T)>( + of::<&fn(&x/T)>()); - subtype::( - of::()); //~ ERROR mismatched types + subtype::<&fn(&x/T)>( + of::<&fn(&b/T)>()); //~ ERROR mismatched types - subtype::( - of::()); + subtype::<&fn(&a/T, &b/T)>( + of::<&fn(&a/T, &a/T)>()); - subtype::( - of::()); //~ ERROR mismatched types + subtype::<&fn(&a/T, &a/T)>( + of::<&fn(&a/T, &b/T)>()); //~ ERROR mismatched types - subtype::( - of::()); + subtype::<&fn(&a/T, &b/T)>( + of::<&fn(&x/T, &y/T)>()); - subtype::( - of::()); //~ ERROR mismatched types + subtype::<&fn(&x/T, &y/T)>( + of::<&fn(&a/T, &b/T)>()); //~ ERROR mismatched types - subtype:: @fn(&a/T)>( - of:: @fn(&a/T)>()); + subtype::<&fn(&x/T) -> @fn(&a/T)>( + of::<&fn(&x/T) -> @fn(&a/T)>()); - subtype:: @fn(&a/T)>( - of:: @fn(&b/T)>()); //~ ERROR mismatched types + subtype::<&fn(&a/T) -> @fn(&a/T)>( + of::<&fn(&a/T) -> @fn(&b/T)>()); //~ ERROR mismatched types - subtype:: @fn(&a/T)>( - of:: @fn(&b/T)>()); //~ ERROR mismatched types + subtype::<&fn(&a/T) -> @fn(&a/T)>( + of::<&fn(&x/T) -> @fn(&b/T)>()); //~ ERROR mismatched types - subtype:: @fn(&b/T)>( - of:: @fn(&a/T)>()); + subtype::<&fn(&a/T) -> @fn(&b/T)>( + of::<&fn(&a/T) -> @fn(&a/T)>()); } fn main() {} diff --git a/src/test/compile-fail/regions-in-consts.rs b/src/test/compile-fail/regions-in-consts.rs index 19dea9a57ee49..2ba27e888cbe0 100644 --- a/src/test/compile-fail/regions-in-consts.rs +++ b/src/test/compile-fail/regions-in-consts.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -const c_x: &'blk int = &22; //~ ERROR Illegal lifetime &blk: only 'static is allowed here +const c_x: &'blk int = &22; //~ ERROR Illegal lifetime 'blk: only 'static is allowed here const c_y: &int = &22; //~ ERROR Illegal anonymous lifetime: only 'static is allowed here const c_z: &'static int = &22; diff --git a/src/test/compile-fail/regions-in-enums.rs b/src/test/compile-fail/regions-in-enums.rs index 5c2269977d194..0adfaccdc0174 100644 --- a/src/test/compile-fail/regions-in-enums.rs +++ b/src/test/compile-fail/regions-in-enums.rs @@ -10,7 +10,7 @@ enum yes0<'lt> { // This will eventually be legal (and in fact the only way): - X3(&'lt uint) //~ ERROR Illegal lifetime <: only 'self is allowed allowed as part of a type declaration + X3(&'lt uint) //~ ERROR Illegal lifetime 'lt: only 'self is allowed allowed as part of a type declaration } enum yes1 { @@ -18,7 +18,7 @@ enum yes1 { } enum yes2 { - X5(&'foo uint) //~ ERROR Illegal lifetime &foo: only 'self is allowed allowed as part of a type declaration + X5(&'foo uint) //~ ERROR Illegal lifetime 'foo: only 'self is allowed allowed as part of a type declaration } fn main() {} diff --git a/src/test/compile-fail/regions-in-structs.rs b/src/test/compile-fail/regions-in-structs.rs index 10d7a921ed031..b425a40114a3d 100644 --- a/src/test/compile-fail/regions-in-structs.rs +++ b/src/test/compile-fail/regions-in-structs.rs @@ -17,7 +17,7 @@ struct yes1<'self> { } struct yes2<'self> { - x: &'foo uint, //~ ERROR Illegal lifetime &foo: only 'self is allowed allowed as part of a type declaration + x: &'foo uint, //~ ERROR Illegal lifetime 'foo: only 'self is allowed allowed as part of a type declaration } fn main() {} diff --git a/src/test/compile-fail/regions-infer-borrow-scope-within-loop.rs b/src/test/compile-fail/regions-infer-borrow-scope-within-loop.rs index 59329195b712c..ef8f6748d36af 100644 --- a/src/test/compile-fail/regions-infer-borrow-scope-within-loop.rs +++ b/src/test/compile-fail/regions-infer-borrow-scope-within-loop.rs @@ -10,7 +10,7 @@ fn borrow(x: &r/T) -> &r/T {x} -fn foo(cond: fn() -> bool, box: fn() -> @int) { +fn foo(cond: &fn() -> bool, box: &fn() -> @int) { let mut y: ∫ loop { let x = box(); diff --git a/src/test/compile-fail/regions-infer-call-3.rs b/src/test/compile-fail/regions-infer-call-3.rs index 762142993f9d9..49d3f6aee65c8 100644 --- a/src/test/compile-fail/regions-infer-call-3.rs +++ b/src/test/compile-fail/regions-infer-call-3.rs @@ -10,7 +10,7 @@ fn select(x: &r/int, y: &r/int) -> &r/int { x } -fn with(f: fn(x: &int) -> T) -> T { +fn with(f: &fn(x: &int) -> T) -> T { f(&20) } diff --git a/src/test/compile-fail/regions-infer-not-param.rs b/src/test/compile-fail/regions-infer-not-param.rs index b5f8d99829870..a0ecb08a08957 100644 --- a/src/test/compile-fail/regions-infer-not-param.rs +++ b/src/test/compile-fail/regions-infer-not-param.rs @@ -13,19 +13,16 @@ struct direct<'self> { } struct indirect1 { + // Here the lifetime parameter of direct is bound by the fn() g: @fn(direct) } -struct indirect2 { - g: @fn(direct/&) -} - -struct indirect3 { +struct indirect2<'self> { + // But here it is set to 'self g: @fn(direct<'self>) } fn take_direct(p: direct) -> direct { p } //~ ERROR mismatched types fn take_indirect1(p: indirect1) -> indirect1 { p } -fn take_indirect2(p: indirect2) -> indirect2 { p } -fn take_indirect3(p: indirect3) -> indirect3 { p } //~ ERROR mismatched types +fn take_indirect2(p: indirect2) -> indirect2 { p } //~ ERROR mismatched types fn main() {} diff --git a/src/test/compile-fail/regions-infer-region-in-fn-but-not-type.rs b/src/test/compile-fail/regions-infer-region-in-fn-but-not-type.rs index 11414a1110847..4c3338d2e1d0c 100644 --- a/src/test/compile-fail/regions-infer-region-in-fn-but-not-type.rs +++ b/src/test/compile-fail/regions-infer-region-in-fn-but-not-type.rs @@ -11,9 +11,9 @@ // check that the &int here does not cause us to think that `foo` // contains region pointers -enum foo = ~fn(x: &int); +struct foo(~fn(x: &int)); -fn take_foo(x: foo/&) {} //~ ERROR no region bound is allowed on `foo` +fn take_foo(x: foo<'static>) {} //~ ERROR no region bound is allowed on `foo` fn main() { } diff --git a/src/test/compile-fail/regions-ret-borrowed-1.rs b/src/test/compile-fail/regions-ret-borrowed-1.rs index 5e2f45293842c..ab6a37b58de6f 100644 --- a/src/test/compile-fail/regions-ret-borrowed-1.rs +++ b/src/test/compile-fail/regions-ret-borrowed-1.rs @@ -12,7 +12,7 @@ // some point regions-ret-borrowed reported an error but this file did // not, due to special hardcoding around the anonymous region. -fn with(f: fn(x: &a/int) -> R) -> R { +fn with(f: &fn(x: &a/int) -> R) -> R { f(&3) } diff --git a/src/test/compile-fail/regions-ret-borrowed.rs b/src/test/compile-fail/regions-ret-borrowed.rs index 52f9770250ee4..157b99de9e806 100644 --- a/src/test/compile-fail/regions-ret-borrowed.rs +++ b/src/test/compile-fail/regions-ret-borrowed.rs @@ -15,7 +15,7 @@ // used to successfully compile because we failed to account for the // fact that fn(x: &int) rebound the region &. -fn with(f: fn(x: &int) -> R) -> R { +fn with(f: &fn(x: &int) -> R) -> R { f(&3) } diff --git a/src/test/compile-fail/regions-scoping.rs b/src/test/compile-fail/regions-scoping.rs index 66f1007afcf97..e675d4d455f2c 100644 --- a/src/test/compile-fail/regions-scoping.rs +++ b/src/test/compile-fail/regions-scoping.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn with(t: T, f: fn(T)) { f(t) } +fn with(t: T, f: &fn(T)) { f(t) } fn nested<'x>(x: &'x int) { // (1) do with( diff --git a/src/test/compile-fail/tps-invariant-enum.rs b/src/test/compile-fail/tps-invariant-enum.rs index 967b201908c4b..9e19ecdcb7556 100644 --- a/src/test/compile-fail/tps-invariant-enum.rs +++ b/src/test/compile-fail/tps-invariant-enum.rs @@ -12,7 +12,7 @@ struct box { f: T } -enum box_impl = box; +struct box_impl(box); fn set_box_impl(b: box_impl<@const T>, v: @const T) { b.f = v; diff --git a/src/test/compile-fail/tps-invariant-trait.rs b/src/test/compile-fail/tps-invariant-trait.rs index 94bcea8f1d3bf..9569e5f1e8210 100644 --- a/src/test/compile-fail/tps-invariant-trait.rs +++ b/src/test/compile-fail/tps-invariant-trait.rs @@ -17,7 +17,7 @@ struct box { f: T } -enum box_impl = box; +struct box_impl(box); impl box_trait for box_impl { fn get() -> T { return self.f; } diff --git a/src/test/compile-fail/type-arg-out-of-scope.rs b/src/test/compile-fail/type-arg-out-of-scope.rs index 4d3005a2a7410..07dc677c04763 100644 --- a/src/test/compile-fail/type-arg-out-of-scope.rs +++ b/src/test/compile-fail/type-arg-out-of-scope.rs @@ -10,6 +10,6 @@ // error-pattern:attempt to use a type argument out of scope fn foo(x: T) { - fn bar(f: fn(T) -> T) { } + fn bar(f: &fn(T) -> T) { } } fn main() { foo(1); } diff --git a/src/test/run-fail/unwind-iter.rs b/src/test/run-fail/unwind-iter.rs index 135c5eecc2e9b..1b28d2f6c6d63 100644 --- a/src/test/run-fail/unwind-iter.rs +++ b/src/test/run-fail/unwind-iter.rs @@ -10,7 +10,7 @@ // error-pattern:fail -fn x(it: fn(int)) { +fn x(it: &fn(int)) { fail!(); it(0); } diff --git a/src/test/run-fail/unwind-iter2.rs b/src/test/run-fail/unwind-iter2.rs index f17f9fb9154bb..286e5f4976430 100644 --- a/src/test/run-fail/unwind-iter2.rs +++ b/src/test/run-fail/unwind-iter2.rs @@ -10,7 +10,7 @@ // error-pattern:fail -fn x(it: fn(int)) { +fn x(it: &fn(int)) { let a = @0; it(1); } diff --git a/src/test/run-pass-fulldeps/qquote.rs b/src/test/run-pass-fulldeps/qquote.rs index 92f80a9aa0d9b..613480e3a63cd 100644 --- a/src/test/run-pass-fulldeps/qquote.rs +++ b/src/test/run-pass-fulldeps/qquote.rs @@ -75,7 +75,7 @@ fn main() { } fn check_pp(cx: fake_ext_ctxt, - expr: T, f: fn(pprust::ps, T), expect: ~str) { + expr: T, f: &fn(pprust::ps, T), expect: ~str) { let s = do io::with_str_writer |wr| { let pp = pprust::rust_printer(wr, cx.parse_sess().interner); f(pp, expr); diff --git a/src/test/run-pass/alignment-gep-tup-like-2.rs b/src/test/run-pass/alignment-gep-tup-like-2.rs index 5bf8051cc1a47..22855bce28fca 100644 --- a/src/test/run-pass/alignment-gep-tup-like-2.rs +++ b/src/test/run-pass/alignment-gep-tup-like-2.rs @@ -12,7 +12,7 @@ struct Pair { a: A, b: B } -enum RecEnum = Rec; +struct RecEnum(Rec); struct Rec { val: A, rec: Option<@mut RecEnum> diff --git a/src/test/run-pass/alt-phi.rs b/src/test/run-pass/alt-phi.rs index 3702db8327e0d..40d2158835002 100644 --- a/src/test/run-pass/alt-phi.rs +++ b/src/test/run-pass/alt-phi.rs @@ -12,7 +12,7 @@ enum thing { a, b, c, } -fn foo(it: fn(int)) { it(10); } +fn foo(it: &fn(int)) { it(10); } pub fn main() { let mut x = true; diff --git a/src/test/run-pass/assignability-trait.rs b/src/test/run-pass/assignability-trait.rs index 9f13147b276d1..ae046babfdf83 100644 --- a/src/test/run-pass/assignability-trait.rs +++ b/src/test/run-pass/assignability-trait.rs @@ -13,11 +13,11 @@ // it. trait iterable { - fn iterate(blk: fn(x: &A) -> bool); + fn iterate(blk: &fn(x: &A) -> bool); } impl iterable for &self/[A] { - fn iterate(f: fn(x: &A) -> bool) { + fn iterate(f: &fn(x: &A) -> bool) { for vec::each(self) |e| { if !f(e) { break; } } @@ -25,7 +25,7 @@ impl iterable for &self/[A] { } impl iterable for ~[A] { - fn iterate(f: fn(x: &A) -> bool) { + fn iterate(f: &fn(x: &A) -> bool) { for vec::each(self) |e| { if !f(e) { break; } } diff --git a/src/test/run-pass/auto-encode.rs b/src/test/run-pass/auto-encode.rs index f9e5ebf261c03..b6fdb07789c8d 100644 --- a/src/test/run-pass/auto-encode.rs +++ b/src/test/run-pass/auto-encode.rs @@ -85,13 +85,6 @@ impl cmp::Eq for Expr { pure fn ne(&self, other: &Expr) -> bool { !(*self).eq(other) } } -impl cmp::Eq for AnEnum { - pure fn eq(&self, other: &AnEnum) -> bool { - (*self).v == other.v - } - pure fn ne(&self, other: &AnEnum) -> bool { !(*self).eq(other) } -} - impl cmp::Eq for Point { pure fn eq(&self, other: &Point) -> bool { self.x == other.x && self.y == other.y @@ -139,10 +132,6 @@ struct Spanned { #[auto_decode] struct SomeStruct { v: ~[uint] } -#[auto_encode] -#[auto_decode] -enum AnEnum = SomeStruct; - #[auto_encode] #[auto_decode] struct Point {x: uint, y: uint} @@ -168,10 +157,6 @@ pub fn main() { test_prettyprint(a, &~"Spanned {lo: 0u, hi: 5u, node: 22u}"); test_ebml(a); - let a = &AnEnum(SomeStruct {v: ~[1u, 2u, 3u]}); - test_prettyprint(a, &~"AnEnum(SomeStruct {v: ~[1u, 2u, 3u]})"); - test_ebml(a); - let a = &Point {x: 3u, y: 5u}; test_prettyprint(a, &~"Point {x: 3u, y: 5u}"); test_ebml(a); diff --git a/src/test/run-pass/auto-ref-newtype.rs b/src/test/run-pass/auto-ref-newtype.rs index cdcf3c54c5838..9a84aa6a10e4a 100644 --- a/src/test/run-pass/auto-ref-newtype.rs +++ b/src/test/run-pass/auto-ref-newtype.rs @@ -11,7 +11,7 @@ // Check that we can define inherent methods on newtype enums that use // an auto-ref'd receiver. -enum Foo = uint; +struct Foo(uint); pub impl Foo { fn len(&self) -> uint { **self } diff --git a/src/test/run-pass/autobind.rs b/src/test/run-pass/autobind.rs index 1ab760307b272..44688a8dfce96 100644 --- a/src/test/run-pass/autobind.rs +++ b/src/test/run-pass/autobind.rs @@ -10,10 +10,10 @@ fn f(x: ~[T]) -> T { return x[0]; } -fn g(act: fn(~[int]) -> int) -> int { return act(~[1, 2, 3]); } +fn g(act: &fn(~[int]) -> int) -> int { return act(~[1, 2, 3]); } pub fn main() { fail_unless!((g(f) == 1)); - let f1: fn(~[~str]) -> ~str = f; + let f1: &fn(~[~str]) -> ~str = f; fail_unless!((f1(~[~"x", ~"y", ~"z"]) == ~"x")); } diff --git a/src/test/run-pass/autoderef-method-newtype.rs b/src/test/run-pass/autoderef-method-newtype.rs index 9cd4093787db9..732c26694adb5 100644 --- a/src/test/run-pass/autoderef-method-newtype.rs +++ b/src/test/run-pass/autoderef-method-newtype.rs @@ -16,7 +16,7 @@ impl double for uint { fn double() -> uint { self * 2u } } -enum foo = uint; +struct foo(uint); pub fn main() { let x = foo(3u); diff --git a/src/test/run-pass/block-arg-can-be-followed-by-block-arg.rs b/src/test/run-pass/block-arg-can-be-followed-by-block-arg.rs index 94d568b71585d..b2e1bc515865a 100644 --- a/src/test/run-pass/block-arg-can-be-followed-by-block-arg.rs +++ b/src/test/run-pass/block-arg-can-be-followed-by-block-arg.rs @@ -9,7 +9,7 @@ // except according to those terms. pub fn main() { - fn f(i: fn() -> uint) -> uint { i() } + fn f(i: &fn() -> uint) -> uint { i() } let v = ~[-1f, 0f, 1f, 2f, 3f]; let z = do do vec::foldl(f, v) |x, _y| { x } { 22u }; fail_unless!(z == 22u); diff --git a/src/test/run-pass/block-arg-used-as-any.rs b/src/test/run-pass/block-arg-used-as-any.rs index 6d311a138288d..ae110a0477374 100644 --- a/src/test/run-pass/block-arg-used-as-any.rs +++ b/src/test/run-pass/block-arg-used-as-any.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn call_any(f: fn() -> uint) -> uint { +fn call_any(f: &fn() -> uint) -> uint { return f(); } diff --git a/src/test/run-pass/block-explicit-types.rs b/src/test/run-pass/block-explicit-types.rs index f6bbb94690f79..b24a655667a6b 100644 --- a/src/test/run-pass/block-explicit-types.rs +++ b/src/test/run-pass/block-explicit-types.rs @@ -9,6 +9,6 @@ // except according to those terms. pub fn main() { - fn as_buf(s: ~str, f: fn(~str) -> T) -> T { f(s) } + fn as_buf(s: ~str, f: &fn(~str) -> T) -> T { f(s) } as_buf(~"foo", |foo: ~str| -> () log(error, foo) ); } diff --git a/src/test/run-pass/block-fn-coerce.rs b/src/test/run-pass/block-fn-coerce.rs index 4593934d52300..dc8ad25e27606 100644 --- a/src/test/run-pass/block-fn-coerce.rs +++ b/src/test/run-pass/block-fn-coerce.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn force(f: fn() -> int) -> int { return f(); } +fn force(f: &fn() -> int) -> int { return f(); } pub fn main() { fn f() -> int { return 7; } fail_unless!((force(f) == 7)); diff --git a/src/test/run-pass/block-iter-1.rs b/src/test/run-pass/block-iter-1.rs index 571e67b4e5b85..d0a24f80c0b90 100644 --- a/src/test/run-pass/block-iter-1.rs +++ b/src/test/run-pass/block-iter-1.rs @@ -10,7 +10,7 @@ // xfail-fast -fn iter_vec(v: ~[T], f: fn(&T)) { for v.each |x| { f(x); } } +fn iter_vec(v: ~[T], f: &fn(&T)) { for v.each |x| { f(x); } } pub fn main() { let v = ~[1, 2, 3, 4, 5, 6, 7]; diff --git a/src/test/run-pass/block-iter-2.rs b/src/test/run-pass/block-iter-2.rs index 1ec5c781807fd..acffb6830dede 100644 --- a/src/test/run-pass/block-iter-2.rs +++ b/src/test/run-pass/block-iter-2.rs @@ -10,7 +10,7 @@ // xfail-fast -fn iter_vec(v: ~[T], f: fn(&T)) { for v.each |x| { f(x); } } +fn iter_vec(v: ~[T], f: &fn(&T)) { for v.each |x| { f(x); } } pub fn main() { let v = ~[1, 2, 3, 4, 5]; diff --git a/src/test/run-pass/borrowck-borrow-from-expr-block.rs b/src/test/run-pass/borrowck-borrow-from-expr-block.rs index f2bde5a9f4bd8..0422be9d333df 100644 --- a/src/test/run-pass/borrowck-borrow-from-expr-block.rs +++ b/src/test/run-pass/borrowck-borrow-from-expr-block.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn borrow(x: &int, f: fn(x: &int)) { +fn borrow(x: &int, f: &fn(x: &int)) { f(x) } diff --git a/src/test/run-pass/borrowck-mut-uniq.rs b/src/test/run-pass/borrowck-mut-uniq.rs index 2cd445ee7af8b..5f5b9c59d7680 100644 --- a/src/test/run-pass/borrowck-mut-uniq.rs +++ b/src/test/run-pass/borrowck-mut-uniq.rs @@ -18,7 +18,7 @@ fn add_int(x: &mut Ints, v: int) { x.values <-> values; } -fn iter_ints(x: &Ints, f: fn(x: &int) -> bool) { +fn iter_ints(x: &Ints, f: &fn(x: &int) -> bool) { let l = x.values.len(); uint::range(0, l, |i| f(&x.values[i])) } diff --git a/src/test/run-pass/borrowck-preserve-box-in-field.rs b/src/test/run-pass/borrowck-preserve-box-in-field.rs index 0b84ba4ff59fb..795b074e37c4f 100644 --- a/src/test/run-pass/borrowck-preserve-box-in-field.rs +++ b/src/test/run-pass/borrowck-preserve-box-in-field.rs @@ -10,7 +10,7 @@ // exec-env:RUST_POISON_ON_FREE=1 -fn borrow(x: &int, f: fn(x: &int)) { +fn borrow(x: &int, f: &fn(x: &int)) { let before = *x; f(x); let after = *x; diff --git a/src/test/run-pass/borrowck-preserve-box-in-uniq.rs b/src/test/run-pass/borrowck-preserve-box-in-uniq.rs index fedd8c42e8fc9..11ec78b681cbb 100644 --- a/src/test/run-pass/borrowck-preserve-box-in-uniq.rs +++ b/src/test/run-pass/borrowck-preserve-box-in-uniq.rs @@ -10,7 +10,7 @@ // exec-env:RUST_POISON_ON_FREE=1 -fn borrow(x: &int, f: fn(x: &int)) { +fn borrow(x: &int, f: &fn(x: &int)) { let before = *x; f(x); let after = *x; diff --git a/src/test/run-pass/borrowck-preserve-box.rs b/src/test/run-pass/borrowck-preserve-box.rs index ec9e82c7731fc..8d625476f57dc 100644 --- a/src/test/run-pass/borrowck-preserve-box.rs +++ b/src/test/run-pass/borrowck-preserve-box.rs @@ -10,7 +10,7 @@ // exec-env:RUST_POISON_ON_FREE=1 -fn borrow(x: &int, f: fn(x: &int)) { +fn borrow(x: &int, f: &fn(x: &int)) { let before = *x; f(x); let after = *x; diff --git a/src/test/run-pass/borrowck-preserve-expl-deref.rs b/src/test/run-pass/borrowck-preserve-expl-deref.rs index fd64507daa19e..fcb84eaaf00ab 100644 --- a/src/test/run-pass/borrowck-preserve-expl-deref.rs +++ b/src/test/run-pass/borrowck-preserve-expl-deref.rs @@ -10,7 +10,7 @@ // exec-env:RUST_POISON_ON_FREE=1 -fn borrow(x: &int, f: fn(x: &int)) { +fn borrow(x: &int, f: &fn(x: &int)) { let before = *x; f(x); let after = *x; diff --git a/src/test/run-pass/class-impl-parameterized-trait.rs b/src/test/run-pass/class-impl-parameterized-trait.rs index 15972d4bcd04d..87573b84dc885 100644 --- a/src/test/run-pass/class-impl-parameterized-trait.rs +++ b/src/test/run-pass/class-impl-parameterized-trait.rs @@ -57,17 +57,17 @@ class cat : map { fn [](&&k:int) -> bool { k <= self.meows } fn find(&&k:int) -> Option { Some(self.get(k)) } fn remove(&&k:int) -> Option { self.meows -= k; Some(true) } - fn each(f: fn(&&int, &&bool) -> bool) { + fn each(f: &fn(&&int, &&bool) -> bool) { let mut n = int::abs(self.meows); while n > 0 { if !f(n, true) { break; } n -= 1; } } - fn each_key(&&f: fn(&&int) -> bool) { + fn each_key(&&f: &fn(&&int) -> bool) { for self.each |k, _v| { if !f(k) { break; } again;}; } - fn each_value(&&f: fn(&&bool) -> bool) { + fn each_value(&&f: &fn(&&bool) -> bool) { for self.each |_k, v| { if !f(v) { break; } again;}; } fn clear() { } diff --git a/src/test/run-pass/class-impl-very-parameterized-trait.rs b/src/test/run-pass/class-impl-very-parameterized-trait.rs index b616937731091..6cb0749ddb57f 100644 --- a/src/test/run-pass/class-impl-very-parameterized-trait.rs +++ b/src/test/run-pass/class-impl-very-parameterized-trait.rs @@ -50,7 +50,7 @@ pub impl cat { } impl BaseIter<(int, &'self T)> for cat { - pure fn each(&self, f: fn(&(int, &'self T)) -> bool) { + pure fn each(&self, f: &fn(&(int, &'self T)) -> bool) { let mut n = int::abs(self.meows); while n > 0 { if !f(&(n, &self.name)) { break; } @@ -73,11 +73,11 @@ impl Mutable for cat { impl Map for cat { pure fn contains_key(&self, k: &int) -> bool { *k <= self.meows } - pure fn each_key(&self, f: fn(v: &int) -> bool) { + pure fn each_key(&self, f: &fn(v: &int) -> bool) { for self.each |&(k, _)| { if !f(&k) { break; } loop;}; } - pure fn each_value(&self, f: fn(v: &T) -> bool) { + pure fn each_value(&self, f: &fn(v: &T) -> bool) { for self.each |&(_, v)| { if !f(v) { break; } loop;}; } diff --git a/src/test/run-pass/class-trait-bounded-param.rs b/src/test/run-pass/class-trait-bounded-param.rs index 294c7264c739e..e525312d6da5b 100644 --- a/src/test/run-pass/class-trait-bounded-param.rs +++ b/src/test/run-pass/class-trait-bounded-param.rs @@ -22,9 +22,9 @@ class keys> self.map = map; } - fn each(blk: fn(K) -> bool) { self.map.each(|k, _v| blk(k) ) } + fn each(blk: &fn(K) -> bool) { self.map.each(|k, _v| blk(k) ) } fn size_hint() -> Option { Some(self.map.size()) } - fn eachi(blk: fn(uint, K) -> bool) { iter::eachi(self, blk) } + fn eachi(blk: &fn(uint, K) -> bool) { iter::eachi(self, blk) } } pub fn main() { diff --git a/src/test/run-pass/closure-inference.rs b/src/test/run-pass/closure-inference.rs index 246450d2a075b..e61636a323a65 100644 --- a/src/test/run-pass/closure-inference.rs +++ b/src/test/run-pass/closure-inference.rs @@ -12,7 +12,7 @@ fn foo(i: int) -> int { i + 1 } -fn apply(f: fn(A) -> A, v: A) -> A { f(v) } +fn apply(f: &fn(A) -> A, v: A) -> A { f(v) } pub fn main() { let f = {|i| foo(i)}; diff --git a/src/test/run-pass/coherence-copy-bound.rs b/src/test/run-pass/coherence-copy-bound.rs deleted file mode 100644 index 9921389da6674..0000000000000 --- a/src/test/run-pass/coherence-copy-bound.rs +++ /dev/null @@ -1,13 +0,0 @@ -trait X {} - -impl X for A {} - -struct S { - x: int, - drop {} -} - -impl X for S {} - -pub fn main(){} - diff --git a/src/test/run-pass/conditional-compile.rs b/src/test/run-pass/conditional-compile.rs index 0a579916e93ce..fa6f59999f84c 100644 --- a/src/test/run-pass/conditional-compile.rs +++ b/src/test/run-pass/conditional-compile.rs @@ -112,8 +112,8 @@ mod test_foreign_items { #[abi = "cdecl"] pub extern { #[cfg(bogus)] - pub fn rust_getcwd() -> ~str; - pub fn rust_getcwd() -> ~str; + pub fn rust_get_stdin() -> ~str; + pub fn rust_get_stdin() -> ~str; } } } diff --git a/src/test/run-pass/const-enum-newtype-align.rs b/src/test/run-pass/const-enum-newtype-align.rs deleted file mode 100644 index 5aa9aeafeed28..0000000000000 --- a/src/test/run-pass/const-enum-newtype-align.rs +++ /dev/null @@ -1,17 +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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -enum E = u32; -struct S { a: u8, b: E } -const C: S = S { a: 0xA5, b: E(0xDEADBEEF) }; - -pub fn main() { - fail_unless!(C.b == 0xDEADBEEF); -} diff --git a/src/test/run-pass/const-newtype-enum.rs b/src/test/run-pass/const-newtype-enum.rs deleted file mode 100644 index b96b0e957c990..0000000000000 --- a/src/test/run-pass/const-newtype-enum.rs +++ /dev/null @@ -1,20 +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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -enum Foo = u32; - -const X: Foo = Foo(17); - -pub fn main() { - fail_unless!((*X == 17)); - fail_unless!((*Y == 23)); -} - -const Y: Foo = Foo(23); diff --git a/src/test/run-pass/deriving-clone-struct.rs b/src/test/run-pass/deriving-clone-struct.rs index 2f371c8920be5..07830e7ee096b 100644 --- a/src/test/run-pass/deriving-clone-struct.rs +++ b/src/test/run-pass/deriving-clone-struct.rs @@ -1,8 +1,24 @@ #[deriving_clone] struct S { - foo: (), - bar: () + _int: int, + _i8: i8, + _i16: i16, + _i32: i32, + _i64: i64, + + _uint: uint, + _u8: u8, + _u16: u16, + _u32: u32, + _u64: u64, + + _float: float, + _f32: f32, + _f64: f64, + + _bool: bool, + _char: char, + _nil: () } fn main() {} - diff --git a/src/test/run-pass/do-for-empty-args.rs b/src/test/run-pass/do-for-empty-args.rs index 2a7091cb16305..c86c1768111f7 100644 --- a/src/test/run-pass/do-for-empty-args.rs +++ b/src/test/run-pass/do-for-empty-args.rs @@ -11,7 +11,7 @@ // no-reformat // Testing various forms of `do` and `for` with empty arg lists -fn f(f: fn() -> bool) { +fn f(f: &fn() -> bool) { } pub fn main() { diff --git a/src/test/run-pass/do-pure.rs b/src/test/run-pass/do-pure.rs index b422f5819f09c..41686cf5b3736 100644 --- a/src/test/run-pass/do-pure.rs +++ b/src/test/run-pass/do-pure.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pure fn f(f: fn()) { +pure fn f(f: &fn()) { } pure fn g() { diff --git a/src/test/run-pass/fn-assign-managed-to-bare-1.rs b/src/test/run-pass/fn-assign-managed-to-bare-1.rs index a9bd5587de240..9ab6af0ac276e 100644 --- a/src/test/run-pass/fn-assign-managed-to-bare-1.rs +++ b/src/test/run-pass/fn-assign-managed-to-bare-1.rs @@ -15,6 +15,6 @@ fn add(n: int) -> @fn(int) -> int { pub fn main() { fail_unless!(add(3)(4) == 7); - let add3 : fn(int)->int = add(3); + let add3 : &fn(int)->int = add(3); fail_unless!(add3(4) == 7); } diff --git a/src/test/run-pass/fn-bare-coerce-to-block.rs b/src/test/run-pass/fn-bare-coerce-to-block.rs index a1ccb8b37eff9..db7604d11484d 100644 --- a/src/test/run-pass/fn-bare-coerce-to-block.rs +++ b/src/test/run-pass/fn-bare-coerce-to-block.rs @@ -10,7 +10,7 @@ fn bare() {} -fn likes_block(f: fn()) { f() } +fn likes_block(f: &fn()) { f() } pub fn main() { likes_block(bare); diff --git a/src/test/run-pass/fn-pattern-expected-type.rs b/src/test/run-pass/fn-pattern-expected-type.rs index 411eb5ffb0946..3f5d3818e1c12 100644 --- a/src/test/run-pass/fn-pattern-expected-type.rs +++ b/src/test/run-pass/fn-pattern-expected-type.rs @@ -9,7 +9,7 @@ // except according to those terms. pub fn main() { - let f: fn((int,int)) = |(x, y)| { + let f: &fn((int,int)) = |(x, y)| { fail_unless!(x == 1); fail_unless!(y == 2); }; diff --git a/src/test/run-pass/foreach-nested.rs b/src/test/run-pass/foreach-nested.rs index 8d705447531f9..a94131b36c051 100644 --- a/src/test/run-pass/foreach-nested.rs +++ b/src/test/run-pass/foreach-nested.rs @@ -12,7 +12,7 @@ // -*- rust -*- -fn two(it: fn(int)) { it(0); it(1); } +fn two(it: &fn(int)) { it(0); it(1); } pub fn main() { let mut a: ~[int] = ~[-1, -1, -1, -1]; diff --git a/src/test/run-pass/foreach-put-structured.rs b/src/test/run-pass/foreach-put-structured.rs index 8bbfe90ba0307..1a71cf52de259 100644 --- a/src/test/run-pass/foreach-put-structured.rs +++ b/src/test/run-pass/foreach-put-structured.rs @@ -10,7 +10,7 @@ -fn pairs(it: fn((int, int))) { +fn pairs(it: &fn((int, int))) { let mut i: int = 0; let mut j: int = 0; while i < 10 { it((i, j)); i += 1; j += i; } diff --git a/src/test/run-pass/foreach-simple-outer-slot.rs b/src/test/run-pass/foreach-simple-outer-slot.rs index 5245158525019..1c0b28982dbe1 100644 --- a/src/test/run-pass/foreach-simple-outer-slot.rs +++ b/src/test/run-pass/foreach-simple-outer-slot.rs @@ -20,7 +20,7 @@ pub fn main() { fail_unless!((sum == 45)); } -fn first_ten(it: fn(int)) { +fn first_ten(it: &fn(int)) { let mut i: int = 0; while i < 10 { debug!("first_ten"); it(i); i = i + 1; } } diff --git a/src/test/run-pass/instantiable.rs b/src/test/run-pass/instantiable.rs index 2230c2df9fcef..c140a66ffe4d6 100644 --- a/src/test/run-pass/instantiable.rs +++ b/src/test/run-pass/instantiable.rs @@ -11,7 +11,7 @@ // check that we do not report a type like this as uninstantiable, // even though it would be if the nxt field had type @foo: -enum foo = X; +struct foo(X); struct X { x: uint, nxt: *foo } diff --git a/src/test/run-pass/issue-1458.rs b/src/test/run-pass/issue-1458.rs index 7ef47ed1dda93..a6556895dda33 100644 --- a/src/test/run-pass/issue-1458.rs +++ b/src/test/run-pass/issue-1458.rs @@ -8,11 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn plus_one(f: fn() -> int) -> int { +fn plus_one(f: &fn() -> int) -> int { return f() + 1; } -fn ret_plus_one() -> extern fn(fn() -> int) -> int { +fn ret_plus_one() -> extern fn(&fn() -> int) -> int { return plus_one; } diff --git a/src/test/run-pass/issue-2185.rs b/src/test/run-pass/issue-2185.rs index cd2273ab173fe..ac680d3d12e41 100644 --- a/src/test/run-pass/issue-2185.rs +++ b/src/test/run-pass/issue-2185.rs @@ -15,15 +15,15 @@ // warrant still having a test, so I inlined the old definitions. trait iterable { - fn iter(blk: fn(A)); + fn iter(blk: &fn(A)); } impl iterable for @fn(&fn(A)) { - fn iter(blk: fn(A)) { self(blk); } + fn iter(blk: &fn(A)) { self(blk); } } impl iterable for @fn(&fn(uint)) { - fn iter(blk: fn(&&v: uint)) { self( |i| blk(i) ) } + fn iter(blk: &fn(&&v: uint)) { self( |i| blk(i) ) } } fn filter>(self: IA, prd: @fn(A) -> bool, blk: &fn(A)) { diff --git a/src/test/run-pass/issue-2312.rs b/src/test/run-pass/issue-2312.rs index 9e45a6b53c2b6..ad6320aed2bb7 100644 --- a/src/test/run-pass/issue-2312.rs +++ b/src/test/run-pass/issue-2312.rs @@ -12,7 +12,7 @@ trait clam { } -enum foo = int; +struct foo(int); pub impl foo { fn bar>(c: C) -> B { fail!(); } diff --git a/src/test/run-pass/issue-2487-a.rs b/src/test/run-pass/issue-2487-a.rs index 33023db5323fc..138860ce72d1f 100644 --- a/src/test/run-pass/issue-2487-a.rs +++ b/src/test/run-pass/issue-2487-a.rs @@ -32,7 +32,7 @@ fn socket() -> socket { } } -fn closure(f: fn()) { f() } +fn closure(f: &fn()) { f() } fn setsockopt_bytes(_sock: int) { } diff --git a/src/test/run-pass/issue-2611.rs b/src/test/run-pass/issue-2611.rs index 83cedc0fe5024..af3e8e9c7a2b5 100644 --- a/src/test/run-pass/issue-2611.rs +++ b/src/test/run-pass/issue-2611.rs @@ -11,11 +11,11 @@ use core::iter::BaseIter; trait FlatMapToVec { - fn flat_map_to_vec>(&self, op: fn(&A) -> IB) -> ~[B]; + fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) -> ~[B]; } impl FlatMapToVec for ~[A] { - fn flat_map_to_vec>(&self, op: fn(&A) -> IB) -> ~[B] { + fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) -> ~[B] { iter::flat_map_to_vec(self, op) } } diff --git a/src/test/run-pass/issue-2718.rs b/src/test/run-pass/issue-2718.rs index d39f02a357418..1376f20571be6 100644 --- a/src/test/run-pass/issue-2718.rs +++ b/src/test/run-pass/issue-2718.rs @@ -225,8 +225,8 @@ pub mod pingpong { use core::cast; use core::ptr; - pub enum ping = ::pipes::send_packet; - pub enum pong = ::pipes::send_packet; + pub struct ping(::pipes::send_packet); + pub struct pong(::pipes::send_packet); pub fn liberate_ping(-p: ping) -> ::pipes::send_packet { unsafe { diff --git a/src/test/run-pass/issue-3874.rs b/src/test/run-pass/issue-3874.rs index d709757adb02d..8d62da9efad42 100644 --- a/src/test/run-pass/issue-3874.rs +++ b/src/test/run-pass/issue-3874.rs @@ -11,7 +11,7 @@ // xfail-test enum PureCounter { PureCounter(uint) } -pure fn each(self: PureCounter, blk: fn(v: &uint)) { +pure fn each(self: PureCounter, blk: &fn(v: &uint)) { let PureCounter(ref x) = self; blk(x); } diff --git a/src/test/run-pass/issue-868.rs b/src/test/run-pass/issue-868.rs index 55c5dcb4e0768..16e8fa18c2a02 100644 --- a/src/test/run-pass/issue-868.rs +++ b/src/test/run-pass/issue-868.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn f(g: fn() -> T) -> T { g() } +fn f(g: &fn() -> T) -> T { g() } pub fn main() { let _x = f( | | { 10 }); diff --git a/src/test/run-pass/issue-912.rs b/src/test/run-pass/issue-912.rs index dddcb8b957f6d..d2c51df2b8fb3 100644 --- a/src/test/run-pass/issue-912.rs +++ b/src/test/run-pass/issue-912.rs @@ -9,7 +9,7 @@ // except according to those terms. // xfail-test -fn find(_f: fn(@T) -> bool, _v: [@T]) {} +fn find(_f: &fn(@T) -> bool, _v: [@T]) {} pub fn main() { let x = 10, arr = []; diff --git a/src/test/run-pass/iter-range.rs b/src/test/run-pass/iter-range.rs index 5fdd60bedb366..0ec8eea52365f 100644 --- a/src/test/run-pass/iter-range.rs +++ b/src/test/run-pass/iter-range.rs @@ -10,7 +10,7 @@ -fn range(a: int, b: int, it: fn(int)) { +fn range(a: int, b: int, it: &fn(int)) { fail_unless!((a < b)); let mut i: int = a; while i < b { it(i); i += 1; } diff --git a/src/test/run-pass/last-use-in-block.rs b/src/test/run-pass/last-use-in-block.rs index e8083dd3f6b21..e2dbf7d29db19 100644 --- a/src/test/run-pass/last-use-in-block.rs +++ b/src/test/run-pass/last-use-in-block.rs @@ -10,7 +10,7 @@ // Issue #1818 -fn lp(s: ~str, f: fn(~str) -> T) -> T { +fn lp(s: ~str, f: &fn(~str) -> T) -> T { while false { let r = f(s); return (r); @@ -18,8 +18,8 @@ fn lp(s: ~str, f: fn(~str) -> T) -> T { fail!(); } -fn apply(s: ~str, f: fn(~str) -> T) -> T { - fn g(s: ~str, f: fn(~str) -> T) -> T {f(s)} +fn apply(s: ~str, f: &fn(~str) -> T) -> T { + fn g(s: ~str, f: &fn(~str) -> T) -> T {f(s)} g(s, |v| { let r = f(v); r }) } diff --git a/src/test/run-pass/let-destruct.rs b/src/test/run-pass/let-destruct.rs index eec3064cbbdf1..05e50e3e66047 100644 --- a/src/test/run-pass/let-destruct.rs +++ b/src/test/run-pass/let-destruct.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -enum xx = int; +struct xx(int); struct X { x: xx, y: int } diff --git a/src/test/run-pass/log-degen-enum.rs b/src/test/run-pass/log-degen-enum.rs deleted file mode 100644 index 79ad6e8a2506a..0000000000000 --- a/src/test/run-pass/log-degen-enum.rs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -enum Foo = uint; - -pub fn main() { - let x = Foo(1); - let y = fmt!("%?", x); - fail_unless!(y == ~"Foo(1)"); -} diff --git a/src/test/run-pass/log-poly.rs b/src/test/run-pass/log-poly.rs new file mode 100644 index 0000000000000..3588016b8ba28 --- /dev/null +++ b/src/test/run-pass/log-poly.rs @@ -0,0 +1,10 @@ +enum Numbers { + Three +} + +fn main() { + debug!(1); + info!(2.0); + warn!(Three); + error!(~[4]); +} diff --git a/src/test/run-pass/monad.rs b/src/test/run-pass/monad.rs index 523348b4ffdea..b21b3b6c7fb26 100644 --- a/src/test/run-pass/monad.rs +++ b/src/test/run-pass/monad.rs @@ -11,11 +11,11 @@ // xfail-fast trait vec_monad { - fn bind(f: fn(&A) -> ~[B]) -> ~[B]; + fn bind(f: &fn(&A) -> ~[B]) -> ~[B]; } impl vec_monad for ~[A] { - fn bind(f: fn(&A) -> ~[B]) -> ~[B] { + fn bind(f: &fn(&A) -> ~[B]) -> ~[B] { let mut r = ~[]; for self.each |elt| { r += f(elt); } r @@ -23,11 +23,11 @@ impl vec_monad for ~[A] { } trait option_monad { - fn bind(f: fn(&A) -> Option) -> Option; + fn bind(f: &fn(&A) -> Option) -> Option; } impl option_monad for Option { - fn bind(f: fn(&A) -> Option) -> Option { + fn bind(f: &fn(&A) -> Option) -> Option { match self { Some(ref a) => { f(a) } None => { None } diff --git a/src/test/run-pass/morestack6.rs b/src/test/run-pass/morestack6.rs index 9d210f2580b8b..7e0b4b47846e0 100644 --- a/src/test/run-pass/morestack6.rs +++ b/src/test/run-pass/morestack6.rs @@ -17,7 +17,6 @@ mod rustrt { pub fn rust_get_sched_id() -> libc::intptr_t; pub fn rust_get_argc() -> libc::c_int; - pub fn rust_getcwd() -> ~str; pub fn get_task_id() -> libc::intptr_t; pub fn rust_sched_threads(); pub fn rust_get_task(); @@ -26,7 +25,6 @@ mod rustrt { fn calllink01() { unsafe { rustrt::rust_get_sched_id(); } } fn calllink02() { unsafe { rustrt::rust_get_argc(); } } -fn calllink03() { unsafe { rustrt::rust_getcwd(); } } fn calllink08() { unsafe { rustrt::get_task_id(); } } fn calllink09() { unsafe { rustrt::rust_sched_threads(); } } fn calllink10() { unsafe { rustrt::rust_get_task(); } } @@ -59,7 +57,6 @@ pub fn main() { let fns = ~[ calllink01, calllink02, - calllink03, calllink08, calllink09, calllink10 diff --git a/src/test/run-pass/mut-function-arguments.rs b/src/test/run-pass/mut-function-arguments.rs index a092e3bcc1889..f61ffc1bc3e00 100644 --- a/src/test/run-pass/mut-function-arguments.rs +++ b/src/test/run-pass/mut-function-arguments.rs @@ -14,7 +14,7 @@ fn f(mut y: ~int) { } fn g() { - let frob: fn(~int) = |mut q| { *q = 2; fail_unless!(*q == 2); }; + let frob: &fn(~int) = |mut q| { *q = 2; fail_unless!(*q == 2); }; let w = ~37; frob(w); diff --git a/src/test/run-pass/newlambdas.rs b/src/test/run-pass/newlambdas.rs index 267946e7b2e01..076e019bab46d 100644 --- a/src/test/run-pass/newlambdas.rs +++ b/src/test/run-pass/newlambdas.rs @@ -12,7 +12,7 @@ fn f(i: int, f: &fn(int) -> int) -> int { f(i) } -fn g(g: fn()) { } +fn g(g: &fn()) { } fn ff() -> @fn(int) -> int { return |x| x + 1; diff --git a/src/test/run-pass/newtype-polymorphic.rs b/src/test/run-pass/newtype-polymorphic.rs index d661fecc52659..18132d15d5787 100644 --- a/src/test/run-pass/newtype-polymorphic.rs +++ b/src/test/run-pass/newtype-polymorphic.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -enum myvec = ~[X]; +struct myvec(~[X]); fn myvec_deref(mv: myvec) -> ~[X] { return copy *mv; } diff --git a/src/test/run-pass/newtype.rs b/src/test/run-pass/newtype.rs index 41b16193ca1ef..6a82f70d9158a 100644 --- a/src/test/run-pass/newtype.rs +++ b/src/test/run-pass/newtype.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -enum mytype = Mytype; +struct mytype(Mytype); struct Mytype {compute: extern fn(mytype) -> int, val: int} diff --git a/src/test/run-pass/non-legacy-modes.rs b/src/test/run-pass/non-legacy-modes.rs index 6260de64cd839..330a9b9de7b8f 100644 --- a/src/test/run-pass/non-legacy-modes.rs +++ b/src/test/run-pass/non-legacy-modes.rs @@ -12,7 +12,7 @@ struct X { repr: int } -fn apply(x: T, f: fn(T)) { +fn apply(x: T, f: &fn(T)) { f(x); } diff --git a/src/test/run-pass/operator-overloading-explicit-self.rs b/src/test/run-pass/operator-overloading-explicit-self.rs deleted file mode 100644 index 3d2fd649f1562..0000000000000 --- a/src/test/run-pass/operator-overloading-explicit-self.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -struct S { - x: int -} - -pub impl S { - pure fn add(&self, other: &S) -> S { - S { x: self.x + other.x } - } -} - -pub fn main() { - let mut s = S { x: 1 }; - s += S { x: 2 }; - fail_unless!(s.x == 3); -} - diff --git a/src/test/run-pass/pipe-bank-proto.rs b/src/test/run-pass/pipe-bank-proto.rs index b74c70d3ea716..20daa894bc128 100644 --- a/src/test/run-pass/pipe-bank-proto.rs +++ b/src/test/run-pass/pipe-bank-proto.rs @@ -49,7 +49,7 @@ macro_rules! move_it ( ) fn switch(+endp: pipes::RecvPacket, - f: fn(+v: Option) -> U) -> U { + f: &fn(+v: Option) -> U) -> U { f(pipes::try_recv(endp)) } diff --git a/src/test/run-pass/pipe-pingpong-bounded.rs b/src/test/run-pass/pipe-pingpong-bounded.rs index 2b270a54d80a0..f1686080f4661 100644 --- a/src/test/run-pass/pipe-pingpong-bounded.rs +++ b/src/test/run-pass/pipe-pingpong-bounded.rs @@ -43,8 +43,8 @@ mod pingpong { ptr::addr_of(&(data.ping)) } } - pub enum ping = server::pong; - pub enum pong = client::ping; + pub struct ping(server::pong); + pub struct pong(client::ping); pub mod client { use core::pipes; use core::pipes::*; diff --git a/src/test/run-pass/purity-infer.rs b/src/test/run-pass/purity-infer.rs index 9aba504695579..d546909de8e1e 100644 --- a/src/test/run-pass/purity-infer.rs +++ b/src/test/run-pass/purity-infer.rs @@ -9,7 +9,7 @@ // except according to those terms. -fn something(f: pure fn()) { f(); } +fn something(f: &pure fn()) { f(); } pub fn main() { something(|| log(error, "hi!") ); } diff --git a/src/test/run-pass/reflect-visit-data.rs b/src/test/run-pass/reflect-visit-data.rs index 029dc37cfb2ee..0f3f4db3bbfe2 100644 --- a/src/test/run-pass/reflect-visit-data.rs +++ b/src/test/run-pass/reflect-visit-data.rs @@ -19,7 +19,7 @@ use intrinsic::{TyDesc, get_tydesc, visit_tydesc, TyVisitor}; /// Trait for visitor that wishes to reflect on data. trait movable_ptr { - fn move_ptr(adjustment: fn(*c_void) -> *c_void); + fn move_ptr(adjustment: &fn(*c_void) -> *c_void); } /// Helper function for alignment calculation. @@ -28,7 +28,7 @@ fn align(size: uint, align: uint) -> uint { ((size + align) - 1u) & !(align - 1u) } -enum ptr_visit_adaptor = Inner; +struct ptr_visit_adaptor(Inner); pub impl ptr_visit_adaptor { @@ -470,7 +470,7 @@ impl TyVisitor for ptr_visit_adaptor { } } -enum my_visitor = @mut Stuff; +struct my_visitor(@mut Stuff); struct Stuff { ptr1: *c_void, @@ -479,7 +479,7 @@ struct Stuff { } pub impl my_visitor { - fn get(f: fn(T)) { + fn get(f: &fn(T)) { unsafe { f(*(self.ptr1 as *T)); } @@ -498,7 +498,7 @@ pub impl my_visitor { struct Inner { inner: V } impl movable_ptr for my_visitor { - fn move_ptr(adjustment: fn(*c_void) -> *c_void) { + fn move_ptr(adjustment: &fn(*c_void) -> *c_void) { self.ptr1 = adjustment(self.ptr1); self.ptr2 = adjustment(self.ptr2); } diff --git a/src/test/run-pass/reflect-visit-type.rs b/src/test/run-pass/reflect-visit-type.rs index 6efd40b1fd6e1..bc67ece79de50 100644 --- a/src/test/run-pass/reflect-visit-type.rs +++ b/src/test/run-pass/reflect-visit-type.rs @@ -10,7 +10,7 @@ // xfail-test use intrinsic::{TyDesc, get_tydesc, visit_tydesc, TyVisitor}; -enum my_visitor = @mut { types: ~[str] }; +struct my_visitor(@mut { types: ~[str] }); impl TyVisitor for my_visitor { fn visit_bot() -> bool { diff --git a/src/test/run-pass/regions-fn-subtyping-2.rs b/src/test/run-pass/regions-fn-subtyping-2.rs index ad9ede07f779b..a995b3d969352 100644 --- a/src/test/run-pass/regions-fn-subtyping-2.rs +++ b/src/test/run-pass/regions-fn-subtyping-2.rs @@ -15,13 +15,13 @@ // Here, `f` is a function that takes a pointer `x` and a function // `g`, where `g` requires its argument `y` to be in the same region // that `x` is in. -fn has_same_region(f: fn(x: &a.int, g: fn(y: &a.int))) { +fn has_same_region(f: &fn(x: &a.int, g: &fn(y: &a.int))) { // `f` should be the type that `wants_same_region` wants, but // right now the compiler complains that it isn't. wants_same_region(f); } -fn wants_same_region(_f: fn(x: &b.int, g: fn(y: &b.int))) { +fn wants_same_region(_f: &fn(x: &b.int, g: &fn(y: &b.int))) { } pub fn main() { diff --git a/src/test/run-pass/regions-infer-call-2.rs b/src/test/run-pass/regions-infer-call-2.rs index eba9bb592bb65..dc38a7baacd21 100644 --- a/src/test/run-pass/regions-infer-call-2.rs +++ b/src/test/run-pass/regions-infer-call-2.rs @@ -10,7 +10,7 @@ fn takes_two(x: &int, y: &int) -> int { *x + *y } -fn with(f: fn(x: &int) -> T) -> T { +fn with(f: &fn(x: &int) -> T) -> T { f(&20) } diff --git a/src/test/run-pass/regions-mock-trans.rs b/src/test/run-pass/regions-mock-trans.rs index 7a1b9ae563aa5..b249a4470cb9e 100644 --- a/src/test/run-pass/regions-mock-trans.rs +++ b/src/test/run-pass/regions-mock-trans.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -enum arena = (); +struct arena(()); struct Bcx { fcx: &'self Fcx<'self> diff --git a/src/test/run-pass/regions-params.rs b/src/test/run-pass/regions-params.rs index 500ce356018c0..0049653dea9d3 100644 --- a/src/test/run-pass/regions-params.rs +++ b/src/test/run-pass/regions-params.rs @@ -12,7 +12,7 @@ fn region_identity(x: &r/uint) -> &r/uint { x } -fn apply(t: T, f: fn(T) -> T) -> T { f(t) } +fn apply(t: T, f: &fn(T) -> T) -> T { f(t) } fn parameterized(x: &uint) -> uint { let z = apply(x, ({|y| diff --git a/src/test/run-pass/resource-cycle.rs b/src/test/run-pass/resource-cycle.rs index f5a959b2dbcab..058cb4ec77e48 100644 --- a/src/test/run-pass/resource-cycle.rs +++ b/src/test/run-pass/resource-cycle.rs @@ -34,7 +34,7 @@ fn r(v: *int) -> r { } } -enum t = Node; +struct t(Node); struct Node { next: Option<@mut t>, diff --git a/src/test/run-pass/resource-cycle2.rs b/src/test/run-pass/resource-cycle2.rs index cf5f36916a041..e3b03060893a2 100644 --- a/src/test/run-pass/resource-cycle2.rs +++ b/src/test/run-pass/resource-cycle2.rs @@ -34,7 +34,7 @@ fn r(v: U) -> r { } } -enum t = Node; +struct t(Node); struct Node { next: Option<@mut t>, diff --git a/src/test/run-pass/resource-cycle3.rs b/src/test/run-pass/resource-cycle3.rs index 4cd3df0f87f90..c76c1c6aeb910 100644 --- a/src/test/run-pass/resource-cycle3.rs +++ b/src/test/run-pass/resource-cycle3.rs @@ -43,7 +43,7 @@ fn r(v: U, w: int, _x: *int) -> R { } } -enum t = Node; +struct t(Node); struct Node { next: Option<@mut t>, diff --git a/src/test/run-pass/ret-break-cont-in-block.rs b/src/test/run-pass/ret-break-cont-in-block.rs index da2aa2b8cd4b3..6fe7575884249 100644 --- a/src/test/run-pass/ret-break-cont-in-block.rs +++ b/src/test/run-pass/ret-break-cont-in-block.rs @@ -12,7 +12,7 @@ use core::cmp::Eq; -fn iter(v: ~[T], it: fn(&T) -> bool) { +fn iter(v: ~[T], it: &fn(&T) -> bool) { let mut i = 0u, l = v.len(); while i < l { if !it(&v[i]) { break; } diff --git a/src/test/run-pass/sendfn-is-a-block.rs b/src/test/run-pass/sendfn-is-a-block.rs index 33e6eb6c85585..0d9d01f9e700f 100644 --- a/src/test/run-pass/sendfn-is-a-block.rs +++ b/src/test/run-pass/sendfn-is-a-block.rs @@ -10,7 +10,7 @@ // xfail-fast -fn test(f: fn(uint) -> uint) -> uint { +fn test(f: &fn(uint) -> uint) -> uint { return f(22u); } diff --git a/src/test/run-pass/static-impl.rs b/src/test/run-pass/static-impl.rs index 2ad01557e800e..2ee6f631ea521 100644 --- a/src/test/run-pass/static-impl.rs +++ b/src/test/run-pass/static-impl.rs @@ -26,12 +26,12 @@ mod b { trait uint_utils { fn str() -> ~str; - fn multi(f: fn(uint)); + fn multi(f: &fn(uint)); } impl uint_utils for uint { fn str() -> ~str { uint::to_str(self) } - fn multi(f: fn(uint)) { + fn multi(f: &fn(uint)) { let mut c = 0u; while c < self { f(c); c += 1u; } } @@ -39,14 +39,14 @@ impl uint_utils for uint { trait vec_utils { fn length_() -> uint; - fn iter_(f: fn(&T)); - fn map_(f: fn(&T) -> U) -> ~[U]; + fn iter_(f: &fn(&T)); + fn map_(f: &fn(&T) -> U) -> ~[U]; } impl vec_utils for ~[T] { fn length_() -> uint { vec::len(self) } - fn iter_(f: fn(&T)) { for self.each |x| { f(x); } } - fn map_(f: fn(&T) -> U) -> ~[U] { + fn iter_(f: &fn(&T)) { for self.each |x| { f(x); } } + fn map_(f: &fn(&T) -> U) -> ~[U] { let mut r = ~[]; for self.each |elt| { r += ~[f(elt)]; } r diff --git a/src/test/run-pass/static-method-test.rs b/src/test/run-pass/static-method-test.rs index a2148fb0ef501..0c6359375d306 100644 --- a/src/test/run-pass/static-method-test.rs +++ b/src/test/run-pass/static-method-test.rs @@ -36,33 +36,33 @@ impl bool_like for int { // A trait for sequences that can be constructed imperatively. trait buildable { static pure fn build_sized(size: uint, - builder: fn(push: pure fn(+v: A))) -> Self; + builder: &fn(push: &pure fn(+v: A))) -> Self; } impl buildable for @[A] { #[inline(always)] static pure fn build_sized(size: uint, - builder: fn(push: pure fn(+v: A))) -> @[A] { + builder: &fn(push: &pure fn(+v: A))) -> @[A] { at_vec::build_sized(size, builder) } } impl buildable for ~[A] { #[inline(always)] static pure fn build_sized(size: uint, - builder: fn(push: pure fn(+v: A))) -> ~[A] { + builder: &fn(push: &pure fn(+v: A))) -> ~[A] { vec::build_sized(size, builder) } } #[inline(always)] -pure fn build>(builder: fn(push: pure fn(+v: A))) -> B { +pure fn build>(builder: &fn(push: &pure fn(+v: A))) -> B { buildable::build_sized(4, builder) } /// Apply a function to each element of an iterable and return the results fn map, U, BU: buildable> - (v: IT, f: fn(T) -> U) -> BU { + (v: IT, f: &fn(T) -> U) -> BU { do build |push| { for v.each() |elem| { push(f(*elem)); diff --git a/src/test/run-pass/task-killjoin-rsrc.rs b/src/test/run-pass/task-killjoin-rsrc.rs index 48a2b30209825..39651f86e227b 100644 --- a/src/test/run-pass/task-killjoin-rsrc.rs +++ b/src/test/run-pass/task-killjoin-rsrc.rs @@ -40,7 +40,7 @@ fn notify(ch: Chan, v: @mut bool) -> notify { } fn joinable(f: ~fn()) -> Port { - fn wrapper(c: Chan, f: fn()) { + fn wrapper(c: Chan, f: &fn()) { let b = @mut false; error!("wrapper: task=%? allocated v=%x", task::get_task(), diff --git a/src/test/run-pass/trait-cast.rs b/src/test/run-pass/trait-cast.rs index 677852a74d69e..4cee3c636c572 100644 --- a/src/test/run-pass/trait-cast.rs +++ b/src/test/run-pass/trait-cast.rs @@ -13,7 +13,7 @@ // Test cyclic detector when using trait instances. -enum Tree = @mut TreeR; +struct Tree(@mut TreeR); struct TreeR { left: Option, right: Option, diff --git a/src/test/run-pass/trait-generic.rs b/src/test/run-pass/trait-generic.rs index b375b5f328f88..7b8ebe6d34cab 100644 --- a/src/test/run-pass/trait-generic.rs +++ b/src/test/run-pass/trait-generic.rs @@ -24,10 +24,10 @@ impl to_str for () { } trait map { - fn map(f: fn(&T) -> U) -> ~[U]; + fn map(f: &fn(&T) -> U) -> ~[U]; } impl map for ~[T] { - fn map(f: fn(&T) -> U) -> ~[U] { + fn map(f: &fn(&T) -> U) -> ~[U] { let mut r = ~[]; for self.each |x| { r += ~[f(x)]; } r diff --git a/src/test/run-pass/type-params-in-for-each.rs b/src/test/run-pass/type-params-in-for-each.rs index bf252ee136491..d600ff25f0298 100644 --- a/src/test/run-pass/type-params-in-for-each.rs +++ b/src/test/run-pass/type-params-in-for-each.rs @@ -13,7 +13,7 @@ struct S { b: uint, } -fn range(lo: uint, hi: uint, it: fn(uint)) { +fn range(lo: uint, hi: uint, it: &fn(uint)) { let mut lo_ = lo; while lo_ < hi { it(lo_); lo_ += 1u; } } diff --git a/src/test/run-pass/unnamed_argument_mode.rs b/src/test/run-pass/unnamed_argument_mode.rs index e8ceeab3bf6ce..649f424ec36be 100644 --- a/src/test/run-pass/unnamed_argument_mode.rs +++ b/src/test/run-pass/unnamed_argument_mode.rs @@ -3,7 +3,7 @@ fn good(a: &int) { // unnamed argument &int is now parse x: &int -fn called(f: fn(&int)) { +fn called(f: &fn(&int)) { } pub fn main() { diff --git a/src/test/run-pass/vec-matching-fold.rs b/src/test/run-pass/vec-matching-fold.rs new file mode 100644 index 0000000000000..1df90bf681cfb --- /dev/null +++ b/src/test/run-pass/vec-matching-fold.rs @@ -0,0 +1,33 @@ +fn foldl( + values: &[T], + initial: U, + function: &fn(partial: U, element: &T) -> U +) -> U { + match values { + [head, ..tail] => + foldl(tail, function(initial, &head), function), + [] => copy initial + } +} + +fn foldr( + values: &[T], + initial: U, + function: &fn(element: &T, partial: U) -> U +) -> U { + match values { + [..head, tail] => + foldr(head, function(&tail, initial), function), + [] => copy initial + } +} + +pub fn main() { + let x = [1, 2, 3, 4, 5]; + + let product = foldl(x, 1, |a, b| a * *b); + fail_unless!(product == 120); + + let sum = foldr(x, 0, |a, b| *a + b); + fail_unless!(sum == 15); +} diff --git a/src/test/run-pass/vec-matching.rs b/src/test/run-pass/vec-matching.rs index 1cbd0d78c021d..1402dd18fc72d 100644 --- a/src/test/run-pass/vec-matching.rs +++ b/src/test/run-pass/vec-matching.rs @@ -1,33 +1,54 @@ -fn foldl( - values: &[T], - initial: U, - function: &fn(partial: U, element: &T) -> U -) -> U { - match values { - [head, ..tail] => - foldl(tail, function(initial, &head), function), - _ => copy initial +fn a() { + let x = [1]; + match x { + [_, _, _, _, _, .._] => ::core::util::unreachable(), + [.._, _, _, _, _] => ::core::util::unreachable(), + [_, .._, _, _] => ::core::util::unreachable(), + [_, _] => ::core::util::unreachable(), + [a] => { + fail_unless!(a == 1); + } + [] => ::core::util::unreachable() } } -pub fn main() { - let x = [1, 2, 3, 4, 5]; +fn b() { + let x = [1, 2, 3]; match x { - [a, b, c, d, e, f] => { - ::core::util::unreachable(); - } - [a, b, c, d, e] => { + [a, b, ..c] => { fail_unless!(a == 1); fail_unless!(b == 2); + fail_unless!(c == &[3]); + } + _ => fail!() + } + match x { + [..a, b, c] => { + fail_unless!(a == &[1]); + fail_unless!(b == 2); fail_unless!(c == 3); - fail_unless!(d == 4); - fail_unless!(e == 5); } - _ => { - ::core::util::unreachable(); + _ => fail!() + } + match x { + [a, ..b, c] => { + fail_unless!(a == 1); + fail_unless!(b == &[2]); + fail_unless!(c == 3); + } + _ => fail!() + } + match x { + [a, b, c] => { + fail_unless!(a == 1); + fail_unless!(b == 2); + fail_unless!(c == 3); } + _ => fail!() } +} - let product = foldl(x, 1, |a, b| a * *b); - fail_unless!(product == 120); +pub fn main() { + a(); + b(); }