diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c6e9478713d58..d934e38c35d24 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,7 +11,7 @@ You're not off the hook even if you just stick to documentation; code examples i Pull requests will be treated as "review requests", and we will give feedback we expect to see corrected on [style](https://github.com/mozilla/rust/wiki/Note-style-guide) and substance before pulling. Changes contributed via pull request should focus on a single issue at a time, like any other. -We will not look accept pull-requests that try to "sneak" unrelated changes in. +We will not accept pull-requests that try to "sneak" unrelated changes in. Normally, all pull requests must include regression tests (see [Note-testsuite](https://github.com/mozilla/rust/wiki/Note-testsuite)) that test your change. Occasionally, a change will be very difficult to test for. diff --git a/doc/rust.md b/doc/rust.md index 13d897a00d2f1..80f8b8f49c1a4 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -908,6 +908,11 @@ function defined above on `[1, 2]` will instantiate type parameter `T` with `int`, and require the closure parameter to have type `fn(int)`. +The type parameters can also be explicitly supplied in a trailing +[path](#paths) component after the function name. This might be necessary +if there is not sufficient context to determine the type parameters. For +example, `sys::size_of::() == 4`. + Since a parameter type is opaque to the generic function, the set of operations that can be performed on it is limited. Values of parameter type can always be moved, but they can only be copied when the @@ -1085,6 +1090,15 @@ let p = Point(10, 11); let px: int = match p { Point(x, _) => x }; ~~~~ +A _unit-like struct_ is a structure without any fields, defined by leaving off the fields list entirely. +Such types will have a single value, just like the [unit value `()`](#unit-and-boolean-literals) of the unit type. +For example: + +~~~~ +struct Cookie; +let c = [Cookie, Cookie, Cookie, Cookie]; +~~~~ + ### Enumerations An _enumeration_ is a simultaneous definition of a nominal [enumerated type](#enumerated-types) as well as a set of *constructors*, @@ -1285,19 +1299,22 @@ An _implementation_ is an item that implements a [trait](#traits) for a specific Implementations are defined with the keyword `impl`. ~~~~ -# type Point = {x: float, y: float}; +# struct Point {x: float, y: float}; # type Surface = int; -# type BoundingBox = {x: float, y: float, width: float, height: float}; +# struct BoundingBox {x: float, y: float, width: float, height: float}; # trait Shape { fn draw(Surface); fn bounding_box() -> BoundingBox; } # fn do_draw_circle(s: Surface, c: Circle) { } -type Circle = {radius: float, center: Point}; +struct Circle { + radius: float, + center: Point, +} impl Shape for Circle { fn draw(s: Surface) { do_draw_circle(s, self); } fn bounding_box() -> BoundingBox { let r = self.radius; - {x: self.center.x - r, y: self.center.y - r, + BoundingBox{x: self.center.x - r, y: self.center.y - r, width: 2.0 * r, height: 2.0 * r} } } @@ -1590,7 +1607,8 @@ struct_expr : expr_path '{' ident ':' expr [ ',' ident ':' expr ] * [ ".." expr ] '}' | expr_path '(' expr - [ ',' expr ] * ')' + [ ',' expr ] * ')' | + expr_path ~~~~~~~~ There are several forms of structure expressions. @@ -1600,23 +1618,28 @@ providing the field values of a new instance of the structure. A field name can be any identifier, and is separated from its value expression by a colon. To indicate that a field is mutable, the `mut` keyword is written before its name. -A _tuple structure expression_ constists of the [path](#paths) of a [structure item](#structures), +A _tuple structure expression_ consists of the [path](#paths) of a [structure item](#structures), followed by a parenthesized list of one or more comma-separated expressions (in other words, the path of a structured item followed by a tuple expression). The structure item must be a tuple structure item. +A _unit-like structure expression_ consists only of the [path](#paths) of a [structure item](#structures). + The following are examples of structure expressions: ~~~~ # struct Point { x: float, y: float } # struct TuplePoint(float, float); # mod game { pub struct User { name: &str, age: uint, score: uint } } +# struct Cookie; fn some_fn(t: T) {} Point {x: 10f, y: 20f}; TuplePoint(10f, 20f); let u = game::User {name: "Joe", age: 35u, score: 100_000}; +some_fn::(Cookie); ~~~~ A structure expression forms a new value of the named structure type. +Note that for a given *unit-like* structure type, this will always be the same value. A structure expression can terminate with the syntax `..` followed by an expression to denote a functional update. The expression following `..` (the base) must be of the same structure type as the new structure type being formed. @@ -1637,38 +1660,6 @@ rec_expr : '{' ident ':' expr [ ".." expr ] '}' ~~~~~~~~ -> **Note:** In future versions of Rust, record expressions and [record types](#record-types) will be removed. - -A [_record_](#record-types) _expression_ is one or more comma-separated -name-value pairs enclosed by braces. A fieldname can be any identifier, -and is separated from its value expression by a -colon. To indicate that a field is mutable, the `mut` keyword is -written before its name. - -~~~~ -{x: 10f, y: 20f}; -{name: "Joe", age: 35u, score: 100_000}; -{ident: "X", mut count: 0u}; -~~~~ - -The order of the fields in a record expression is significant, and -determines the type of the resulting value. `{a: u8, b: u8}` and `{b: -u8, a: u8}` are two different fields. - -A record expression can terminate with the syntax `..` followed by an -expression to denote a functional update. The expression following -`..` (the base) must be of a record type that includes at least all the -fields mentioned in the record expression. A new record will be -created, of the same type as the base expression, with the given -values for the fields that were explicitly specified, and the values -in the base record for all other fields. The ordering of the fields in -such a record expression is not significant. - -~~~~ -let base = {x: 1, y: 2, z: 3}; -{y: 0, z: 10, .. base}; -~~~~ - ### Method-call expressions ~~~~~~~~{.ebnf .gram} @@ -1689,7 +1680,7 @@ field_expr : expr '.' ident A _field expression_ consists of an expression followed by a single dot and an identifier, when not immediately followed by a parenthesized expression-list (the latter is a [method call expression](#method-call-expressions)). -A field expression denotes a field of a [structure](#structure-types) or [record](#record-types). +A field expression denotes a field of a [structure](#structure-types). ~~~~~~~~ {.field} myrecord.myfield; @@ -1905,8 +1896,10 @@ An example of three different swap expressions: # let mut x = &mut [0]; # let mut a = &mut [0]; # let i = 0; -# let y = {mut z: 0}; -# let b = {mut c: 0}; +# struct S1 { z: int }; +# struct S2 { c: int }; +# let mut y = S1{z: 0}; +# let mut b = S2{c: 0}; x <-> a; x[i] <-> a[i]; @@ -2040,12 +2033,14 @@ an optional reference slot to serve as the function's output, bound to the `lval` on the right hand side of the call. If the function eventually returns, then the expression completes. -An example of a call expression: +Some examples of call expressions: ~~~~ # fn add(x: int, y: int) -> int { 0 } +# use core::from_str::FromStr::from_str; let x: int = add(1, 2); +let pi = from_str::("3.14"); ~~~~ ### Lambda expressions @@ -2328,42 +2323,6 @@ match x { } ~~~~ -Records and structures can also be pattern-matched and their fields bound to variables. -When matching fields of a record, -the fields being matched are specified first, -then a placeholder (`_`) represents the remaining fields. - -~~~~ -# type options = {choose: bool, size: ~str}; -# type player = {player: ~str, stats: (), options: options}; -# fn load_stats() { } -# fn choose_player(r: &player) { } -# fn next_player() { } - -fn main() { - let r = { - player: ~"ralph", - stats: load_stats(), - options: { - choose: true, - size: ~"small" - } - }; - - match r { - {options: {choose: true, _}, _} => { - choose_player(&r) - } - {player: ref p, options: {size: ~"small", _}, _} => { - log(info, (copy *p) + ~" is small"); - } - _ => { - next_player(); - } - } -} -~~~~ - Patterns that bind variables default to binding to a copy of the matched value. This can be made explicit using the ```copy``` keyword, changed to bind to a borrowed pointer by using the ```ref``` keyword, or to a mutable borrowed pointer using ```ref mut```, or the value can be moved into @@ -2643,7 +2602,10 @@ the resulting `struct` value will always be laid out in memory in the order spec The fields of a `struct` may be qualified by [visibility modifiers](#visibility-modifiers), to restrict access to implementation-private data in a structure. -A `tuple struct` type is just like a structure type, except that the fields are anonymous. +A _tuple struct_ type is just like a structure type, except that the fields are anonymous. + +A _unit-like struct_ type is like a structure type, except that it has no fields. +The one value constructed by the associated [structure expression](#structure-expression) is the only value that inhabits such a type. ### Enumerated types @@ -2692,25 +2654,6 @@ let a: List = Cons(7, @Cons(13, @Nil)); ~~~~ -### Record types - -> **Note:** Records are not nominal types, thus do not directly support recursion, visibility control, -> out-of-order field initialization, or coherent trait implementation. -> Records are therefore deprecated and will be removed in future versions of Rust. -> [Structure types](#structure-types) should be used instead. - -The record type-constructor forms a new heterogeneous product of values. -Fields of a record type are accessed by name and are arranged in memory in the order specified by the record type. - -An example of a record type and its use: - -~~~~ -type Point = {x: int, y: int}; -let p: Point = {x: 10, y: 11}; -let px: int = p.x; -~~~~ - - ### Pointer types All pointers in Rust are explicit first-class values. @@ -3040,7 +2983,8 @@ Some operations (such as field selection) implicitly dereference boxes. An example of an _implicit dereference_ operation performed on box values: ~~~~~~~~ -let x = @{y: 10}; +struct Foo { y: int } +let x = @Foo{y: 10}; assert x.y == 10; ~~~~~~~~ diff --git a/doc/tutorial-borrowed-ptr.md b/doc/tutorial-borrowed-ptr.md index 0c1624706bfeb..e638579253fed 100644 --- a/doc/tutorial-borrowed-ptr.md +++ b/doc/tutorial-borrowed-ptr.md @@ -166,9 +166,9 @@ operator. For example, I could write: # struct Point {x: float, y: float} // as before # struct Size {w: float, h: float} // as before # struct Rectangle {origin: Point, size: Size} -# let rect_stack = &{origin: Point {x: 1f, y: 2f}, size: Size {w: 3f, h: 4f}}; -# let rect_managed = @{origin: Point {x: 3f, y: 4f}, size: Size {w: 3f, h: 4f}}; -# let rect_unique = ~{origin: Point {x: 5f, y: 6f}, size: Size {w: 3f, h: 4f}}; +# let rect_stack = &Rectangle {origin: Point {x: 1f, y: 2f}, size: Size {w: 3f, h: 4f}}; +# let rect_managed = @Rectangle {origin: Point {x: 3f, y: 4f}, size: Size {w: 3f, h: 4f}}; +# let rect_unique = ~Rectangle {origin: Point {x: 5f, y: 6f}, size: Size {w: 3f, h: 4f}}; # fn compute_distance(p1: &Point, p2: &Point) -> float { 0f } compute_distance(&rect_stack.origin, &rect_managed.origin); ~~~ @@ -274,13 +274,14 @@ the following function is legal: ~~~ # fn some_condition() -> bool { true } +# struct Foo { f: int } fn example3() -> int { - let mut x = ~{f: 3}; + let mut x = ~Foo {f: 3}; if some_condition() { let y = &x.f; // -+ L return *y; // | } // -+ - x = ~{f: 4}; + x = ~Foo {f: 4}; ... # return 0; } diff --git a/src/libcore/at_vec.rs b/src/libcore/at_vec.rs index ab604d1f0b6fe..d89481766c0af 100644 --- a/src/libcore/at_vec.rs +++ b/src/libcore/at_vec.rs @@ -183,7 +183,7 @@ pub mod raw { use at_vec::{capacity, rustrt}; use cast::transmute; use libc; - use private::intrinsics::{move_val_init}; + use unstable::intrinsics::{move_val_init}; use ptr::addr_of; use ptr; use sys; diff --git a/src/libcore/cleanup.rs b/src/libcore/cleanup.rs index 6912d6d995b8f..393a71562ad05 100644 --- a/src/libcore/cleanup.rs +++ b/src/libcore/cleanup.rs @@ -154,7 +154,7 @@ fn debug_mem() -> bool { #[cfg(notest)] #[lang="annihilate"] pub unsafe fn annihilate() { - use rt::local_free; + use unstable::lang::local_free; use io::WriterUtil; use io; use libc; diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index fd99235bd270c..d588f0c53b17e 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -37,6 +37,70 @@ pub trait Eq { pure fn ne(&self, other: &Self) -> bool; } +#[deriving_eq] +pub enum Ordering { Less, Equal, Greater } + +/// Trait for types that form a total order +pub trait TotalOrd { + pure fn cmp(&self, other: &Self) -> Ordering; +} + +pure fn icmp(a: &T, b: &T) -> Ordering { + if *a < *b { Less } + else if *a > *b { Greater } + else { Equal } +} + +impl TotalOrd for u8 { + #[inline(always)] + pure fn cmp(&self, other: &u8) -> Ordering { icmp(self, other) } +} + +impl TotalOrd for u16 { + #[inline(always)] + pure fn cmp(&self, other: &u16) -> Ordering { icmp(self, other) } +} + +impl TotalOrd for u32 { + #[inline(always)] + pure fn cmp(&self, other: &u32) -> Ordering { icmp(self, other) } +} + +impl TotalOrd for u64 { + #[inline(always)] + pure fn cmp(&self, other: &u64) -> Ordering { icmp(self, other) } +} + +impl TotalOrd for i8 { + #[inline(always)] + pure fn cmp(&self, other: &i8) -> Ordering { icmp(self, other) } +} + +impl TotalOrd for i16 { + #[inline(always)] + pure fn cmp(&self, other: &i16) -> Ordering { icmp(self, other) } +} + +impl TotalOrd for i32 { + #[inline(always)] + pure fn cmp(&self, other: &i32) -> Ordering { icmp(self, other) } +} + +impl TotalOrd for i64 { + #[inline(always)] + pure fn cmp(&self, other: &i64) -> Ordering { icmp(self, other) } +} + +impl TotalOrd for int { + #[inline(always)] + pure fn cmp(&self, other: &int) -> Ordering { icmp(self, other) } +} + +impl TotalOrd for uint { + #[inline(always)] + pure fn cmp(&self, other: &uint) -> Ordering { icmp(self, other) } +} + /** * Trait for values that can be compared for a sort-order. * @@ -94,3 +158,15 @@ pub pure fn min(v1: T, v2: T) -> T { pub pure fn max(v1: T, v2: T) -> T { if v1 > v2 { v1 } else { v2 } } + +#[cfg(test)] +mod test { + #[test] + fn test_int() { + assert 5.cmp(&10) == Less; + assert 10.cmp(&5) == Greater; + assert 5.cmp(&5) == Equal; + assert (-5).cmp(&12) == Less; + assert 12.cmp(-5) == Greater; + } +} diff --git a/src/libcore/comm.rs b/src/libcore/comm.rs index 238207f12b63e..94272f63e6727 100644 --- a/src/libcore/comm.rs +++ b/src/libcore/comm.rs @@ -12,7 +12,7 @@ use either::{Either, Left, Right}; use kinds::Owned; use option; use option::{Option, Some, None, unwrap}; -use private; +use unstable; use vec; use pipes::{recv, try_recv, wait_many, peek, PacketHeader}; @@ -242,7 +242,7 @@ impl Peekable for PortSet { } /// A channel that can be shared between many senders. -pub type SharedChan = private::Exclusive>; +pub type SharedChan = unstable::Exclusive>; impl GenericChan for SharedChan { fn send(x: T) { @@ -268,7 +268,7 @@ impl GenericSmartChan for SharedChan { /// Converts a `chan` into a `shared_chan`. pub fn SharedChan(c: Chan) -> SharedChan { - private::exclusive(c) + unstable::exclusive(c) } /// Receive a message from one of two endpoints. diff --git a/src/libcore/core.rc b/src/libcore/core.rc index 3e514ce249ffb..c8d2da28255f1 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -225,11 +225,13 @@ pub const debug : u32 = 4_u32; /* Unsupported interfaces */ -// The runtime interface used by the compiler -#[cfg(notest)] pub mod rt; // Private APIs -pub mod private; - +pub mod unstable; +// NOTE: Remove after snapshot +#[cfg(stage0)] +pub mod private { + pub use super::unstable::extfmt; +} /* For internal use, not exported */ diff --git a/src/libcore/dvec.rs b/src/libcore/dvec.rs index 1fef4ad42f1de..7197de36404ed 100644 --- a/src/libcore/dvec.rs +++ b/src/libcore/dvec.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. // @@ -62,17 +62,17 @@ pub struct DVec { /// Creates a new, empty dvec pub pure fn DVec() -> DVec { - DVec {mut data: ~[]} + DVec {data: ~[]} } /// Creates a new dvec with a single element pub pure fn from_elem(e: A) -> DVec { - DVec {mut data: ~[e]} + DVec {data: ~[e]} } /// Creates a new dvec with the contents of a vector pub pure fn from_vec(v: ~[A]) -> DVec { - DVec {mut data: v} + DVec {data: v} } /// Consumes the vector and returns its contents diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index c4f2704ab9f6e..d4808bd111ffa 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -18,7 +18,7 @@ use num::strconv; use num; use ops; use option::Option; -use private::intrinsics::floorf32; +use unstable::intrinsics::floorf32; use from_str; use to_str; diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index 8f3771312e4d6..5362a65f7cef7 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -19,7 +19,7 @@ use num::strconv; use num; use ops; use option::Option; -use private::intrinsics::floorf64; +use unstable::intrinsics::floorf64; use to_str; use from_str; diff --git a/src/libcore/os.rs b/src/libcore/os.rs index 8b6d27496d909..cf74ec6d77a22 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.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. // @@ -35,7 +35,6 @@ use libc::{mode_t, pid_t, FILE}; use option; use option::{Some, None}; use prelude::*; -use private; use ptr; use str; use task; @@ -145,8 +144,8 @@ This uses a per-runtime lock to serialize access. FIXME #4726: It would probably be appropriate to make this a real global */ fn with_env_lock(f: &fn() -> T) -> T { - use private::global::global_data_clone_create; - use private::{Exclusive, exclusive}; + use unstable::global::global_data_clone_create; + use unstable::{Exclusive, exclusive}; struct SharedValue(()); type ValueMutex = Exclusive; @@ -322,8 +321,8 @@ pub struct Pipe { mut in: c_int, mut out: c_int } #[cfg(unix)] pub fn pipe() -> Pipe { unsafe { - let mut fds = Pipe {mut in: 0 as c_int, - mut out: 0 as c_int }; + let mut fds = Pipe {in: 0 as c_int, + out: 0 as c_int }; assert (libc::pipe(&mut fds.in) == (0 as c_int)); return Pipe {in: fds.in, out: fds.out}; } @@ -339,8 +338,8 @@ pub fn pipe() -> Pipe { // fully understand. Here we explicitly make the pipe non-inheritable, // which means to pass it to a subprocess they need to be duplicated // first, as in rust_run_program. - let mut fds = Pipe { mut in: 0 as c_int, - mut out: 0 as c_int }; + let mut fds = Pipe {in: 0 as c_int, + out: 0 as c_int }; let res = libc::pipe(&mut fds.in, 1024 as c_uint, (libc::O_BINARY | libc::O_NOINHERIT) as c_int); assert (res == 0 as c_int); @@ -566,13 +565,17 @@ pub fn path_exists(p: &Path) -> bool { * * If the given path is relative, return it prepended with the current working * directory. If the given path is already an absolute path, return it - * as is. This is a shortcut for calling os::getcwd().unsafe_join(p) + * as is. */ // NB: this is here rather than in path because it is a form of environment // querying; what it does depends on the process working directory, not just // the input paths. pub fn make_absolute(p: &Path) -> Path { - getcwd().unsafe_join(p) + if p.is_absolute { + copy *p + } else { + getcwd().push_many(p.components) + } } diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs index 77554656913c4..58ab2ce78f5f9 100644 --- a/src/libcore/pipes.rs +++ b/src/libcore/pipes.rs @@ -91,9 +91,9 @@ use libc; use option; use option::{None, Option, Some, unwrap}; use pipes; -use private::intrinsics; +use unstable::intrinsics; use ptr; -use private; +use unstable; use task; use vec; diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs index d0a16f7875b5c..e4be0cf98dd4e 100644 --- a/src/libcore/prelude.rs +++ b/src/libcore/prelude.rs @@ -24,10 +24,10 @@ pub use result::{Result, Ok, Err}; /* Reexported types and traits */ pub use clone::Clone; -pub use cmp::{Eq, Ord}; +pub use cmp::{Eq, Ord, TotalOrd, Ordering, Less, Equal, Greater}; pub use container::{Container, Mutable, Map, Set}; pub use hash::Hash; -pub use iter::{BaseIter, ExtendedIter, EqIter, CopyableIter}; +pub use iter::{BaseIter, ReverseIter, ExtendedIter, EqIter, CopyableIter}; pub use iter::{CopyableOrderedIter, CopyableNonstrictIter, Times}; pub use num::NumCast; pub use path::GenericPath; @@ -69,7 +69,7 @@ pub use option; pub use os; pub use path; pub use comm; -pub use private; +pub use unstable; pub use ptr; pub use rand; pub use result; diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 2266c2511f8f3..ecbce18e6daae 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.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. // @@ -14,7 +14,7 @@ use cast; use cmp::{Eq, Ord}; use libc; use libc::{c_void, size_t}; -use private::intrinsics::{memmove32,memmove64}; +use unstable::intrinsics::{memmove32,memmove64}; use ptr; use str; use sys; @@ -300,7 +300,7 @@ impl Ord for &const T { pub fn test() { unsafe { struct Pair {mut fst: int, mut snd: int}; - let mut p = Pair {mut fst: 10, mut snd: 20}; + let mut p = Pair {fst: 10, snd: 20}; let pptr: *mut Pair = &mut p; let iptr: *mut int = cast::reinterpret_cast(&pptr); assert (*iptr == 10);; @@ -308,7 +308,7 @@ pub fn test() { assert (*iptr == 30); assert (p.fst == 30);; - *pptr = Pair {mut fst: 50, mut snd: 60}; + *pptr = Pair {fst: 50, snd: 60}; assert (*iptr == 50); assert (p.fst == 50); assert (p.snd == 60); diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 7dfc52c458aed..f1e23f01e7b51 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -20,7 +20,7 @@ use at_vec; use cast; use char; -use cmp::{Eq, Ord}; +use cmp::{Eq, Ord, TotalOrd, Ordering, Less, Equal, Greater}; use libc; use libc::size_t; use io::WriterUtil; @@ -773,6 +773,35 @@ pub pure fn eq(a: &~str, b: &~str) -> bool { eq_slice(*a, *b) } +pure fn cmp(a: &str, b: &str) -> Ordering { + let low = uint::min(a.len(), b.len()); + + for uint::range(0, low) |idx| { + match a[idx].cmp(&b[idx]) { + Greater => return Greater, + Less => return Less, + Equal => () + } + } + + a.len().cmp(&b.len()) +} + +#[cfg(notest)] +impl TotalOrd for &str { + pure fn cmp(&self, other: & &self/str) -> Ordering { cmp(*self, *other) } +} + +#[cfg(notest)] +impl TotalOrd for ~str { + pure fn cmp(&self, other: &~str) -> Ordering { cmp(*self, *other) } +} + +#[cfg(notest)] +impl TotalOrd for @str { + pure fn cmp(&self, other: &@str) -> Ordering { cmp(*self, *other) } +} + /// Bytewise slice less than pure fn lt(a: &str, b: &str) -> bool { let (a_len, b_len) = (a.len(), b.len()); @@ -2389,6 +2418,7 @@ mod tests { use ptr; use str::*; use vec; + use cmp::{TotalOrd, Less, Equal, Greater}; #[test] fn test_eq() { @@ -3395,4 +3425,12 @@ mod tests { assert view("abcdef", 1, 5).to_managed() == @"bcde"; } + #[test] + fn test_total_ord() { + "1234".cmp(& &"123") == Greater; + "123".cmp(& &"1234") == Less; + "1234".cmp(& &"1234") == Equal; + "12345555".cmp(& &"123456") == Less; + "22".cmp(& &"1234") == Greater; + } } diff --git a/src/libcore/task/local_data_priv.rs b/src/libcore/task/local_data_priv.rs index df5a5af74cabf..fc15276532282 100644 --- a/src/libcore/task/local_data_priv.rs +++ b/src/libcore/task/local_data_priv.rs @@ -19,11 +19,7 @@ use prelude::*; use task::rt; use task::local_data::LocalDataKey; -#[cfg(notest)] -use rt::rust_task; -#[cfg(test)] -#[allow(non_camel_case_types)] -type rust_task = libc::c_void; +use super::rt::rust_task; pub trait LocalData { } impl LocalData for @T { } diff --git a/src/libcore/task/spawn.rs b/src/libcore/task/spawn.rs index bf7209f9fc3fc..6cc3657a32b4e 100644 --- a/src/libcore/task/spawn.rs +++ b/src/libcore/task/spawn.rs @@ -79,7 +79,7 @@ use option; use comm::{Chan, GenericChan, GenericPort, Port, stream}; use pipes; use prelude::*; -use private; +use unstable; use ptr; use hashmap::linear::LinearSet; use task::local_data_priv::{local_get, local_set}; @@ -123,7 +123,7 @@ struct TaskGroupData { // tasks in this group. mut descendants: TaskSet, } -type TaskGroupArc = private::Exclusive>; +type TaskGroupArc = unstable::Exclusive>; type TaskGroupInner = &mut Option; @@ -153,7 +153,7 @@ struct AncestorNode { mut ancestors: AncestorList, } -enum AncestorList = Option>; +enum AncestorList = Option>; // Accessors for taskgroup arcs and ancestor arcs that wrap the unsafety. #[inline(always)] @@ -162,7 +162,7 @@ fn access_group(x: &TaskGroupArc, blk: fn(TaskGroupInner) -> U) -> U { } #[inline(always)] -fn access_ancestors(x: &private::Exclusive, +fn access_ancestors(x: &unstable::Exclusive, blk: fn(x: &mut AncestorNode) -> U) -> U { unsafe { x.with(blk) } } @@ -458,7 +458,7 @@ fn gen_child_taskgroup(linked: bool, supervised: bool) // Main task, doing first spawn ever. Lazily initialise here. let mut members = new_taskset(); taskset_insert(&mut members, spawner); - let tasks = private::exclusive(Some(TaskGroupData { + let tasks = unstable::exclusive(Some(TaskGroupData { members: members, descendants: new_taskset(), })); @@ -482,7 +482,7 @@ fn gen_child_taskgroup(linked: bool, supervised: bool) (g, a, spawner_group.is_main) } else { // Child is in a separate group from spawner. - let g = private::exclusive(Some(TaskGroupData { + let g = unstable::exclusive(Some(TaskGroupData { members: new_taskset(), descendants: new_taskset(), })); @@ -502,7 +502,7 @@ fn gen_child_taskgroup(linked: bool, supervised: bool) }; assert new_generation < uint::max_value; // Build a new node in the ancestor list. - AncestorList(Some(private::exclusive(AncestorNode { + AncestorList(Some(unstable::exclusive(AncestorNode { generation: new_generation, parent_group: Some(spawner_group.tasks.clone()), ancestors: old_ancestors, diff --git a/src/libcore/private.rs b/src/libcore/unstable.rs similarity index 96% rename from src/libcore/private.rs rename to src/libcore/unstable.rs index d19951e76dbd5..8c0c029a90fcc 100644 --- a/src/libcore/private.rs +++ b/src/libcore/unstable.rs @@ -22,20 +22,23 @@ use task; use task::{TaskBuilder, atomically}; use uint; -#[path = "private/at_exit.rs"] +#[path = "unstable/at_exit.rs"] pub mod at_exit; -#[path = "private/global.rs"] +#[path = "unstable/global.rs"] pub mod global; -#[path = "private/finally.rs"] +#[path = "unstable/finally.rs"] pub mod finally; -#[path = "private/weak_task.rs"] +#[path = "unstable/weak_task.rs"] pub mod weak_task; -#[path = "private/exchange_alloc.rs"] +#[path = "unstable/exchange_alloc.rs"] pub mod exchange_alloc; -#[path = "private/intrinsics.rs"] +#[path = "unstable/intrinsics.rs"] pub mod intrinsics; -#[path = "private/extfmt.rs"] +#[path = "unstable/extfmt.rs"] pub mod extfmt; +#[path = "unstable/lang.rs"] +#[cfg(notest)] +pub mod lang; extern mod rustrt { pub unsafe fn rust_create_little_lock() -> rust_little_lock; @@ -312,7 +315,7 @@ pub mod tests { use cell::Cell; use comm; use option; - use private::exclusive; + use super::exclusive; use result; use task; use uint; diff --git a/src/libcore/private/at_exit.rs b/src/libcore/unstable/at_exit.rs similarity index 100% rename from src/libcore/private/at_exit.rs rename to src/libcore/unstable/at_exit.rs diff --git a/src/libcore/private/exchange_alloc.rs b/src/libcore/unstable/exchange_alloc.rs similarity index 97% rename from src/libcore/private/exchange_alloc.rs rename to src/libcore/unstable/exchange_alloc.rs index b6af9891e118b..f59037445ebd0 100644 --- a/src/libcore/private/exchange_alloc.rs +++ b/src/libcore/unstable/exchange_alloc.rs @@ -14,7 +14,7 @@ use c_malloc = libc::malloc; use c_free = libc::free; use managed::raw::{BoxHeaderRepr, BoxRepr}; use cast::transmute; -use private::intrinsics::{atomic_xadd,atomic_xsub}; +use unstable::intrinsics::{atomic_xadd,atomic_xsub}; use ptr::null; use intrinsic::TyDesc; diff --git a/src/libcore/private/extfmt.rs b/src/libcore/unstable/extfmt.rs similarity index 100% rename from src/libcore/private/extfmt.rs rename to src/libcore/unstable/extfmt.rs diff --git a/src/libcore/private/finally.rs b/src/libcore/unstable/finally.rs similarity index 100% rename from src/libcore/private/finally.rs rename to src/libcore/unstable/finally.rs diff --git a/src/libcore/private/global.rs b/src/libcore/unstable/global.rs similarity index 97% rename from src/libcore/private/global.rs rename to src/libcore/unstable/global.rs index 77b61347250d2..aa28310f7ba29 100644 --- a/src/libcore/private/global.rs +++ b/src/libcore/unstable/global.rs @@ -32,11 +32,11 @@ use libc::{c_void, uintptr_t}; use option::{Option, Some, None}; use ops::Drop; use pipes; -use private::{Exclusive, exclusive}; -use private::{SharedMutableState, shared_mutable_state}; -use private::{get_shared_immutable_state}; -use private::at_exit::at_exit; -use private::intrinsics::atomic_cxchg; +use unstable::{Exclusive, exclusive}; +use unstable::{SharedMutableState, shared_mutable_state}; +use unstable::{get_shared_immutable_state}; +use unstable::at_exit::at_exit; +use unstable::intrinsics::atomic_cxchg; use hashmap::linear::LinearMap; use sys::Closure; use task::spawn; diff --git a/src/libcore/private/intrinsics.rs b/src/libcore/unstable/intrinsics.rs similarity index 100% rename from src/libcore/private/intrinsics.rs rename to src/libcore/unstable/intrinsics.rs diff --git a/src/libcore/rt.rs b/src/libcore/unstable/lang.rs similarity index 97% rename from src/libcore/rt.rs rename to src/libcore/unstable/lang.rs index 5d0bad3ceb3c2..e74052995e6ce 100644 --- a/src/libcore/rt.rs +++ b/src/libcore/unstable/lang.rs @@ -15,14 +15,11 @@ use libc::{c_char, c_uchar, c_void, size_t, uintptr_t, c_int}; use managed::raw::BoxRepr; use str; use sys; -use private::exchange_alloc; +use unstable::exchange_alloc; use cast::transmute; use gc::{cleanup_stack_for_failure, gc, Word}; -#[allow(non_camel_case_types)] -pub type rust_task = c_void; - #[cfg(target_word_size = "32")] pub const FROZEN_BIT: uint = 0x80000000; #[cfg(target_word_size = "64")] diff --git a/src/libcore/private/weak_task.rs b/src/libcore/unstable/weak_task.rs similarity index 97% rename from src/libcore/private/weak_task.rs rename to src/libcore/unstable/weak_task.rs index 8445638850cd0..0e1181f43dbc9 100644 --- a/src/libcore/private/weak_task.rs +++ b/src/libcore/unstable/weak_task.rs @@ -24,9 +24,9 @@ use comm::{Port, Chan, SharedChan, GenericChan, GenericPort}; use hashmap::linear::LinearMap; use ops::Drop; use option::{Some, None, swap_unwrap}; -use private::at_exit::at_exit; -use private::finally::Finally; -use private::global::global_data_clone_create; +use unstable::at_exit::at_exit; +use unstable::finally::Finally; +use unstable::global::global_data_clone_create; use task::rt::{task_id, get_task_id}; use task::{Task, task, spawn}; diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 4d28c769b184f..925d78a3b81b0 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -15,14 +15,14 @@ use container::{Container, Mutable}; use cast::transmute; use cast; -use cmp::{Eq, Ord}; +use cmp::{Eq, Ord, TotalOrd, Ordering, Less, Equal, Greater}; use iter::BaseIter; use iter; use kinds::Copy; use libc; use libc::size_t; use option::{None, Option, Some}; -use private::intrinsics; +use unstable::intrinsics; use ptr; use ptr::addr_of; use sys; @@ -1425,7 +1425,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 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) { assert len(v1) == len(v2); for uint::range(0u, len(v1)) |i| { if !f(&v1[i], &v2[i]) { @@ -1575,6 +1575,38 @@ impl Eq for @[T] { // Lexicographical comparison +pure fn cmp(a: &[T], b: &[T]) -> Ordering { + let low = uint::min(a.len(), b.len()); + + for uint::range(0, low) |idx| { + match a[idx].cmp(&b[idx]) { + Greater => return Greater, + Less => return Less, + Equal => () + } + } + + a.len().cmp(&b.len()) +} + +#[cfg(notest)] +impl TotalOrd for &[T] { + #[inline(always)] + pure fn cmp(&self, other: & &self/[T]) -> Ordering { cmp(*self, *other) } +} + +#[cfg(notest)] +impl TotalOrd for ~[T] { + #[inline(always)] + pure fn cmp(&self, other: &~[T]) -> Ordering { cmp(*self, *other) } +} + +#[cfg(notest)] +impl TotalOrd for @[T] { + #[inline(always)] + pure fn cmp(&self, other: &@[T]) -> Ordering { cmp(*self, *other) } +} + pure fn lt(a: &[T], b: &[T]) -> bool { let (a_len, b_len) = (a.len(), b.len()); let mut end = uint::min(a_len, b_len); @@ -2008,7 +2040,7 @@ pub mod raw { use managed; use option::{None, Some}; use option; - use private::intrinsics; + use unstable::intrinsics; use ptr::addr_of; use ptr; use sys; @@ -2151,7 +2183,7 @@ pub mod bytes { use vec; /// Bytewise string comparison - pub pure fn cmp(a: &~[u8], b: &~[u8]) -> int { + pub pure fn memcmp(a: &~[u8], b: &~[u8]) -> int { let a_len = len(*a); let b_len = len(*b); let n = uint::min(a_len, b_len) as libc::size_t; @@ -2172,22 +2204,22 @@ pub mod bytes { } /// Bytewise less than or equal - pub pure fn lt(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) < 0 } + pub pure fn lt(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) < 0 } /// Bytewise less than or equal - pub pure fn le(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) <= 0 } + pub pure fn le(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) <= 0 } /// Bytewise equality - pub pure fn eq(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) == 0 } + pub pure fn eq(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) == 0 } /// Bytewise inequality - pub pure fn ne(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) != 0 } + pub pure fn ne(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) != 0 } /// Bytewise greater than or equal - pub pure fn ge(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) >= 0 } + pub pure fn ge(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) >= 0 } /// Bytewise greater than - pub pure fn gt(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) > 0 } + pub pure fn gt(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) > 0 } /** * Copies data from one vector to another. @@ -2429,6 +2461,7 @@ mod tests { use option; use sys; use vec::*; + use cmp::*; fn square(n: uint) -> uint { return n * n; } @@ -2622,8 +2655,8 @@ mod tests { #[test] fn test_swap_remove_noncopyable() { // Tests that we don't accidentally run destructors twice. - let mut v = ~[::private::exclusive(()), ::private::exclusive(()), - ::private::exclusive(())]; + let mut v = ~[::unstable::exclusive(()), ::unstable::exclusive(()), + ::unstable::exclusive(())]; let mut _e = v.swap_remove(0); assert (len(v) == 2); _e = v.swap_remove(1); @@ -3942,6 +3975,14 @@ mod tests { } } + #[test] + fn test_total_ord() { + [1, 2, 3, 4].cmp(& &[1, 2, 3]) == Greater; + [1, 2, 3].cmp(& &[1, 2, 3, 4]) == Less; + [1, 2, 3, 4].cmp(& &[1, 2, 3, 4]) == Equal; + [1, 2, 3, 4, 5, 5, 5, 5].cmp(& &[1, 2, 3, 4, 5, 6]) == Less; + [2, 2].cmp(& &[1, 2, 3, 4]) == Greater; + } } // Local Variables: diff --git a/src/libstd/arc.rs b/src/libstd/arc.rs index 69c5026cbd1ff..ea59d6a54c6d6 100644 --- a/src/libstd/arc.rs +++ b/src/libstd/arc.rs @@ -20,9 +20,9 @@ use core::cast; use core::cell::Cell; use core::pipes; use core::prelude::*; -use core::private::{SharedMutableState, shared_mutable_state}; -use core::private::{clone_shared_mutable_state}; -use core::private::{get_shared_mutable_state, get_shared_immutable_state}; +use core::unstable::{SharedMutableState, shared_mutable_state}; +use core::unstable::{clone_shared_mutable_state}; +use core::unstable::{get_shared_mutable_state, get_shared_immutable_state}; use core::ptr; use core::task; use core::util; diff --git a/src/libstd/ebml.rs b/src/libstd/ebml.rs index 7d04f6760793e..cbe0580a60968 100644 --- a/src/libstd/ebml.rs +++ b/src/libstd/ebml.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. // @@ -219,7 +219,7 @@ pub mod reader { } pub fn Decoder(d: Doc) -> Decoder { - Decoder { mut parent: d, mut pos: d.start } + Decoder { parent: d, pos: d.start } } priv impl Decoder { diff --git a/src/libstd/net_tcp.rs b/src/libstd/net_tcp.rs index dcbf7e60d8956..4266cab0a056e 100644 --- a/src/libstd/net_tcp.rs +++ b/src/libstd/net_tcp.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. // @@ -43,7 +43,7 @@ extern mod rustrt { /** * Encapsulates an open TCP/IP connection through libuv * - * `tcp_socket` is non-copyable/sendable and automagically handles closing the + * `TcpSocket` is non-copyable/sendable and automagically handles closing the * underlying libuv data structures when it goes out of scope. This is the * data structure that is used for read/write operations over a TCP stream. */ @@ -66,10 +66,10 @@ pub fn TcpSocket(socket_data: @TcpSocketData) -> TcpSocket { } /** - * A buffered wrapper for `net::tcp::tcp_socket` + * A buffered wrapper for `net::tcp::TcpSocket` * * It is created with a call to `net::tcp::socket_buf()` and has impls that - * satisfy both the `io::reader` and `io::writer` traits. + * satisfy both the `io::Reader` and `io::Writer` traits. */ pub struct TcpSocketBuf { data: @TcpBufferedSocketData, @@ -89,7 +89,7 @@ pub struct TcpErrData { err_msg: ~str, } -/// Details returned as part of a `result::err` result from `tcp::listen` +/// Details returned as part of a `Result::Err` result from `tcp::listen` pub enum TcpListenErrData { /** * Some unplanned-for error. The first and second fields correspond @@ -116,7 +116,7 @@ pub enum TcpListenErrData { */ AccessDenied } -/// Details returned as part of a `result::err` result from `tcp::connect` +/// Details returned as part of a `Result::Err` result from `tcp::connect` pub enum TcpConnectErrData { /** * Some unplanned-for error. The first and second fields correspond @@ -139,9 +139,9 @@ pub enum TcpConnectErrData { * # Returns * * A `result` that, if the operation succeeds, contains a - * `net::net::tcp_socket` that can be used to send and receive data to/from + * `net::net::TcpSocket` that can be used to send and receive data to/from * the remote host. In the event of failure, a - * `net::tcp::tcp_connect_err_data` instance will be returned + * `net::tcp::TcpConnectErrData` instance will be returned */ pub fn connect(input_ip: ip::IpAddr, port: uint, iotask: &IoTask) @@ -288,14 +288,14 @@ pub fn connect(input_ip: ip::IpAddr, port: uint, * * # Arguments * - * * sock - a `tcp_socket` to write to + * * sock - a `TcpSocket` to write to * * raw_write_data - a vector of `~[u8]` that will be written to the stream. * This value must remain valid for the duration of the `write` call * * # Returns * - * A `result` object with a `nil` value as the `ok` variant, or a - * `tcp_err_data` value as the `err` variant + * A `Result` object with a `()` value as the `Ok` variant, or a + * `TcpErrData` value as the `Err` variant */ pub fn write(sock: &TcpSocket, raw_write_data: ~[u8]) -> result::Result<(), TcpErrData> { @@ -306,7 +306,7 @@ pub fn write(sock: &TcpSocket, raw_write_data: ~[u8]) } /** - * Write binary data to tcp stream; Returns a `future::future` value + * Write binary data to tcp stream; Returns a `future::Future` value * immediately * * # Safety @@ -314,27 +314,27 @@ pub fn write(sock: &TcpSocket, raw_write_data: ~[u8]) * This function can produce unsafe results if: * * 1. the call to `write_future` is made - * 2. the `future::future` value returned is never resolved via - * `future::get` - * 3. and then the `tcp_socket` passed in to `write_future` leaves + * 2. the `future::Future` value returned is never resolved via + * `Future::get` + * 3. and then the `TcpSocket` passed in to `write_future` leaves * scope and is destructed before the task that runs the libuv write * operation completes. * * As such: If using `write_future`, always be sure to resolve the returned - * `future` so as to ensure libuv doesn't try to access a released write + * `Future` so as to ensure libuv doesn't try to access a released write * handle. Otherwise, use the blocking `tcp::write` function instead. * * # Arguments * - * * sock - a `tcp_socket` to write to + * * sock - a `TcpSocket` to write to * * raw_write_data - a vector of `~[u8]` that will be written to the stream. * This value must remain valid for the duration of the `write` call * * # Returns * - * A `future` value that, once the `write` operation completes, resolves to a - * `result` object with a `nil` value as the `ok` variant, or a `tcp_err_data` - * value as the `err` variant + * A `Future` value that, once the `write` operation completes, resolves to a + * `Result` object with a `nil` value as the `Ok` variant, or a `TcpErrData` + * value as the `Err` variant */ pub fn write_future(sock: &TcpSocket, raw_write_data: ~[u8]) -> future::Future> { @@ -353,14 +353,14 @@ pub fn write_future(sock: &TcpSocket, raw_write_data: ~[u8]) * * # Arguments * - * * sock -- a `net::tcp::tcp_socket` for the connection to read from + * * sock -- a `net::tcp::TcpSocket` for the connection to read from * * # Returns * - * * A `result` instance that will either contain a - * `core::comm::port` that the user can read (and - * optionally, loop on) from until `read_stop` is called, or a - * `tcp_err_data` record + * * A `Result` instance that will either contain a + * `core::comm::Port>` that the user can read + * (and * optionally, loop on) from until `read_stop` is called, or a + * `TcpErrData` record */ pub fn read_start(sock: &TcpSocket) -> result::Result<@Port< @@ -376,7 +376,7 @@ pub fn read_start(sock: &TcpSocket) * * # Arguments * - * * `sock` - a `net::tcp::tcp_socket` that you wish to stop reading on + * * `sock` - a `net::tcp::TcpSocket` that you wish to stop reading on */ pub fn read_stop(sock: &TcpSocket) -> result::Result<(), TcpErrData> { @@ -387,17 +387,17 @@ pub fn read_stop(sock: &TcpSocket) -> } /** - * Reads a single chunk of data from `tcp_socket`; block until data/error + * Reads a single chunk of data from `TcpSocket`; block until data/error * recv'd * * Does a blocking read operation for a single chunk of data from a - * `tcp_socket` until a data arrives or an error is received. The provided + * `TcpSocket` until a data arrives or an error is received. The provided * `timeout_msecs` value is used to raise an error if the timeout period * passes without any data received. * * # Arguments * - * * `sock` - a `net::tcp::tcp_socket` that you wish to read from + * * `sock` - a `net::tcp::TcpSocket` that you wish to read from * * `timeout_msecs` - a `uint` value, in msecs, to wait before dropping the * read attempt. Pass `0u` to wait indefinitely */ @@ -408,12 +408,12 @@ pub fn read(sock: &TcpSocket, timeout_msecs: uint) } /** - * Reads a single chunk of data; returns a `future::future<~[u8]>` + * Reads a single chunk of data; returns a `future::Future<~[u8]>` * immediately * * Does a non-blocking read operation for a single chunk of data from a - * `tcp_socket` and immediately returns a `future` value representing the - * result. When resolving the returned `future`, it will block until data + * `TcpSocket` and immediately returns a `Future` value representing the + * result. When resolving the returned `Future`, it will block until data * arrives or an error is received. The provided `timeout_msecs` * value is used to raise an error if the timeout period passes without any * data received. @@ -421,18 +421,18 @@ pub fn read(sock: &TcpSocket, timeout_msecs: uint) * # Safety * * This function can produce unsafe results if the call to `read_future` is - * made, the `future::future` value returned is never resolved via - * `future::get`, and then the `tcp_socket` passed in to `read_future` leaves + * made, the `future::Future` value returned is never resolved via + * `Future::get`, and then the `TcpSocket` passed in to `read_future` leaves * scope and is destructed before the task that runs the libuv read * operation completes. * * As such: If using `read_future`, always be sure to resolve the returned - * `future` so as to ensure libuv doesn't try to access a released read + * `Future` so as to ensure libuv doesn't try to access a released read * handle. Otherwise, use the blocking `tcp::read` function instead. * * # Arguments * - * * `sock` - a `net::tcp::tcp_socket` that you wish to read from + * * `sock` - a `net::tcp::TcpSocket` that you wish to read from * * `timeout_msecs` - a `uint` value, in msecs, to wait before dropping the * read attempt. Pass `0u` to wait indefinitely */ @@ -445,7 +445,7 @@ fn read_future(sock: &TcpSocket, timeout_msecs: uint) } /** - * Bind an incoming client connection to a `net::tcp::tcp_socket` + * Bind an incoming client connection to a `net::tcp::TcpSocket` * * # Notes * @@ -461,7 +461,7 @@ fn read_future(sock: &TcpSocket, timeout_msecs: uint) * * This implies that a port/chan pair must be used to make sure that the * `new_connect_cb` call blocks until an attempt to create a - * `net::tcp::tcp_socket` is completed. + * `net::tcp::TcpSocket` is completed. * * # Example * @@ -469,49 +469,49 @@ fn read_future(sock: &TcpSocket, timeout_msecs: uint) * a task spawned by the `new_connect_cb` passed into `listen` * * ~~~~~~~~~~~ - * net::tcp::listen(remote_ip, remote_port, backlog) + * do net::tcp::listen(remote_ip, remote_port, backlog, iotask, * // this callback is ran once after the connection is successfully * // set up - * {|kill_ch| + * |kill_ch| { * // pass the kill_ch to your main loop or wherever you want * // to be able to externally kill the server from - * } + * }) * // this callback is ran when a new connection arrives - * {|new_conn, kill_ch| - * let cont_po = core::comm::port::>(); - * let cont_ch = core::comm::chan(cont_po); - * task::spawn {|| + * |new_conn, kill_ch| { + * let (cont_po, cont_ch) = comm::stream::>(); + * do task::spawn { * let accept_result = net::tcp::accept(new_conn); - * if accept_result.is_err() { - * core::comm::send(cont_ch, result::get_err(accept_result)); - * // fail? - * } - * else { - * let sock = result::get(accept_result); - * core::comm::send(cont_ch, true); - * // do work here + * match accept_result { + * Err(accept_error) => { + * cont_ch.send(Some(accept_error)); + * // fail? + * }, + * Ok(sock) => { + * cont_ch.send(None); + * // do work here + * } * } * }; - * match core::comm::recv(cont_po) { + * match cont_po.recv() { * // shut down listen() - * Some(err_data) { core::comm::send(kill_chan, Some(err_data)) } + * Some(err_data) => kill_ch.send(Some(err_data)), * // wait for next connection - * None {} + * None => () * } * }; * ~~~~~~~~~~~ * * # Arguments * - * * `new_conn` - an opaque value used to create a new `tcp_socket` + * * `new_conn` - an opaque value used to create a new `TcpSocket` * * # Returns * - * On success, this function will return a `net::tcp::tcp_socket` as the - * `ok` variant of a `result`. The `net::tcp::tcp_socket` is anchored within + * On success, this function will return a `net::tcp::TcpSocket` as the + * `Ok` variant of a `Result`. The `net::tcp::TcpSocket` is anchored within * the task that `accept` was called within for its lifetime. On failure, - * this function will return a `net::tcp::tcp_err_data` record - * as the `err` variant of a `result`. + * this function will return a `net::tcp::TcpErrData` record + * as the `Err` variant of a `Result`. */ pub fn accept(new_conn: TcpNewConnection) -> result::Result { @@ -600,27 +600,27 @@ pub fn accept(new_conn: TcpNewConnection) * * # Arguments * - * * `host_ip` - a `net::ip::ip_addr` representing a unique IP + * * `host_ip` - a `net::ip::IpAddr` representing a unique IP * (versions 4 or 6) * * `port` - a uint representing the port to listen on * * `backlog` - a uint representing the number of incoming connections * to cache in memory - * * `hl_loop` - a `uv::hl::high_level_loop` that the tcp request will run on + * * `hl_loop` - a `uv_iotask::IoTask` that the tcp request will run on * * `on_establish_cb` - a callback that is evaluated if/when the listener * is successfully established. it takes no parameters * * `new_connect_cb` - a callback to be evaluated, on the libuv thread, * whenever a client attempts to conect on the provided ip/port. the * callback's arguments are: * * `new_conn` - an opaque type that can be passed to - * `net::tcp::accept` in order to be converted to a `tcp_socket`. - * * `kill_ch` - channel of type `core::comm::chan>`. + * `net::tcp::accept` in order to be converted to a `TcpSocket`. + * * `kill_ch` - channel of type `core::comm::Chan>`. * this channel can be used to send a message to cause `listen` to begin * closing the underlying libuv data structures. * * # returns * - * a `result` instance containing empty data of type `()` on a - * successful/normal shutdown, and a `tcp_listen_err_data` enum in the event + * a `Result` instance containing empty data of type `()` on a + * successful/normal shutdown, and a `TcpListenErrData` enum in the event * of listen exiting because of an error */ pub fn listen(host_ip: ip::IpAddr, port: uint, backlog: uint, @@ -799,19 +799,19 @@ fn listen_common(host_ip: ip::IpAddr, port: uint, backlog: uint, /** - * Convert a `net::tcp::tcp_socket` to a `net::tcp::tcp_socket_buf`. + * Convert a `net::tcp::TcpSocket` to a `net::tcp::TcpSocketBuf`. * - * This function takes ownership of a `net::tcp::tcp_socket`, returning it - * stored within a buffered wrapper, which can be converted to a `io::reader` - * or `io::writer` + * This function takes ownership of a `net::tcp::TcpSocket`, returning it + * stored within a buffered wrapper, which can be converted to a `io::Reader` + * or `io::Writer` * * # Arguments * - * * `sock` -- a `net::tcp::tcp_socket` that you want to buffer + * * `sock` -- a `net::tcp::TcpSocket` that you want to buffer * * # Returns * - * A buffered wrapper that you can cast as an `io::reader` or `io::writer` + * A buffered wrapper that you can cast as an `io::Reader` or `io::Writer` */ pub fn socket_buf(sock: TcpSocket) -> TcpSocketBuf { TcpSocketBuf(@TcpBufferedSocketData { @@ -819,7 +819,7 @@ pub fn socket_buf(sock: TcpSocket) -> TcpSocketBuf { }) } -/// Convenience methods extending `net::tcp::tcp_socket` +/// Convenience methods extending `net::tcp::TcpSocket` pub impl TcpSocket { pub fn read_start() -> result::Result<@Port< result::Result<~[u8], TcpErrData>>, TcpErrData> { @@ -862,7 +862,7 @@ pub impl TcpSocket { } } -/// Implementation of `io::reader` trait for a buffered `net::tcp::tcp_socket` +/// Implementation of `io::Reader` trait for a buffered `net::tcp::TcpSocket` impl io::Reader for TcpSocketBuf { fn read(&self, buf: &mut [u8], len: uint) -> uint { if len == 0 { return 0 } @@ -962,7 +962,7 @@ impl io::Reader for TcpSocketBuf { } } -/// Implementation of `io::reader` trait for a buffered `net::tcp::tcp_socket` +/// Implementation of `io::Reader` trait for a buffered `net::tcp::TcpSocket` impl io::Writer for TcpSocketBuf { pub fn write(&self, data: &[const u8]) { unsafe { diff --git a/src/libstd/sync.rs b/src/libstd/sync.rs index 39d3fd569a626..a8a609b1f8ad0 100644 --- a/src/libstd/sync.rs +++ b/src/libstd/sync.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. // @@ -19,7 +19,7 @@ use core::cell::Cell; use core::option; use core::pipes; use core::prelude::*; -use core::private::{Exclusive, exclusive}; +use core::unstable::{Exclusive, exclusive}; use core::ptr; use core::task; use core::util; @@ -87,7 +87,7 @@ enum Sem = Exclusive>; #[doc(hidden)] fn new_sem(count: int, q: Q) -> Sem { Sem(exclusive(SemInner { - mut count: count, waiters: new_waitqueue(), blocked: q })) + count: count, waiters: new_waitqueue(), blocked: q })) } #[doc(hidden)] fn new_sem_and_signal(count: int, num_condvars: uint) diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs index 88e4ade4b826e..a093351c4a763 100644 --- a/src/libstd/treemap.rs +++ b/src/libstd/treemap.rs @@ -10,12 +10,8 @@ //! An ordered map and set implemented as self-balancing binary search //! trees. The only requirement for the types is that the key implements -//! `Ord`, and that the `lt` method provides a total ordering. +//! `TotalOrd`. -use core::container::{Container, Mutable, Map, Set}; -use core::cmp::{Eq, Ord}; -use core::iter::{BaseIter, ReverseIter}; -use core::option::{Option, Some, None}; use core::prelude::*; // This is implemented as an AA tree, which is a simplified variation of @@ -39,7 +35,7 @@ pub struct TreeMap { priv length: uint } -impl Eq for TreeMap { +impl Eq for TreeMap { pure fn eq(&self, other: &TreeMap) -> bool { if self.len() != other.len() { false @@ -61,7 +57,8 @@ impl Eq for TreeMap { } // Lexicographical comparison -pure fn lt(a: &TreeMap, b: &TreeMap) -> bool { +pure fn lt(a: &TreeMap, + b: &TreeMap) -> bool { let mut x = a.iter(); let mut y = b.iter(); @@ -78,7 +75,7 @@ pure fn lt(a: &TreeMap, b: &TreeMap) -> bool { return a_len < b_len; } -impl Ord for TreeMap { +impl Ord for TreeMap { #[inline(always)] pure fn lt(&self, other: &TreeMap) -> bool { lt(self, other) @@ -97,7 +94,7 @@ impl Ord for TreeMap { } } -impl BaseIter<(&K, &V)> for TreeMap { +impl BaseIter<(&K, &V)> for TreeMap { /// Visit all key-value pairs in order pure fn each(&self, f: fn(&(&self/K, &self/V)) -> bool) { each(&self.root, f) @@ -105,14 +102,14 @@ impl BaseIter<(&K, &V)> for TreeMap { pure fn size_hint(&self) -> Option { Some(self.len()) } } -impl ReverseIter<(&K, &V)> for TreeMap { +impl ReverseIter<(&K, &V)> for TreeMap { /// Visit all key-value pairs in reverse order pure fn each_reverse(&self, f: fn(&(&self/K, &self/V)) -> bool) { each_reverse(&self.root, f); } } -impl Container for TreeMap { +impl Container for TreeMap { /// Return the number of elements in the map pure fn len(&self) -> uint { self.length } @@ -120,7 +117,7 @@ impl Container for TreeMap { pure fn is_empty(&self) -> bool { self.root.is_none() } } -impl Mutable for TreeMap { +impl Mutable for TreeMap { /// Clear the map, removing all key-value pairs. fn clear(&mut self) { self.root = None; @@ -128,7 +125,7 @@ impl Mutable for TreeMap { } } -impl Map for TreeMap { +impl Map for TreeMap { /// Return true if the map contains a value for the specified key pure fn contains_key(&self, key: &K) -> bool { self.find(key).is_some() @@ -146,12 +143,10 @@ impl Map for TreeMap { loop { match *current { Some(ref r) => { - if *key < r.key { - current = &r.left; - } else if r.key < *key { - current = &r.right; - } else { - return Some(&r.value); + match key.cmp(&r.key) { + Less => current = &r.left, + Greater => current = &r.right, + Equal => return Some(&r.value) } } None => return None @@ -177,7 +172,7 @@ impl Map for TreeMap { } } -pub impl TreeMap { +pub impl TreeMap { /// Create an empty TreeMap static pure fn new() -> TreeMap { TreeMap{root: None, length: 0} } @@ -207,7 +202,7 @@ pub struct TreeMapIterator { /// Advance the iterator to the next node (in order) and return a /// tuple with a reference to the key and value. If there are no /// more nodes, return `None`. -pub fn map_next(iter: &mut TreeMapIterator/&r) +pub fn map_next(iter: &mut TreeMapIterator/&r) -> Option<(&r/K, &r/V)> { while !iter.stack.is_empty() || iter.node.is_some() { match *iter.node { @@ -226,8 +221,8 @@ 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) { +pub fn map_advance(iter: &mut TreeMapIterator/&r, + f: fn((&r/K, &r/V)) -> bool) { loop { match map_next(iter) { Some(x) => { @@ -242,25 +237,25 @@ pub struct TreeSet { priv map: TreeMap } -impl BaseIter for 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 size_hint(&self) -> Option { Some(self.len()) } } -impl ReverseIter for TreeSet { +impl ReverseIter for TreeSet { /// Visit all values in reverse order pure fn each_reverse(&self, f: fn(&T) -> bool) { self.map.each_key_reverse(f) } } -impl Eq for TreeSet { +impl Eq for TreeSet { pure fn eq(&self, other: &TreeSet) -> bool { self.map == other.map } pure fn ne(&self, other: &TreeSet) -> bool { self.map != other.map } } -impl Ord for TreeSet { +impl Ord for TreeSet { #[inline(always)] pure fn lt(&self, other: &TreeSet) -> bool { self.map < other.map } #[inline(always)] @@ -271,7 +266,7 @@ impl Ord for TreeSet { pure fn gt(&self, other: &TreeSet) -> bool { self.map > other.map } } -impl Container for TreeSet { +impl Container for TreeSet { /// Return the number of elements in the set pure fn len(&self) -> uint { self.map.len() } @@ -279,12 +274,12 @@ impl Container for TreeSet { pure fn is_empty(&self) -> bool { self.map.is_empty() } } -impl Mutable for TreeSet { +impl Mutable for TreeSet { /// Clear the set, removing all values. fn clear(&mut self) { self.map.clear() } } -impl Set for TreeSet { +impl Set for TreeSet { /// Return true if the set contains a value pure fn contains(&self, value: &T) -> bool { self.map.contains_key(value) @@ -309,12 +304,10 @@ impl Set for TreeSet { while a.is_some() && b.is_some() { let a1 = a.unwrap(); let b1 = b.unwrap(); - if a1 < b1 { - a = set_next(&mut x); - } else if b1 < a1 { - b = set_next(&mut y); - } else { - return false; + match a1.cmp(b1) { + Less => a = set_next(&mut x), + Greater => b = set_next(&mut y), + Equal => return false } } } @@ -341,13 +334,12 @@ impl Set for TreeSet { let a1 = a.unwrap(); let b1 = b.unwrap(); - if b1 < a1 { - return false + match a1.cmp(b1) { + Less => (), + Greater => return false, + Equal => b = set_next(&mut y), } - if !(a1 < b1) { - b = set_next(&mut y); - } a = set_next(&mut x); } } @@ -373,11 +365,13 @@ impl Set for TreeSet { let a1 = a.unwrap(); let b1 = b.unwrap(); - if a1 < b1 { + let cmp = a1.cmp(b1); + + if cmp == Less { if !f(a1) { return } a = set_next(&mut x); } else { - if !(b1 < a1) { a = set_next(&mut x) } + if cmp == Equal { a = set_next(&mut x) } b = set_next(&mut y); } } @@ -404,11 +398,13 @@ impl Set for TreeSet { let a1 = a.unwrap(); let b1 = b.unwrap(); - if a1 < b1 { + let cmp = a1.cmp(b1); + + if cmp == Less { if !f(a1) { return } a = set_next(&mut x); } else { - if b1 < a1 { + if cmp == Greater { if !f(b1) { return } } else { a = set_next(&mut x); @@ -434,10 +430,13 @@ impl Set for TreeSet { while a.is_some() && b.is_some() { let a1 = a.unwrap(); let b1 = b.unwrap(); - if a1 < b1 { + + let cmp = a1.cmp(b1); + + if cmp == Less { a = set_next(&mut x); } else { - if !(b1 < a1) { + if cmp == Equal { if !f(a1) { return } } b = set_next(&mut y); @@ -465,12 +464,14 @@ impl Set for TreeSet { let a1 = a.unwrap(); let b1 = b.unwrap(); - if b1 < a1 { + let cmp = a1.cmp(b1); + + if cmp == Greater { if !f(b1) { return } b = set_next(&mut y); } else { if !f(a1) { return } - if !(a1 < b1) { + if cmp == Equal { b = set_next(&mut y); } a = set_next(&mut x); @@ -480,7 +481,7 @@ impl Set for TreeSet { } } -pub impl TreeSet { +pub impl TreeSet { /// Create an empty TreeSet static pure fn new() -> TreeSet { TreeSet{map: TreeMap::new()} } @@ -498,12 +499,12 @@ pub struct TreeSetIterator { /// Advance the iterator to the next node (in order). If this iterator is /// finished, does nothing. -pub fn set_next(iter: &mut TreeSetIterator/&r) -> Option<&r/T> { +pub fn set_next(iter: &mut TreeSetIterator/&r) -> Option<&r/T> { do map_next(&mut iter.iter).map |&(value, _)| { value } } /// Advance the iterator through the set -fn set_advance(iter: &mut TreeSetIterator/&r, +fn set_advance(iter: &mut TreeSetIterator/&r, f: fn(&r/T) -> bool) { do map_advance(&mut iter.iter) |(k, _)| { f(k) } } @@ -518,14 +519,14 @@ struct TreeNode { level: uint } -pub impl TreeNode { +pub impl TreeNode { #[inline(always)] static pure fn new(key: K, value: V) -> TreeNode { TreeNode{key: key, value: value, left: None, right: None, level: 1} } } -pure fn each(node: &r/Option<~TreeNode>, +pure fn each(node: &r/Option<~TreeNode>, f: fn(&(&r/K, &r/V)) -> bool) { do node.iter |x| { each(&x.left, f); @@ -533,7 +534,7 @@ pure fn each(node: &r/Option<~TreeNode>, } } -pure fn each_reverse(node: &r/Option<~TreeNode>, +pure fn each_reverse(node: &r/Option<~TreeNode>, f: fn(&(&r/K, &r/V)) -> bool) { do node.iter |x| { each_reverse(&x.right, f); @@ -542,7 +543,7 @@ pure fn each_reverse(node: &r/Option<~TreeNode>, } // Remove left horizontal link by rotating right -fn skew(node: &mut ~TreeNode) { +fn skew(node: &mut ~TreeNode) { if node.left.map_default(false, |x| x.level == node.level) { let mut save = node.left.swap_unwrap(); node.left <-> save.right; // save.right now None @@ -553,7 +554,7 @@ fn skew(node: &mut ~TreeNode) { // Remove dual horizontal link by rotating left and increasing level of // the parent -fn split(node: &mut ~TreeNode) { +fn split(node: &mut ~TreeNode) { if node.right.map_default(false, |x| x.right.map_default(false, |y| y.level == node.level)) { let mut save = node.right.swap_unwrap(); @@ -564,24 +565,28 @@ fn split(node: &mut ~TreeNode) { } } -fn insert(node: &mut Option<~TreeNode>, key: K, - value: V) -> bool { +fn insert(node: &mut Option<~TreeNode>, key: K, + value: V) -> bool { match *node { Some(ref mut save) => { - if key < save.key { + match key.cmp(&save.key) { + Less => { let inserted = insert(&mut save.left, key, value); skew(save); split(save); inserted - } else if save.key < key { + } + Greater => { let inserted = insert(&mut save.right, key, value); skew(save); split(save); inserted - } else { + } + Equal => { save.key = key; save.value = value; false + } } } None => { @@ -591,8 +596,9 @@ fn insert(node: &mut Option<~TreeNode>, key: K, } } -fn remove(node: &mut Option<~TreeNode>, key: &K) -> bool { - fn heir_swap(node: &mut ~TreeNode, +fn remove(node: &mut Option<~TreeNode>, + key: &K) -> bool { + fn heir_swap(node: &mut ~TreeNode, child: &mut Option<~TreeNode>) { // *could* be done without recursion, but it won't borrow check do child.mutate |mut child| { @@ -611,11 +617,10 @@ fn remove(node: &mut Option<~TreeNode>, key: &K) -> bool { return false // bottom of tree } Some(ref mut save) => { - let (removed, this) = if save.key < *key { - (remove(&mut save.right, key), false) - } else if *key < save.key { - (remove(&mut save.left, key), false) - } else { + let (removed, this) = match key.cmp(&save.key) { + Less => (remove(&mut save.left, key), false), + Greater => (remove(&mut save.right, key), false), + Equal => { if save.left.is_some() { if save.right.is_some() { let mut left = save.left.swap_unwrap(); @@ -637,6 +642,7 @@ fn remove(node: &mut Option<~TreeNode>, key: &K) -> bool { } else { (true, true) } + } }; if !this { @@ -682,12 +688,9 @@ fn remove(node: &mut Option<~TreeNode>, key: &K) -> bool { #[cfg(test)] mod test_treemap { + use core::prelude::*; use super::*; - use core::cmp::{Ord, Eq}; - use core::option::{Some, Option, None}; use core::rand; - use core::str; - use core::vec; #[test] fn find_empty() { @@ -742,7 +745,8 @@ mod test_treemap { assert m.find(&k1) == Some(&v1); } - fn check_equal(ctrl: &[(K, V)], map: &TreeMap) { + fn check_equal(ctrl: &[(K, V)], + map: &TreeMap) { assert ctrl.is_empty() == map.is_empty(); for ctrl.each |x| { let &(k, v) = x; @@ -762,11 +766,11 @@ mod test_treemap { } } - fn check_left(node: &Option<~TreeNode>, - parent: &~TreeNode) { + fn check_left(node: &Option<~TreeNode>, + parent: &~TreeNode) { match *node { Some(ref r) => { - assert r.key < parent.key; + assert r.key.cmp(&parent.key) == Less; assert r.level == parent.level - 1; // left is black check_left(&r.left, r); check_right(&r.right, r, false); @@ -775,11 +779,12 @@ mod test_treemap { } } - fn check_right(node: &Option<~TreeNode>, - parent: &~TreeNode, parent_red: bool) { + fn check_right(node: &Option<~TreeNode>, + parent: &~TreeNode, + parent_red: bool) { match *node { Some(ref r) => { - assert r.key > parent.key; + assert r.key.cmp(&parent.key) == Greater; let red = r.level == parent.level; if parent_red { assert !red } // no dual horizontal links assert red || r.level == parent.level - 1; // right red or black @@ -790,7 +795,7 @@ mod test_treemap { } } - fn check_structure(map: &TreeMap) { + fn check_structure(map: &TreeMap) { match map.root { Some(ref r) => { check_left(&r.left, r); diff --git a/src/libstd/uv_global_loop.rs b/src/libstd/uv_global_loop.rs index 37d9b3221b2d1..52cfc078bace2 100644 --- a/src/libstd/uv_global_loop.rs +++ b/src/libstd/uv_global_loop.rs @@ -18,9 +18,9 @@ use uv_iotask::{IoTask, spawn_iotask}; use core::either::{Left, Right}; use core::libc; use core::comm::{Port, Chan, SharedChan, select2i}; -use core::private::global::{global_data_clone_create, +use core::unstable::global::{global_data_clone_create, global_data_clone}; -use core::private::weak_task::weaken_task; +use core::unstable::weak_task::weaken_task; use core::str; use core::task::{task, SingleThreaded, spawn}; use core::task; diff --git a/src/libsyntax/ext/fmt.rs b/src/libsyntax/ext/fmt.rs index 35b1196252499..e06e43f6287ce 100644 --- a/src/libsyntax/ext/fmt.rs +++ b/src/libsyntax/ext/fmt.rs @@ -24,7 +24,7 @@ use ext::base::*; use ext::base; use ext::build; use ext::build::*; -use private::extfmt::ct::*; +use unstable::extfmt::ct::*; pub fn expand_syntax_ext(cx: ext_ctxt, sp: span, tts: &[ast::token_tree]) -> base::MacResult { @@ -57,7 +57,7 @@ fn pieces_to_expr(cx: ext_ctxt, sp: span, -> @ast::expr { fn make_path_vec(cx: ext_ctxt, ident: @~str) -> ~[ast::ident] { let intr = cx.parse_sess().interner; - return ~[intr.intern(@~"private"), intr.intern(@~"extfmt"), + return ~[intr.intern(@~"unstable"), intr.intern(@~"extfmt"), intr.intern(@~"rt"), intr.intern(ident)]; } fn make_rt_path_expr(cx: ext_ctxt, sp: span, nm: @~str) -> @ast::expr { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 127af5b73ac8a..4c48b49b5d61e 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.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. // @@ -1130,15 +1130,10 @@ pub impl Parser { self.mk_expr(lo, hi, expr_tup(es)) } } else if *self.token == token::LBRACE { - if self.looking_at_record_literal() { - ex = self.parse_record_literal(); - hi = self.span.hi; - } else { - self.bump(); - let blk = self.parse_block_tail(lo, default_blk); - return self.mk_expr(blk.span.lo, blk.span.hi, - expr_block(blk)); - } + self.bump(); + let blk = self.parse_block_tail(lo, default_blk); + return self.mk_expr(blk.span.lo, blk.span.hi, + expr_block(blk)); } else if token::is_bar(&*self.token) { return self.parse_lambda_expr(); } else if self.eat_keyword(&~"if") { @@ -1263,6 +1258,7 @@ pub impl Parser { self.bump(); let mut fields = ~[]; let mut base = None; + fields.push(self.parse_field(token::COLON)); while *self.token != token::RBRACE { if self.try_parse_obsolete_with() { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index f08b042ad6aed..282980f0faaea 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -714,30 +714,26 @@ pub fn print_struct(s: @ps, ident: ast::ident, span: codemap::span) { print_ident(s, ident); - nbsp(s); print_generics(s, generics); if ast_util::struct_def_is_tuple_like(struct_def) { - popen(s); - let mut first = true; - for struct_def.fields.each |field| { - if first { - first = false; - } else { - word_space(s, ~","); - } - - match field.node.kind { - ast::named_field(*) => fail!(~"unexpected named field"), - ast::unnamed_field => { - maybe_print_comment(s, field.span.lo); - print_type(s, field.node.ty); + if !struct_def.fields.is_empty() { + popen(s); + do commasep(s, inconsistent, struct_def.fields) |s, field| { + match field.node.kind { + ast::named_field(*) => fail!(~"unexpected named field"), + ast::unnamed_field => { + maybe_print_comment(s, field.span.lo); + print_type(s, field.node.ty); + } } } + pclose(s); } - pclose(s); word(s.s, ~";"); + end(s); end(s); // close the outer-box } else { + nbsp(s); bopen(s); hardbreak_if_not_bol(s); do struct_def.dtor.iter |dtor| { @@ -1214,7 +1210,7 @@ pub fn print_expr(s: @ps, &&expr: @ast::expr) { print_expr(s, expr); end(s); } - _ => word(s.s, ~",") + _ => (word(s.s, ~",")) } word(s.s, ~"}"); } diff --git a/src/test/compile-fail/autoderef-full-lval.rs b/src/test/compile-fail/autoderef-full-lval.rs index fec5c994de780..cbbf484ad5570 100644 --- a/src/test/compile-fail/autoderef-full-lval.rs +++ b/src/test/compile-fail/autoderef-full-lval.rs @@ -9,18 +9,23 @@ // except according to those terms. // error-pattern: mismatched types -type clam = {x: @int, y: @int}; +struct clam { + x: @int, + y: @int, +} -type fish = {a: @int}; +struct fish { + a: @int, +} fn main() { - let a: clam = {x: @1, y: @2}; - let b: clam = {x: @10, y: @20}; + let a: clam = clam{x: @1, y: @2}; + let b: clam = clam{x: @10, y: @20}; let z: int = a.x + b.y; log(debug, z); assert (z == 21); - let forty: fish = {a: @40}; - let two: fish = {a: @2}; + let forty: fish = fish{a: @40}; + let two: fish = fish{a: @2}; let answer: int = forty.a + two.a; log(debug, answer); assert (answer == 42); diff --git a/src/test/compile-fail/bad-record-pat-2.rs b/src/test/compile-fail/bad-record-pat-2.rs deleted file mode 100644 index 3707dc923c8c1..0000000000000 --- a/src/test/compile-fail/bad-record-pat-2.rs +++ /dev/null @@ -1,13 +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. - -// error-pattern:did not expect a record with a field `q` - -fn main() { match {x: 1, y: 2} { {x: x, q: q} => { } } } diff --git a/src/test/compile-fail/bad-record-pat.rs b/src/test/compile-fail/bad-record-pat.rs deleted file mode 100644 index a7ce8e2ef5c79..0000000000000 --- a/src/test/compile-fail/bad-record-pat.rs +++ /dev/null @@ -1,13 +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. - -// error-pattern:expected a record with 2 fields, found one with 1 - -fn main() { match {x: 1, y: 2} { {x: x} => { } } } diff --git a/src/test/compile-fail/binop-add-tup-assign.rs b/src/test/compile-fail/binop-add-tup-assign.rs deleted file mode 100644 index 3e560c8eaf6eb..0000000000000 --- a/src/test/compile-fail/binop-add-tup-assign.rs +++ /dev/null @@ -1,13 +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. - -// error-pattern:+ cannot be applied to type `{x: bool}` - -fn main() { let x = {x: true}; x += {x: false}; } diff --git a/src/test/compile-fail/binop-add-tup.rs b/src/test/compile-fail/binop-add-tup.rs deleted file mode 100644 index 660e951c84732..0000000000000 --- a/src/test/compile-fail/binop-add-tup.rs +++ /dev/null @@ -1,13 +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. - -// error-pattern:+ cannot be applied to type `{x: bool}` - -fn main() { let x = {x: true} + {x: false}; } diff --git a/src/test/compile-fail/break-outside-loop.rs b/src/test/compile-fail/break-outside-loop.rs index c36d60fdac1be..b3154c9742aca 100644 --- a/src/test/compile-fail/break-outside-loop.rs +++ b/src/test/compile-fail/break-outside-loop.rs @@ -9,9 +9,14 @@ // except according to those terms. // error-pattern:`break` outside of loop + +struct Foo { + t: ~str +} + fn main() { let pth = break; - let rs: {t: ~str} = {t: pth}; + let rs: Foo = Foo{t: pth}; } diff --git a/src/test/compile-fail/fru-extra-field.rs b/src/test/compile-fail/fru-extra-field.rs deleted file mode 100644 index 64d76d6fb7445..0000000000000 --- a/src/test/compile-fail/fru-extra-field.rs +++ /dev/null @@ -1,21 +0,0 @@ -// -*- rust -*- -// 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. - - -// error-pattern: record - -type point = {x: int, y: int}; - -fn main() { - let origin: point = {x: 0, y: 0}; - - let origin3d: point = {z: 0,.. origin}; -} diff --git a/src/test/compile-fail/let-destruct-refutable.rs b/src/test/compile-fail/let-destruct-refutable.rs deleted file mode 100644 index 9bd9db2077993..0000000000000 --- a/src/test/compile-fail/let-destruct-refutable.rs +++ /dev/null @@ -1,21 +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. - -// error-pattern:refutable pattern -// error-pattern:refutable pattern - -enum xx { xx(int), yy, } - -fn main() { - let @{x: xx(x), y: y} = @{x: xx(10), y: 20}; - assert (x + y == 30); - - let [a, b] = ~[1, 2]; -} diff --git a/src/test/compile-fail/noncopyable-match-pattern.rs b/src/test/compile-fail/noncopyable-match-pattern.rs index 9f21d5a647ae1..d90e2f372a84e 100644 --- a/src/test/compile-fail/noncopyable-match-pattern.rs +++ b/src/test/compile-fail/noncopyable-match-pattern.rs @@ -9,7 +9,7 @@ // except according to those terms. fn main() { - let x = Some(private::exclusive(false)); + let x = Some(unstable::exclusive(false)); match x { Some(copy z) => { //~ ERROR copying a value of non-copyable type do z.with |b| { assert !*b; } diff --git a/src/test/compile-fail/nonscalar-cast.rs b/src/test/compile-fail/nonscalar-cast.rs index 54c0f6ca07fa5..d84775d02ac64 100644 --- a/src/test/compile-fail/nonscalar-cast.rs +++ b/src/test/compile-fail/nonscalar-cast.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. // @@ -10,6 +10,10 @@ // error-pattern:non-scalar cast +struct foo { + x:int +} + fn main() { - log(debug, { x: 1 } as int); + log(debug, foo{ x: 1 } as int); } diff --git a/src/test/compile-fail/rec-expected.rs b/src/test/compile-fail/rec-expected.rs deleted file mode 100644 index 962201aa9b966..0000000000000 --- a/src/test/compile-fail/rec-expected.rs +++ /dev/null @@ -1,19 +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. - -type foo = {a: int}; -type bar = {b: int}; - -fn want_foo(f: foo) {} -fn have_bar(b: bar) { - want_foo(b); //~ ERROR expected a record with field `a` -} - -fn main() {} diff --git a/src/test/compile-fail/rec-extend.rs b/src/test/compile-fail/rec-extend.rs deleted file mode 100644 index aa4f9d0501a2a..0000000000000 --- a/src/test/compile-fail/rec-extend.rs +++ /dev/null @@ -1,18 +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. - -// error-pattern:expected `int` but found `bool` - -fn main() { - - let a = {foo: 0i}; - - let b = {foo: true,.. a}; -} diff --git a/src/test/compile-fail/rec-missing-fields.rs b/src/test/compile-fail/rec-missing-fields.rs deleted file mode 100644 index 2ad2f00ee266f..0000000000000 --- a/src/test/compile-fail/rec-missing-fields.rs +++ /dev/null @@ -1,19 +0,0 @@ -// -*- rust -*- -// 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. - - -// error-pattern: mismatched types - -// Issue #51. - -type point = {x: int, y: int}; - -fn main() { let p: point = {x: 10}; log(debug, p.y); } diff --git a/src/test/compile-fail/writing-through-read-alias.rs b/src/test/compile-fail/writing-through-read-alias.rs deleted file mode 100644 index 3b2591c3bfab6..0000000000000 --- a/src/test/compile-fail/writing-through-read-alias.rs +++ /dev/null @@ -1,19 +0,0 @@ -// -*- rust -*- -// 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. - - -// error-pattern:assigning to immutable field - -type point = {x: int, y: int, z: int}; - -fn f(p: point) { p.x = 13; } - -fn main() { let x: point = {x: 10, y: 11, z: 12}; f(x); } diff --git a/src/test/compile-fail/writing-to-immutable-rec.rs b/src/test/compile-fail/writing-to-immutable-rec.rs deleted file mode 100644 index 4cc9dae7debfa..0000000000000 --- a/src/test/compile-fail/writing-to-immutable-rec.rs +++ /dev/null @@ -1,12 +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. - -// error-pattern: assigning to immutable field -fn main() { let r: {x: int} = {x: 1}; r.x = 6; } diff --git a/src/test/pretty/struct-tuple.rs b/src/test/pretty/struct-tuple.rs new file mode 100644 index 0000000000000..0d54848a4a962 --- /dev/null +++ b/src/test/pretty/struct-tuple.rs @@ -0,0 +1,10 @@ +// pp-exact +struct Foo; +struct Bar(int, int); + +fn main() { + struct Foo2; + struct Bar2(int, int, int); + let a = Bar(5, 5); + let b = Foo; +} diff --git a/src/test/run-pass/alt-ref-binding-in-guard-3256.rs b/src/test/run-pass/alt-ref-binding-in-guard-3256.rs index 4474aec3d2e50..d9c348cf99335 100644 --- a/src/test/run-pass/alt-ref-binding-in-guard-3256.rs +++ b/src/test/run-pass/alt-ref-binding-in-guard-3256.rs @@ -9,7 +9,7 @@ // except according to those terms. pub fn main() { - let x = Some(private::exclusive(true)); + let x = Some(unstable::exclusive(true)); match x { Some(ref z) if z.with(|b| *b) => { do z.with |b| { assert *b; } diff --git a/src/test/run-pass/foreign-call-no-runtime.rs b/src/test/run-pass/foreign-call-no-runtime.rs index 5d400e98d41aa..86f23dd5210df 100644 --- a/src/test/run-pass/foreign-call-no-runtime.rs +++ b/src/test/run-pass/foreign-call-no-runtime.rs @@ -1,4 +1,4 @@ -use core::private::run_in_bare_thread; +use core::unstable::run_in_bare_thread; extern { pub fn rust_dbg_call(cb: *u8, diff --git a/src/test/run-pass/lint-structural-records.rs b/src/test/run-pass/lint-structural-records.rs deleted file mode 100644 index e5107ba187cbb..0000000000000 --- a/src/test/run-pass/lint-structural-records.rs +++ /dev/null @@ -1,14 +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. - -#[warn(structural_records)]; -pub fn main() { - let _foo = {x:5}; -} diff --git a/src/test/run-pass/type-use-i1-versus-i8.rs b/src/test/run-pass/type-use-i1-versus-i8.rs index d16b2e3e996ce..d180f6c726043 100644 --- a/src/test/run-pass/type-use-i1-versus-i8.rs +++ b/src/test/run-pass/type-use-i1-versus-i8.rs @@ -11,5 +11,5 @@ pub fn main() { let mut x: bool = false; // this line breaks it - private::intrinsics::move_val_init(&mut x, false); + unstable::intrinsics::move_val_init(&mut x, false); } diff --git a/src/test/run-pass/uniq-cc-generic.rs b/src/test/run-pass/uniq-cc-generic.rs index 1b602ab7d3009..def49ef0f8c33 100644 --- a/src/test/run-pass/uniq-cc-generic.rs +++ b/src/test/run-pass/uniq-cc-generic.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. // @@ -24,7 +24,7 @@ fn make_uniq_closure(a: A) -> fn~() -> uint { fn empty_pointy() -> @mut Pointy { return @mut Pointy { - mut a : none, + a : none, d : make_uniq_closure(~"hi") } }