Merge remote-tracking branch 'remotes/origin/incoming' into incoming
This commit is contained in:
commit
5515fd5c8c
58 changed files with 520 additions and 593 deletions
|
@ -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.
|
||||
|
|
142
doc/rust.md
142
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::<u32>() == 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: T) {}
|
||||
Point {x: 10f, y: 20f};
|
||||
TuplePoint(10f, 20f);
|
||||
let u = game::User {name: "Joe", age: 35u, score: 100_000};
|
||||
some_fn::<Cookie>(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::<f32>("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<int> = 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;
|
||||
~~~~~~~~
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<T: Ord>(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<T:Ord>(v1: T, v2: T) -> T {
|
|||
pub pure fn max<T:Ord>(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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<T: Owned> Peekable<T> for PortSet<T> {
|
|||
}
|
||||
|
||||
/// A channel that can be shared between many senders.
|
||||
pub type SharedChan<T> = private::Exclusive<Chan<T>>;
|
||||
pub type SharedChan<T> = unstable::Exclusive<Chan<T>>;
|
||||
|
||||
impl<T: Owned> GenericChan<T> for SharedChan<T> {
|
||||
fn send(x: T) {
|
||||
|
@ -268,7 +268,7 @@ impl<T: Owned> GenericSmartChan<T> for SharedChan<T> {
|
|||
|
||||
/// Converts a `chan` into a `shared_chan`.
|
||||
pub fn SharedChan<T:Owned>(c: Chan<T>) -> SharedChan<T> {
|
||||
private::exclusive(c)
|
||||
unstable::exclusive(c)
|
||||
}
|
||||
|
||||
/// Receive a message from one of two endpoints.
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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<A> {
|
|||
|
||||
/// Creates a new, empty dvec
|
||||
pub pure fn DVec<A>() -> DVec<A> {
|
||||
DVec {mut data: ~[]}
|
||||
DVec {data: ~[]}
|
||||
}
|
||||
|
||||
/// Creates a new dvec with a single element
|
||||
pub pure fn from_elem<A>(e: A) -> DVec<A> {
|
||||
DVec {mut data: ~[e]}
|
||||
DVec {data: ~[e]}
|
||||
}
|
||||
|
||||
/// Creates a new dvec with the contents of a vector
|
||||
pub pure fn from_vec<A>(v: ~[A]) -> DVec<A> {
|
||||
DVec {mut data: v}
|
||||
DVec {data: v}
|
||||
}
|
||||
|
||||
/// Consumes the vector and returns its contents
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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<T>(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<SharedValue>;
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<T:Ord> 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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<T:Durable> LocalData for @T { }
|
||||
|
|
|
@ -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<Option<TaskGroupData>>;
|
||||
type TaskGroupArc = unstable::Exclusive<Option<TaskGroupData>>;
|
||||
|
||||
type TaskGroupInner = &mut Option<TaskGroupData>;
|
||||
|
||||
|
@ -153,7 +153,7 @@ struct AncestorNode {
|
|||
mut ancestors: AncestorList,
|
||||
}
|
||||
|
||||
enum AncestorList = Option<private::Exclusive<AncestorNode>>;
|
||||
enum AncestorList = Option<unstable::Exclusive<AncestorNode>>;
|
||||
|
||||
// Accessors for taskgroup arcs and ancestor arcs that wrap the unsafety.
|
||||
#[inline(always)]
|
||||
|
@ -162,7 +162,7 @@ fn access_group<U>(x: &TaskGroupArc, blk: fn(TaskGroupInner) -> U) -> U {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn access_ancestors<U>(x: &private::Exclusive<AncestorNode>,
|
||||
fn access_ancestors<U>(x: &unstable::Exclusive<AncestorNode>,
|
||||
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,
|
||||
|
|
|
@ -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;
|
|
@ -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;
|
||||
|
|
@ -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;
|
|
@ -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")]
|
|
@ -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};
|
||||
|
|
@ -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<T>(v: &r/[T], blk: fn(i: uint, v: &r/T) -> bool) {
|
|||
* Both vectors must have the same length
|
||||
*/
|
||||
#[inline]
|
||||
pub fn each2<U, T>(v1: &[U], v2: &[T], f: fn(u: &U, t: &T) -> bool) {
|
||||
pub pure fn each2<U, T>(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<T:Eq> Eq for @[T] {
|
|||
|
||||
// Lexicographical comparison
|
||||
|
||||
pure fn cmp<T: TotalOrd>(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<T: TotalOrd> TotalOrd for &[T] {
|
||||
#[inline(always)]
|
||||
pure fn cmp(&self, other: & &self/[T]) -> Ordering { cmp(*self, *other) }
|
||||
}
|
||||
|
||||
#[cfg(notest)]
|
||||
impl<T: TotalOrd> TotalOrd for ~[T] {
|
||||
#[inline(always)]
|
||||
pure fn cmp(&self, other: &~[T]) -> Ordering { cmp(*self, *other) }
|
||||
}
|
||||
|
||||
#[cfg(notest)]
|
||||
impl<T: TotalOrd> TotalOrd for @[T] {
|
||||
#[inline(always)]
|
||||
pure fn cmp(&self, other: &@[T]) -> Ordering { cmp(*self, *other) }
|
||||
}
|
||||
|
||||
pure fn lt<T:Ord>(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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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<result::Result<(), TcpErrData>> {
|
||||
|
@ -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<tcp_read_result>` 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<Result<~[u8], TcpErrData>>` 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::<Option<tcp_err_data>>();
|
||||
* let cont_ch = core::comm::chan(cont_po);
|
||||
* task::spawn {||
|
||||
* |new_conn, kill_ch| {
|
||||
* let (cont_po, cont_ch) = comm::stream::<option::Option<TcpErrData>>();
|
||||
* 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<TcpSocket, TcpErrData> {
|
||||
|
@ -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<Option<tcp_err_data>>`.
|
||||
* `net::tcp::accept` in order to be converted to a `TcpSocket`.
|
||||
* * `kill_ch` - channel of type `core::comm::Chan<Option<tcp_err_data>>`.
|
||||
* 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 {
|
||||
|
|
|
@ -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<Q> = Exclusive<SemInner<Q>>;
|
|||
#[doc(hidden)]
|
||||
fn new_sem<Q:Owned>(count: int, q: Q) -> Sem<Q> {
|
||||
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)
|
||||
|
|
|
@ -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<K, V> {
|
|||
priv length: uint
|
||||
}
|
||||
|
||||
impl<K:Eq + Ord,V:Eq> Eq for TreeMap<K, V> {
|
||||
impl<K: Eq + TotalOrd, V: Eq> Eq for TreeMap<K, V> {
|
||||
pure fn eq(&self, other: &TreeMap<K, V>) -> bool {
|
||||
if self.len() != other.len() {
|
||||
false
|
||||
|
@ -61,7 +57,8 @@ impl<K:Eq + Ord,V:Eq> Eq for TreeMap<K, V> {
|
|||
}
|
||||
|
||||
// Lexicographical comparison
|
||||
pure fn lt<K:Ord,V>(a: &TreeMap<K, V>, b: &TreeMap<K, V>) -> bool {
|
||||
pure fn lt<K: Ord + TotalOrd, V>(a: &TreeMap<K, V>,
|
||||
b: &TreeMap<K, V>) -> bool {
|
||||
let mut x = a.iter();
|
||||
let mut y = b.iter();
|
||||
|
||||
|
@ -78,7 +75,7 @@ pure fn lt<K:Ord,V>(a: &TreeMap<K, V>, b: &TreeMap<K, V>) -> bool {
|
|||
return a_len < b_len;
|
||||
}
|
||||
|
||||
impl<K:Ord,V> Ord for TreeMap<K, V> {
|
||||
impl<K: Ord + TotalOrd, V> Ord for TreeMap<K, V> {
|
||||
#[inline(always)]
|
||||
pure fn lt(&self, other: &TreeMap<K, V>) -> bool {
|
||||
lt(self, other)
|
||||
|
@ -97,7 +94,7 @@ impl<K:Ord,V> Ord for TreeMap<K, V> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<K:Ord,V> BaseIter<(&K, &V)> for TreeMap<K, V> {
|
||||
impl<K: TotalOrd, V> BaseIter<(&K, &V)> for TreeMap<K, V> {
|
||||
/// 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<K:Ord,V> BaseIter<(&K, &V)> for TreeMap<K, V> {
|
|||
pure fn size_hint(&self) -> Option<uint> { Some(self.len()) }
|
||||
}
|
||||
|
||||
impl<K:Ord,V> ReverseIter<(&K, &V)> for TreeMap<K, V> {
|
||||
impl<K: TotalOrd, V> ReverseIter<(&K, &V)> for TreeMap<K, V> {
|
||||
/// 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<K:Ord,V> Container for TreeMap<K, V> {
|
||||
impl<K: TotalOrd, V> Container for TreeMap<K, V> {
|
||||
/// Return the number of elements in the map
|
||||
pure fn len(&self) -> uint { self.length }
|
||||
|
||||
|
@ -120,7 +117,7 @@ impl<K:Ord,V> Container for TreeMap<K, V> {
|
|||
pure fn is_empty(&self) -> bool { self.root.is_none() }
|
||||
}
|
||||
|
||||
impl<K:Ord,V> Mutable for TreeMap<K, V> {
|
||||
impl<K: TotalOrd, V> Mutable for TreeMap<K, V> {
|
||||
/// Clear the map, removing all key-value pairs.
|
||||
fn clear(&mut self) {
|
||||
self.root = None;
|
||||
|
@ -128,7 +125,7 @@ impl<K:Ord,V> Mutable for TreeMap<K, V> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<K:Ord,V> Map<K, V> for TreeMap<K, V> {
|
||||
impl<K: TotalOrd, V> Map<K, V> for TreeMap<K, V> {
|
||||
/// 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<K:Ord,V> Map<K, V> for TreeMap<K, V> {
|
|||
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<K:Ord,V> Map<K, V> for TreeMap<K, V> {
|
|||
}
|
||||
}
|
||||
|
||||
pub impl <K:Ord,V> TreeMap<K, V> {
|
||||
pub impl<K: TotalOrd, V> TreeMap<K, V> {
|
||||
/// Create an empty TreeMap
|
||||
static pure fn new() -> TreeMap<K, V> { TreeMap{root: None, length: 0} }
|
||||
|
||||
|
@ -207,7 +202,7 @@ pub struct TreeMapIterator<K, V> {
|
|||
/// 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<K: Ord, V>(iter: &mut TreeMapIterator/&r<K, V>)
|
||||
pub fn map_next<K, V>(iter: &mut TreeMapIterator/&r<K, V>)
|
||||
-> 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<K: Ord, V>(iter: &mut TreeMapIterator/&r<K, V>)
|
|||
}
|
||||
|
||||
/// Advance the iterator through the map
|
||||
pub fn map_advance<K: Ord, V>(iter: &mut TreeMapIterator/&r<K, V>,
|
||||
f: fn((&r/K, &r/V)) -> bool) {
|
||||
pub fn map_advance<K, V>(iter: &mut TreeMapIterator/&r<K, V>,
|
||||
f: fn((&r/K, &r/V)) -> bool) {
|
||||
loop {
|
||||
match map_next(iter) {
|
||||
Some(x) => {
|
||||
|
@ -242,25 +237,25 @@ pub struct TreeSet<T> {
|
|||
priv map: TreeMap<T, ()>
|
||||
}
|
||||
|
||||
impl<T:Ord> BaseIter<T> for TreeSet<T> {
|
||||
impl<T: TotalOrd> BaseIter<T> for TreeSet<T> {
|
||||
/// Visit all values in order
|
||||
pure fn each(&self, f: fn(&T) -> bool) { self.map.each_key(f) }
|
||||
pure fn size_hint(&self) -> Option<uint> { Some(self.len()) }
|
||||
}
|
||||
|
||||
impl<T:Ord> ReverseIter<T> for TreeSet<T> {
|
||||
impl<T: TotalOrd> ReverseIter<T> for TreeSet<T> {
|
||||
/// Visit all values in reverse order
|
||||
pure fn each_reverse(&self, f: fn(&T) -> bool) {
|
||||
self.map.each_key_reverse(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Eq + Ord> Eq for TreeSet<T> {
|
||||
impl<T: Eq + TotalOrd> Eq for TreeSet<T> {
|
||||
pure fn eq(&self, other: &TreeSet<T>) -> bool { self.map == other.map }
|
||||
pure fn ne(&self, other: &TreeSet<T>) -> bool { self.map != other.map }
|
||||
}
|
||||
|
||||
impl<T:Ord> Ord for TreeSet<T> {
|
||||
impl<T: Ord + TotalOrd> Ord for TreeSet<T> {
|
||||
#[inline(always)]
|
||||
pure fn lt(&self, other: &TreeSet<T>) -> bool { self.map < other.map }
|
||||
#[inline(always)]
|
||||
|
@ -271,7 +266,7 @@ impl<T:Ord> Ord for TreeSet<T> {
|
|||
pure fn gt(&self, other: &TreeSet<T>) -> bool { self.map > other.map }
|
||||
}
|
||||
|
||||
impl<T:Ord> Container for TreeSet<T> {
|
||||
impl<T: TotalOrd> Container for TreeSet<T> {
|
||||
/// Return the number of elements in the set
|
||||
pure fn len(&self) -> uint { self.map.len() }
|
||||
|
||||
|
@ -279,12 +274,12 @@ impl<T:Ord> Container for TreeSet<T> {
|
|||
pure fn is_empty(&self) -> bool { self.map.is_empty() }
|
||||
}
|
||||
|
||||
impl<T:Ord> Mutable for TreeSet<T> {
|
||||
impl<T: TotalOrd> Mutable for TreeSet<T> {
|
||||
/// Clear the set, removing all values.
|
||||
fn clear(&mut self) { self.map.clear() }
|
||||
}
|
||||
|
||||
impl<T:Ord> Set<T> for TreeSet<T> {
|
||||
impl<T: TotalOrd> Set<T> for TreeSet<T> {
|
||||
/// 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<T:Ord> Set<T> for TreeSet<T> {
|
|||
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<T:Ord> Set<T> for TreeSet<T> {
|
|||
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<T:Ord> Set<T> for TreeSet<T> {
|
|||
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<T:Ord> Set<T> for TreeSet<T> {
|
|||
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<T:Ord> Set<T> for TreeSet<T> {
|
|||
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<T:Ord> Set<T> for TreeSet<T> {
|
|||
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<T:Ord> Set<T> for TreeSet<T> {
|
|||
}
|
||||
}
|
||||
|
||||
pub impl <T:Ord> TreeSet<T> {
|
||||
pub impl <T: TotalOrd> TreeSet<T> {
|
||||
/// Create an empty TreeSet
|
||||
static pure fn new() -> TreeSet<T> { TreeSet{map: TreeMap::new()} }
|
||||
|
||||
|
@ -498,12 +499,12 @@ pub struct TreeSetIterator<T> {
|
|||
|
||||
/// Advance the iterator to the next node (in order). If this iterator is
|
||||
/// finished, does nothing.
|
||||
pub fn set_next<T: Ord>(iter: &mut TreeSetIterator/&r<T>) -> Option<&r/T> {
|
||||
pub fn set_next<T>(iter: &mut TreeSetIterator/&r<T>) -> Option<&r/T> {
|
||||
do map_next(&mut iter.iter).map |&(value, _)| { value }
|
||||
}
|
||||
|
||||
/// Advance the iterator through the set
|
||||
fn set_advance<T: Ord>(iter: &mut TreeSetIterator/&r<T>,
|
||||
fn set_advance<T>(iter: &mut TreeSetIterator/&r<T>,
|
||||
f: fn(&r/T) -> bool) {
|
||||
do map_advance(&mut iter.iter) |(k, _)| { f(k) }
|
||||
}
|
||||
|
@ -518,14 +519,14 @@ struct TreeNode<K, V> {
|
|||
level: uint
|
||||
}
|
||||
|
||||
pub impl <K:Ord,V> TreeNode<K, V> {
|
||||
pub impl<K: TotalOrd, V> TreeNode<K, V> {
|
||||
#[inline(always)]
|
||||
static pure fn new(key: K, value: V) -> TreeNode<K, V> {
|
||||
TreeNode{key: key, value: value, left: None, right: None, level: 1}
|
||||
}
|
||||
}
|
||||
|
||||
pure fn each<K:Ord,V>(node: &r/Option<~TreeNode<K, V>>,
|
||||
pure fn each<K: TotalOrd, V>(node: &r/Option<~TreeNode<K, V>>,
|
||||
f: fn(&(&r/K, &r/V)) -> bool) {
|
||||
do node.iter |x| {
|
||||
each(&x.left, f);
|
||||
|
@ -533,7 +534,7 @@ pure fn each<K:Ord,V>(node: &r/Option<~TreeNode<K, V>>,
|
|||
}
|
||||
}
|
||||
|
||||
pure fn each_reverse<K:Ord,V>(node: &r/Option<~TreeNode<K, V>>,
|
||||
pure fn each_reverse<K: TotalOrd, V>(node: &r/Option<~TreeNode<K, V>>,
|
||||
f: fn(&(&r/K, &r/V)) -> bool) {
|
||||
do node.iter |x| {
|
||||
each_reverse(&x.right, f);
|
||||
|
@ -542,7 +543,7 @@ pure fn each_reverse<K:Ord,V>(node: &r/Option<~TreeNode<K, V>>,
|
|||
}
|
||||
|
||||
// Remove left horizontal link by rotating right
|
||||
fn skew<K:Ord,V>(node: &mut ~TreeNode<K, V>) {
|
||||
fn skew<K: TotalOrd, V>(node: &mut ~TreeNode<K, V>) {
|
||||
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<K:Ord,V>(node: &mut ~TreeNode<K, V>) {
|
|||
|
||||
// Remove dual horizontal link by rotating left and increasing level of
|
||||
// the parent
|
||||
fn split<K:Ord,V>(node: &mut ~TreeNode<K, V>) {
|
||||
fn split<K: TotalOrd, V>(node: &mut ~TreeNode<K, V>) {
|
||||
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<K:Ord,V>(node: &mut ~TreeNode<K, V>) {
|
|||
}
|
||||
}
|
||||
|
||||
fn insert<K:Ord,V>(node: &mut Option<~TreeNode<K, V>>, key: K,
|
||||
value: V) -> bool {
|
||||
fn insert<K: TotalOrd, V>(node: &mut Option<~TreeNode<K, V>>, 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<K:Ord,V>(node: &mut Option<~TreeNode<K, V>>, key: K,
|
|||
}
|
||||
}
|
||||
|
||||
fn remove<K:Ord,V>(node: &mut Option<~TreeNode<K, V>>, key: &K) -> bool {
|
||||
fn heir_swap<K:Ord,V>(node: &mut ~TreeNode<K, V>,
|
||||
fn remove<K: TotalOrd, V>(node: &mut Option<~TreeNode<K, V>>,
|
||||
key: &K) -> bool {
|
||||
fn heir_swap<K: TotalOrd, V>(node: &mut ~TreeNode<K, V>,
|
||||
child: &mut Option<~TreeNode<K, V>>) {
|
||||
// *could* be done without recursion, but it won't borrow check
|
||||
do child.mutate |mut child| {
|
||||
|
@ -611,11 +617,10 @@ fn remove<K:Ord,V>(node: &mut Option<~TreeNode<K, V>>, 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<K:Ord,V>(node: &mut Option<~TreeNode<K, V>>, key: &K) -> bool {
|
|||
} else {
|
||||
(true, true)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if !this {
|
||||
|
@ -682,12 +688,9 @@ fn remove<K:Ord,V>(node: &mut Option<~TreeNode<K, V>>, 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<K:Eq + Ord,V:Eq>(ctrl: &[(K, V)], map: &TreeMap<K, V>) {
|
||||
fn check_equal<K: Eq + TotalOrd, V: Eq>(ctrl: &[(K, V)],
|
||||
map: &TreeMap<K, V>) {
|
||||
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<K:Ord,V>(node: &Option<~TreeNode<K, V>>,
|
||||
parent: &~TreeNode<K, V>) {
|
||||
fn check_left<K: TotalOrd, V>(node: &Option<~TreeNode<K, V>>,
|
||||
parent: &~TreeNode<K, V>) {
|
||||
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<K:Ord,V>(node: &Option<~TreeNode<K, V>>,
|
||||
parent: &~TreeNode<K, V>, parent_red: bool) {
|
||||
fn check_right<K: TotalOrd, V>(node: &Option<~TreeNode<K, V>>,
|
||||
parent: &~TreeNode<K, V>,
|
||||
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<K:Ord,V>(map: &TreeMap<K, V>) {
|
||||
fn check_structure<K: TotalOrd, V>(map: &TreeMap<K, V>) {
|
||||
match map.root {
|
||||
Some(ref r) => {
|
||||
check_left(&r.left, r);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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, ~"}");
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern:did not expect a record with a field `q`
|
||||
|
||||
fn main() { match {x: 1, y: 2} { {x: x, q: q} => { } } }
|
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern:expected a record with 2 fields, found one with 1
|
||||
|
||||
fn main() { match {x: 1, y: 2} { {x: x} => { } } }
|
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern:+ cannot be applied to type `{x: bool}`
|
||||
|
||||
fn main() { let x = {x: true}; x += {x: false}; }
|
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern:+ cannot be applied to type `{x: bool}`
|
||||
|
||||
fn main() { let x = {x: true} + {x: false}; }
|
|
@ -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};
|
||||
|
||||
}
|
||||
|
|
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
|
||||
// error-pattern: record
|
||||
|
||||
type point = {x: int, y: int};
|
||||
|
||||
fn main() {
|
||||
let origin: point = {x: 0, y: 0};
|
||||
|
||||
let origin3d: point = {z: 0,.. origin};
|
||||
}
|
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// 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];
|
||||
}
|
|
@ -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; }
|
||||
|
|
|
@ -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
|
||||
|
||||
fn main() {
|
||||
log(debug, { x: 1 } as int);
|
||||
struct foo {
|
||||
x:int
|
||||
}
|
||||
|
||||
fn main() {
|
||||
log(debug, foo{ x: 1 } as int);
|
||||
}
|
||||
|
|
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
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() {}
|
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern:expected `int` but found `bool`
|
||||
|
||||
fn main() {
|
||||
|
||||
let a = {foo: 0i};
|
||||
|
||||
let b = {foo: true,.. a};
|
||||
}
|
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
|
||||
// error-pattern: mismatched types
|
||||
|
||||
// Issue #51.
|
||||
|
||||
type point = {x: int, y: int};
|
||||
|
||||
fn main() { let p: point = {x: 10}; log(debug, p.y); }
|
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
|
||||
// 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); }
|
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern: assigning to immutable field
|
||||
fn main() { let r: {x: int} = {x: 1}; r.x = 6; }
|
10
src/test/pretty/struct-tuple.rs
Normal file
10
src/test/pretty/struct-tuple.rs
Normal file
|
@ -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;
|
||||
}
|
|
@ -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; }
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[warn(structural_records)];
|
||||
pub fn main() {
|
||||
let _foo = {x:5};
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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:Owned + Copy>(a: A) -> fn~() -> uint {
|
|||
|
||||
fn empty_pointy() -> @mut Pointy {
|
||||
return @mut Pointy {
|
||||
mut a : none,
|
||||
a : none,
|
||||
d : make_uniq_closure(~"hi")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue