diff --git a/AUTHORS.txt b/AUTHORS.txt index e4199ac5c57b4..645d6be9babee 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -57,6 +57,7 @@ Grahame Bowland Haitao Li Huon Wilson Ian D. Bollinger +Isaac Aggrey Ivano Coppola Jacob Harris Cryer Kragh Jacob Parker diff --git a/README.md b/README.md index 9f875ac346e1c..1c0a86b1fdfbb 100644 --- a/README.md +++ b/README.md @@ -42,9 +42,9 @@ packages: Assuming you're on a relatively modern *nix system and have met the prerequisites, something along these lines should work. - $ wget http://dl.rust-lang.org/dist/rust-0.4.tar.gz - $ tar -xzf rust-0.4.tar.gz - $ cd rust-0.4 + $ wget http://dl.rust-lang.org/dist/rust-0.5.tar.gz + $ tar -xzf rust-0.5.tar.gz + $ cd rust-0.5 $ ./configure $ make && make install @@ -59,8 +59,8 @@ When complete, `make install` will place several programs into API-documentation tool, and `cargo`, the Rust package manager. [wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust -[tarball]: http://dl.rust-lang.org/dist/rust-0.4.tar.gz -[win-exe]: http://dl.rust-lang.org/dist/rust-0.4-install.exe +[tarball]: http://dl.rust-lang.org/dist/rust-0.5.tar.gz +[win-exe]: http://dl.rust-lang.org/dist/rust-0.5-install.exe ## License diff --git a/RELEASES.txt b/RELEASES.txt index cafbe059b4435..b3b81964d85ad 100644 --- a/RELEASES.txt +++ b/RELEASES.txt @@ -26,6 +26,9 @@ Version 0.5 (December 2012) * `&T` may now be coerced to `*T` * Coercions happen in `let` statements as well as function calls * `use` statements now take crate-relative paths + * The module and type namespaces have been merged so that static + method names can be resolved under the trait in which they are + declared * Improved support for language features * Trait inheritance works in many scenarios diff --git a/doc/rust.md b/doc/rust.md index c22756657b76a..b16c56be63361 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -1072,6 +1072,15 @@ let p = Point {x: 10, y: 11}; let px: int = p.x; ~~~~ +A _tuple structure_ is a nominal [tuple type](#tuple-types), also defined with the keyword `struct`. +For example: + +~~~~ +struct Point(int, int); +let p = Point(10, 11); +let px: int = match p { Point(x, _) => x }; +~~~~ + ### Enumerations An _enumeration_ is a simultaneous definition of a nominal [enumerated type](#enumerated-types) as well as a set of *constructors*, @@ -1195,8 +1204,34 @@ Values with a trait type can have [methods called](#method-call-expressions) on for any method in the trait, and can be used to instantiate type parameters that are bounded by the trait. -Trait methods may be static. Currently implementations of static methods behave like -functions declared in the implentation's module. +Trait methods may be static, +which means that they lack a `self` argument. +This means that they can only be called with function call syntax (`f(x)`) +and not method call syntax (`obj.f()`). +The way to refer to the name of a static method is to qualify it with the trait name, +treating the trait name like a module. +For example: + +~~~~ +trait Num { + static pure fn from_int(n: int) -> self; +} +impl float: Num { + static pure fn from_int(n: int) -> float { n as float } +} +let x: float = Num::from_int(42); +~~~~ + +Traits can have _constraints_ for example, in + +~~~~ +trait Shape { fn area() -> float; } +trait Circle : Shape { fn radius() -> float; } +~~~~ + +the syntax `Circle : Shape` means that types that implement `Circle` must also have an implementation for `Shape`. +In an implementation of `Circle` for a given type `T`, methods can refer to `Shape` methods, +since the typechecker checks that any type with an implementation of `Circle` also has an implementation of `Shape`. ### Implementations @@ -1465,6 +1500,14 @@ when evaluated in an _rvalue context_, it denotes the value held _in_ that memor When an rvalue is used in lvalue context, a temporary un-named lvalue is created and used instead. A temporary's lifetime equals the largest lifetime of any borrowed pointer that points to it. +#### Moved and copied types + +When a [local variable](#memory-slots) is used as an [rvalue](#lvalues-rvalues-and-temporaries) +the variable will either be [moved](#move-expressions) or [copied](#copy-expressions), +depending on its type. +For types that contain mutable fields or [owning pointers](#owning-pointers), the variable is moved. +All other types are copied. + ### Literal expressions @@ -1495,6 +1538,53 @@ values. ("a", 4u, true); ~~~~~~~~ +### Structure expressions + +~~~~~~~~{.ebnf .gram} +struct_expr : expr_path '{' ident ':' expr + [ ',' ident ':' expr ] * + [ ".." expr ] '}' | + expr_path '(' expr + [ ',' expr ] * ')' +~~~~~~~~ + +There are several forms of structure expressions. +A _structure expression_ consists of the [path](#paths) of a [structure item](#structures), +followed by a brace-enclosed list of one or more comma-separated name-value pairs, +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), +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. + +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, mut score: uint } } +# use game; +Point {x: 10f, y: 20f}; +TuplePoint(10f, 20f); +let u = game::User {name: "Joe", age: 35u, mut score: 100_000}; +~~~~ + +A structure expression forms a new value of the named structure type. + +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. +A new structure 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. + +~~~~ +# struct Point3d { x: int, y: int, z: int } +let base = Point3d {x: 1, y: 2, z: 3}; +Point3d {y: 0, z: 10, .. base}; +~~~~ + ### Record expressions ~~~~~~~~{.ebnf .gram} @@ -1503,9 +1593,11 @@ 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 -(including keywords), and is separated from its value expression by a +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. @@ -1787,7 +1879,7 @@ y.z <-> b.c; An _assignment expression_ consists of an [lvalue](#lvalues-rvalues-and-temporaries) expression followed by an equals sign (`=`) and an [rvalue](#lvalues-rvalues-and-temporaries) expression. -Evaluating an assignment expression copies the expression on the right-hand side and stores it in the location on the left-hand side. +Evaluating an assignment expression [either copies or moves](#moved-and-copied-types) its right-hand operand to its left-hand operand. ~~~~ # let mut x = 0; @@ -1860,7 +1952,7 @@ copy. as are raw and borrowed pointers. [Owned boxes](#pointer-types), [owned vectors](#vector-types) and similar owned types are deep-copied. -Since the binary [assignment operator](#assignment-expressions) `=` performs a copy implicitly, +Since the binary [assignment operator](#assignment-expressions) `=` performs a copy or move implicitly, the unary copy operator is typically only used to cause an argument to a function to be copied and passed by value. An example of a copy expression: @@ -1884,13 +1976,17 @@ move_expr : "move" expr ; ~~~~~~~~ A _unary move expression_ is similar to a [unary copy](#unary-copy-expressions) expression, -except that it can only be applied to an [lvalue](#lvalues-rvalues-and-temporaries), +except that it can only be applied to a [local variable](#memory-slots), and it performs a _move_ on its operand, rather than a copy. That is, the memory location denoted by its operand is de-initialized after evaluation, and the resulting value is a shallow copy of the operand, even if the operand is an [owning type](#type-kinds). +> **Note:** In future versions of Rust, `move` may be removed as a separate operator; +> moves are now [automatically performed](#moved-and-copied-types) for most cases `move` would be appropriate. + + ### Call expressions ~~~~~~~~ {.abnf .gram} @@ -2520,6 +2616,7 @@ 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. ### Enumerated types diff --git a/doc/tutorial.md b/doc/tutorial.md index 7ba24197678e9..6ea0aa67e4e1e 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -100,9 +100,9 @@ If you've fulfilled those prerequisites, something along these lines should work. ~~~~ {.notrust} -$ curl -O http://dl.rust-lang.org/dist/rust-0.4.tar.gz -$ tar -xzf rust-0.4.tar.gz -$ cd rust-0.4 +$ curl -O http://dl.rust-lang.org/dist/rust-0.5.tar.gz +$ tar -xzf rust-0.5.tar.gz +$ cd rust-0.5 $ ./configure $ make && make install ~~~~ @@ -118,8 +118,8 @@ When complete, `make install` will place several programs into API-documentation tool, and `cargo`, the Rust package manager. [wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust -[tarball]: http://dl.rust-lang.org/dist/rust-0.4.tar.gz -[win-exe]: http://dl.rust-lang.org/dist/rust-0.4-install.exe +[tarball]: http://dl.rust-lang.org/dist/rust-0.5.tar.gz +[win-exe]: http://dl.rust-lang.org/dist/rust-0.5-install.exe ## Compiling your first program @@ -902,6 +902,22 @@ match mytup { } ~~~~ +## Tuple structs + +Rust also has _nominal tuples_, which behave like both structs and tuples, +except that nominal tuple types have names +(so `Foo(1, 2)` has a different type from `Bar(1, 2)`), +and nominal tuple types' _fields_ do not have names. + +For example: +~~~~ +struct MyTup(int, int, float); +let mytup: MyTup = MyTup(10, 20, 30.0); +match mytup { + MyTup(a, b, c) => log(info, a + b + (c as int)) +} +~~~~ + # Functions and methods We've already seen several function definitions. Like all other static @@ -1924,7 +1940,7 @@ types by the compiler, and may not be overridden: Additionally, the `Drop` trait is used to define destructors. This trait defines one method called `finalize`, which is automatically -called when value of the a type that implements this trait is +called when a value of the type that implements this trait is destroyed, either because the value went out of scope or because the garbage collector reclaimed it. @@ -2076,6 +2092,65 @@ the preferred way to use traits polymorphically. This usage of traits is similar to Haskell type classes. +## Static methods + +Traits can define _static_ methods, which don't have an implicit `self` argument. +The `static` keyword distinguishes static methods from methods that have a `self`: + +~~~~ +trait Shape { + fn area() -> float; + static fn new_shape(area: float) -> Shape; +} +~~~~ + +Constructors are one application for static methods, as in `new_shape` above. +To call a static method, you have to prefix it with the trait name and a double colon: + +~~~~ +# trait Shape { static fn new_shape(area: float) -> self; } +# use float::consts::pi; +# use float::sqrt; +struct Circle { radius: float } +impl Circle: Shape { + static fn new_shape(area: float) -> Circle { Circle { radius: sqrt(area / pi) } } +} +let s: Circle = Shape::new_shape(42.5); +~~~~ + +## Trait constraints + +We can write a trait declaration that is _constrained_ to only be implementable on types that +also implement some other trait. + +For example, we can define a `Circle` trait that only types that also have the `Shape` trait can have: + +~~~~ +trait Shape { fn area() -> float; } +trait Circle : Shape { fn radius() -> float; } +~~~~ + +Now, implementations of `Circle` methods can call `Shape` methods: + +~~~~ +# trait Shape { fn area() -> float; } +# trait Circle : Shape { fn radius() -> float; } +# struct Point { x: float, y: float } +# use float::consts::pi; +# use float::sqrt; +# fn square(x: float) -> float { x * x } +struct CircleStruct { center: Point, radius: float } +impl CircleStruct: Circle { + fn radius() -> float { sqrt(self.area() / pi) } +} +impl CircleStruct: Shape { + fn area() -> float { pi * square(self.radius) } +} +~~~~ + +This is a silly way to compute the radius of a circle +(since we could just return the `circle` field), but you get the idea. + ## Trait objects and dynamic method dispatch The above allows us to define functions that polymorphically act on diff --git a/src/libcore/dvec.rs b/src/libcore/dvec.rs index 874a36eb9f0cb..b02a6f5c8b538 100644 --- a/src/libcore/dvec.rs +++ b/src/libcore/dvec.rs @@ -110,6 +110,9 @@ priv impl DVec { self.data = move data; } } + + #[inline(always)] + fn unwrap(self) -> ~[A] { unwrap(self) } } // In theory, most everything should work with any A, but in practice diff --git a/src/libcore/either.rs b/src/libcore/either.rs index 74b29f3a5f1ca..6c0254ff77902 100644 --- a/src/libcore/either.rs +++ b/src/libcore/either.rs @@ -142,6 +142,14 @@ pub pure fn unwrap_right(eith: Either) -> U { } } +impl Either { + #[inline(always)] + fn unwrap_left(self) -> T { unwrap_left(self) } + + #[inline(always)] + fn unwrap_right(self) -> U { unwrap_right(self) } +} + #[test] fn test_either_left() { let val = Left(10); diff --git a/src/libcore/mutable.rs b/src/libcore/mutable.rs index ccefda41fdad5..e5090f02b41bc 100644 --- a/src/libcore/mutable.rs +++ b/src/libcore/mutable.rs @@ -73,6 +73,9 @@ impl Data { op(unsafe{transmute_immut(&mut self.value)}) } } + + #[inline(always)] + fn unwrap(self) -> T { unwrap(self) } } #[test] diff --git a/src/libcore/option.rs b/src/libcore/option.rs index f7de25bf021a5..a4f385ea12cd8 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -96,19 +96,6 @@ pub pure fn get_ref(opt: &r/Option) -> &r/T { } } -pub pure fn expect(opt: Option, reason: ~str) -> T { - /*! - * Gets the value out of an option without copying, printing a - * specified message on failure. - * - * # Failure - * - * Fails if the value equals `none` - */ - if opt.is_some() { move option::unwrap(move opt) } - else { fail reason } -} - pub pure fn map(opt: &Option, f: fn(x: &T) -> U) -> Option { //! Maps a `some` value by reference from one type to another @@ -235,35 +222,46 @@ pub fn swap_unwrap(opt: &mut Option) -> T { unwrap(util::replace(opt, None)) } -pub pure fn unwrap_expect(opt: Option, reason: &str) -> T { +pub pure fn expect(opt: Option, reason: &str) -> T { //! As unwrap, but with a specified failure message. - if opt.is_none() { fail reason.to_owned(); } - unwrap(move opt) + match move opt { + Some(move val) => val, + None => fail reason.to_owned(), + } } -// Some of these should change to be &Option, some should not. See below. impl Option { /// Returns true if the option equals `none` - pure fn is_none() -> bool { is_none(&self) } + #[inline(always)] + pure fn is_none(&self) -> bool { is_none(self) } + /// Returns true if the option contains some value - pure fn is_some() -> bool { is_some(&self) } -} + #[inline(always)] + pure fn is_some(&self) -> bool { is_some(self) } -impl &Option { /** * Update an optional value by optionally running its content by reference * through a function that returns an option. */ - pure fn chain_ref(f: fn(x: &T) -> Option) -> Option { + #[inline(always)] + pure fn chain_ref(&self, f: fn(x: &T) -> Option) -> Option { chain_ref(self, f) } + + /// Maps a `some` value from one type to another by reference + #[inline(always)] + pure fn map(&self, f: fn(x: &T) -> U) -> Option { map(self, f) } + /// Applies a function to the contained value or returns a default - pure fn map_default(def: U, f: fn(x: &T) -> U) -> U - { map_default(self, move def, f) } + #[inline(always)] + pure fn map_default(&self, def: U, f: fn(x: &T) -> U) -> U { + map_default(self, move def, f) + } + /// Performs an operation on the contained value by reference - pure fn iter(f: fn(x: &T)) { iter(self, f) } - /// Maps a `some` value from one type to another by reference - pure fn map(f: fn(x: &T) -> U) -> Option { map(self, f) } + #[inline(always)] + pure fn iter(&self, f: fn(x: &T)) { iter(self, f) } + /** Gets an immutable reference to the value inside an option. @@ -278,7 +276,29 @@ impl &Option { Instead, prefer to use pattern matching and handle the `None` case explicitly. */ - pure fn get_ref() -> &self/T { get_ref(self) } + #[inline(always)] + pure fn get_ref(&self) -> &self/T { get_ref(self) } + + /** + * Gets the value out of an option without copying. + * + * # Failure + * + * Fails if the value equals `none` + */ + #[inline(always)] + pure fn unwrap(self) -> T { unwrap(self) } + + /** + * Gets the value out of an option, printing a specified message on + * failure + * + * # Failure + * + * Fails if the value equals `none` + */ + #[inline(always)] + pure fn expect(self, reason: &str) -> T { expect(self, reason) } } impl Option { @@ -296,19 +316,17 @@ impl Option { Instead, prefer to use pattern matching and handle the `None` case explicitly. */ - pure fn get() -> T { get(self) } - pure fn get_default(def: T) -> T { get_default(self, def) } - /** - * Gets the value out of an option, printing a specified message on - * failure - * - * # Failure - * - * Fails if the value equals `none` - */ - pure fn expect(reason: ~str) -> T { expect(self, move reason) } + #[inline(always)] + pure fn get(self) -> T { get(self) } + + #[inline(always)] + pure fn get_default(self, def: T) -> T { get_default(self, def) } + /// Applies a function zero or more times until the result is none. - pure fn while_some(blk: fn(v: T) -> Option) { while_some(self, blk) } + #[inline(always)] + pure fn while_some(self, blk: fn(v: T) -> Option) { + while_some(self, blk) + } } #[test] diff --git a/src/libcore/os.rs b/src/libcore/os.rs index b5e0983a420d1..b7f0327ec5da9 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -355,13 +355,7 @@ fn dup2(src: c_int, dst: c_int) -> c_int { pub fn dll_filename(base: &str) -> ~str { - return pre() + str::from_slice(base) + dll_suffix(); - - #[cfg(unix)] - fn pre() -> ~str { ~"lib" } - - #[cfg(windows)] - fn pre() -> ~str { ~"" } + return dll_prefix() + str::from_slice(base) + dll_suffix(); } @@ -857,32 +851,48 @@ pub fn family() -> ~str { ~"unix" } #[cfg(windows)] pub fn family() -> ~str { ~"windows" } -#[cfg(target_os = "macos")] -mod consts { - pub fn sysname() -> ~str { ~"macos" } - pub fn exe_suffix() -> ~str { ~"" } - pub fn dll_suffix() -> ~str { ~".dylib" } -} -#[cfg(target_os = "freebsd")] mod consts { - pub fn sysname() -> ~str { ~"freebsd" } - pub fn exe_suffix() -> ~str { ~"" } - pub fn dll_suffix() -> ~str { ~".so" } -} -#[cfg(target_os = "linux")] -mod consts { - pub fn sysname() -> ~str { ~"linux" } - pub fn exe_suffix() -> ~str { ~"" } - pub fn dll_suffix() -> ~str { ~".so" } -} + #[cfg(target_os = "macos")] + use os::consts::macos::*; -#[cfg(target_os = "win32")] -mod consts { - pub fn sysname() -> ~str { ~"win32" } - pub fn exe_suffix() -> ~str { ~".exe" } - pub fn dll_suffix() -> ~str { ~".dll" } + #[cfg(target_os = "freebsd")] + use os::consts::freebsd::*; + + #[cfg(target_os = "linux")] + use os::consts::linux::*; + + #[cfg(target_os = "win32")] + use os::consts::win32::*; + + pub mod macos { + pub fn sysname() -> ~str { ~"macos" } + pub fn dll_prefix() -> ~str { ~"lib" } + pub fn dll_suffix() -> ~str { ~".dylib" } + pub fn exe_suffix() -> ~str { ~"" } + } + + pub mod freebsd { + pub fn sysname() -> ~str { ~"freebsd" } + pub fn dll_prefix() -> ~str { ~"lib" } + pub fn dll_suffix() -> ~str { ~".so" } + pub fn exe_suffix() -> ~str { ~"" } + } + + pub mod linux { + pub fn sysname() -> ~str { ~"linux" } + pub fn dll_prefix() -> ~str { ~"lib" } + pub fn dll_suffix() -> ~str { ~".so" } + pub fn exe_suffix() -> ~str { ~"" } + } + + pub mod win32 { + pub fn sysname() -> ~str { ~"win32" } + pub fn dll_prefix() -> ~str { ~"" } + pub fn dll_suffix() -> ~str { ~".dll" } + pub fn exe_suffix() -> ~str { ~".exe" } + } } #[cfg(target_arch = "x86")] diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs index 914530c065309..59d59d3351896 100644 --- a/src/libcore/pipes.rs +++ b/src/libcore/pipes.rs @@ -412,7 +412,7 @@ Fails if the sender closes the connection. */ pub fn recv( p: RecvPacketBuffered) -> T { - option::unwrap_expect(try_recv(move p), "connection closed") + try_recv(move p).expect("connection closed") } /** Attempts to receive a message from a pipe. @@ -1102,7 +1102,7 @@ impl PortSet : GenericPort { } fn recv() -> T { - option::unwrap_expect(self.try_recv(), "port_set: endpoints closed") + self.try_recv().expect("port_set: endpoints closed") } } diff --git a/src/libcore/result.rs b/src/libcore/result.rs index a1e7df28872a8..26064345b59f2 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -114,7 +114,7 @@ pub pure fn to_either(res: &Result) * ok(parse_bytes(buf)) * } */ -pub fn chain(res: Result, op: fn(t: T) +pub pure fn chain(res: Result, op: fn(T) -> Result) -> Result { match move res { Ok(move t) => op(move t), @@ -130,7 +130,7 @@ pub fn chain(res: Result, op: fn(t: T) * immediately returned. This function can be used to pass through a * successful result while handling an error. */ -pub fn chain_err( +pub pure fn chain_err( res: Result, op: fn(t: V) -> Result) -> Result { @@ -154,7 +154,7 @@ pub fn chain_err( * print_buf(buf) * } */ -pub fn iter(res: &Result, f: fn(&T)) { +pub pure fn iter(res: &Result, f: fn(&T)) { match *res { Ok(ref t) => f(t), Err(_) => () @@ -169,7 +169,7 @@ pub fn iter(res: &Result, f: fn(&T)) { * This function can be used to pass through a successful result while * handling an error. */ -pub fn iter_err(res: &Result, f: fn(&E)) { +pub pure fn iter_err(res: &Result, f: fn(&E)) { match *res { Ok(_) => (), Err(ref e) => f(e) @@ -190,7 +190,7 @@ pub fn iter_err(res: &Result, f: fn(&E)) { * parse_bytes(buf) * } */ -pub fn map(res: &Result, op: fn(&T) -> U) +pub pure fn map(res: &Result, op: fn(&T) -> U) -> Result { match *res { Ok(ref t) => Ok(op(t)), @@ -206,7 +206,7 @@ pub fn map(res: &Result, op: fn(&T) -> U) * is immediately returned. This function can be used to pass through a * successful result while handling an error. */ -pub fn map_err(res: &Result, op: fn(&E) -> F) +pub pure fn map_err(res: &Result, op: fn(&E) -> F) -> Result { match *res { Ok(copy t) => Ok(t), @@ -215,58 +215,55 @@ pub fn map_err(res: &Result, op: fn(&E) -> F) } impl Result { + #[inline(always)] pure fn get_ref(&self) -> &self/T { get_ref(self) } - pure fn is_ok() -> bool { is_ok(&self) } + #[inline(always)] + pure fn is_ok(&self) -> bool { is_ok(self) } - pure fn is_err() -> bool { is_err(&self) } + #[inline(always)] + pure fn is_err(&self) -> bool { is_err(self) } - pure fn iter(f: fn(&T)) { - match self { - Ok(ref t) => f(t), - Err(_) => () - } + #[inline(always)] + pure fn iter(&self, f: fn(&T)) { iter(self, f) } + + #[inline(always)] + pure fn iter_err(&self, f: fn(&E)) { iter_err(self, f) } + + #[inline(always)] + pure fn unwrap(self) -> T { unwrap(self) } + + #[inline(always)] + pure fn unwrap_err(self) -> T { unwrap(self) } + + #[inline(always)] + pure fn chain(self, op: fn(T) -> Result) -> Result { + chain(self, op) } - fn iter_err(f: fn(&E)) { - match self { - Ok(_) => (), - Err(ref e) => f(e) - } + #[inline(always)] + pure fn chain_err(self, op: fn(E) -> Result) -> Result { + chain_err(self, op) } } impl Result { - pure fn get() -> T { get(&self) } + #[inline(always)] + pure fn get(&self) -> T { get(self) } - fn map_err(op: fn(&E) -> F) -> Result { - match self { - Ok(copy t) => Ok(t), - Err(ref e) => Err(op(e)) - } + #[inline(always)] + pure fn map_err(&self, op: fn(&E) -> F) -> Result { + map_err(self, op) } } impl Result { - pure fn get_err() -> E { get_err(&self) } - - fn map(op: fn(&T) -> U) -> Result { - match self { - Ok(ref t) => Ok(op(t)), - Err(copy e) => Err(e) - } - } -} - -impl Result { - fn chain(op: fn(t: T) -> Result) -> Result { - // XXX: Bad copy - chain(copy self, op) - } + #[inline(always)] + pure fn get_err(&self) -> E { get_err(self) } - fn chain_err(op: fn(t: E) -> Result) -> Result { - // XXX: Bad copy - chain_err(copy self, op) + #[inline(always)] + pure fn map(&self, op: fn(&T) -> U) -> Result { + map(self, op) } } @@ -360,7 +357,8 @@ pub fn iter_vec2(ss: &[S], ts: &[T], } /// Unwraps a result, assuming it is an `ok(T)` -pub fn unwrap(res: Result) -> T { +#[inline(always)] +pub pure fn unwrap(res: Result) -> T { match move res { Ok(move t) => move t, Err(_) => fail ~"unwrap called on an err result" @@ -368,7 +366,8 @@ pub fn unwrap(res: Result) -> T { } /// Unwraps a result, assuming it is an `err(U)` -pub fn unwrap_err(res: Result) -> U { +#[inline(always)] +pub pure fn unwrap_err(res: Result) -> U { match move res { Err(move u) => move u, Ok(_) => fail ~"unwrap called on an ok result" diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index c091f48728f98..5071fb903d91d 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -2024,6 +2024,32 @@ impl &[A]: iter::BaseIter { pure fn size_hint(&self) -> Option { Some(len(*self)) } } +// FIXME(#4148): This should be redundant +impl ~[A]: iter::BaseIter { + pub pure fn each(&self, blk: fn(v: &A) -> bool) { + // FIXME(#2263)---should be able to call each(self, blk) + for each(*self) |e| { + if (!blk(e)) { + return; + } + } + } + pure fn size_hint(&self) -> Option { Some(len(*self)) } +} + +// FIXME(#4148): This should be redundant +impl @[A]: iter::BaseIter { + pub pure fn each(&self, blk: fn(v: &A) -> bool) { + // FIXME(#2263)---should be able to call each(self, blk) + for each(*self) |e| { + if (!blk(e)) { + return; + } + } + } + pure fn size_hint(&self) -> Option { Some(len(*self)) } +} + impl &[A]: iter::ExtendedIter { pub pure fn eachi(&self, blk: fn(uint, v: &A) -> bool) { iter::eachi(self, blk) @@ -2049,11 +2075,75 @@ impl &[A]: iter::ExtendedIter { } } +// FIXME(#4148): This should be redundant +impl ~[A]: iter::ExtendedIter { + pub pure fn eachi(&self, blk: fn(uint, v: &A) -> bool) { + iter::eachi(self, blk) + } + pub pure fn all(&self, blk: fn(&A) -> bool) -> bool { + iter::all(self, blk) + } + pub pure fn any(&self, blk: fn(&A) -> bool) -> bool { + iter::any(self, blk) + } + pub pure fn foldl(&self, b0: B, blk: fn(&B, &A) -> B) -> B { + iter::foldl(self, b0, blk) + } + pub pure fn position(&self, f: fn(&A) -> bool) -> Option { + iter::position(self, f) + } + pure fn map_to_vec(&self, op: fn(&A) -> B) -> ~[B] { + iter::map_to_vec(self, op) + } + pure fn flat_map_to_vec>(&self, op: fn(&A) -> IB) + -> ~[B] { + iter::flat_map_to_vec(self, op) + } +} + +// FIXME(#4148): This should be redundant +impl @[A]: iter::ExtendedIter { + pub pure fn eachi(&self, blk: fn(uint, v: &A) -> bool) { + iter::eachi(self, blk) + } + pub pure fn all(&self, blk: fn(&A) -> bool) -> bool { + iter::all(self, blk) + } + pub pure fn any(&self, blk: fn(&A) -> bool) -> bool { + iter::any(self, blk) + } + pub pure fn foldl(&self, b0: B, blk: fn(&B, &A) -> B) -> B { + iter::foldl(self, b0, blk) + } + pub pure fn position(&self, f: fn(&A) -> bool) -> Option { + iter::position(self, f) + } + pure fn map_to_vec(&self, op: fn(&A) -> B) -> ~[B] { + iter::map_to_vec(self, op) + } + pure fn flat_map_to_vec>(&self, op: fn(&A) -> IB) + -> ~[B] { + iter::flat_map_to_vec(self, op) + } +} + impl &[A]: iter::EqIter { pub pure fn contains(&self, x: &A) -> bool { iter::contains(self, x) } pub pure fn count(&self, x: &A) -> uint { iter::count(self, x) } } +// FIXME(#4148): This should be redundant +impl ~[A]: iter::EqIter { + pub pure fn contains(&self, x: &A) -> bool { iter::contains(self, x) } + pub pure fn count(&self, x: &A) -> uint { iter::count(self, x) } +} + +// FIXME(#4148): This should be redundant +impl @[A]: iter::EqIter { + pub pure fn contains(&self, x: &A) -> bool { iter::contains(self, x) } + pub pure fn count(&self, x: &A) -> uint { iter::count(self, x) } +} + impl &[A]: iter::CopyableIter { pure fn filter_to_vec(&self, pred: fn(&A) -> bool) -> ~[A] { iter::filter_to_vec(self, pred) @@ -2064,11 +2154,45 @@ impl &[A]: iter::CopyableIter { } } +// FIXME(#4148): This should be redundant +impl ~[A]: iter::CopyableIter { + pure fn filter_to_vec(&self, pred: fn(&A) -> bool) -> ~[A] { + iter::filter_to_vec(self, pred) + } + pure fn to_vec(&self) -> ~[A] { iter::to_vec(self) } + pub pure fn find(&self, f: fn(&A) -> bool) -> Option { + iter::find(self, f) + } +} + +// FIXME(#4148): This should be redundant +impl @[A]: iter::CopyableIter { + pure fn filter_to_vec(&self, pred: fn(&A) -> bool) -> ~[A] { + iter::filter_to_vec(self, pred) + } + pure fn to_vec(&self) -> ~[A] { iter::to_vec(self) } + pub pure fn find(&self, f: fn(&A) -> bool) -> Option { + iter::find(self, f) + } +} + impl &[A]: iter::CopyableOrderedIter { pure fn min(&self) -> A { iter::min(self) } pure fn max(&self) -> A { iter::max(self) } } +// FIXME(#4148): This should be redundant +impl ~[A]: iter::CopyableOrderedIter { + pure fn min(&self) -> A { iter::min(self) } + pure fn max(&self) -> A { iter::max(self) } +} + +// FIXME(#4148): This should be redundant +impl @[A]: iter::CopyableOrderedIter { + pure fn min(&self) -> A { iter::min(self) } + pure fn max(&self) -> A { iter::max(self) } +} + impl &[A] : iter::CopyableNonstrictIter { pure fn each_val(&const self, f: fn(A) -> bool) { let mut i = 0; @@ -2079,6 +2203,7 @@ impl &[A] : iter::CopyableNonstrictIter { } } +// FIXME(#4148): This should be redundant impl ~[A] : iter::CopyableNonstrictIter { pure fn each_val(&const self, f: fn(A) -> bool) { let mut i = 0; @@ -2089,6 +2214,7 @@ impl ~[A] : iter::CopyableNonstrictIter { } } +// FIXME(#4148): This should be redundant impl @[A] : iter::CopyableNonstrictIter { pure fn each_val(&const self, f: fn(A) -> bool) { let mut i = 0; diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 52b94b76fe614..60c43e7f526b4 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -26,6 +26,7 @@ use lib::llvm::{ModuleRef, mk_pass_manager, mk_target_data, True, False, use metadata::filesearch; use syntax::ast_map::{path, path_mod, path_name}; use io::{Writer, WriterUtil}; +use os::consts::{macos, freebsd, linux, win32}; enum output_type { output_type_none, @@ -631,6 +632,21 @@ fn mangle_internal_name_by_seq(ccx: @crate_ctxt, flav: ~str) -> ~str { return fmt!("%s_%u", flav, (ccx.names)(flav).repr); } + +fn output_dll_filename(os: session::os, lm: &link_meta) -> ~str { + let libname = fmt!("%s-%s-%s", lm.name, lm.extras_hash, lm.vers); + match os { + session::os_macos => + macos::dll_prefix() + libname + macos::dll_suffix(), + session::os_freebsd => + freebsd::dll_prefix() + libname + freebsd::dll_suffix(), + session::os_linux => + linux::dll_prefix() + libname + linux::dll_suffix(), + session::os_win32 => + win32::dll_prefix() + libname + win32::dll_suffix(), + } +} + // If the user wants an exe generated we need to invoke // cc to link the object file with some libs fn link_binary(sess: Session, @@ -648,9 +664,7 @@ fn link_binary(sess: Session, } let output = if sess.building_library { - let long_libname = - os::dll_filename(fmt!("%s-%s-%s", - lm.name, lm.extras_hash, lm.vers)); + let long_libname = output_dll_filename(sess.targ_cfg.os, &lm); debug!("link_meta.name: %s", lm.name); debug!("long_libname: %s", long_libname); debug!("out_filename: %s", out_filename.to_str()); diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index b907d8ea2146a..08023f5371d57 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -25,7 +25,11 @@ use reader = std::ebml::reader; use std::ebml; use std::map::HashMap; use std::map; +#[cfg(stage0)] use std::serialize::traits::Decodable; +#[cfg(stage1)] +#[cfg(stage2)] +use std::serialize::Decodable; use syntax::ast_map; use syntax::attr; use syntax::diagnostic::span_handler; diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 5901e58aeb190..5d2af4a37fe7b 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -18,6 +18,7 @@ use lib::llvm::{False, llvm, mk_object_file, mk_section_iter}; use metadata::filesearch::FileSearch; use io::WriterUtil; use syntax::parse::token::ident_interner; +use core::os::consts::{macos, freebsd, linux, win32}; export os; export os_macos, os_win32, os_linux, os_freebsd; @@ -67,10 +68,14 @@ fn find_library_crate(cx: ctxt) -> Option<{ident: ~str, data: @~[u8]}> { fn libname(cx: ctxt) -> {prefix: ~str, suffix: ~str} { if cx.static { return {prefix: ~"lib", suffix: ~".rlib"}; } match cx.os { - os_win32 => return {prefix: ~"", suffix: ~".dll"}, - os_macos => return {prefix: ~"lib", suffix: ~".dylib"}, - os_linux => return {prefix: ~"lib", suffix: ~".so"}, - os_freebsd => return {prefix: ~"lib", suffix: ~".so"} + os_win32 => return {prefix: win32::dll_prefix(), + suffix: win32::dll_suffix()}, + os_macos => return {prefix: macos::dll_prefix(), + suffix: macos::dll_suffix()}, + os_linux => return {prefix: linux::dll_prefix(), + suffix: linux::dll_suffix()}, + os_freebsd => return {prefix: freebsd::dll_prefix(), + suffix: freebsd::dll_suffix()} } } diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index e2f80aeeb6ac9..9e23276c8a437 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -29,7 +29,11 @@ use std::ebml; use std::map::HashMap; use std::serialize; use std::serialize::{Encodable, EncoderHelpers, DecoderHelpers}; +#[cfg(stage0)] use std::serialize::traits::Decodable; +#[cfg(stage1)] +#[cfg(stage2)] +use std::serialize::Decodable; use syntax::ast; use syntax::ast_map; use syntax::ast_util; diff --git a/src/librustc/rustc.rc b/src/librustc/rustc.rc index ae37c160cbad3..85d440ebff9cc 100644 --- a/src/librustc/rustc.rc +++ b/src/librustc/rustc.rc @@ -104,7 +104,7 @@ mod middle { mod ty; #[legacy_exports] mod resolve; - #[path2 = "typeck/mod.rs"] + #[path = "typeck/mod.rs"] pub mod typeck; #[legacy_exports] mod check_loop; @@ -114,7 +114,7 @@ mod middle { mod check_const; #[legacy_exports] mod lint; - #[path2 = "borrowck/mod.rs"] + #[path = "borrowck/mod.rs"] pub mod borrowck; #[legacy_exports] mod mem_categorization; diff --git a/src/libstd/ebml.rs b/src/libstd/ebml.rs index e72eaa08c3e3e..59e0a1e84fe8f 100644 --- a/src/libstd/ebml.rs +++ b/src/libstd/ebml.rs @@ -657,7 +657,7 @@ mod tests { }; let ebml_doc = reader::Doc(@bytes); let deser = reader::Decoder(ebml_doc); - let v1 = serialize::traits::Decodable::decode(&deser); + let v1 = serialize::Decodable::decode(&deser); debug!("v1 == %?", v1); assert v == v1; } diff --git a/src/libstd/par.rs b/src/libstd/par.rs index 55f88d4427cef..10cbcaa0c3b3a 100644 --- a/src/libstd/par.rs +++ b/src/libstd/par.rs @@ -85,7 +85,7 @@ fn map_slices( /// A parallel version of map. pub fn map( - xs: &[A], f: fn~((&A)) -> B) -> ~[B] { + xs: &[A], f: fn~(&A) -> B) -> ~[B] { vec::concat(map_slices(xs, || { fn~(_base: uint, slice : &[A], copy f) -> ~[B] { vec::map(slice, |x| f(x)) @@ -95,7 +95,7 @@ pub fn map( /// A parallel version of mapi. pub fn mapi(xs: &[A], - f: fn~(uint, (&A)) -> B) -> ~[B] { + f: fn~(uint, &A) -> B) -> ~[B] { let slices = map_slices(xs, || { fn~(base: uint, slice : &[A], copy f) -> ~[B] { vec::mapi(slice, |i, x| { @@ -132,7 +132,7 @@ pub fn mapi_factory( } /// Returns true if the function holds for all elements in the vector. -pub fn alli(xs: &[A], f: fn~(uint, (&A)) -> bool) -> bool { +pub fn alli(xs: &[A], f: fn~(uint, &A) -> bool) -> bool { do vec::all(map_slices(xs, || { fn~(base: uint, slice : &[A], copy f) -> bool { vec::alli(slice, |i, x| { @@ -143,7 +143,7 @@ pub fn alli(xs: &[A], f: fn~(uint, (&A)) -> bool) -> bool { } /// Returns true if the function holds for any elements in the vector. -pub fn any(xs: &[A], f: fn~(&(A)) -> bool) -> bool { +pub fn any(xs: &[A], f: fn~(&A) -> bool) -> bool { do vec::any(map_slices(xs, || { fn~(_base : uint, slice: &[A], copy f) -> bool { vec::any(slice, |x| f(x)) diff --git a/src/libstd/serialization.rs b/src/libstd/serialization.rs deleted file mode 100644 index 8a3e6213325a7..0000000000000 --- a/src/libstd/serialization.rs +++ /dev/null @@ -1,585 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Support code for serialization. - -/* -Core serialization interfaces. -*/ - -#[forbid(deprecated_mode)]; -#[forbid(non_camel_case_types)]; - -pub trait Serializer { - // Primitive types: - fn emit_nil(&self); - fn emit_uint(&self, v: uint); - fn emit_u64(&self, v: u64); - fn emit_u32(&self, v: u32); - fn emit_u16(&self, v: u16); - fn emit_u8(&self, v: u8); - fn emit_int(&self, v: int); - fn emit_i64(&self, v: i64); - fn emit_i32(&self, v: i32); - fn emit_i16(&self, v: i16); - fn emit_i8(&self, v: i8); - fn emit_bool(&self, v: bool); - fn emit_float(&self, v: float); - fn emit_f64(&self, v: f64); - fn emit_f32(&self, v: f32); - fn emit_char(&self, v: char); - fn emit_borrowed_str(&self, v: &str); - fn emit_owned_str(&self, v: &str); - fn emit_managed_str(&self, v: &str); - - // Compound types: - fn emit_borrowed(&self, f: fn()); - fn emit_owned(&self, f: fn()); - fn emit_managed(&self, f: fn()); - - fn emit_enum(&self, name: &str, f: fn()); - fn emit_enum_variant(&self, v_name: &str, v_id: uint, sz: uint, f: fn()); - fn emit_enum_variant_arg(&self, idx: uint, f: fn()); - - fn emit_borrowed_vec(&self, len: uint, f: fn()); - fn emit_owned_vec(&self, len: uint, f: fn()); - fn emit_managed_vec(&self, len: uint, f: fn()); - fn emit_vec_elt(&self, idx: uint, f: fn()); - - fn emit_rec(&self, f: fn()); - fn emit_struct(&self, name: &str, f: fn()); - fn emit_field(&self, f_name: &str, f_idx: uint, f: fn()); - - fn emit_tup(&self, len: uint, f: fn()); - fn emit_tup_elt(&self, idx: uint, f: fn()); -} - -pub trait Deserializer { - // Primitive types: - fn read_nil(&self) -> (); - fn read_uint(&self) -> uint; - fn read_u64(&self) -> u64; - fn read_u32(&self) -> u32; - fn read_u16(&self) -> u16; - fn read_u8(&self) -> u8; - fn read_int(&self) -> int; - fn read_i64(&self) -> i64; - fn read_i32(&self) -> i32; - fn read_i16(&self) -> i16; - fn read_i8(&self) -> i8; - fn read_bool(&self) -> bool; - fn read_f64(&self) -> f64; - fn read_f32(&self) -> f32; - fn read_float(&self) -> float; - fn read_char(&self) -> char; - fn read_owned_str(&self) -> ~str; - fn read_managed_str(&self) -> @str; - - // Compound types: - fn read_enum(&self, name: &str, f: fn() -> T) -> T; - fn read_enum_variant(&self, f: fn(uint) -> T) -> T; - fn read_enum_variant_arg(&self, idx: uint, f: fn() -> T) -> T; - - fn read_owned(&self, f: fn() -> T) -> T; - fn read_managed(&self, f: fn() -> T) -> T; - - fn read_owned_vec(&self, f: fn(uint) -> T) -> T; - fn read_managed_vec(&self, f: fn(uint) -> T) -> T; - fn read_vec_elt(&self, idx: uint, f: fn() -> T) -> T; - - fn read_rec(&self, f: fn() -> T) -> T; - fn read_struct(&self, name: &str, f: fn() -> T) -> T; - fn read_field(&self, name: &str, idx: uint, f: fn() -> T) -> T; - - fn read_tup(&self, sz: uint, f: fn() -> T) -> T; - fn read_tup_elt(&self, idx: uint, f: fn() -> T) -> T; -} - -pub mod traits { -pub trait Serializable { - fn serialize(&self, s: &S); -} - -pub trait Deserializable { - static fn deserialize(&self, d: &D) -> self; -} - -pub impl uint: Serializable { - fn serialize(&self, s: &S) { s.emit_uint(*self) } -} - -pub impl uint: Deserializable { - static fn deserialize(&self, d: &D) -> uint { - d.read_uint() - } -} - -pub impl u8: Serializable { - fn serialize(&self, s: &S) { s.emit_u8(*self) } -} - -pub impl u8: Deserializable { - static fn deserialize(&self, d: &D) -> u8 { - d.read_u8() - } -} - -pub impl u16: Serializable { - fn serialize(&self, s: &S) { s.emit_u16(*self) } -} - -pub impl u16: Deserializable { - static fn deserialize(&self, d: &D) -> u16 { - d.read_u16() - } -} - -pub impl u32: Serializable { - fn serialize(&self, s: &S) { s.emit_u32(*self) } -} - -pub impl u32: Deserializable { - static fn deserialize(&self, d: &D) -> u32 { - d.read_u32() - } -} - -pub impl u64: Serializable { - fn serialize(&self, s: &S) { s.emit_u64(*self) } -} - -pub impl u64: Deserializable { - static fn deserialize(&self, d: &D) -> u64 { - d.read_u64() - } -} - -pub impl int: Serializable { - fn serialize(&self, s: &S) { s.emit_int(*self) } -} - -pub impl int: Deserializable { - static fn deserialize(&self, d: &D) -> int { - d.read_int() - } -} - -pub impl i8: Serializable { - fn serialize(&self, s: &S) { s.emit_i8(*self) } -} - -pub impl i8: Deserializable { - static fn deserialize(&self, d: &D) -> i8 { - d.read_i8() - } -} - -pub impl i16: Serializable { - fn serialize(&self, s: &S) { s.emit_i16(*self) } -} - -pub impl i16: Deserializable { - static fn deserialize(&self, d: &D) -> i16 { - d.read_i16() - } -} - -pub impl i32: Serializable { - fn serialize(&self, s: &S) { s.emit_i32(*self) } -} - -pub impl i32: Deserializable { - static fn deserialize(&self, d: &D) -> i32 { - d.read_i32() - } -} - -pub impl i64: Serializable { - fn serialize(&self, s: &S) { s.emit_i64(*self) } -} - -pub impl i64: Deserializable { - static fn deserialize(&self, d: &D) -> i64 { - d.read_i64() - } -} - -pub impl &str: Serializable { - fn serialize(&self, s: &S) { s.emit_borrowed_str(*self) } -} - -pub impl ~str: Serializable { - fn serialize(&self, s: &S) { s.emit_owned_str(*self) } -} - -pub impl ~str: Deserializable { - static fn deserialize(&self, d: &D) -> ~str { - d.read_owned_str() - } -} - -pub impl @str: Serializable { - fn serialize(&self, s: &S) { s.emit_managed_str(*self) } -} - -pub impl @str: Deserializable { - static fn deserialize(&self, d: &D) -> @str { - d.read_managed_str() - } -} - -pub impl float: Serializable { - fn serialize(&self, s: &S) { s.emit_float(*self) } -} - -pub impl float: Deserializable { - static fn deserialize(&self, d: &D) -> float { - d.read_float() - } -} - -pub impl f32: Serializable { - fn serialize(&self, s: &S) { s.emit_f32(*self) } -} - -pub impl f32: Deserializable { - static fn deserialize(&self, d: &D) -> f32 { - d.read_f32() } -} - -pub impl f64: Serializable { - fn serialize(&self, s: &S) { s.emit_f64(*self) } -} - -pub impl f64: Deserializable { - static fn deserialize(&self, d: &D) -> f64 { - d.read_f64() - } -} - -pub impl bool: Serializable { - fn serialize(&self, s: &S) { s.emit_bool(*self) } -} - -pub impl bool: Deserializable { - static fn deserialize(&self, d: &D) -> bool { - d.read_bool() - } -} - -pub impl (): Serializable { - fn serialize(&self, s: &S) { s.emit_nil() } -} - -pub impl (): Deserializable { - static fn deserialize(&self, d: &D) -> () { - d.read_nil() - } -} - -pub impl> &T: Serializable { - fn serialize(&self, s: &S) { - s.emit_borrowed(|| (**self).serialize(s)) - } -} - -pub impl> ~T: Serializable { - fn serialize(&self, s: &S) { - s.emit_owned(|| (**self).serialize(s)) - } -} - -pub impl> ~T: Deserializable { - static fn deserialize(&self, d: &D) -> ~T { - d.read_owned(|| ~deserialize(d)) - } -} - -pub impl> @T: Serializable { - fn serialize(&self, s: &S) { - s.emit_managed(|| (**self).serialize(s)) - } -} - -pub impl> @T: Deserializable { - static fn deserialize(&self, d: &D) -> @T { - d.read_managed(|| @deserialize(d)) - } -} - -pub impl> &[T]: Serializable { - fn serialize(&self, s: &S) { - do s.emit_borrowed_vec(self.len()) { - for self.eachi |i, e| { - s.emit_vec_elt(i, || e.serialize(s)) - } - } - } -} - -pub impl> ~[T]: Serializable { - fn serialize(&self, s: &S) { - do s.emit_owned_vec(self.len()) { - for self.eachi |i, e| { - s.emit_vec_elt(i, || e.serialize(s)) - } - } - } -} - -pub impl> ~[T]: Deserializable { - static fn deserialize(&self, d: &D) -> ~[T] { - do d.read_owned_vec |len| { - do vec::from_fn(len) |i| { - d.read_vec_elt(i, || deserialize(d)) - } - } - } -} - -pub impl> @[T]: Serializable { - fn serialize(&self, s: &S) { - do s.emit_managed_vec(self.len()) { - for self.eachi |i, e| { - s.emit_vec_elt(i, || e.serialize(s)) - } - } - } -} - -pub impl> @[T]: Deserializable { - static fn deserialize(&self, d: &D) -> @[T] { - do d.read_managed_vec |len| { - do at_vec::from_fn(len) |i| { - d.read_vec_elt(i, || deserialize(d)) - } - } - } -} - -pub impl> Option: Serializable { - fn serialize(&self, s: &S) { - do s.emit_enum(~"option") { - match *self { - None => do s.emit_enum_variant(~"none", 0u, 0u) { - }, - - Some(ref v) => do s.emit_enum_variant(~"some", 1u, 1u) { - s.emit_enum_variant_arg(0u, || v.serialize(s)) - } - } - } - } -} - -pub impl> Option: Deserializable { - static fn deserialize(&self, d: &D) -> Option { - do d.read_enum(~"option") { - do d.read_enum_variant |i| { - match i { - 0 => None, - 1 => Some(d.read_enum_variant_arg(0u, || deserialize(d))), - _ => fail(fmt!("Bad variant for option: %u", i)) - } - } - } - } -} - -pub impl< - S: Serializer, - T0: Serializable, - T1: Serializable -> (T0, T1): Serializable { - fn serialize(&self, s: &S) { - match *self { - (ref t0, ref t1) => { - do s.emit_tup(2) { - s.emit_tup_elt(0, || t0.serialize(s)); - s.emit_tup_elt(1, || t1.serialize(s)); - } - } - } - } -} - -pub impl< - D: Deserializer, - T0: Deserializable, - T1: Deserializable -> (T0, T1): Deserializable { - static fn deserialize(&self, d: &D) -> (T0, T1) { - do d.read_tup(2) { - ( - d.read_tup_elt(0, || deserialize(d)), - d.read_tup_elt(1, || deserialize(d)) - ) - } - } -} - -pub impl< - S: Serializer, - T0: Serializable, - T1: Serializable, - T2: Serializable -> (T0, T1, T2): Serializable { - fn serialize(&self, s: &S) { - match *self { - (ref t0, ref t1, ref t2) => { - do s.emit_tup(3) { - s.emit_tup_elt(0, || t0.serialize(s)); - s.emit_tup_elt(1, || t1.serialize(s)); - s.emit_tup_elt(2, || t2.serialize(s)); - } - } - } - } -} - -pub impl< - D: Deserializer, - T0: Deserializable, - T1: Deserializable, - T2: Deserializable -> (T0, T1, T2): Deserializable { - static fn deserialize(&self, d: &D) -> (T0, T1, T2) { - do d.read_tup(3) { - ( - d.read_tup_elt(0, || deserialize(d)), - d.read_tup_elt(1, || deserialize(d)), - d.read_tup_elt(2, || deserialize(d)) - ) - } - } -} - -pub impl< - S: Serializer, - T0: Serializable, - T1: Serializable, - T2: Serializable, - T3: Serializable -> (T0, T1, T2, T3): Serializable { - fn serialize(&self, s: &S) { - match *self { - (ref t0, ref t1, ref t2, ref t3) => { - do s.emit_tup(4) { - s.emit_tup_elt(0, || t0.serialize(s)); - s.emit_tup_elt(1, || t1.serialize(s)); - s.emit_tup_elt(2, || t2.serialize(s)); - s.emit_tup_elt(3, || t3.serialize(s)); - } - } - } - } -} - -pub impl< - D: Deserializer, - T0: Deserializable, - T1: Deserializable, - T2: Deserializable, - T3: Deserializable -> (T0, T1, T2, T3): Deserializable { - static fn deserialize(&self, d: &D) -> (T0, T1, T2, T3) { - do d.read_tup(4) { - ( - d.read_tup_elt(0, || deserialize(d)), - d.read_tup_elt(1, || deserialize(d)), - d.read_tup_elt(2, || deserialize(d)), - d.read_tup_elt(3, || deserialize(d)) - ) - } - } -} - -pub impl< - S: Serializer, - T0: Serializable, - T1: Serializable, - T2: Serializable, - T3: Serializable, - T4: Serializable -> (T0, T1, T2, T3, T4): Serializable { - fn serialize(&self, s: &S) { - match *self { - (ref t0, ref t1, ref t2, ref t3, ref t4) => { - do s.emit_tup(5) { - s.emit_tup_elt(0, || t0.serialize(s)); - s.emit_tup_elt(1, || t1.serialize(s)); - s.emit_tup_elt(2, || t2.serialize(s)); - s.emit_tup_elt(3, || t3.serialize(s)); - s.emit_tup_elt(4, || t4.serialize(s)); - } - } - } - } -} - -pub impl< - D: Deserializer, - T0: Deserializable, - T1: Deserializable, - T2: Deserializable, - T3: Deserializable, - T4: Deserializable -> (T0, T1, T2, T3, T4): Deserializable { - static fn deserialize(&self, d: &D) - -> (T0, T1, T2, T3, T4) { - do d.read_tup(5) { - ( - d.read_tup_elt(0, || deserialize(d)), - d.read_tup_elt(1, || deserialize(d)), - d.read_tup_elt(2, || deserialize(d)), - d.read_tup_elt(3, || deserialize(d)), - d.read_tup_elt(4, || deserialize(d)) - ) - } - } -} - -// ___________________________________________________________________________ -// Helper routines -// -// In some cases, these should eventually be coded as traits. - -pub trait SerializerHelpers { - fn emit_from_vec(&self, v: ~[T], f: fn(v: &T)); -} - -pub impl S: SerializerHelpers { - fn emit_from_vec(&self, v: ~[T], f: fn(v: &T)) { - do self.emit_owned_vec(v.len()) { - for v.eachi |i, e| { - do self.emit_vec_elt(i) { - f(e) - } - } - } - } -} - -pub trait DeserializerHelpers { - fn read_to_vec(&self, f: fn() -> T) -> ~[T]; -} - -pub impl D: DeserializerHelpers { - fn read_to_vec(&self, f: fn() -> T) -> ~[T] { - do self.read_owned_vec |len| { - do vec::from_fn(len) |i| { - self.read_vec_elt(i, || f()) - } - } - } -} -} - -pub use serialization::traits::*; diff --git a/src/libstd/serialize.rs b/src/libstd/serialize.rs index e32dda045794c..79ceab6241f31 100644 --- a/src/libstd/serialize.rs +++ b/src/libstd/serialize.rs @@ -102,6 +102,7 @@ pub trait Decoder { fn read_tup_elt(&self, idx: uint, f: fn() -> T) -> T; } +#[cfg(stage0)] pub mod traits { pub trait Encodable { fn encode(&self, s: &S); @@ -583,4 +584,606 @@ pub impl D: DecoderHelpers { } } +#[cfg(stage0)] pub use serialize::traits::*; + +#[cfg(stage1)] +#[cfg(stage2)] +pub trait Encodable { + fn encode(&self, s: &S); +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub trait Decodable { + static fn decode(&self, d: &D) -> self; +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl uint: Encodable { + fn encode(&self, s: &S) { s.emit_uint(*self) } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl uint: Decodable { + static fn decode(&self, d: &D) -> uint { + d.read_uint() + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl u8: Encodable { + fn encode(&self, s: &S) { s.emit_u8(*self) } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl u8: Decodable { + static fn decode(&self, d: &D) -> u8 { + d.read_u8() + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl u16: Encodable { + fn encode(&self, s: &S) { s.emit_u16(*self) } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl u16: Decodable { + static fn decode(&self, d: &D) -> u16 { + d.read_u16() + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl u32: Encodable { + fn encode(&self, s: &S) { s.emit_u32(*self) } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl u32: Decodable { + static fn decode(&self, d: &D) -> u32 { + d.read_u32() + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl u64: Encodable { + fn encode(&self, s: &S) { s.emit_u64(*self) } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl u64: Decodable { + static fn decode(&self, d: &D) -> u64 { + d.read_u64() + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl int: Encodable { + fn encode(&self, s: &S) { s.emit_int(*self) } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl int: Decodable { + static fn decode(&self, d: &D) -> int { + d.read_int() + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl i8: Encodable { + fn encode(&self, s: &S) { s.emit_i8(*self) } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl i8: Decodable { + static fn decode(&self, d: &D) -> i8 { + d.read_i8() + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl i16: Encodable { + fn encode(&self, s: &S) { s.emit_i16(*self) } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl i16: Decodable { + static fn decode(&self, d: &D) -> i16 { + d.read_i16() + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl i32: Encodable { + fn encode(&self, s: &S) { s.emit_i32(*self) } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl i32: Decodable { + static fn decode(&self, d: &D) -> i32 { + d.read_i32() + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl i64: Encodable { + fn encode(&self, s: &S) { s.emit_i64(*self) } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl i64: Decodable { + static fn decode(&self, d: &D) -> i64 { + d.read_i64() + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl &str: Encodable { + fn encode(&self, s: &S) { s.emit_borrowed_str(*self) } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl ~str: Encodable { + fn encode(&self, s: &S) { s.emit_owned_str(*self) } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl ~str: Decodable { + static fn decode(&self, d: &D) -> ~str { + d.read_owned_str() + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl @str: Encodable { + fn encode(&self, s: &S) { s.emit_managed_str(*self) } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl @str: Decodable { + static fn decode(&self, d: &D) -> @str { + d.read_managed_str() + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl float: Encodable { + fn encode(&self, s: &S) { s.emit_float(*self) } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl float: Decodable { + static fn decode(&self, d: &D) -> float { + d.read_float() + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl f32: Encodable { + fn encode(&self, s: &S) { s.emit_f32(*self) } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl f32: Decodable { + static fn decode(&self, d: &D) -> f32 { + d.read_f32() } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl f64: Encodable { + fn encode(&self, s: &S) { s.emit_f64(*self) } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl f64: Decodable { + static fn decode(&self, d: &D) -> f64 { + d.read_f64() + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl bool: Encodable { + fn encode(&self, s: &S) { s.emit_bool(*self) } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl bool: Decodable { + static fn decode(&self, d: &D) -> bool { + d.read_bool() + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl (): Encodable { + fn encode(&self, s: &S) { s.emit_nil() } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl (): Decodable { + static fn decode(&self, d: &D) -> () { + d.read_nil() + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl> &T: Encodable { + fn encode(&self, s: &S) { + s.emit_borrowed(|| (**self).encode(s)) + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl> ~T: Encodable { + fn encode(&self, s: &S) { + s.emit_owned(|| (**self).encode(s)) + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl> ~T: Decodable { + static fn decode(&self, d: &D) -> ~T { + d.read_owned(|| ~Decodable::decode(d)) + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl> @T: Encodable { + fn encode(&self, s: &S) { + s.emit_managed(|| (**self).encode(s)) + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl> @T: Decodable { + static fn decode(&self, d: &D) -> @T { + d.read_managed(|| @Decodable::decode(d)) + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl> &[T]: Encodable { + fn encode(&self, s: &S) { + do s.emit_borrowed_vec(self.len()) { + for self.eachi |i, e| { + s.emit_vec_elt(i, || e.encode(s)) + } + } + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl> ~[T]: Encodable { + fn encode(&self, s: &S) { + do s.emit_owned_vec(self.len()) { + for self.eachi |i, e| { + s.emit_vec_elt(i, || e.encode(s)) + } + } + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl> ~[T]: Decodable { + static fn decode(&self, d: &D) -> ~[T] { + do d.read_owned_vec |len| { + do vec::from_fn(len) |i| { + d.read_vec_elt(i, || Decodable::decode(d)) + } + } + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl> @[T]: Encodable { + fn encode(&self, s: &S) { + do s.emit_managed_vec(self.len()) { + for self.eachi |i, e| { + s.emit_vec_elt(i, || e.encode(s)) + } + } + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl> @[T]: Decodable { + static fn decode(&self, d: &D) -> @[T] { + do d.read_managed_vec |len| { + do at_vec::from_fn(len) |i| { + d.read_vec_elt(i, || Decodable::decode(d)) + } + } + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl> Option: Encodable { + fn encode(&self, s: &S) { + do s.emit_enum(~"option") { + match *self { + None => do s.emit_enum_variant(~"none", 0u, 0u) { + }, + + Some(ref v) => do s.emit_enum_variant(~"some", 1u, 1u) { + s.emit_enum_variant_arg(0u, || v.encode(s)) + } + } + } + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl> Option: Decodable { + static fn decode(&self, d: &D) -> Option { + do d.read_enum(~"option") { + do d.read_enum_variant |i| { + match i { + 0 => None, + 1 => Some(d.read_enum_variant_arg( + 0u, || Decodable::decode(d))), + _ => fail(fmt!("Bad variant for option: %u", i)) + } + } + } + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl< + S: Encoder, + T0: Encodable, + T1: Encodable +> (T0, T1): Encodable { + fn encode(&self, s: &S) { + match *self { + (ref t0, ref t1) => { + do s.emit_tup(2) { + s.emit_tup_elt(0, || t0.encode(s)); + s.emit_tup_elt(1, || t1.encode(s)); + } + } + } + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl< + D: Decoder, + T0: Decodable, + T1: Decodable +> (T0, T1): Decodable { + static fn decode(&self, d: &D) -> (T0, T1) { + do d.read_tup(2) { + ( + d.read_tup_elt(0, || Decodable::decode(d)), + d.read_tup_elt(1, || Decodable::decode(d)) + ) + } + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl< + S: Encoder, + T0: Encodable, + T1: Encodable, + T2: Encodable +> (T0, T1, T2): Encodable { + fn encode(&self, s: &S) { + match *self { + (ref t0, ref t1, ref t2) => { + do s.emit_tup(3) { + s.emit_tup_elt(0, || t0.encode(s)); + s.emit_tup_elt(1, || t1.encode(s)); + s.emit_tup_elt(2, || t2.encode(s)); + } + } + } + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl< + D: Decoder, + T0: Decodable, + T1: Decodable, + T2: Decodable +> (T0, T1, T2): Decodable { + static fn decode(&self, d: &D) -> (T0, T1, T2) { + do d.read_tup(3) { + ( + d.read_tup_elt(0, || Decodable::decode(d)), + d.read_tup_elt(1, || Decodable::decode(d)), + d.read_tup_elt(2, || Decodable::decode(d)) + ) + } + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl< + S: Encoder, + T0: Encodable, + T1: Encodable, + T2: Encodable, + T3: Encodable +> (T0, T1, T2, T3): Encodable { + fn encode(&self, s: &S) { + match *self { + (ref t0, ref t1, ref t2, ref t3) => { + do s.emit_tup(4) { + s.emit_tup_elt(0, || t0.encode(s)); + s.emit_tup_elt(1, || t1.encode(s)); + s.emit_tup_elt(2, || t2.encode(s)); + s.emit_tup_elt(3, || t3.encode(s)); + } + } + } + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl< + D: Decoder, + T0: Decodable, + T1: Decodable, + T2: Decodable, + T3: Decodable +> (T0, T1, T2, T3): Decodable { + static fn decode(&self, d: &D) -> (T0, T1, T2, T3) { + do d.read_tup(4) { + ( + d.read_tup_elt(0, || Decodable::decode(d)), + d.read_tup_elt(1, || Decodable::decode(d)), + d.read_tup_elt(2, || Decodable::decode(d)), + d.read_tup_elt(3, || Decodable::decode(d)) + ) + } + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl< + S: Encoder, + T0: Encodable, + T1: Encodable, + T2: Encodable, + T3: Encodable, + T4: Encodable +> (T0, T1, T2, T3, T4): Encodable { + fn encode(&self, s: &S) { + match *self { + (ref t0, ref t1, ref t2, ref t3, ref t4) => { + do s.emit_tup(5) { + s.emit_tup_elt(0, || t0.encode(s)); + s.emit_tup_elt(1, || t1.encode(s)); + s.emit_tup_elt(2, || t2.encode(s)); + s.emit_tup_elt(3, || t3.encode(s)); + s.emit_tup_elt(4, || t4.encode(s)); + } + } + } + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl< + D: Decoder, + T0: Decodable, + T1: Decodable, + T2: Decodable, + T3: Decodable, + T4: Decodable +> (T0, T1, T2, T3, T4): Decodable { + static fn decode(&self, d: &D) + -> (T0, T1, T2, T3, T4) { + do d.read_tup(5) { + ( + d.read_tup_elt(0, || Decodable::decode(d)), + d.read_tup_elt(1, || Decodable::decode(d)), + d.read_tup_elt(2, || Decodable::decode(d)), + d.read_tup_elt(3, || Decodable::decode(d)), + d.read_tup_elt(4, || Decodable::decode(d)) + ) + } + } +} + +// ___________________________________________________________________________ +// Helper routines +// +// In some cases, these should eventually be coded as traits. + +#[cfg(stage1)] +#[cfg(stage2)] +pub trait EncoderHelpers { + fn emit_from_vec(&self, v: ~[T], f: fn(v: &T)); +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl S: EncoderHelpers { + fn emit_from_vec(&self, v: ~[T], f: fn(v: &T)) { + do self.emit_owned_vec(v.len()) { + for v.eachi |i, e| { + do self.emit_vec_elt(i) { + f(e) + } + } + } + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub trait DecoderHelpers { + fn read_to_vec(&self, f: fn() -> T) -> ~[T]; +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl D: DecoderHelpers { + fn read_to_vec(&self, f: fn() -> T) -> ~[T] { + do self.read_owned_vec |len| { + do vec::from_fn(len) |i| { + self.read_vec_elt(i, || f()) + } + } + } +} diff --git a/src/libstd/std.rc b/src/libstd/std.rc index 918781cffb5d5..eb3a741082801 100644 --- a/src/libstd/std.rc +++ b/src/libstd/std.rc @@ -30,7 +30,7 @@ not required in or otherwise suitable for the core library. #[allow(vecs_implicitly_copyable)]; #[deny(non_camel_case_types)]; -// XXX this is set to allow because there are two methods in serialization +// XXX this is set to allow because there are two methods in encoding // that can't be silenced otherwise. Most every module is set to forbid #[allow(deprecated_mode)]; #[forbid(deprecated_pattern)]; @@ -107,8 +107,6 @@ mod unicode; pub mod test; pub mod serialize; -#[cfg(stage0)] -pub mod serialization; // A curious inner-module that's not exported that contains the binding // 'std' so that macro-expanded references to std::serialize and such @@ -116,8 +114,6 @@ pub mod serialization; #[doc(hidden)] // FIXME #3538 mod std { pub use serialize; - #[cfg(stage0)] - pub use serialization; } // Local Variables: diff --git a/src/libstd/workcache.rs b/src/libstd/workcache.rs index 9b7bbb1660f6a..4d49e98a8b7ec 100644 --- a/src/libstd/workcache.rs +++ b/src/libstd/workcache.rs @@ -335,7 +335,7 @@ fn test() { let pth = Path("foo.c"); { let file = io::file_writer(&pth, [io::Create]).get(); - file.write_str("void main() { }"); + file.write_str("int main() { return 0; }"); } prep.declare_input("file", pth.to_str(), digest_file(&pth)); diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs index 6995155af18cd..8eb37386364f4 100644 --- a/src/libsyntax/ext/auto_encode.rs +++ b/src/libsyntax/ext/auto_encode.rs @@ -818,7 +818,6 @@ fn mk_deser_fields( cx.expr_path(span, ~[ cx.ident_of(~"std"), cx.ident_of(~"serialize"), - cx.ident_of(~"traits"), cx.ident_of(~"Decodable"), cx.ident_of(~"decode"), ]), @@ -1023,7 +1022,6 @@ fn mk_enum_deser_variant_nary( cx.expr_path(span, ~[ cx.ident_of(~"std"), cx.ident_of(~"serialize"), - cx.ident_of(~"traits"), cx.ident_of(~"Decodable"), cx.ident_of(~"decode"), ]), diff --git a/src/libsyntax/ext/auto_serialize.rs b/src/libsyntax/ext/auto_serialize.rs deleted file mode 100644 index 4c1725b10000c..0000000000000 --- a/src/libsyntax/ext/auto_serialize.rs +++ /dev/null @@ -1,1028 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -/* - -The compiler code necessary to implement the #[auto_serialize] and -#[auto_deserialize] extension. The idea here is that type-defining items may -be tagged with #[auto_serialize] and #[auto_deserialize], which will cause -us to generate a little companion module with the same name as the item. - -For example, a type like: - - #[auto_serialize] - #[auto_deserialize] - struct Node {id: uint} - -would generate two implementations like: - - impl node_id: Serializable { - fn serialize(s: &S) { - do s.emit_struct("Node") { - s.emit_field("id", 0, || s.emit_uint(self)) - } - } - } - - impl node_id: Deserializable { - static fn deserialize(d: &D) -> Node { - do d.read_struct("Node") { - Node { - id: d.read_field(~"x", 0, || deserialize(d)) - } - } - } - } - -Other interesting scenarios are whe the item has type parameters or -references other non-built-in types. A type definition like: - - #[auto_serialize] - #[auto_deserialize] - type spanned = {node: T, span: span}; - -would yield functions like: - - impl< - S: Serializer, - T: Serializable - > spanned: Serializable { - fn serialize(s: &S) { - do s.emit_rec { - s.emit_field("node", 0, || self.node.serialize(s)); - s.emit_field("span", 1, || self.span.serialize(s)); - } - } - } - - impl< - D: Deserializer, - T: Deserializable - > spanned: Deserializable { - static fn deserialize(d: &D) -> spanned { - do d.read_rec { - { - node: d.read_field(~"node", 0, || deserialize(d)), - span: d.read_field(~"span", 1, || deserialize(d)), - } - } - } - } - -FIXME (#2810)--Hygiene. Search for "__" strings. We also assume "std" is the -standard library. - -Misc notes: ------------ - -I use move mode arguments for ast nodes that will get inserted as is -into the tree. This is intended to prevent us from inserting the same -node twice. - -*/ - -use ext::base::*; -use codemap::span; -use std::map; -use std::map::HashMap; - -export expand_auto_serialize; -export expand_auto_deserialize; - -// Transitional reexports so qquote can find the paths it is looking for -mod syntax { - pub use ext; - pub use parse; -} - -fn expand_auto_serialize( - cx: ext_ctxt, - span: span, - _mitem: ast::meta_item, - in_items: ~[@ast::item] -) -> ~[@ast::item] { - fn is_auto_serialize(a: &ast::attribute) -> bool { - attr::get_attr_name(*a) == ~"auto_serialize" - } - - fn filter_attrs(item: @ast::item) -> @ast::item { - @{attrs: vec::filter(item.attrs, |a| !is_auto_serialize(a)), - .. *item} - } - - do vec::flat_map(in_items) |item| { - if item.attrs.any(is_auto_serialize) { - match item.node { - ast::item_ty(@{node: ast::ty_rec(ref fields), _}, tps) => { - let ser_impl = mk_rec_ser_impl( - cx, - item.span, - item.ident, - (*fields), - tps - ); - - ~[filter_attrs(*item), ser_impl] - }, - ast::item_struct(@{ fields, _}, tps) => { - let ser_impl = mk_struct_ser_impl( - cx, - item.span, - item.ident, - fields, - tps - ); - - ~[filter_attrs(*item), ser_impl] - }, - ast::item_enum(ref enum_def, tps) => { - let ser_impl = mk_enum_ser_impl( - cx, - item.span, - item.ident, - (*enum_def), - tps - ); - - ~[filter_attrs(*item), ser_impl] - }, - _ => { - cx.span_err(span, ~"#[auto_serialize] can only be \ - applied to structs, record types, \ - and enum definitions"); - ~[*item] - } - } - } else { - ~[*item] - } - } -} - -fn expand_auto_deserialize( - cx: ext_ctxt, - span: span, - _mitem: ast::meta_item, - in_items: ~[@ast::item] -) -> ~[@ast::item] { - fn is_auto_deserialize(a: &ast::attribute) -> bool { - attr::get_attr_name(*a) == ~"auto_deserialize" - } - - fn filter_attrs(item: @ast::item) -> @ast::item { - @{attrs: vec::filter(item.attrs, |a| !is_auto_deserialize(a)), - .. *item} - } - - do vec::flat_map(in_items) |item| { - if item.attrs.any(is_auto_deserialize) { - match item.node { - ast::item_ty(@{node: ast::ty_rec(ref fields), _}, tps) => { - let deser_impl = mk_rec_deser_impl( - cx, - item.span, - item.ident, - (*fields), - tps - ); - - ~[filter_attrs(*item), deser_impl] - }, - ast::item_struct(@{ fields, _}, tps) => { - let deser_impl = mk_struct_deser_impl( - cx, - item.span, - item.ident, - fields, - tps - ); - - ~[filter_attrs(*item), deser_impl] - }, - ast::item_enum(ref enum_def, tps) => { - let deser_impl = mk_enum_deser_impl( - cx, - item.span, - item.ident, - (*enum_def), - tps - ); - - ~[filter_attrs(*item), deser_impl] - }, - _ => { - cx.span_err(span, ~"#[auto_deserialize] can only be \ - applied to structs, record types, \ - and enum definitions"); - ~[*item] - } - } - } else { - ~[*item] - } - } -} - -fn mk_impl( - cx: ext_ctxt, - span: span, - ident: ast::ident, - ty_param: ast::ty_param, - path: @ast::path, - tps: ~[ast::ty_param], - f: fn(@ast::Ty) -> @ast::method -) -> @ast::item { - // All the type parameters need to bound to the trait. - let mut trait_tps = vec::append( - ~[ty_param], - do tps.map |tp| { - let t_bound = ast::ty_param_bound(@{ - id: cx.next_id(), - node: ast::ty_path(path, cx.next_id()), - span: span, - }); - - { - ident: tp.ident, - id: cx.next_id(), - bounds: @vec::append(~[t_bound], *tp.bounds) - } - } - ); - - let opt_trait = Some(@{ - path: path, - ref_id: cx.next_id(), - }); - - let ty = cx.ty_path( - span, - ~[ident], - tps.map(|tp| cx.ty_path(span, ~[tp.ident], ~[])) - ); - - @{ - // This is a new-style impl declaration. - // XXX: clownshoes - ident: ast::token::special_idents::clownshoes_extensions, - attrs: ~[], - id: cx.next_id(), - node: ast::item_impl(trait_tps, opt_trait, ty, ~[f(ty)]), - vis: ast::public, - span: span, - } -} - -fn mk_ser_impl( - cx: ext_ctxt, - span: span, - ident: ast::ident, - tps: ~[ast::ty_param], - body: @ast::expr -) -> @ast::item { - // Make a path to the std::serialization::Serializable typaram. - let ty_param = cx.bind_path( - span, - cx.ident_of(~"__S"), - cx.path( - span, - ~[ - cx.ident_of(~"std"), - cx.ident_of(~"serialization"), - cx.ident_of(~"Serializer"), - ] - ), - @~[] - ); - - // Make a path to the std::serialization::Serializable trait. - let path = cx.path_tps( - span, - ~[ - cx.ident_of(~"std"), - cx.ident_of(~"serialization"), - cx.ident_of(~"Serializable"), - ], - ~[cx.ty_path(span, ~[cx.ident_of(~"__S")], ~[])] - ); - - mk_impl( - cx, - span, - ident, - ty_param, - path, - tps, - |_ty| mk_ser_method(cx, span, cx.expr_blk(body)) - ) -} - -fn mk_deser_impl( - cx: ext_ctxt, - span: span, - ident: ast::ident, - tps: ~[ast::ty_param], - body: @ast::expr -) -> @ast::item { - // Make a path to the std::serialization::Deserializable typaram. - let ty_param = cx.bind_path( - span, - cx.ident_of(~"__D"), - cx.path( - span, - ~[ - cx.ident_of(~"std"), - cx.ident_of(~"serialization"), - cx.ident_of(~"Deserializer"), - ] - ), - @~[] - ); - - // Make a path to the std::serialization::Deserializable trait. - let path = cx.path_tps( - span, - ~[ - cx.ident_of(~"std"), - cx.ident_of(~"serialization"), - cx.ident_of(~"Deserializable"), - ], - ~[cx.ty_path(span, ~[cx.ident_of(~"__D")], ~[])] - ); - - mk_impl( - cx, - span, - ident, - ty_param, - path, - tps, - |ty| mk_deser_method(cx, span, ty, cx.expr_blk(body)) - ) -} - -fn mk_ser_method( - cx: ext_ctxt, - span: span, - ser_body: ast::blk -) -> @ast::method { - let ty_s = @{ - id: cx.next_id(), - node: ast::ty_rptr( - @{ - id: cx.next_id(), - node: ast::re_anon, - }, - { - ty: cx.ty_path(span, ~[cx.ident_of(~"__S")], ~[]), - mutbl: ast::m_imm - } - ), - span: span, - }; - - let ser_inputs = ~[{ - mode: ast::infer(cx.next_id()), - ty: ty_s, - pat: @{id: cx.next_id(), - node: ast::pat_ident( - ast::bind_by_value, - ast_util::ident_to_path(span, cx.ident_of(~"__s")), - None), - span: span}, - id: cx.next_id(), - }]; - - let ser_output = @{ - id: cx.next_id(), - node: ast::ty_nil, - span: span, - }; - - let ser_decl = { - inputs: ser_inputs, - output: ser_output, - cf: ast::return_val, - }; - - @{ - ident: cx.ident_of(~"serialize"), - attrs: ~[], - tps: ~[], - self_ty: { node: ast::sty_region(ast::m_imm), span: span }, - purity: ast::impure_fn, - decl: ser_decl, - body: ser_body, - id: cx.next_id(), - span: span, - self_id: cx.next_id(), - vis: ast::public, - } -} - -fn mk_deser_method( - cx: ext_ctxt, - span: span, - ty: @ast::Ty, - deser_body: ast::blk -) -> @ast::method { - let ty_d = @{ - id: cx.next_id(), - node: ast::ty_rptr( - @{ - id: cx.next_id(), - node: ast::re_anon, - }, - { - ty: cx.ty_path(span, ~[cx.ident_of(~"__D")], ~[]), - mutbl: ast::m_imm - } - ), - span: span, - }; - - let deser_inputs = ~[{ - mode: ast::infer(cx.next_id()), - ty: ty_d, - pat: @{id: cx.next_id(), - node: ast::pat_ident( - ast::bind_by_value, - ast_util::ident_to_path(span, cx.ident_of(~"__d")), - None), - span: span}, - id: cx.next_id(), - }]; - - let deser_decl = { - inputs: deser_inputs, - output: ty, - cf: ast::return_val, - }; - - @{ - ident: cx.ident_of(~"deserialize"), - attrs: ~[], - tps: ~[], - self_ty: { node: ast::sty_static, span: span }, - purity: ast::impure_fn, - decl: deser_decl, - body: deser_body, - id: cx.next_id(), - span: span, - self_id: cx.next_id(), - vis: ast::public, - } -} - -fn mk_rec_ser_impl( - cx: ext_ctxt, - span: span, - ident: ast::ident, - fields: ~[ast::ty_field], - tps: ~[ast::ty_param] -) -> @ast::item { - let fields = mk_ser_fields(cx, span, mk_rec_fields(fields)); - - // ast for `__s.emit_rec(|| $(fields))` - let body = cx.expr_call( - span, - cx.expr_field( - span, - cx.expr_var(span, ~"__s"), - cx.ident_of(~"emit_rec") - ), - ~[cx.lambda_stmts(span, fields)] - ); - - mk_ser_impl(cx, span, ident, tps, body) -} - -fn mk_rec_deser_impl( - cx: ext_ctxt, - span: span, - ident: ast::ident, - fields: ~[ast::ty_field], - tps: ~[ast::ty_param] -) -> @ast::item { - let fields = mk_deser_fields(cx, span, mk_rec_fields(fields)); - - // ast for `read_rec(|| $(fields))` - let body = cx.expr_call( - span, - cx.expr_field( - span, - cx.expr_var(span, ~"__d"), - cx.ident_of(~"read_rec") - ), - ~[ - cx.lambda_expr( - cx.expr( - span, - ast::expr_rec(fields, None) - ) - ) - ] - ); - - mk_deser_impl(cx, span, ident, tps, body) -} - -fn mk_struct_ser_impl( - cx: ext_ctxt, - span: span, - ident: ast::ident, - fields: ~[@ast::struct_field], - tps: ~[ast::ty_param] -) -> @ast::item { - let fields = mk_ser_fields(cx, span, mk_struct_fields(fields)); - - // ast for `__s.emit_struct($(name), || $(fields))` - let ser_body = cx.expr_call( - span, - cx.expr_field( - span, - cx.expr_var(span, ~"__s"), - cx.ident_of(~"emit_struct") - ), - ~[ - cx.lit_str(span, @cx.str_of(ident)), - cx.lambda_stmts(span, fields), - ] - ); - - mk_ser_impl(cx, span, ident, tps, ser_body) -} - -fn mk_struct_deser_impl( - cx: ext_ctxt, - span: span, - ident: ast::ident, - fields: ~[@ast::struct_field], - tps: ~[ast::ty_param] -) -> @ast::item { - let fields = mk_deser_fields(cx, span, mk_struct_fields(fields)); - - // ast for `read_struct($(name), || $(fields))` - let body = cx.expr_call( - span, - cx.expr_field( - span, - cx.expr_var(span, ~"__d"), - cx.ident_of(~"read_struct") - ), - ~[ - cx.lit_str(span, @cx.str_of(ident)), - cx.lambda_expr( - cx.expr( - span, - ast::expr_struct( - cx.path(span, ~[ident]), - fields, - None - ) - ) - ), - ] - ); - - mk_deser_impl(cx, span, ident, tps, body) -} - -// Records and structs don't have the same fields types, but they share enough -// that if we extract the right subfields out we can share the serialization -// generator code. -type field = { span: span, ident: ast::ident, mutbl: ast::mutability }; - -fn mk_rec_fields(fields: ~[ast::ty_field]) -> ~[field] { - do fields.map |field| { - { - span: field.span, - ident: field.node.ident, - mutbl: field.node.mt.mutbl, - } - } -} - -fn mk_struct_fields(fields: ~[@ast::struct_field]) -> ~[field] { - do fields.map |field| { - let (ident, mutbl) = match field.node.kind { - ast::named_field(ident, mutbl, _) => (ident, mutbl), - _ => fail ~"[auto_serialize] does not support \ - unnamed fields", - }; - - { - span: field.span, - ident: ident, - mutbl: match mutbl { - ast::struct_mutable => ast::m_mutbl, - ast::struct_immutable => ast::m_imm, - }, - } - } -} - -fn mk_ser_fields( - cx: ext_ctxt, - span: span, - fields: ~[field] -) -> ~[@ast::stmt] { - do fields.mapi |idx, field| { - // ast for `|| self.$(name).serialize(__s)` - let expr_lambda = cx.lambda_expr( - cx.expr_call( - span, - cx.expr_field( - span, - cx.expr_field( - span, - cx.expr_var(span, ~"self"), - field.ident - ), - cx.ident_of(~"serialize") - ), - ~[cx.expr_var(span, ~"__s")] - ) - ); - - // ast for `__s.emit_field($(name), $(idx), $(expr_lambda))` - cx.stmt( - cx.expr_call( - span, - cx.expr_field( - span, - cx.expr_var(span, ~"__s"), - cx.ident_of(~"emit_field") - ), - ~[ - cx.lit_str(span, @cx.str_of(field.ident)), - cx.lit_uint(span, idx), - expr_lambda, - ] - ) - ) - } -} - -fn mk_deser_fields( - cx: ext_ctxt, - span: span, - fields: ~[{ span: span, ident: ast::ident, mutbl: ast::mutability }] -) -> ~[ast::field] { - do fields.mapi |idx, field| { - // ast for `|| std::serialization::deserialize(__d)` - let expr_lambda = cx.lambda( - cx.expr_blk( - cx.expr_call( - span, - cx.expr_path(span, ~[ - cx.ident_of(~"std"), - cx.ident_of(~"serialization"), - cx.ident_of(~"deserialize"), - ]), - ~[cx.expr_var(span, ~"__d")] - ) - ) - ); - - // ast for `__d.read_field($(name), $(idx), $(expr_lambda))` - let expr: @ast::expr = cx.expr_call( - span, - cx.expr_field( - span, - cx.expr_var(span, ~"__d"), - cx.ident_of(~"read_field") - ), - ~[ - cx.lit_str(span, @cx.str_of(field.ident)), - cx.lit_uint(span, idx), - expr_lambda, - ] - ); - - { - node: { mutbl: field.mutbl, ident: field.ident, expr: expr }, - span: span, - } - } -} - -fn mk_enum_ser_impl( - cx: ext_ctxt, - span: span, - ident: ast::ident, - enum_def: ast::enum_def, - tps: ~[ast::ty_param] -) -> @ast::item { - let body = mk_enum_ser_body( - cx, - span, - ident, - enum_def.variants - ); - - mk_ser_impl(cx, span, ident, tps, body) -} - -fn mk_enum_deser_impl( - cx: ext_ctxt, - span: span, - ident: ast::ident, - enum_def: ast::enum_def, - tps: ~[ast::ty_param] -) -> @ast::item { - let body = mk_enum_deser_body( - cx, - span, - ident, - enum_def.variants - ); - - mk_deser_impl(cx, span, ident, tps, body) -} - -fn ser_variant( - cx: ext_ctxt, - span: span, - v_name: ast::ident, - v_idx: uint, - args: ~[ast::variant_arg] -) -> ast::arm { - // Name the variant arguments. - let names = args.mapi(|i, _arg| cx.ident_of(fmt!("__v%u", i))); - - // Bind the names to the variant argument type. - let pats = args.mapi(|i, arg| cx.binder_pat(arg.ty.span, names[i])); - - let pat_node = if pats.is_empty() { - ast::pat_ident( - ast::bind_by_ref(ast::m_imm), - cx.path(span, ~[v_name]), - None - ) - } else { - ast::pat_enum( - cx.path(span, ~[v_name]), - Some(pats) - ) - }; - - let pat = @{ - id: cx.next_id(), - node: pat_node, - span: span, - }; - - let stmts = do args.mapi |a_idx, _arg| { - // ast for `__s.emit_enum_variant_arg` - let expr_emit = cx.expr_field( - span, - cx.expr_var(span, ~"__s"), - cx.ident_of(~"emit_enum_variant_arg") - ); - - // ast for `|| $(v).serialize(__s)` - let expr_serialize = cx.lambda_expr( - cx.expr_call( - span, - cx.expr_field( - span, - cx.expr_path(span, ~[names[a_idx]]), - cx.ident_of(~"serialize") - ), - ~[cx.expr_var(span, ~"__s")] - ) - ); - - // ast for `$(expr_emit)($(a_idx), $(expr_serialize))` - cx.stmt( - cx.expr_call( - span, - expr_emit, - ~[cx.lit_uint(span, a_idx), expr_serialize] - ) - ) - }; - - // ast for `__s.emit_enum_variant($(name), $(idx), $(sz), $(lambda))` - let body = cx.expr_call( - span, - cx.expr_field( - span, - cx.expr_var(span, ~"__s"), - cx.ident_of(~"emit_enum_variant") - ), - ~[ - cx.lit_str(span, @cx.str_of(v_name)), - cx.lit_uint(span, v_idx), - cx.lit_uint(span, stmts.len()), - cx.lambda_stmts(span, stmts), - ] - ); - - { pats: ~[pat], guard: None, body: cx.expr_blk(body) } -} - -fn mk_enum_ser_body( - cx: ext_ctxt, - span: span, - name: ast::ident, - variants: ~[ast::variant] -) -> @ast::expr { - let arms = do variants.mapi |v_idx, variant| { - match variant.node.kind { - ast::tuple_variant_kind(args) => - ser_variant(cx, span, variant.node.name, v_idx, args), - ast::struct_variant_kind(*) => - fail ~"struct variants unimplemented", - ast::enum_variant_kind(*) => - fail ~"enum variants unimplemented", - } - }; - - // ast for `match *self { $(arms) }` - let match_expr = cx.expr( - span, - ast::expr_match( - cx.expr( - span, - ast::expr_unary(ast::deref, cx.expr_var(span, ~"self")) - ), - arms - ) - ); - - // ast for `__s.emit_enum($(name), || $(match_expr))` - cx.expr_call( - span, - cx.expr_field( - span, - cx.expr_var(span, ~"__s"), - cx.ident_of(~"emit_enum") - ), - ~[ - cx.lit_str(span, @cx.str_of(name)), - cx.lambda_expr(match_expr), - ] - ) -} - -fn mk_enum_deser_variant_nary( - cx: ext_ctxt, - span: span, - name: ast::ident, - args: ~[ast::variant_arg] -) -> @ast::expr { - let args = do args.mapi |idx, _arg| { - // ast for `|| std::serialization::deserialize(__d)` - let expr_lambda = cx.lambda_expr( - cx.expr_call( - span, - cx.expr_path(span, ~[ - cx.ident_of(~"std"), - cx.ident_of(~"serialization"), - cx.ident_of(~"deserialize"), - ]), - ~[cx.expr_var(span, ~"__d")] - ) - ); - - // ast for `__d.read_enum_variant_arg($(a_idx), $(expr_lambda))` - cx.expr_call( - span, - cx.expr_field( - span, - cx.expr_var(span, ~"__d"), - cx.ident_of(~"read_enum_variant_arg") - ), - ~[cx.lit_uint(span, idx), expr_lambda] - ) - }; - - // ast for `$(name)($(args))` - cx.expr_call(span, cx.expr_path(span, ~[name]), args) -} - -fn mk_enum_deser_body( - cx: ext_ctxt, - span: span, - name: ast::ident, - variants: ~[ast::variant] -) -> @ast::expr { - let mut arms = do variants.mapi |v_idx, variant| { - let body = match variant.node.kind { - ast::tuple_variant_kind(args) => { - if args.is_empty() { - // for a nullary variant v, do "v" - cx.expr_path(span, ~[variant.node.name]) - } else { - // for an n-ary variant v, do "v(a_1, ..., a_n)" - mk_enum_deser_variant_nary( - cx, - span, - variant.node.name, - args - ) - } - }, - ast::struct_variant_kind(*) => - fail ~"struct variants unimplemented", - ast::enum_variant_kind(*) => - fail ~"enum variants unimplemented", - }; - - let pat = @{ - id: cx.next_id(), - node: ast::pat_lit(cx.lit_uint(span, v_idx)), - span: span, - }; - - { - pats: ~[pat], - guard: None, - body: cx.expr_blk(body), - } - }; - - let impossible_case = { - pats: ~[@{ id: cx.next_id(), node: ast::pat_wild, span: span}], - guard: None, - - // FIXME(#3198): proper error message - body: cx.expr_blk(cx.expr(span, ast::expr_fail(None))), - }; - - arms.push(impossible_case); - - // ast for `|i| { match i { $(arms) } }` - let expr_lambda = cx.expr( - span, - ast::expr_fn_block( - { - inputs: ~[{ - mode: ast::infer(cx.next_id()), - ty: @{ - id: cx.next_id(), - node: ast::ty_infer, - span: span - }, - pat: @{id: cx.next_id(), - node: ast::pat_ident( - ast::bind_by_value, - ast_util::ident_to_path(span, - cx.ident_of(~"i")), - None), - span: span}, - id: cx.next_id(), - }], - output: @{ - id: cx.next_id(), - node: ast::ty_infer, - span: span, - }, - cf: ast::return_val, - }, - cx.expr_blk( - cx.expr( - span, - ast::expr_match(cx.expr_var(span, ~"i"), arms) - ) - ), - @~[] - ) - ); - - // ast for `__d.read_enum_variant($(expr_lambda))` - let expr_lambda = cx.lambda_expr( - cx.expr_call( - span, - cx.expr_field( - span, - cx.expr_var(span, ~"__d"), - cx.ident_of(~"read_enum_variant") - ), - ~[expr_lambda] - ) - ); - - // ast for `__d.read_enum($(e_name), $(expr_lambda))` - cx.expr_call( - span, - cx.expr_field( - span, - cx.expr_var(span, ~"__d"), - cx.ident_of(~"read_enum") - ), - ~[ - cx.lit_str(span, @cx.str_of(name)), - expr_lambda - ] - ) -} diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index d245aa1c050c4..cf994e0ea5224 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -73,12 +73,6 @@ fn syntax_expander_table() -> HashMap<~str, syntax_extension> { ext::tt::macro_rules::add_new_extension)); syntax_expanders.insert(~"fmt", builtin_normal_tt(ext::fmt::expand_syntax_ext)); - syntax_expanders.insert( - ~"auto_serialize", - item_decorator(ext::auto_serialize::expand_auto_serialize)); - syntax_expanders.insert( - ~"auto_deserialize", - item_decorator(ext::auto_serialize::expand_auto_deserialize)); syntax_expanders.insert( ~"auto_encode", item_decorator(ext::auto_encode::expand_auto_encode)); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 8622222e49bf8..2b83404e065e2 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3038,23 +3038,17 @@ impl Parser { let prefix = prefix.dir_path(); let mod_path = Path(".").push_many(self.mod_path_stack); let default_path = self.sess.interner.get(id) + ~".rs"; - // XXX path2 and path are synonyms. Remove path2 after snapshot let file_path = match ::attr::first_attr_value_str_by_name( - outer_attrs, ~"path2") { - - Some(ref d) => mod_path.push(*d), - None => match ::attr::first_attr_value_str_by_name( - outer_attrs, ~"path") { - Some(ref d) => { - let path = Path(*d); - if !path.is_absolute { - mod_path.push(*d) - } else { - path - } + outer_attrs, ~"path") { + Some(ref d) => { + let path = Path(*d); + if !path.is_absolute { + mod_path.push(*d) + } else { + path } - None => mod_path.push(default_path) } + None => mod_path.push(default_path) }; self.eval_src_mod_from_path(prefix, file_path, diff --git a/src/libsyntax/syntax.rc b/src/libsyntax/syntax.rc index 50dcf5de63db9..522e46422d62c 100644 --- a/src/libsyntax/syntax.rc +++ b/src/libsyntax/syntax.rc @@ -55,7 +55,7 @@ mod fold; mod util { #[legacy_exports]; #[legacy_exports] - #[path2 = "interner.rs"] + #[path = "interner.rs"] mod interner; } @@ -105,12 +105,10 @@ mod ext { #[legacy_exports] mod auto_encode; #[legacy_exports] - mod auto_serialize; - #[legacy_exports] mod source_util; #[legacy_exports] - #[path2 = "pipes/mod.rs"] + #[path = "pipes/mod.rs"] mod pipes; #[legacy_exports] diff --git a/src/snapshots.txt b/src/snapshots.txt index 4c37c3f4027dc..1baf5728a58fb 100644 --- a/src/snapshots.txt +++ b/src/snapshots.txt @@ -1,3 +1,11 @@ +S 2012-12-18 9057e98 + linux-i386 9af73f943484188db6723d027f1cd9bdcb8d7598 + linux-x86_64 f7046c4bd5e0ce792f030fb87f7ee1d489181e36 + macos-i386 9ca811bf461d52878eaaebe24c8a17cbeed4536f + macos-x86_64 ebdd7ba76f24bb7a345cb9cdb5b41455858b8b25 + winnt-i386 da8074c67dc6843818353341bfa83069f9383b88 + freebsd-x86_64 5c13f1231eb0c9fef76465b9dbcb0f3865300e78 + S 2012-12-14 dbc52ce macos-i386 994697c57810b8f139d71df47024512970db860c macos-x86_64 f8faa6a80b0b98b27ceee6fec71ded7ca058104d diff --git a/src/test/run-pass/auto-encode.rs b/src/test/run-pass/auto-encode.rs index c5bba615e2857..555171f9d5f30 100644 --- a/src/test/run-pass/auto-encode.rs +++ b/src/test/run-pass/auto-encode.rs @@ -22,7 +22,7 @@ use std::ebml; use EBReader = std::ebml::reader; use EBWriter = std::ebml::writer; use io::Writer; -use std::serialize::traits::{Encodable, Decodable}; +use std::serialize::{Encodable, Decodable}; use std::prettyprint; use std::time; diff --git a/src/test/run-pass/iter-flat-map-to-vec.rs b/src/test/run-pass/iter-flat-map-to-vec.rs index 2177066a03374..a90206188e388 100644 --- a/src/test/run-pass/iter-flat-map-to-vec.rs +++ b/src/test/run-pass/iter-flat-map-to-vec.rs @@ -8,23 +8,22 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test -- flat_map_to_vec currently disable -fn repeat(x: &uint) -> ~[uint] { ~[x, x] } +fn repeat(x: &uint) -> ~[uint] { ~[*x, *x] } -fn incd_if_even(x: &uint) -> option { - if (x % 2u) == 0u {some(x + 1u)} else {none} +fn incd_if_even(x: &uint) -> Option { + if (*x % 2u) == 0u {Some(*x + 1u)} else {None} } fn main() { - assert ~[1u, 3u].flat_map_to_vec(repeat) == ~[1u, 1u, 3u, 3u]; - assert ~[].flat_map_to_vec(repeat) == ~[]; - assert none.flat_map_to_vec(repeat) == ~[]; - assert some(1u).flat_map_to_vec(repeat) == ~[1u, 1u]; - assert some(2u).flat_map_to_vec(repeat) == ~[2u, 2u]; + assert (~[1u, 3u]).flat_map_to_vec(repeat) == ~[1u, 1u, 3u, 3u]; + assert (~[]).flat_map_to_vec(repeat) == ~[]; + assert None.flat_map_to_vec(repeat) == ~[]; + assert Some(1u).flat_map_to_vec(repeat) == ~[1u, 1u]; + assert Some(2u).flat_map_to_vec(repeat) == ~[2u, 2u]; - assert ~[1u, 2u, 5u].flat_map_to_vec(incd_if_even) == ~[3u]; - assert ~[].flat_map_to_vec(incd_if_even) == ~[]; - assert none.flat_map_to_vec(incd_if_even) == ~[]; - assert some(1u).flat_map_to_vec(incd_if_even) == ~[]; - assert some(2u).flat_map_to_vec(incd_if_even) == ~[3u]; + assert (~[1u, 2u, 5u]).flat_map_to_vec(incd_if_even) == ~[3u]; + assert (~[]).flat_map_to_vec(incd_if_even) == ~[]; + assert None.flat_map_to_vec(incd_if_even) == ~[]; + assert Some(1u).flat_map_to_vec(incd_if_even) == ~[]; + assert Some(2u).flat_map_to_vec(incd_if_even) == ~[3u]; }