Merge remote-tracking branch 'remotes/origin/incoming' into incoming

This commit is contained in:
Erick Tryzelaar 2013-03-02 07:12:53 -08:00
commit 5515fd5c8c
58 changed files with 520 additions and 593 deletions

View file

@ -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.

View file

@ -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;
~~~~~~~~

View file

@ -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;
}

View file

@ -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;

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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.

View file

@ -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 */

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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)
}
}

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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;
}
}

View file

@ -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 { }

View file

@ -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,

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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")]

View file

@ -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};

View file

@ -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:

View file

@ -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;

View file

@ -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 {

View file

@ -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 {

View file

@ -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)

View file

@ -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);

View file

@ -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;

View file

@ -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 {

View file

@ -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() {

View file

@ -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, ~"}");
}

View file

@ -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);

View file

@ -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} => { } } }

View file

@ -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} => { } } }

View file

@ -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}; }

View file

@ -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}; }

View file

@ -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};
}

View file

@ -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};
}

View file

@ -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];
}

View file

@ -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; }

View file

@ -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);
}

View file

@ -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() {}

View file

@ -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};
}

View file

@ -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); }

View file

@ -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); }

View file

@ -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; }

View 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;
}

View file

@ -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; }

View file

@ -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,

View file

@ -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};
}

View file

@ -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);
}

View file

@ -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")
}
}