From 0b434af7ebefdc82dfa58396b374970d1bbb5a7d Mon Sep 17 00:00:00 2001 From: Kevin Cantu Date: Wed, 3 Oct 2012 17:52:04 -0700 Subject: [PATCH 01/80] A run through the tutorial, small changes --- doc/tutorial.md | 100 ++++++++++++++++++++++++++++-------------------- 1 file changed, 58 insertions(+), 42 deletions(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index 7f60492e06ff..a9a86262d972 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -152,9 +152,9 @@ example, by changing `io::println` to some nonexistent function), and then compile it, you'll see an error message like this: ~~~~ {.notrust} -hello.rs:2:4: 2:16 error: unresolved name: io::print_it -hello.rs:2 io::print_it("hello? yes, this is rust"); - ^~~~~~~~~~~~ +hello.rs:2:4: 2:16 error: unresolved name: io::print_with_unicorns +hello.rs:2 io::print_with_unicorns("hello? yes, this is rust"); + ^~~~~~~~~~~~~~~~~~~~~~~ ~~~~ In its simplest form, a Rust program is a `.rs` file with some types @@ -178,9 +178,11 @@ included in that directory. In particular, if you are running emacs 24, then using emacs's internal package manager to install `rust-mode` is the easiest way to keep it up to date. There is also a package for Sublime Text 2, available both [standalone][sublime] and through -[Sublime Package Control][sublime-pkg]. +[Sublime Package Control][sublime-pkg], and support for Kate +under `src/etc/kate`. -Other editors are not provided for yet. If you end up writing a Rust +There is ctags support via `src/etc/ctags.rust`, but many other +tools and editors are not provided for yet. If you end up writing a Rust mode for your favorite editor, let us know so that we can link to it. [sublime]: http://github.com/dbp/sublime-rust @@ -191,7 +193,7 @@ mode for your favorite editor, let us know so that we can link to it. Assuming you've programmed in any C-family language (C++, Java, JavaScript, C#, or PHP), Rust will feel familiar. Code is arranged in blocks delineated by curly braces; there are control structures -for branching and looping, like the familiar `if` and `when`; function +for branching and looping, like the familiar `if` and `while`; function calls are written `myfunc(arg1, arg2)`; operators are written the same and mostly have the same precedence as in C; comments are again like C. @@ -227,13 +229,14 @@ while count < 10 { } ~~~~ -Although Rust can almost always infer the types of local variables, it -can help readability to specify a variable's type by following it with -a colon, then the type name. +Although Rust can almost always infer the types of local variables, you +can specify a variable's type by following it with a colon, then the type +name. ~~~~ -let my_favorite_value: float = 57.8; -let my_favorite_value: int = my_favorite_value as int; +let monster_size: float = 57.8; +let imaginary_size = monster_size * 10; +let monster_size: int = 50; ~~~~ Local variables may shadow earlier declarations, as in the previous @@ -248,14 +251,14 @@ underscores where they help readability, while writing types in camel case. ~~~ let my_variable = 100; -type MyType = int; // built-in types though are _not_ camel case +type MyType = int; // some built-in types are _not_ camel case ~~~ ## Expression syntax Though it isn't apparent in all code, there is a fundamental -difference between Rust's syntax and its predecessors in this family -of languages. Many constructs that are statements in C are expressions +difference between Rust's syntax and predecessors like C. +Many constructs that are statements in C are expressions in Rust, allowing code to be more concise. For example, you might write a piece of code like this: @@ -275,24 +278,25 @@ But, in Rust, you don't have to repeat the name `price`: ~~~~ # let item = "salad"; -let price = if item == "salad" { - 3.50 -} else if item == "muffin" { - 2.25 -} else { - 2.00 -}; +let price = + if item == "salad" { + 3.50 + } else if item == "muffin" { + 2.25 + } else { + 2.00 + }; ~~~~ Both pieces of code are exactly equivalent—they assign a value to -`price` depending on the condition that holds. Note that the -semicolons are omitted from the blocks in the second snippet. This is +`price` depending on the condition that holds. Note that there +are not semicolons in the blocks of the second snippet. This is important; the lack of a semicolon after the last statement in a braced block gives the whole block the value of that last expression. Put another way, the semicolon in Rust *ignores the value of an expression*. Thus, if the branches of the `if` had looked like `{ 4; }`, the above example -would simply assign nil (void) to `price`. But without the semicolon, each +would simply assign `()` (nil or void) to `price`. But without the semicolon, each branch has a different value, and `price` gets the value of the branch that was taken. @@ -346,8 +350,7 @@ if x { let y = if x { foo() } else { bar() }; ~~~ -This may sound a bit intricate, but it is super-useful, and it will -grow on you (hopefully). +This may sound a intricate, but it is super-useful and will grow on you. ## Types @@ -365,7 +368,8 @@ The basic types include the usual boolean, integral, and floating point types. ------------------------- ----------------------------------------------- These can be combined in composite types, which will be described in -more detail later on (the `T`s here stand for any other type): +more detail later on (the `T`s here stand for any other type, +while N should be a literal number): ------------------------- ----------------------------------------------- `[T * N]` Vector (like an array in other languages) with N elements @@ -392,7 +396,7 @@ the type `fn() -> bool` or the function declaration `fn foo() -> bool optionally write `-> ()`, but usually the return annotation is simply left off, as in `fn main() { ... }`. -Types can be given names with `type` declarations: +Types can be given names or aliases with `type` declarations: ~~~~ type MonsterSize = uint; @@ -401,9 +405,25 @@ type MonsterSize = uint; This will provide a synonym, `MonsterSize`, for unsigned integers. It will not actually create a new, incompatible type—`MonsterSize` and `uint` can be used interchangeably, and using one where the other is expected is not a type -error. Read about [single-variant enums](#single_variant_enum) -further on if you need to create a type name that's not just a -synonym. +error. + +To create data types which are not synonyms, `struct` and `enum` +can be used. They're described in more detail below, but they look like this: + +~~~~ +enum HidingPlaces { + Closet(uint), + UnderTheBed(uint) +} + +struct HeroicBabysitter { + bedtime_stories: uint, + sharpened_stakes: uint +} + +struct BabysitterSize(uint); // a single-variant struct +enum MonsterSize = uint; // a single-variant enum +~~~~ ## Literals @@ -435,7 +455,7 @@ The nil literal is written just like the type: `()`. The keywords Character literals are written between single quotes, as in `'x'`. Just as in C, Rust understands a number of character escapes, using the backslash -character, `\n`, `\r`, and `\t` being the most common. String literals, +character, such as `\n`, `\r`, and `\t`. String literals, written between double quotes, allow the same escape sequences. Rust strings may contain newlines. @@ -466,8 +486,8 @@ assert y == 4u; The main difference with C is that `++` and `--` are missing, and that the logical bitwise operators have higher precedence — in C, `x & 2 > 0` -comes out as `x & (2 > 0)`, in Rust, it means `(x & 2) > 0`, which is -more likely to be what you expect (unless you are a C veteran). +means `x & (2 > 0)`, but in Rust, it means `(x & 2) > 0`, which is +more likely what a novice expects. ## Syntax extensions @@ -485,7 +505,7 @@ don't match the types of the arguments. ~~~~ # let mystery_object = (); -io::println(fmt!("%s is %d", "the answer", 43)); +io::println(fmt!("%s is %d", "the answer", 42)); // %? will conveniently print any type io::println(fmt!("what is this thing: %?", mystery_object)); @@ -556,18 +576,14 @@ underscore (`_`) is a wildcard pattern that matches everything. The patterns in an match arm are followed by a fat arrow, `=>`, then an expression to evaluate. Each case is separated by commas. It's often -convenient to use a block expression for a case, in which case the +convenient to use a block expression for each case, in which case the commas are optional. ~~~ # let my_number = 1; match my_number { - 0 => { - io::println("zero") - } - _ => { - io::println("something else") - } + 0 => { io::println("zero") } + _ => { io::println("something else") } } ~~~ From 82fd71137a87ad4568eee24142d22bf87a4d2e2b Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Wed, 3 Oct 2012 19:24:06 -0700 Subject: [PATCH 02/80] libcore: De-export core.rc and core.rs --- src/libcore/core.rc | 157 ++++++++++++++++++++++---------------------- src/libcore/core.rs | 93 ++++++++++---------------- 2 files changed, 113 insertions(+), 137 deletions(-) diff --git a/src/libcore/core.rc b/src/libcore/core.rc index 818e1e890ec9..0a8641b4a1b0 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -36,7 +36,7 @@ Implicitly, all crates behave as if they included the following prologue: // Don't link to core. We are core. #[no_core]; -#[legacy_exports]; +//#[legacy_exports]; #[warn(deprecated_mode)]; #[warn(deprecated_pattern)]; @@ -44,6 +44,7 @@ Implicitly, all crates behave as if they included the following prologue: #[warn(vecs_implicitly_copyable)]; #[deny(non_camel_case_types)]; +/* export int, i8, i16, i32, i64; export uint, u8, u16, u32, u64; export float, f32, f64; @@ -81,182 +82,182 @@ export option_iter; // This creates some APIs that I do not want to commit to, but it must be // exported from core in order for uv to remain in std (see #2648). export private; - +*/ // Built-in-type support modules /// Operations and constants for `int` #[path = "int-template"] -mod int { +pub mod int { pub use inst::{ pow }; #[path = "int.rs"] - mod inst; + pub mod inst; } /// Operations and constants for `i8` #[path = "int-template"] -mod i8 { +pub mod i8 { #[path = "i8.rs"] - mod inst; + pub mod inst; } /// Operations and constants for `i16` #[path = "int-template"] -mod i16 { +pub mod i16 { #[path = "i16.rs"] - mod inst; + pub mod inst; } /// Operations and constants for `i32` #[path = "int-template"] -mod i32 { +pub mod i32 { #[path = "i32.rs"] - mod inst; + pub mod inst; } /// Operations and constants for `i64` #[path = "int-template"] -mod i64 { +pub mod i64 { #[path = "i64.rs"] - mod inst; + pub mod inst; } /// Operations and constants for `uint` #[path = "uint-template"] -mod uint { +pub mod uint { pub use inst::{ div_ceil, div_round, div_floor, iterate, next_power_of_two }; #[path = "uint.rs"] - mod inst; + pub mod inst; } /// Operations and constants for `u8` #[path = "uint-template"] -mod u8 { +pub mod u8 { pub use inst::is_ascii; #[path = "u8.rs"] - mod inst; + pub mod inst; } /// Operations and constants for `u16` #[path = "uint-template"] -mod u16 { +pub mod u16 { #[path = "u16.rs"] - mod inst; + pub mod inst; } /// Operations and constants for `u32` #[path = "uint-template"] -mod u32 { +pub mod u32 { #[path = "u32.rs"] - mod inst; + pub mod inst; } /// Operations and constants for `u64` #[path = "uint-template"] -mod u64 { +pub mod u64 { #[path = "u64.rs"] - mod inst; + pub mod inst; } -mod box; -mod char; -mod float; -mod f32; -mod f64; -mod str; -mod ptr; -mod vec; -mod at_vec; -mod bool; -mod tuple; -mod unit; -mod uniq; +pub mod box; +pub mod char; +pub mod float; +pub mod f32; +pub mod f64; +pub mod str; +pub mod ptr; +pub mod vec; +pub mod at_vec; +pub mod bool; +pub mod tuple; +pub mod unit; +pub mod uniq; // Ubiquitous-utility-type modules #[cfg(notest)] -mod ops; -mod cmp; -mod num; -mod hash; -mod either; -mod iter; -mod logging; -mod option; +pub mod ops; +pub mod cmp; +pub mod num; +pub mod hash; +pub mod either; +pub mod iter; +pub mod logging; +pub mod option; #[path="iter-trait"] -mod option_iter { +pub mod option_iter { #[path = "option.rs"] - mod inst; + pub mod inst; } -mod result; -mod to_str; -mod to_bytes; -mod from_str; -mod util; +pub mod result; +pub mod to_str; +pub mod to_bytes; +pub mod from_str; +pub mod util; // Data structure modules -mod dvec; +pub mod dvec; #[path="iter-trait"] -mod dvec_iter { +pub mod dvec_iter { #[path = "dvec.rs"] - mod inst; + pub mod inst; } -mod dlist; +pub mod dlist; #[path="iter-trait"] -mod dlist_iter { +pub mod dlist_iter { #[path ="dlist.rs"] - mod inst; + pub mod inst; } -mod send_map; +pub mod send_map; // Concurrency -mod comm; -mod task { +pub mod comm; +pub mod task { pub mod local_data; mod local_data_priv; pub mod spawn; pub mod rt; } -mod future; -mod pipes; +pub mod future; +pub mod pipes; // Runtime and language-primitive support -mod gc; -mod io; -mod libc; -mod os; -mod path; -mod rand; -mod run; -mod sys; -mod cast; -mod mutable; -mod flate; -mod repr; -mod cleanup; -mod reflect; +pub mod gc; +pub mod io; +pub mod libc; +pub mod os; +pub mod path; +pub mod rand; +pub mod run; +pub mod sys; +pub mod cast; +pub mod mutable; +pub mod flate; +pub mod repr; +pub mod cleanup; +pub mod reflect; // Modules supporting compiler-generated code // Exported but not part of the public interface #[legacy_exports] -mod extfmt; +pub mod extfmt; // The test harness links against core, so don't include runtime in tests. #[cfg(notest)] #[legacy_exports] -mod rt; +pub mod rt; // For internal use, not exported +pub mod private; mod unicode; -mod private; mod cmath; mod stackwalk; diff --git a/src/libcore/core.rs b/src/libcore/core.rs index c7261aa8c29c..a14b67b40f13 100644 --- a/src/libcore/core.rs +++ b/src/libcore/core.rs @@ -2,101 +2,76 @@ // Export various ubiquitous types, constructors, methods. -use option::{Some, None}; -use Option = option::Option; -use result::{Result, Ok, Err}; +pub use option::{Some, None}; +pub use Option = option::Option; +pub use result::{Result, Ok, Err}; -use Path = path::Path; -use GenericPath = path::GenericPath; -use WindowsPath = path::WindowsPath; -use PosixPath = path::PosixPath; +pub use Path = path::Path; +pub use GenericPath = path::GenericPath; +pub use WindowsPath = path::WindowsPath; +pub use PosixPath = path::PosixPath; -use tuple::{TupleOps, ExtendedTupleOps}; -use str::{StrSlice, UniqueStr}; -use vec::{ConstVector, CopyableVector, ImmutableVector}; -use vec::{ImmutableEqVector, ImmutableCopyableVector}; -use vec::{MutableVector, MutableCopyableVector}; -use iter::{BaseIter, ExtendedIter, EqIter, CopyableIter}; -use iter::{CopyableOrderedIter, Times, TimesIx}; -use num::Num; -use ptr::Ptr; -use to_str::ToStr; - -export Path, WindowsPath, PosixPath, GenericPath; -export Option, Some, None; -export Result, Ok, Err; -export extensions; -// The following exports are the extension impls for numeric types -export Num, Times, TimesIx; -// The following exports are the common traits -export StrSlice, UniqueStr; -export ConstVector, CopyableVector, ImmutableVector; -export ImmutableEqVector, ImmutableCopyableVector, IterTraitExtensions; -export MutableVector, MutableCopyableVector; -export BaseIter, CopyableIter, CopyableOrderedIter, ExtendedIter, EqIter; -export TupleOps, ExtendedTupleOps; -export Ptr; -export ToStr; +pub use tuple::{TupleOps, ExtendedTupleOps}; +pub use str::{StrSlice, UniqueStr}; +pub use vec::{ConstVector, CopyableVector, ImmutableVector}; +pub use vec::{ImmutableEqVector, ImmutableCopyableVector}; +pub use vec::{MutableVector, MutableCopyableVector}; +pub use iter::{BaseIter, ExtendedIter, EqIter, CopyableIter}; +pub use iter::{CopyableOrderedIter, Times, TimesIx}; +pub use num::Num; +pub use ptr::Ptr; +pub use to_str::ToStr; // The following exports are the core operators and kinds // The compiler has special knowlege of these so we must not duplicate them // when compiling for testing #[cfg(notest)] -use ops::{Const, Copy, Send, Owned}; +pub use ops::{Const, Copy, Send, Owned}; #[cfg(notest)] -use ops::{Add, Sub, Mul, Div, Modulo, Neg, BitAnd, BitOr, BitXor}; +pub use ops::{Add, Sub, Mul, Div, Modulo, Neg, BitAnd, BitOr, BitXor}; #[cfg(notest)] -use ops::{Shl, Shr, Index}; - -#[cfg(notest)] -export Const, Copy, Send, Owned; -#[cfg(notest)] -export Add, Sub, Mul, Div, Modulo, Neg, BitAnd, BitOr, BitXor; -#[cfg(notest)] -export Shl, Shr, Index; +pub use ops::{Shl, Shr, Index}; #[cfg(test)] extern mod coreops(name = "core", vers = "0.4"); #[cfg(test)] -use coreops::ops::{Const, Copy, Send, Owned}; +pub use coreops::ops::{Const, Copy, Send, Owned}; #[cfg(test)] -use coreops::ops::{Add, Sub, Mul, Div, Modulo, Neg, BitAnd, BitOr, BitXor}; +pub use coreops::ops::{Add, Sub, Mul, Div, Modulo, Neg, BitAnd, BitOr}; #[cfg(test)] -use coreops::ops::{Shl, Shr, Index}; +pub use coreops::ops::{BitXor}; +#[cfg(test)] +pub use coreops::ops::{Shl, Shr, Index}; // Export the log levels as global constants. Higher levels mean // more-verbosity. Error is the bottom level, default logging level is // warn-and-below. -export error, warn, info, debug; - /// The error log level -const error : u32 = 0_u32; +pub const error : u32 = 0_u32; /// The warning log level -const warn : u32 = 1_u32; +pub const warn : u32 = 1_u32; /// The info log level -const info : u32 = 2_u32; +pub const info : u32 = 2_u32; /// The debug log level -const debug : u32 = 3_u32; +pub const debug : u32 = 3_u32; // A curious inner-module that's not exported that contains the binding // 'core' so that macro-expanded references to core::error and such // can be resolved within libcore. #[doc(hidden)] // FIXME #3538 mod core { - #[legacy_exports]; - const error : u32 = 0_u32; - const warn : u32 = 1_u32; - const info : u32 = 2_u32; - const debug : u32 = 3_u32; + pub const error : u32 = 0_u32; + pub const warn : u32 = 1_u32; + pub const info : u32 = 2_u32; + pub const debug : u32 = 3_u32; } // Similar to above. Some magic to make core testable. #[cfg(test)] mod std { - #[legacy_exports]; extern mod std(vers = "0.4"); - use std::test; + pub use std::test; } From 1c3bfa4550c5e8c245499e9214ce0f758dcbed58 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Wed, 3 Oct 2012 19:25:24 -0700 Subject: [PATCH 03/80] libstd: Make vec_from_set pure --- src/libstd/map.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/map.rs b/src/libstd/map.rs index cc42c5623762..90476ea101a5 100644 --- a/src/libstd/map.rs +++ b/src/libstd/map.rs @@ -382,7 +382,7 @@ pub fn set_add(set: Set, key: K) -> bool { } /// Convert a set into a vector. -pub fn vec_from_set(s: Set) -> ~[T] { +pub pure fn vec_from_set(s: Set) -> ~[T] { do vec::build_sized(s.size()) |push| { for s.each_key() |k| { push(k); From d0893fe219dc1cad9887e68bc7198180492ea0b9 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Wed, 3 Oct 2012 20:03:37 -0700 Subject: [PATCH 04/80] docs: The real answer --- doc/tutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index a9a86262d972..24df990d5970 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -505,7 +505,7 @@ don't match the types of the arguments. ~~~~ # let mystery_object = (); -io::println(fmt!("%s is %d", "the answer", 42)); +io::println(fmt!("%s is %d", "the answer", 43)); // %? will conveniently print any type io::println(fmt!("what is this thing: %?", mystery_object)); From c8ee49a5b68ad0b0a33eb30e757fadb0be47f8da Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Wed, 3 Oct 2012 20:06:24 -0700 Subject: [PATCH 05/80] docs: Call () 'unit' instead of 'nil' --- doc/tutorial-ffi.md | 2 +- doc/tutorial.md | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/tutorial-ffi.md b/doc/tutorial-ffi.md index 463bd4746fee..0a48b734fa01 100644 --- a/doc/tutorial-ffi.md +++ b/doc/tutorial-ffi.md @@ -246,7 +246,7 @@ define a struct type with the same contents, and declare `gettimeofday` to take a pointer to such a struct. The second argument to `gettimeofday` (the time zone) is not used by -this program, so it simply declares it to be a pointer to the nil +this program, so it simply declares it to be a pointer to the unit type. Since all null pointers have the same representation regardless of their referent type, this is safe. diff --git a/doc/tutorial.md b/doc/tutorial.md index 24df990d5970..259328b0974f 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -294,11 +294,11 @@ are not semicolons in the blocks of the second snippet. This is important; the lack of a semicolon after the last statement in a braced block gives the whole block the value of that last expression. -Put another way, the semicolon in Rust *ignores the value of an expression*. -Thus, if the branches of the `if` had looked like `{ 4; }`, the above example -would simply assign `()` (nil or void) to `price`. But without the semicolon, each -branch has a different value, and `price` gets the value of the branch that -was taken. +Put another way, the semicolon in Rust *ignores the value of an +expression*. Thus, if the branches of the `if` had looked like `{ 4; }`, +the above example would simply assign `()` (unit or void) to +`price`. But without the semicolon, each branch has a different value, +and `price` gets the value of the branch that was taken. In short, everything that's not a declaration (`let` for variables, `fn` for functions, et cetera) is an expression, including function bodies. @@ -839,7 +839,7 @@ fn point_from_direction(dir: Direction) -> Point { Tuples in Rust behave exactly like structs, except that their fields do not have names (and can thus not be accessed with dot notation). Tuples can have any arity except for 0 or 1 (though you may consider -nil, `()`, as the empty tuple if you like). +unit, `()`, as the empty tuple if you like). ~~~~ let mytup: (int, int, float) = (10, 20, 30.0); @@ -891,7 +891,7 @@ fn int_to_str(i: int) -> ~str { } ~~~~ -Functions that do not return a value are said to return nil, `()`, +Functions that do not return a value are said to return unit, `()`, and both the return type and the return value may be omitted from the definition. The following two functions are equivalent. From a35dc85b683d02e2f38f5b76c38f2818d2426e86 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Wed, 3 Oct 2012 20:06:54 -0700 Subject: [PATCH 06/80] docs: Typo --- doc/tutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index 259328b0974f..9ea8bcd148dd 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -350,7 +350,7 @@ if x { let y = if x { foo() } else { bar() }; ~~~ -This may sound a intricate, but it is super-useful and will grow on you. +This may sound intricate, but it is super-useful and will grow on you. ## Types From c2fc7316a98af57645c38590d3606fac60823c90 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Wed, 3 Oct 2012 21:13:58 -0700 Subject: [PATCH 07/80] test: Fix error message in vtable-res-trait-param --- src/test/compile-fail/vtable-res-trait-param.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/compile-fail/vtable-res-trait-param.rs b/src/test/compile-fail/vtable-res-trait-param.rs index 550be31d1a4a..8032c199bf09 100644 --- a/src/test/compile-fail/vtable-res-trait-param.rs +++ b/src/test/compile-fail/vtable-res-trait-param.rs @@ -14,7 +14,7 @@ impl int: TraitB { fn call_it(b: B) -> int { let y = 4u; - b.gimme_an_a(y) //~ ERROR failed to find an implementation of trait @TraitA for uint + b.gimme_an_a(y) //~ ERROR failed to find an implementation of trait @TraitA } fn main() { From ae42318bef7e76fd94c534724d23ab8e87ddc809 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Wed, 3 Oct 2012 22:06:51 -0700 Subject: [PATCH 08/80] core: Make some parts of task private --- src/libcore/task/local_data.rs | 16 +++++------ src/libcore/task/local_data_priv.rs | 14 +++++----- src/libcore/task/spawn.rs | 42 ++++++++++++++--------------- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/libcore/task/local_data.rs b/src/libcore/task/local_data.rs index 2130354229a2..991011893152 100644 --- a/src/libcore/task/local_data.rs +++ b/src/libcore/task/local_data.rs @@ -78,7 +78,7 @@ pub unsafe fn local_data_modify( } #[test] -pub fn test_tls_multitask() unsafe { +fn test_tls_multitask() unsafe { fn my_key(_x: @~str) { } local_data_set(my_key, @~"parent data"); do task::spawn unsafe { @@ -94,7 +94,7 @@ pub fn test_tls_multitask() unsafe { } #[test] -pub fn test_tls_overwrite() unsafe { +fn test_tls_overwrite() unsafe { fn my_key(_x: @~str) { } local_data_set(my_key, @~"first data"); local_data_set(my_key, @~"next data"); // Shouldn't leak. @@ -102,7 +102,7 @@ pub fn test_tls_overwrite() unsafe { } #[test] -pub fn test_tls_pop() unsafe { +fn test_tls_pop() unsafe { fn my_key(_x: @~str) { } local_data_set(my_key, @~"weasel"); assert *(local_data_pop(my_key).get()) == ~"weasel"; @@ -111,7 +111,7 @@ pub fn test_tls_pop() unsafe { } #[test] -pub fn test_tls_modify() unsafe { +fn test_tls_modify() unsafe { fn my_key(_x: @~str) { } local_data_modify(my_key, |data| { match data { @@ -130,7 +130,7 @@ pub fn test_tls_modify() unsafe { } #[test] -pub fn test_tls_crust_automorestack_memorial_bug() unsafe { +fn test_tls_crust_automorestack_memorial_bug() unsafe { // This might result in a stack-canary clobber if the runtime fails to set // sp_limit to 0 when calling the cleanup extern - it might automatically // jump over to the rust stack, which causes next_c_sp to get recorded as @@ -143,7 +143,7 @@ pub fn test_tls_crust_automorestack_memorial_bug() unsafe { } #[test] -pub fn test_tls_multiple_types() unsafe { +fn test_tls_multiple_types() unsafe { fn str_key(_x: @~str) { } fn box_key(_x: @@()) { } fn int_key(_x: @int) { } @@ -155,7 +155,7 @@ pub fn test_tls_multiple_types() unsafe { } #[test] -pub fn test_tls_overwrite_multiple_types() { +fn test_tls_overwrite_multiple_types() { fn str_key(_x: @~str) { } fn box_key(_x: @@()) { } fn int_key(_x: @int) { } @@ -171,7 +171,7 @@ pub fn test_tls_overwrite_multiple_types() { #[test] #[should_fail] #[ignore(cfg(windows))] -pub fn test_tls_cleanup_on_failure() unsafe { +fn test_tls_cleanup_on_failure() unsafe { fn str_key(_x: @~str) { } fn box_key(_x: @@()) { } fn int_key(_x: @int) { } diff --git a/src/libcore/task/local_data_priv.rs b/src/libcore/task/local_data_priv.rs index 9849ce7b68cd..e84e4dad164f 100644 --- a/src/libcore/task/local_data_priv.rs +++ b/src/libcore/task/local_data_priv.rs @@ -17,11 +17,11 @@ impl LocalData: Eq { // We use dvec because it's the best data structure in core. If TLS is used // heavily in future, this could be made more efficient with a proper map. -pub type TaskLocalElement = (*libc::c_void, *libc::c_void, LocalData); +type TaskLocalElement = (*libc::c_void, *libc::c_void, LocalData); // Has to be a pointer at outermost layer; the foreign call returns void *. -pub type TaskLocalMap = @dvec::DVec>; +type TaskLocalMap = @dvec::DVec>; -pub extern fn cleanup_task_local_map(map_ptr: *libc::c_void) unsafe { +extern fn cleanup_task_local_map(map_ptr: *libc::c_void) unsafe { assert !map_ptr.is_null(); // Get and keep the single reference that was created at the beginning. let _map: TaskLocalMap = cast::reinterpret_cast(&map_ptr); @@ -29,7 +29,7 @@ pub extern fn cleanup_task_local_map(map_ptr: *libc::c_void) unsafe { } // Gets the map from the runtime. Lazily initialises if not done so already. -pub unsafe fn get_task_local_map(task: *rust_task) -> TaskLocalMap { +unsafe fn get_task_local_map(task: *rust_task) -> TaskLocalMap { // Relies on the runtime initialising the pointer to null. // NOTE: The map's box lives in TLS invisibly referenced once. Each time @@ -52,7 +52,7 @@ pub unsafe fn get_task_local_map(task: *rust_task) -> TaskLocalMap { } } -pub unsafe fn key_to_key_value( +unsafe fn key_to_key_value( key: LocalDataKey) -> *libc::c_void { // Keys are closures, which are (fnptr,envptr) pairs. Use fnptr. @@ -62,7 +62,7 @@ pub unsafe fn key_to_key_value( } // If returning Some(..), returns with @T with the map's reference. Careful! -pub unsafe fn local_data_lookup( +unsafe fn local_data_lookup( map: TaskLocalMap, key: LocalDataKey) -> Option<(uint, *libc::c_void)> { @@ -80,7 +80,7 @@ pub unsafe fn local_data_lookup( } } -pub unsafe fn local_get_helper( +unsafe fn local_get_helper( task: *rust_task, key: LocalDataKey, do_pop: bool) -> Option<@T> { diff --git a/src/libcore/task/spawn.rs b/src/libcore/task/spawn.rs index 0e1284da3bcb..ff07150cfa2d 100644 --- a/src/libcore/task/spawn.rs +++ b/src/libcore/task/spawn.rs @@ -69,16 +69,16 @@ macro_rules! move_it ( { $x:expr } => { unsafe { let y <- *ptr::addr_of(&($x)); move y } } ) -pub type TaskSet = send_map::linear::LinearMap<*rust_task,()>; +type TaskSet = send_map::linear::LinearMap<*rust_task,()>; -pub fn new_taskset() -> TaskSet { +fn new_taskset() -> TaskSet { send_map::linear::LinearMap() } -pub fn taskset_insert(tasks: &mut TaskSet, task: *rust_task) { +fn taskset_insert(tasks: &mut TaskSet, task: *rust_task) { let didnt_overwrite = tasks.insert(task, ()); assert didnt_overwrite; } -pub fn taskset_remove(tasks: &mut TaskSet, task: *rust_task) { +fn taskset_remove(tasks: &mut TaskSet, task: *rust_task) { let was_present = tasks.remove(&task); assert was_present; } @@ -87,7 +87,7 @@ pub fn taskset_each(tasks: &TaskSet, blk: fn(v: *rust_task) -> bool) { } // One of these per group of linked-failure tasks. -pub type TaskGroupData = { +type TaskGroupData = { // All tasks which might kill this group. When this is empty, the group // can be "GC"ed (i.e., its link in the ancestor list can be removed). mut members: TaskSet, @@ -95,12 +95,12 @@ pub type TaskGroupData = { // tasks in this group. mut descendants: TaskSet, }; -pub type TaskGroupArc = private::Exclusive>; +type TaskGroupArc = private::Exclusive>; -pub type TaskGroupInner = &mut Option; +type TaskGroupInner = &mut Option; // A taskgroup is 'dead' when nothing can cause it to fail; only members can. -pub pure fn taskgroup_is_dead(tg: &TaskGroupData) -> bool { +pure fn taskgroup_is_dead(tg: &TaskGroupData) -> bool { (&tg.members).is_empty() } @@ -111,7 +111,7 @@ pub pure fn taskgroup_is_dead(tg: &TaskGroupData) -> bool { // taskgroup which was spawned-unlinked. Tasks from intermediate generations // have references to the middle of the list; when intermediate generations // die, their node in the list will be collected at a descendant's spawn-time. -pub type AncestorNode = { +type AncestorNode = { // Since the ancestor list is recursive, we end up with references to // exclusives within other exclusives. This is dangerous business (if // circular references arise, deadlock and memory leaks are imminent). @@ -124,16 +124,16 @@ pub type AncestorNode = { // Recursive rest of the list. mut ancestors: AncestorList, }; -pub enum AncestorList = Option>; +enum AncestorList = Option>; // Accessors for taskgroup arcs and ancestor arcs that wrap the unsafety. #[inline(always)] -pub fn access_group(x: &TaskGroupArc, blk: fn(TaskGroupInner) -> U) -> U { +fn access_group(x: &TaskGroupArc, blk: fn(TaskGroupInner) -> U) -> U { unsafe { x.with(blk) } } #[inline(always)] -pub fn access_ancestors(x: &private::Exclusive, +fn access_ancestors(x: &private::Exclusive, blk: fn(x: &mut AncestorNode) -> U) -> U { unsafe { x.with(blk) } } @@ -146,7 +146,7 @@ pub fn access_ancestors(x: &private::Exclusive, // (3) As a bonus, coalesces away all 'dead' taskgroup nodes in the list. // FIXME(#2190): Change Option to Option, to save on // allocations. Once that bug is fixed, changing the sigil should suffice. -pub fn each_ancestor(list: &mut AncestorList, +fn each_ancestor(list: &mut AncestorList, bail_opt: Option, forward_blk: fn(TaskGroupInner) -> bool) -> bool { @@ -271,7 +271,7 @@ pub fn each_ancestor(list: &mut AncestorList, } // One of these per task. -pub struct TCB { +struct TCB { me: *rust_task, // List of tasks with whose fates this one's is intertwined. tasks: TaskGroupArc, // 'none' means the group has failed. @@ -303,7 +303,7 @@ pub struct TCB { } } -pub fn TCB(me: *rust_task, tasks: TaskGroupArc, ancestors: AncestorList, +fn TCB(me: *rust_task, tasks: TaskGroupArc, ancestors: AncestorList, is_main: bool, notifier: Option) -> TCB { let notifier = move notifier; @@ -318,7 +318,7 @@ pub fn TCB(me: *rust_task, tasks: TaskGroupArc, ancestors: AncestorList, } } -pub struct AutoNotify { +struct AutoNotify { notify_chan: Chan, mut failed: bool, drop { @@ -327,14 +327,14 @@ pub struct AutoNotify { } } -pub fn AutoNotify(chan: Chan) -> AutoNotify { +fn AutoNotify(chan: Chan) -> AutoNotify { AutoNotify { notify_chan: chan, failed: true // Un-set above when taskgroup successfully made. } } -pub fn enlist_in_taskgroup(state: TaskGroupInner, me: *rust_task, +fn enlist_in_taskgroup(state: TaskGroupInner, me: *rust_task, is_member: bool) -> bool { let newstate = util::replace(state, None); // If 'None', the group was failing. Can't enlist. @@ -350,7 +350,7 @@ pub fn enlist_in_taskgroup(state: TaskGroupInner, me: *rust_task, } // NB: Runs in destructor/post-exit context. Can't 'fail'. -pub fn leave_taskgroup(state: TaskGroupInner, me: *rust_task, +fn leave_taskgroup(state: TaskGroupInner, me: *rust_task, is_member: bool) { let newstate = util::replace(state, None); // If 'None', already failing and we've already gotten a kill signal. @@ -363,7 +363,7 @@ pub fn leave_taskgroup(state: TaskGroupInner, me: *rust_task, } // NB: Runs in destructor/post-exit context. Can't 'fail'. -pub fn kill_taskgroup(state: TaskGroupInner, me: *rust_task, is_main: bool) { +fn kill_taskgroup(state: TaskGroupInner, me: *rust_task, is_main: bool) { // NB: We could do the killing iteration outside of the group arc, by // having "let mut newstate" here, swapping inside, and iterating after. // But that would let other exiting tasks fall-through and exit while we @@ -405,7 +405,7 @@ macro_rules! taskgroup_key ( () => (cast::transmute((-2 as uint, 0u))) ) -pub fn gen_child_taskgroup(linked: bool, supervised: bool) +fn gen_child_taskgroup(linked: bool, supervised: bool) -> (TaskGroupArc, AncestorList, bool) { let spawner = rt::rust_get_task(); /*######################################################################* From 83fdeddb914ce792aef609978675ee5c3dea0e57 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Wed, 3 Oct 2012 22:10:43 -0700 Subject: [PATCH 09/80] xfail-pretty reexport-star --- src/test/run-pass/reexport-star.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/run-pass/reexport-star.rs b/src/test/run-pass/reexport-star.rs index 1709ddc70f2d..daa8d9d67964 100644 --- a/src/test/run-pass/reexport-star.rs +++ b/src/test/run-pass/reexport-star.rs @@ -1,3 +1,6 @@ +// xfail-pretty +// FIXME #3654 + mod a { pub fn f() {} pub fn g() {} From 3e47b4f17e690cb42b30fe6d09d1947556149406 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Wed, 3 Oct 2012 22:18:46 -0700 Subject: [PATCH 10/80] Revert "docs: Call () 'unit' instead of 'nil'" This reverts commit c8ee49a5b68ad0b0a33eb30e757fadb0be47f8da. --- doc/tutorial-ffi.md | 2 +- doc/tutorial.md | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/tutorial-ffi.md b/doc/tutorial-ffi.md index 0a48b734fa01..463bd4746fee 100644 --- a/doc/tutorial-ffi.md +++ b/doc/tutorial-ffi.md @@ -246,7 +246,7 @@ define a struct type with the same contents, and declare `gettimeofday` to take a pointer to such a struct. The second argument to `gettimeofday` (the time zone) is not used by -this program, so it simply declares it to be a pointer to the unit +this program, so it simply declares it to be a pointer to the nil type. Since all null pointers have the same representation regardless of their referent type, this is safe. diff --git a/doc/tutorial.md b/doc/tutorial.md index 9ea8bcd148dd..889dd7ab3dc2 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -294,11 +294,11 @@ are not semicolons in the blocks of the second snippet. This is important; the lack of a semicolon after the last statement in a braced block gives the whole block the value of that last expression. -Put another way, the semicolon in Rust *ignores the value of an -expression*. Thus, if the branches of the `if` had looked like `{ 4; }`, -the above example would simply assign `()` (unit or void) to -`price`. But without the semicolon, each branch has a different value, -and `price` gets the value of the branch that was taken. +Put another way, the semicolon in Rust *ignores the value of an expression*. +Thus, if the branches of the `if` had looked like `{ 4; }`, the above example +would simply assign `()` (nil or void) to `price`. But without the semicolon, each +branch has a different value, and `price` gets the value of the branch that +was taken. In short, everything that's not a declaration (`let` for variables, `fn` for functions, et cetera) is an expression, including function bodies. @@ -839,7 +839,7 @@ fn point_from_direction(dir: Direction) -> Point { Tuples in Rust behave exactly like structs, except that their fields do not have names (and can thus not be accessed with dot notation). Tuples can have any arity except for 0 or 1 (though you may consider -unit, `()`, as the empty tuple if you like). +nil, `()`, as the empty tuple if you like). ~~~~ let mytup: (int, int, float) = (10, 20, 30.0); @@ -891,7 +891,7 @@ fn int_to_str(i: int) -> ~str { } ~~~~ -Functions that do not return a value are said to return unit, `()`, +Functions that do not return a value are said to return nil, `()`, and both the return type and the return value may be omitted from the definition. The following two functions are equivalent. From 5585514c02b1f7c7df2503e3e75814994ccdb8b7 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Wed, 3 Oct 2012 23:53:26 -0700 Subject: [PATCH 11/80] docs: Fix a broken test --- doc/tutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index 889dd7ab3dc2..d56f1340c950 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -235,7 +235,7 @@ name. ~~~~ let monster_size: float = 57.8; -let imaginary_size = monster_size * 10; +let imaginary_size = monster_size * 10.0; let monster_size: int = 50; ~~~~ From 0bb437aafad7f96ef47e93e299878a60f959821e Mon Sep 17 00:00:00 2001 From: auREAX Date: Thu, 4 Oct 2012 03:46:32 +0200 Subject: [PATCH 12/80] Add GRSecurity compatibility with --enable-pax-marks configure flag; add GRSecurity autodetection code to configure. --- configure | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++ mk/stage0.mk | 4 ++++ mk/target.mk | 4 ++++ 3 files changed, 63 insertions(+) diff --git a/configure b/configure index 9f3ecddefe13..07e22bed8d6d 100755 --- a/configure +++ b/configure @@ -295,6 +295,7 @@ opt manage-submodules 1 "let the build manage the git submodules" opt mingw-cross 0 "cross-compile for win32 using mingw" opt clang 0 "prefer clang to gcc for building the runtime" opt local-rust 0 "use an installed rustc rather than downloading a snapshot" +opt pax-marks 0 "apply PaX markings to rustc binaries (required for GRSecurity/PaX-patched kernels)" valopt prefix "/usr/local" "set installation prefix" valopt local-rust-root "/usr/local" "set prefix for local rust binary" valopt llvm-root "" "set LLVM root" @@ -343,6 +344,8 @@ probe CFG_PDFLATEX pdflatex probe CFG_XETEX xetex probe CFG_LUATEX luatex probe CFG_NODE nodejs node +probe CFG_PAXCTL paxctl /sbin/paxctl +probe CFG_ZCAT zcat if [ ! -z "$CFG_PANDOC" ] then @@ -354,6 +357,52 @@ then fi fi +if [ "$CFG_OSTYPE" = "unknown-linux-gnu" ] +then + if [ ! -z "$CFG_ENABLE_PAX_MARKS" -a -z "$CFG_PAXCTL" ] + then + err "enabled PaX markings but no paxctl binary found" + fi + + if [ -z "$CFG_DISABLE_PAX_MARKS" ] + then + # GRSecurity/PaX detection. This can be very flaky. + GRSEC_DETECTED= + + # /dev/grsec only exists if CONFIG_GRKERNSEC_NO_RBAC is not set. + # /proc is normally only available to root and users in the CONFIG_GRKERNSEC_PROC_GID group, + # and /proc/sys/kernel/grsecurity is not available if ÇONFIG_GRKERNSEC_SYSCTL is not set. + if [ -e /dev/grsec -o -d /proc/sys/kernel/grsecurity ] + then + GRSEC_DETECTED=1 + # /proc/config.gz is normally only available to root, and only if CONFIG_IKCONFIG_PROC has been set. + elif [ -r /proc/config.gz -a ! -z "$CFG_ZCAT" ] + then + if "$CFG_ZCAT" /proc/config.gz | grep --quiet "CONFIG_GRKERNSEC=y" + then + GRSEC_DETECTED=1 + fi + # Flaky. + elif grep --quiet grsec /proc/version + then + GRSEC_DETECTED=1 + fi + + if [ ! -z "$GRSEC_DETECTED" ] + then + step_msg "GRSecurity: yes" + if [ ! -z "$CFG_PAXCTL" ] + then + CFG_ENABLE_PAX_MARKS=1 + else + warn "GRSecurity kernel detected but no paxctl binary found: not setting CFG_ENABLE_PAX_MARKS" + fi + else + step_msg "GRSecurity: no" + fi + fi +fi + if [ ! -z "$CFG_ENABLE_LOCAL_RUST" ] then if [ ! -f ${CFG_LOCAL_RUST_ROOT}/bin/rustc ] @@ -699,6 +748,12 @@ putvar CFG_C_COMPILER putvar CFG_LIBDIR putvar CFG_DISABLE_MANAGE_SUBMODULES +if [ ! -z "$CFG_ENABLE_PAX_MARKS" ] +then + putvar CFG_ENABLE_PAX_MARKS + putvar CFG_PAXCTL +fi + if [ ! -z $BAD_PANDOC ] then CFG_PANDOC= diff --git a/mk/stage0.mk b/mk/stage0.mk index e55b9f70c8ff..fae6b3742f81 100644 --- a/mk/stage0.mk +++ b/mk/stage0.mk @@ -12,6 +12,10 @@ ifdef CFG_ENABLE_LOCAL_RUST $(Q)$(S)src/etc/local_stage0.sh $(CFG_HOST_TRIPLE) $(CFG_LOCAL_RUST_ROOT) else $(Q)$(S)src/etc/get-snapshot.py $(CFG_HOST_TRIPLE) $(SNAPSHOT_FILE) +ifdef CFG_ENABLE_PAX_MARKS + @$(call E, apply PaX markings: $@) + @"$(CFG_PAXCTL)" -cm "$@" +endif endif $(Q)touch $@ diff --git a/mk/target.mk b/mk/target.mk index 5ddc825d335b..458d2a4ac63b 100644 --- a/mk/target.mk +++ b/mk/target.mk @@ -29,6 +29,10 @@ $$(TBIN$(1)_T_$(2)_H_$(3))/rustc$$(X): \ $$(TLIBRUSTC_DEFAULT$(1)_T_$(2)_H_$(3)) @$$(call E, compile_and_link: $$@) $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< +ifdef CFG_ENABLE_PAX_MARKS + @$$(call E, apply PaX markings: $$@) + @"$(CFG_PAXCTL)" -cm "$$@" +endif $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTC): \ $$(COMPILER_CRATE) $$(COMPILER_INPUTS) \ From 56c9c815227a107e527ef1c978bc23d9f351efb2 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Thu, 4 Oct 2012 12:18:13 -0700 Subject: [PATCH 13/80] Add auREAX to AUTHORS.txt. --- AUTHORS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.txt b/AUTHORS.txt index e7fa662c603f..2ce2d4c51ab4 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -12,6 +12,7 @@ Andreas Gal Arkaitz Jimenez Armin Ronacher Austin Seipp +auREAX Ben Blum Ben Striegel Benjamin Herr From 0eb9d41454083d2e9cb11859669f35c25c0f3347 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gon=C3=A7alo=20Cabrita?= <_@gmcabrita.com> Date: Thu, 4 Oct 2012 21:28:45 +0100 Subject: [PATCH 14/80] Fixed a few typos in the tutorials. --- doc/tutorial-macros.md | 4 ++-- doc/tutorial-tasks.md | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/tutorial-macros.md b/doc/tutorial-macros.md index 5cd5d79bd297..8202fbe8dc53 100644 --- a/doc/tutorial-macros.md +++ b/doc/tutorial-macros.md @@ -65,7 +65,7 @@ forbidden. To take as an argument a fragment of Rust code, write `$` followed by a name (for use on the right-hand side), followed by a `:`, followed by the sort of fragment to match (the most common ones are `ident`, `expr`, `ty`, `pat`, and -`block`). Anything not preceeded by a `$` is taken literally. The standard +`block`). Anything not preceded by a `$` is taken literally. The standard rules of tokenization apply, So `($x:ident => (($e:expr)))`, though excessively fancy, would create a macro @@ -88,7 +88,7 @@ position). Going back to the motivating example, suppose that we wanted each invocation of `early_return` to potentially accept multiple "special" identifiers. The -syntax `$(...)*` accepts zero or more occurences of its contents, much like +syntax `$(...)*` accepts zero or more occurrences of its contents, much like the Kleene star operator in regular expressions. It also supports a separator token (a comma-separated list could be written `$(...),*`), and `+` instead of `*` to mean "at least one". diff --git a/doc/tutorial-tasks.md b/doc/tutorial-tasks.md index 405f4ac73478..8b9d0c0c2a7d 100644 --- a/doc/tutorial-tasks.md +++ b/doc/tutorial-tasks.md @@ -47,7 +47,7 @@ In particular, there are currently two independent modules that provide a message passing interface to Rust code: `core::comm` and `core::pipes`. `core::comm` is an older, less efficient system that is being phased out in favor of `pipes`. At some point the existing `core::comm` API will -be romoved and the user-facing portions of `core::pipes` will be moved +be removed and the user-facing portions of `core::pipes` will be moved to `core::comm`. In this tutorial we will discuss `pipes` and ignore the `comm` API. @@ -58,7 +58,7 @@ concurrency at the moment. * [`core::comm`] - The deprecated message passing API * [`core::pipes`] - The new message passing infrastructure and API * [`std::comm`] - Higher level messaging types based on `core::pipes` -* [`std::sync`] - More exotic synchronization tools, including locks +* [`std::sync`] - More exotic synchronization tools, including locks * [`std::arc`] - The ARC type, for safely sharing immutable data * [`std::par`] - Some basic tools for implementing parallel algorithms @@ -151,7 +151,7 @@ commonly used, which we will cover presently. The simplest way to create a pipe is to use the `pipes::stream` function to create a `(Chan, Port)` pair. In Rust parlance a 'channel' -is a sending endpoint of a pipe, and a 'port' is the recieving +is a sending endpoint of a pipe, and a 'port' is the receiving endpoint. Consider the following example of performing two calculations concurrently. @@ -183,7 +183,7 @@ let (chan, port): (Chan, Port) = stream(); ~~~~ The channel will be used by the child task to send data to the parent task, -which will wait to recieve the data on the port. The next statement +which will wait to receive the data on the port. The next statement spawns the child task. ~~~~ @@ -307,7 +307,7 @@ unrecoverable within a single task - once a task fails there is no way to "catch" the exception. All tasks are, by default, _linked_ to each other, meaning their fate -is interwined, and if one fails so do all of them. +is intertwined, and if one fails so do all of them. ~~~ # use task::spawn; From a06b90322cb4b61a3a20e12ab3406cff809c586c Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Thu, 4 Oct 2012 13:47:24 -0700 Subject: [PATCH 15/80] Finish de-exporting std. Part of #3583. --- src/libstd/serialization.rs | 76 +++++++++++++-------------- src/libstd/std.rc | 102 +++++++++++++++--------------------- 2 files changed, 80 insertions(+), 98 deletions(-) diff --git a/src/libstd/serialization.rs b/src/libstd/serialization.rs index e9067bc64042..502dba0be05c 100644 --- a/src/libstd/serialization.rs +++ b/src/libstd/serialization.rs @@ -4,7 +4,7 @@ Core serialization interfaces. */ -trait Serializer { +pub trait Serializer { // Primitive types: fn emit_nil(); fn emit_uint(v: uint); @@ -37,7 +37,7 @@ trait Serializer { fn emit_tup_elt(idx: uint, f: fn()); } -trait Deserializer { +pub trait Deserializer { // Primitive types: fn read_nil() -> (); @@ -81,7 +81,7 @@ trait Deserializer { // // In some cases, these should eventually be coded as traits. -fn emit_from_vec(&&s: S, &&v: ~[T], f: fn(&&x: T)) { +pub fn emit_from_vec(&&s: S, &&v: ~[T], f: fn(&&x: T)) { do s.emit_vec(vec::len(v)) { for vec::eachi(v) |i,e| { do s.emit_vec_elt(i) { @@ -91,7 +91,7 @@ fn emit_from_vec(&&s: S, &&v: ~[T], f: fn(&&x: T)) { } } -fn read_to_vec(&&d: D, f: fn() -> T) -> ~[T] { +pub fn read_to_vec(&&d: D, f: fn() -> T) -> ~[T] { do d.read_vec |len| { do vec::from_fn(len) |i| { d.read_vec_elt(i, || f()) @@ -99,7 +99,7 @@ fn read_to_vec(&&d: D, f: fn() -> T) -> ~[T] { } } -trait SerializerHelpers { +pub trait SerializerHelpers { fn emit_from_vec(&&v: ~[T], f: fn(&&x: T)); } @@ -109,7 +109,7 @@ impl S: SerializerHelpers { } } -trait DeserializerHelpers { +pub trait DeserializerHelpers { fn read_to_vec(f: fn() -> T) -> ~[T]; } @@ -119,127 +119,127 @@ impl D: DeserializerHelpers { } } -fn serialize_uint(&&s: S, v: uint) { +pub fn serialize_uint(&&s: S, v: uint) { s.emit_uint(v); } -fn deserialize_uint(&&d: D) -> uint { +pub fn deserialize_uint(&&d: D) -> uint { d.read_uint() } -fn serialize_u8(&&s: S, v: u8) { +pub fn serialize_u8(&&s: S, v: u8) { s.emit_u8(v); } -fn deserialize_u8(&&d: D) -> u8 { +pub fn deserialize_u8(&&d: D) -> u8 { d.read_u8() } -fn serialize_u16(&&s: S, v: u16) { +pub fn serialize_u16(&&s: S, v: u16) { s.emit_u16(v); } -fn deserialize_u16(&&d: D) -> u16 { +pub fn deserialize_u16(&&d: D) -> u16 { d.read_u16() } -fn serialize_u32(&&s: S, v: u32) { +pub fn serialize_u32(&&s: S, v: u32) { s.emit_u32(v); } -fn deserialize_u32(&&d: D) -> u32 { +pub fn deserialize_u32(&&d: D) -> u32 { d.read_u32() } -fn serialize_u64(&&s: S, v: u64) { +pub fn serialize_u64(&&s: S, v: u64) { s.emit_u64(v); } -fn deserialize_u64(&&d: D) -> u64 { +pub fn deserialize_u64(&&d: D) -> u64 { d.read_u64() } -fn serialize_int(&&s: S, v: int) { +pub fn serialize_int(&&s: S, v: int) { s.emit_int(v); } -fn deserialize_int(&&d: D) -> int { +pub fn deserialize_int(&&d: D) -> int { d.read_int() } -fn serialize_i8(&&s: S, v: i8) { +pub fn serialize_i8(&&s: S, v: i8) { s.emit_i8(v); } -fn deserialize_i8(&&d: D) -> i8 { +pub fn deserialize_i8(&&d: D) -> i8 { d.read_i8() } -fn serialize_i16(&&s: S, v: i16) { +pub fn serialize_i16(&&s: S, v: i16) { s.emit_i16(v); } -fn deserialize_i16(&&d: D) -> i16 { +pub fn deserialize_i16(&&d: D) -> i16 { d.read_i16() } -fn serialize_i32(&&s: S, v: i32) { +pub fn serialize_i32(&&s: S, v: i32) { s.emit_i32(v); } -fn deserialize_i32(&&d: D) -> i32 { +pub fn deserialize_i32(&&d: D) -> i32 { d.read_i32() } -fn serialize_i64(&&s: S, v: i64) { +pub fn serialize_i64(&&s: S, v: i64) { s.emit_i64(v); } -fn deserialize_i64(&&d: D) -> i64 { +pub fn deserialize_i64(&&d: D) -> i64 { d.read_i64() } -fn serialize_str(&&s: S, v: &str) { +pub fn serialize_str(&&s: S, v: &str) { s.emit_str(v); } -fn deserialize_str(&&d: D) -> ~str { +pub fn deserialize_str(&&d: D) -> ~str { d.read_str() } -fn serialize_float(&&s: S, v: float) { +pub fn serialize_float(&&s: S, v: float) { s.emit_float(v); } -fn deserialize_float(&&d: D) -> float { +pub fn deserialize_float(&&d: D) -> float { d.read_float() } -fn serialize_f32(&&s: S, v: f32) { +pub fn serialize_f32(&&s: S, v: f32) { s.emit_f32(v); } -fn deserialize_f32(&&d: D) -> f32 { +pub fn deserialize_f32(&&d: D) -> f32 { d.read_f32() } -fn serialize_f64(&&s: S, v: f64) { +pub fn serialize_f64(&&s: S, v: f64) { s.emit_f64(v); } -fn deserialize_f64(&&d: D) -> f64 { +pub fn deserialize_f64(&&d: D) -> f64 { d.read_f64() } -fn serialize_bool(&&s: S, v: bool) { +pub fn serialize_bool(&&s: S, v: bool) { s.emit_bool(v); } -fn deserialize_bool(&&d: D) -> bool { +pub fn deserialize_bool(&&d: D) -> bool { d.read_bool() } -fn serialize_Option(&&s: S, &&v: Option, st: fn(&&x: T)) { +pub fn serialize_Option(&&s: S, &&v: Option, st: fn(&&x: T)) { do s.emit_enum(~"option") { match v { None => do s.emit_enum_variant(~"none", 0u, 0u) { @@ -254,7 +254,7 @@ fn serialize_Option(&&s: S, &&v: Option, st: fn(&&x: T)) { } } -fn deserialize_Option(&&d: D, st: fn() -> T) +pub fn deserialize_Option(&&d: D, st: fn() -> T) -> Option { do d.read_enum(~"option") { do d.read_enum_variant |i| { diff --git a/src/libstd/std.rc b/src/libstd/std.rc index 6a5658d24eb0..7622f1b8de6b 100644 --- a/src/libstd/std.rc +++ b/src/libstd/std.rc @@ -18,8 +18,6 @@ not required in or otherwise suitable for the core library. #[no_core]; -#[legacy_exports]; - #[allow(vecs_implicitly_copyable)]; #[deny(non_camel_case_types)]; #[forbid(deprecated_pattern)]; @@ -27,77 +25,62 @@ not required in or otherwise suitable for the core library. extern mod core(vers = "0.4"); use core::*; -export net, net_tcp, net_ip, net_url; -export uv, uv_ll, uv_iotask, uv_global_loop; -export c_vec, timer; -export sync, arc, comm; -export bitv, deque, fun_treemap, list, map; -export smallintmap, sort, treemap; -export rope, arena, par; -export ebml, ebml2; -export dbg, getopts, json, rand, sha1, term, time; -export prettyprint, prettyprint2; -export test, tempfile, serialization, serialization2; -export cmp; -export base64; -export cell; - // General io and system-services modules -mod net; -mod net_ip; -mod net_tcp; -mod net_url; +pub mod net; +pub mod net_ip; +pub mod net_tcp; +pub mod net_url; // libuv modules -mod uv; -mod uv_ll; -mod uv_iotask; -mod uv_global_loop; +pub mod uv; +pub mod uv_ll; +pub mod uv_iotask; +pub mod uv_global_loop; // Utility modules -mod c_vec; -mod timer; -mod cell; +pub mod c_vec; +pub mod timer; +pub mod cell; // Concurrency -mod sync; -mod arc; -mod comm; +pub mod sync; +pub mod arc; +pub mod comm; // Collections -mod bitv; -mod deque; -mod fun_treemap; -mod list; -mod map; -mod rope; -mod smallintmap; -mod sort; -mod treemap; +pub mod bitv; +pub mod deque; +pub mod fun_treemap; +pub mod list; +pub mod map; +pub mod rope; +pub mod smallintmap; +pub mod sort; +pub mod treemap; // And ... other stuff -mod ebml; -mod ebml2; -mod dbg; -mod getopts; -mod json; -mod sha1; -mod md4; -mod tempfile; -mod term; -mod time; -mod prettyprint; -mod prettyprint2; -mod arena; -mod par; -mod cmp; -mod base64; +pub mod ebml; +pub mod ebml2; +pub mod dbg; +pub mod getopts; +pub mod json; +pub mod sha1; +pub mod md4; +pub mod tempfile; +pub mod term; +pub mod time; +pub mod prettyprint; +pub mod prettyprint2; +pub mod arena; +pub mod par; +pub mod cmp; +pub mod base64; #[cfg(unicode)] mod unicode; @@ -105,10 +88,9 @@ mod unicode; // Compiler support modules -mod test; -#[legacy_exports] -mod serialization; -mod serialization2; +pub mod test; +pub mod serialization; +pub mod serialization2; // Local Variables: // mode: rust; From 6ffce1a1c305d2bfeb530bac7628e2f28b4b880c Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Thu, 4 Oct 2012 13:49:37 -0700 Subject: [PATCH 16/80] De-export extfmt. Part of #3583. --- src/libcore/core.rc | 1 - src/libcore/extfmt.rs | 138 +++++++++++++++++++++--------------------- 2 files changed, 69 insertions(+), 70 deletions(-) diff --git a/src/libcore/core.rc b/src/libcore/core.rc index 0a8641b4a1b0..d59eabb22c14 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -246,7 +246,6 @@ pub mod reflect; // Modules supporting compiler-generated code // Exported but not part of the public interface -#[legacy_exports] pub mod extfmt; // The test harness links against core, so don't include runtime in tests. #[cfg(notest)] diff --git a/src/libcore/extfmt.rs b/src/libcore/extfmt.rs index e10ff4bac714..6bcf260a7290 100644 --- a/src/libcore/extfmt.rs +++ b/src/libcore/extfmt.rs @@ -41,11 +41,10 @@ use option::{Some, None}; */ // Functions used by the fmt extension at compile time -mod ct { - #[legacy_exports]; - enum Signedness { Signed, Unsigned, } - enum Caseness { CaseUpper, CaseLower, } - enum Ty { +pub mod ct { + pub enum Signedness { Signed, Unsigned, } + pub enum Caseness { CaseUpper, CaseLower, } + pub enum Ty { TyBool, TyStr, TyChar, @@ -56,14 +55,14 @@ mod ct { TyFloat, TyPoly, } - enum Flag { + pub enum Flag { FlagLeftJustify, FlagLeftZeroPad, FlagSpaceForSign, FlagSignAlways, FlagAlternate, } - enum Count { + pub enum Count { CountIs(int), CountIsParam(int), CountIsNextParam, @@ -71,7 +70,7 @@ mod ct { } // A formatted conversion from an expression to a string - type Conv = + pub type Conv = {param: Option, flags: ~[Flag], width: Count, @@ -80,10 +79,10 @@ mod ct { // A fragment of the output sequence - enum Piece { PieceString(~str), PieceConv(Conv), } - type ErrorFn = fn@(&str) -> ! ; + pub enum Piece { PieceString(~str), PieceConv(Conv), } + pub type ErrorFn = fn@(&str) -> ! ; - fn parse_fmt_string(s: &str, error: ErrorFn) -> ~[Piece] { + pub fn parse_fmt_string(s: &str, error: ErrorFn) -> ~[Piece] { let mut pieces: ~[Piece] = ~[]; let lim = str::len(s); let mut buf = ~""; @@ -118,7 +117,7 @@ mod ct { flush_buf(move buf, &mut pieces); move pieces } - fn peek_num(s: &str, i: uint, lim: uint) -> + pub fn peek_num(s: &str, i: uint, lim: uint) -> Option<{num: uint, next: uint}> { let mut j = i; let mut accum = 0u; @@ -140,7 +139,8 @@ mod ct { None } } - fn parse_conversion(s: &str, i: uint, lim: uint, error: ErrorFn) -> + pub fn parse_conversion(s: &str, i: uint, lim: uint, + error: ErrorFn) -> {piece: Piece, next: uint} { let parm = parse_parameter(s, i, lim); let flags = parse_flags(s, parm.next, lim); @@ -155,7 +155,7 @@ mod ct { ty: ty.ty}), next: ty.next}; } - fn parse_parameter(s: &str, i: uint, lim: uint) -> + pub fn parse_parameter(s: &str, i: uint, lim: uint) -> {param: Option, next: uint} { if i >= lim { return {param: None, next: i}; } let num = peek_num(s, i, lim); @@ -170,7 +170,7 @@ mod ct { } }; } - fn parse_flags(s: &str, i: uint, lim: uint) -> + pub fn parse_flags(s: &str, i: uint, lim: uint) -> {flags: ~[Flag], next: uint} { let noflags: ~[Flag] = ~[]; if i >= lim { return {flags: move noflags, next: i}; } @@ -198,7 +198,7 @@ mod ct { more(FlagAlternate, s, i, lim) } else { {flags: move noflags, next: i} }; } - fn parse_count(s: &str, i: uint, lim: uint) + pub fn parse_count(s: &str, i: uint, lim: uint) -> {count: Count, next: uint} { return if i >= lim { {count: CountImplied, next: i} @@ -220,7 +220,7 @@ mod ct { } }; } - fn parse_precision(s: &str, i: uint, lim: uint) -> + pub fn parse_precision(s: &str, i: uint, lim: uint) -> {count: Count, next: uint} { return if i >= lim { {count: CountImplied, next: i} @@ -236,7 +236,7 @@ mod ct { } } else { {count: CountImplied, next: i} }; } - fn parse_type(s: &str, i: uint, lim: uint, error: ErrorFn) -> + pub fn parse_type(s: &str, i: uint, lim: uint, error: ErrorFn) -> {ty: Ty, next: uint} { if i >= lim { error(~"missing type in conversion"); } let tstr = str::slice(s, i, i+1u); @@ -274,21 +274,20 @@ mod ct { // decisions made a runtime. If it proves worthwhile then some of these // conditions can be evaluated at compile-time. For now though it's cleaner to // implement it 0this way, I think. -mod rt { - #[legacy_exports]; - const flag_none : u32 = 0u32; - const flag_left_justify : u32 = 0b00000000000000000000000000000001u32; - const flag_left_zero_pad : u32 = 0b00000000000000000000000000000010u32; - const flag_space_for_sign : u32 = 0b00000000000000000000000000000100u32; - const flag_sign_always : u32 = 0b00000000000000000000000000001000u32; - const flag_alternate : u32 = 0b00000000000000000000000000010000u32; +pub mod rt { + pub const flag_none : u32 = 0u32; + pub const flag_left_justify : u32 = 0b00000000000001u32; + pub const flag_left_zero_pad : u32 = 0b00000000000010u32; + pub const flag_space_for_sign : u32 = 0b00000000000100u32; + pub const flag_sign_always : u32 = 0b00000000001000u32; + pub const flag_alternate : u32 = 0b00000000010000u32; - enum Count { CountIs(int), CountImplied, } - enum Ty { TyDefault, TyBits, TyHexUpper, TyHexLower, TyOctal, } + pub enum Count { CountIs(int), CountImplied, } + pub enum Ty { TyDefault, TyBits, TyHexUpper, TyHexLower, TyOctal, } - type Conv = {flags: u32, width: Count, precision: Count, ty: Ty}; + pub type Conv = {flags: u32, width: Count, precision: Count, ty: Ty}; - pure fn conv_int(cv: Conv, i: int) -> ~str { + pub pure fn conv_int(cv: Conv, i: int) -> ~str { let radix = 10; let prec = get_int_precision(cv); let mut s : ~str = int_to_str_prec(i, radix, prec); @@ -301,7 +300,7 @@ mod rt { } return unsafe { pad(cv, s, PadSigned) }; } - pure fn conv_uint(cv: Conv, u: uint) -> ~str { + pub pure fn conv_uint(cv: Conv, u: uint) -> ~str { let prec = get_int_precision(cv); let mut rs = match cv.ty { @@ -313,17 +312,17 @@ mod rt { }; return unsafe { pad(cv, rs, PadUnsigned) }; } - pure fn conv_bool(cv: Conv, b: bool) -> ~str { + pub pure fn conv_bool(cv: Conv, b: bool) -> ~str { let s = if b { ~"true" } else { ~"false" }; // run the boolean conversion through the string conversion logic, // giving it the same rules for precision, etc. return conv_str(cv, s); } - pure fn conv_char(cv: Conv, c: char) -> ~str { + pub pure fn conv_char(cv: Conv, c: char) -> ~str { let mut s = str::from_char(c); return unsafe { pad(cv, s, PadNozero) }; } - pure fn conv_str(cv: Conv, s: &str) -> ~str { + pub pure fn conv_str(cv: Conv, s: &str) -> ~str { // For strings, precision is the maximum characters // displayed let mut unpadded = match cv.precision { @@ -336,7 +335,7 @@ mod rt { }; return unsafe { pad(cv, unpadded, PadNozero) }; } - pure fn conv_float(cv: Conv, f: float) -> ~str { + pub pure fn conv_float(cv: Conv, f: float) -> ~str { let (to_str, digits) = match cv.precision { CountIs(c) => (float::to_str_exact, c as uint), CountImplied => (float::to_str, 6u) @@ -351,14 +350,14 @@ mod rt { } return unsafe { pad(cv, s, PadFloat) }; } - pure fn conv_poly(cv: Conv, v: &T) -> ~str { + pub pure fn conv_poly(cv: Conv, v: &T) -> ~str { let s = sys::log_str(v); return conv_str(cv, s); } // Convert an int to string with minimum number of digits. If precision is // 0 and num is 0 then the result is the empty string. - pure fn int_to_str_prec(num: int, radix: uint, prec: uint) -> ~str { + pub pure fn int_to_str_prec(num: int, radix: uint, prec: uint) -> ~str { return if num < 0 { ~"-" + uint_to_str_prec(-num as uint, radix, prec) } else { uint_to_str_prec(num as uint, radix, prec) }; @@ -367,7 +366,8 @@ mod rt { // Convert a uint to string with a minimum number of digits. If precision // is 0 and num is 0 then the result is the empty string. Could move this // to uint: but it doesn't seem all that useful. - pure fn uint_to_str_prec(num: uint, radix: uint, prec: uint) -> ~str { + pub pure fn uint_to_str_prec(num: uint, radix: uint, + prec: uint) -> ~str { return if prec == 0u && num == 0u { ~"" } else { @@ -380,16 +380,16 @@ mod rt { } else { move s } }; } - pure fn get_int_precision(cv: Conv) -> uint { + pub pure fn get_int_precision(cv: Conv) -> uint { return match cv.precision { CountIs(c) => c as uint, CountImplied => 1u }; } - enum PadMode { PadSigned, PadUnsigned, PadNozero, PadFloat } + pub enum PadMode { PadSigned, PadUnsigned, PadNozero, PadFloat } - impl PadMode : Eq { + pub impl PadMode : Eq { pure fn eq(other: &PadMode) -> bool { match (self, (*other)) { (PadSigned, PadSigned) => true, @@ -405,7 +405,7 @@ mod rt { pure fn ne(other: &PadMode) -> bool { !self.eq(other) } } - fn pad(cv: Conv, s: ~str, mode: PadMode) -> ~str { + pub fn pad(cv: Conv, s: ~str, mode: PadMode) -> ~str { let mut s = move s; // sadtimes let uwidth : uint = match cv.width { CountImplied => return s, @@ -458,7 +458,7 @@ mod rt { } return padstr + s; } - pure fn have_flag(flags: u32, f: u32) -> bool { + pub pure fn have_flag(flags: u32, f: u32) -> bool { flags & f != 0 } } @@ -469,21 +469,21 @@ mod rt { // decisions made a runtime. If it proves worthwhile then some of these // conditions can be evaluated at compile-time. For now though it's cleaner to // implement it 0this way, I think. -mod rt2 { - #[legacy_exports]; - const flag_none : u32 = 0u32; - const flag_left_justify : u32 = 0b00000000000000000000000000000001u32; - const flag_left_zero_pad : u32 = 0b00000000000000000000000000000010u32; - const flag_space_for_sign : u32 = 0b00000000000000000000000000000100u32; - const flag_sign_always : u32 = 0b00000000000000000000000000001000u32; - const flag_alternate : u32 = 0b00000000000000000000000000010000u32; +pub mod rt2 { - enum Count { CountIs(int), CountImplied, } - enum Ty { TyDefault, TyBits, TyHexUpper, TyHexLower, TyOctal, } + pub const flag_none : u32 = 0u32; + pub const flag_left_justify : u32 = 0b00000000000001u32; + pub const flag_left_zero_pad : u32 = 0b00000000000010u32; + pub const flag_space_for_sign : u32 = 0b00000000000100u32; + pub const flag_sign_always : u32 = 0b00000000001000u32; + pub const flag_alternate : u32 = 0b00000000010000u32; - type Conv = {flags: u32, width: Count, precision: Count, ty: Ty}; + pub enum Count { CountIs(int), CountImplied, } + pub enum Ty { TyDefault, TyBits, TyHexUpper, TyHexLower, TyOctal, } - pure fn conv_int(cv: Conv, i: int) -> ~str { + pub type Conv = {flags: u32, width: Count, precision: Count, ty: Ty}; + + pub pure fn conv_int(cv: Conv, i: int) -> ~str { let radix = 10; let prec = get_int_precision(cv); let mut s : ~str = int_to_str_prec(i, radix, prec); @@ -496,7 +496,7 @@ mod rt2 { } return unsafe { pad(cv, s, PadSigned) }; } - pure fn conv_uint(cv: Conv, u: uint) -> ~str { + pub pure fn conv_uint(cv: Conv, u: uint) -> ~str { let prec = get_int_precision(cv); let mut rs = match cv.ty { @@ -508,17 +508,17 @@ mod rt2 { }; return unsafe { pad(cv, rs, PadUnsigned) }; } - pure fn conv_bool(cv: Conv, b: bool) -> ~str { + pub pure fn conv_bool(cv: Conv, b: bool) -> ~str { let s = if b { ~"true" } else { ~"false" }; // run the boolean conversion through the string conversion logic, // giving it the same rules for precision, etc. return conv_str(cv, s); } - pure fn conv_char(cv: Conv, c: char) -> ~str { + pub pure fn conv_char(cv: Conv, c: char) -> ~str { let mut s = str::from_char(c); return unsafe { pad(cv, s, PadNozero) }; } - pure fn conv_str(cv: Conv, s: &str) -> ~str { + pub pure fn conv_str(cv: Conv, s: &str) -> ~str { // For strings, precision is the maximum characters // displayed let mut unpadded = match cv.precision { @@ -531,7 +531,7 @@ mod rt2 { }; return unsafe { pad(cv, unpadded, PadNozero) }; } - pure fn conv_float(cv: Conv, f: float) -> ~str { + pub pure fn conv_float(cv: Conv, f: float) -> ~str { let (to_str, digits) = match cv.precision { CountIs(c) => (float::to_str_exact, c as uint), CountImplied => (float::to_str, 6u) @@ -546,14 +546,14 @@ mod rt2 { } return unsafe { pad(cv, s, PadFloat) }; } - pure fn conv_poly(cv: Conv, v: &T) -> ~str { + pub pure fn conv_poly(cv: Conv, v: &T) -> ~str { let s = sys::log_str(v); return conv_str(cv, s); } // Convert an int to string with minimum number of digits. If precision is // 0 and num is 0 then the result is the empty string. - pure fn int_to_str_prec(num: int, radix: uint, prec: uint) -> ~str { + pub pure fn int_to_str_prec(num: int, radix: uint, prec: uint) -> ~str { return if num < 0 { ~"-" + uint_to_str_prec(-num as uint, radix, prec) } else { uint_to_str_prec(num as uint, radix, prec) }; @@ -562,7 +562,8 @@ mod rt2 { // Convert a uint to string with a minimum number of digits. If precision // is 0 and num is 0 then the result is the empty string. Could move this // to uint: but it doesn't seem all that useful. - pure fn uint_to_str_prec(num: uint, radix: uint, prec: uint) -> ~str { + pub pure fn uint_to_str_prec(num: uint, radix: uint, + prec: uint) -> ~str { return if prec == 0u && num == 0u { ~"" } else { @@ -575,16 +576,16 @@ mod rt2 { } else { move s } }; } - pure fn get_int_precision(cv: Conv) -> uint { + pub pure fn get_int_precision(cv: Conv) -> uint { return match cv.precision { CountIs(c) => c as uint, CountImplied => 1u }; } - enum PadMode { PadSigned, PadUnsigned, PadNozero, PadFloat } + pub enum PadMode { PadSigned, PadUnsigned, PadNozero, PadFloat } - impl PadMode : Eq { + pub impl PadMode : Eq { pure fn eq(other: &PadMode) -> bool { match (self, (*other)) { (PadSigned, PadSigned) => true, @@ -600,7 +601,7 @@ mod rt2 { pure fn ne(other: &PadMode) -> bool { !self.eq(other) } } - fn pad(cv: Conv, s: ~str, mode: PadMode) -> ~str { + pub fn pad(cv: Conv, s: ~str, mode: PadMode) -> ~str { let mut s = move s; // sadtimes let uwidth : uint = match cv.width { CountImplied => return s, @@ -653,14 +654,13 @@ mod rt2 { } return padstr + s; } - pure fn have_flag(flags: u32, f: u32) -> bool { + pub pure fn have_flag(flags: u32, f: u32) -> bool { flags & f != 0 } } #[cfg(test)] mod test { - #[legacy_exports]; #[test] fn fmt_slice() { let s = "abc"; From f05bf26f859f9e373d5044048b8c937023497690 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Thu, 4 Oct 2012 14:08:59 -0700 Subject: [PATCH 17/80] Fix long line. --- src/libstd/serialization.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libstd/serialization.rs b/src/libstd/serialization.rs index 502dba0be05c..269027a80e51 100644 --- a/src/libstd/serialization.rs +++ b/src/libstd/serialization.rs @@ -239,7 +239,8 @@ pub fn deserialize_bool(&&d: D) -> bool { d.read_bool() } -pub fn serialize_Option(&&s: S, &&v: Option, st: fn(&&x: T)) { +pub fn serialize_Option(&&s: S, &&v: Option, + st: fn(&&x: T)) { do s.emit_enum(~"option") { match v { None => do s.emit_enum_variant(~"none", 0u, 0u) { From 738cd00f1d3b40a4856785e5a96b2ca4b0cc4e7f Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 4 Oct 2012 14:09:42 -0700 Subject: [PATCH 18/80] rt: Remove CHECK_CLAIMS --- src/rt/rust.cpp | 8 -------- src/rt/rust_env.cpp | 2 -- src/rt/rust_env.h | 1 - src/rt/rust_globals.h | 4 ---- 4 files changed, 15 deletions(-) diff --git a/src/rt/rust.cpp b/src/rt/rust.cpp index 11e65347f11b..805ec37bfeae 100644 --- a/src/rt/rust.cpp +++ b/src/rt/rust.cpp @@ -67,11 +67,6 @@ command_line_args : public kernel_owned } }; -// A global that indicates whether Rust typestate claim statements should be -// executed Generated code will read this variable directly (I think). -// FIXME (#2670): This belongs somewhere else -int check_claims = 0; - void* global_crate_map = NULL; /** @@ -94,9 +89,6 @@ rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map) { update_log_settings(crate_map, env->logspec); - // Maybe turn on typestate claim checking - check_claims = env->check_claims; - rust_kernel *kernel = new rust_kernel(env); // Create the main scheduler and the main task diff --git a/src/rt/rust_env.cpp b/src/rt/rust_env.cpp index 4e653c8f9e63..268aca965d70 100644 --- a/src/rt/rust_env.cpp +++ b/src/rt/rust_env.cpp @@ -10,7 +10,6 @@ #define RUST_MIN_STACK "RUST_MIN_STACK" #define RUST_MAX_STACK "RUST_MAX_STACK" #define RUST_LOG "RUST_LOG" -#define CHECK_CLAIMS "CHECK_CLAIMS" #define DETAILED_LEAKS "DETAILED_LEAKS" #define RUST_SEED "RUST_SEED" #define RUST_POISON_ON_FREE "RUST_POISON_ON_FREE" @@ -114,7 +113,6 @@ load_env(int argc, char **argv) { env->min_stack_size = get_min_stk_size(); env->max_stack_size = get_max_stk_size(); env->logspec = copyenv(RUST_LOG); - env->check_claims = getenv(CHECK_CLAIMS) != NULL; env->detailed_leaks = getenv(DETAILED_LEAKS) != NULL; env->rust_seed = copyenv(RUST_SEED); env->poison_on_free = getenv(RUST_POISON_ON_FREE) != NULL; diff --git a/src/rt/rust_env.h b/src/rt/rust_env.h index 0e3af9eae60c..8a0ff4d1df18 100644 --- a/src/rt/rust_env.h +++ b/src/rt/rust_env.h @@ -9,7 +9,6 @@ struct rust_env { size_t min_stack_size; size_t max_stack_size; char* logspec; - bool check_claims; bool detailed_leaks; char* rust_seed; bool poison_on_free; diff --git a/src/rt/rust_globals.h b/src/rt/rust_globals.h index 84c5eca0afb6..ec60af87b6b2 100644 --- a/src/rt/rust_globals.h +++ b/src/rt/rust_globals.h @@ -69,10 +69,6 @@ extern "C" { #define FASTCALL #endif -/* Controls whether claims are turned into checks */ -/* Variable name must be kept consistent with trans.rs */ -extern "C" int check_claims; - #define CHECKED(call) \ { \ int res = (call); \ From 096bcd59b8f306a9f638058061e8f0e4ddeabae7 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 4 Oct 2012 14:16:29 -0700 Subject: [PATCH 19/80] =?UTF-8?q?Add=20Gon=C3=A7alo=20Cabrita=20to=20AUTHO?= =?UTF-8?q?RS.txt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AUTHORS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.txt b/AUTHORS.txt index 2ce2d4c51ab4..e9ff7db43848 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -42,6 +42,7 @@ Evan McClanahan Francisco Souza Gareth Daniel Smith Glenn Willen +Gonçalo Cabrita <_@gmcabrita.com> Graham Fawcett Grahame Bowland Haitao Li From e3f458e6390d66b9634e7dce4aa7e91c091aebc6 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 4 Oct 2012 14:44:19 -0700 Subject: [PATCH 20/80] docs: Explain underscore prefix in tutorial --- doc/tutorial.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index d56f1340c950..4706f47b3d9c 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -240,8 +240,13 @@ let monster_size: int = 50; ~~~~ Local variables may shadow earlier declarations, as in the previous -example in which `my_favorite_value` is first declared as a `float` -then a second `my_favorite_value` is declared as an int. +example in which `monster_size` is first declared as a `float` +then a second `monster_size` is declared as an int. If you were to actually +compile this example though, the compiler will see that the second +`monster_size` is unused, assume that you have made a mistake, and issue +a warning. For occasions where unused variables are intentional, their +name may be prefixed with an underscore to silence the warning, like +`let _monster_size = 50;`. Rust identifiers follow the same rules as C; they start with an alphabetic character or an underscore, and after that may contain any sequence of From 039110ba22f84122dc34f4a0f1a81ea225f1b6aa Mon Sep 17 00:00:00 2001 From: auREAX Date: Thu, 4 Oct 2012 23:51:54 +0200 Subject: [PATCH 21/80] Fix unnecessary tool detection at non-Linux OSes, fix GRSecurity detection documentation error. --- configure | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/configure b/configure index 07e22bed8d6d..dd734f53a3fd 100755 --- a/configure +++ b/configure @@ -344,8 +344,11 @@ probe CFG_PDFLATEX pdflatex probe CFG_XETEX xetex probe CFG_LUATEX luatex probe CFG_NODE nodejs node -probe CFG_PAXCTL paxctl /sbin/paxctl -probe CFG_ZCAT zcat +if [ "$CFG_OSTYPE" = "unknown-linux-gnu" ] +then + probe CFG_PAXCTL paxctl /sbin/paxctl + probe CFG_ZCAT zcat +fi if [ ! -z "$CFG_PANDOC" ] then @@ -370,8 +373,7 @@ then GRSEC_DETECTED= # /dev/grsec only exists if CONFIG_GRKERNSEC_NO_RBAC is not set. - # /proc is normally only available to root and users in the CONFIG_GRKERNSEC_PROC_GID group, - # and /proc/sys/kernel/grsecurity is not available if ÇONFIG_GRKERNSEC_SYSCTL is not set. + # /proc/sys/kernel/grsecurity is not available if ÇONFIG_GRKERNSEC_SYSCTL is not set. if [ -e /dev/grsec -o -d /proc/sys/kernel/grsecurity ] then GRSEC_DETECTED=1 From edc317b8212fe1c29b5e7e2e4e260b9a4d72b447 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Wed, 3 Oct 2012 19:16:27 -0700 Subject: [PATCH 22/80] Remove arg vectors from main functions. Stop supporting them. --- src/cargo/cargo.rs | 3 +- src/compiletest/compiletest.rs | 3 +- src/etc/combine-tests.py | 8 +--- src/fuzzer/fuzzer.rs | 3 +- src/rustc/driver/rustc.rs | 3 +- src/rustc/front/test.rs | 40 ++++++------------- src/rustc/middle/trans/base.rs | 20 ++-------- src/rustc/middle/typeck.rs | 6 +-- src/rustdoc/rustdoc.rs | 3 +- src/test/bench/core-map.rs | 3 +- src/test/bench/core-std.rs | 3 +- src/test/bench/core-uint-to-str.rs | 3 +- src/test/bench/core-vec-append.rs | 3 +- src/test/bench/graph500-bfs.rs | 3 +- src/test/bench/msgsend-pipes-shared.rs | 3 +- src/test/bench/msgsend-pipes.rs | 3 +- src/test/bench/msgsend-ring-mutex-arcs.rs | 3 +- src/test/bench/msgsend-ring-pipes.rs | 3 +- src/test/bench/msgsend-ring-rw-arcs.rs | 3 +- src/test/bench/msgsend-ring.rs | 3 +- src/test/bench/msgsend.rs | 3 +- src/test/bench/shootout-ackermann.rs | 3 +- src/test/bench/shootout-binarytrees.rs | 3 +- src/test/bench/shootout-chameneos-redux.rs | 3 +- src/test/bench/shootout-fannkuchredux.rs | 3 +- src/test/bench/shootout-fasta.rs | 3 +- src/test/bench/shootout-fibo.rs | 3 +- src/test/bench/shootout-k-nucleotide-pipes.rs | 3 +- src/test/bench/shootout-k-nucleotide.rs | 3 +- src/test/bench/shootout-mandelbrot.rs | 3 +- src/test/bench/shootout-nbody.rs | 3 +- src/test/bench/shootout-pfib.rs | 3 +- src/test/bench/shootout-spectralnorm.rs | 3 +- src/test/bench/shootout-threadring.rs | 3 +- src/test/bench/std-smallintmap.rs | 3 +- src/test/bench/sudoku.rs | 3 +- .../bench/task-perf-jargon-metal-smoke.rs | 3 +- src/test/bench/task-perf-linked-failure.rs | 3 +- src/test/bench/task-perf-one-million.rs | 3 +- src/test/bench/task-perf-spawnalot.rs | 3 +- .../bench/task-perf-word-count-generic.rs | 3 +- src/test/compile-fail/bad-main.rs | 2 +- src/test/run-pass/argv.rs | 5 --- src/test/run-pass/command-line-args.rs | 3 -- src/test/run-pass/main-ivec.rs | 1 - 45 files changed, 95 insertions(+), 101 deletions(-) delete mode 100644 src/test/run-pass/argv.rs delete mode 100644 src/test/run-pass/command-line-args.rs delete mode 100644 src/test/run-pass/main-ivec.rs diff --git a/src/cargo/cargo.rs b/src/cargo/cargo.rs index 81c0ce9a5b7a..e5ca758ebf4e 100644 --- a/src/cargo/cargo.rs +++ b/src/cargo/cargo.rs @@ -1889,7 +1889,8 @@ Commands: set-method Change the method for a source."); } -fn main(argv: ~[~str]) { +fn main() { + let argv = os::args(); let o = build_cargo_options(argv); if vec::len(o.free) < 2u { diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index 264ee61018bf..55fa67402687 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -12,7 +12,8 @@ use common::mode_pretty; use common::mode; use util::logv; -fn main(++args: ~[~str]) { +fn main() { + let args = os::args(); let config = parse_config(args); log_config(config); run_tests(config); diff --git a/src/etc/combine-tests.py b/src/etc/combine-tests.py index 7016713f2fee..1e3c0bcfbfc3 100755 --- a/src/etc/combine-tests.py +++ b/src/etc/combine-tests.py @@ -19,7 +19,6 @@ if not src_dir: run_pass = os.path.join(src_dir, "src", "test", "run-pass") run_pass = os.path.abspath(run_pass) stage2_tests = [] -take_args = {} for t in os.listdir(run_pass): if t.endswith(".rs") and not ( @@ -30,8 +29,6 @@ for t in os.listdir(run_pass): "xfail-fast" in s or "xfail-win32" in s): stage2_tests.append(t) - if "fn main(args:" in s or "fn main(++args:" in s: - take_args[t] = True f.close() stage2_tests.sort() @@ -64,9 +61,6 @@ for t in stage2_tests: p = os.path.join("test", "run-pass", t) p = p.replace("\\", "\\\\") d.write(" out.write_str(~\"run-pass [stage2]: %s\\n\");\n" % p) - if t in take_args: - d.write(" t_%d::main(~[~\"arg0\"]);\n" % i) - else: - d.write(" t_%d::main();\n" % i) + d.write(" t_%d::main();\n" % i) i += 1 d.write("}\n") diff --git a/src/fuzzer/fuzzer.rs b/src/fuzzer/fuzzer.rs index cd312362d6a4..3e31287e3cd1 100644 --- a/src/fuzzer/fuzzer.rs +++ b/src/fuzzer/fuzzer.rs @@ -599,7 +599,8 @@ fn check_variants(files: &[Path], cx: context) { } } -fn main(args: ~[~str]) { +fn main() { + let args = os::args(); if vec::len(args) != 2u { error!("usage: %s ", args[0]); return; diff --git a/src/rustc/driver/rustc.rs b/src/rustc/driver/rustc.rs index c6b93fc0603a..5fc48e2b6a2c 100644 --- a/src/rustc/driver/rustc.rs +++ b/src/rustc/driver/rustc.rs @@ -277,7 +277,8 @@ fn monitor(+f: fn~(diagnostic::emitter)) { } } -fn main(args: ~[~str]) { +fn main() { + let args = os::args(); do monitor |demitter| { run_compiler(args, demitter); } diff --git a/src/rustc/front/test.rs b/src/rustc/front/test.rs index 952d7b9ab793..1a6cc6dd895e 100644 --- a/src/rustc/front/test.rs +++ b/src/rustc/front/test.rs @@ -415,34 +415,12 @@ fn mk_test_wrapper(cx: test_ctxt, } fn mk_main(cx: test_ctxt) -> @ast::item { - let str_pt = path_node(~[cx.sess.ident_of(~"str")]); - let str_ty_inner = @{id: cx.sess.next_node_id(), - node: ast::ty_path(str_pt, cx.sess.next_node_id()), - span: dummy_sp()}; - let str_ty = @{id: cx.sess.next_node_id(), - node: ast::ty_uniq({ty: str_ty_inner, mutbl: ast::m_imm}), - span: dummy_sp()}; - let args_mt = {ty: str_ty, mutbl: ast::m_imm}; - let args_ty_inner = @{id: cx.sess.next_node_id(), - node: ast::ty_vec(args_mt), - span: dummy_sp()}; - let args_ty = {id: cx.sess.next_node_id(), - node: ast::ty_uniq({ty: args_ty_inner, mutbl: ast::m_imm}), - span: dummy_sp()}; - - - let args_arg: ast::arg = - {mode: ast::expl(ast::by_val), - ty: @args_ty, - ident: cx.sess.ident_of(~"args"), - id: cx.sess.next_node_id()}; - let ret_ty = {id: cx.sess.next_node_id(), node: ast::ty_nil, span: dummy_sp()}; let decl: ast::fn_decl = - {inputs: ~[args_arg], + {inputs: ~[], output: @ret_ty, cf: ast::return_val}; @@ -465,9 +443,11 @@ fn mk_main(cx: test_ctxt) -> @ast::item { } fn mk_test_main_call(cx: test_ctxt) -> @ast::expr { - - // Get the args passed to main so we can pass the to test_main - let args_path = path_node(~[cx.sess.ident_of(~"args")]); + // Call os::args to generate the vector of test_descs + let args_path = path_node(~[ + cx.sess.ident_of(~"os"), + cx.sess.ident_of(~"args") + ]); let args_path_expr_: ast::expr_ = ast::expr_path(args_path); @@ -475,6 +455,12 @@ fn mk_test_main_call(cx: test_ctxt) -> @ast::expr { {id: cx.sess.next_node_id(), callee_id: cx.sess.next_node_id(), node: args_path_expr_, span: dummy_sp()}; + let args_call_expr_ = ast::expr_call(@args_path_expr, ~[], false); + + let args_call_expr: ast::expr = + {id: cx.sess.next_node_id(), callee_id: cx.sess.next_node_id(), + node: args_call_expr_, span: dummy_sp()}; + // Call __test::test to generate the vector of test_descs let test_path = path_node(~[cx.sess.ident_of(~"tests")]); @@ -503,7 +489,7 @@ fn mk_test_main_call(cx: test_ctxt) -> @ast::expr { let test_main_call_expr_: ast::expr_ = ast::expr_call(@test_main_path_expr, - ~[@args_path_expr, @test_call_expr], false); + ~[@args_call_expr, @test_call_expr], false); let test_main_call_expr: ast::expr = {id: cx.sess.next_node_id(), callee_id: cx.sess.next_node_id(), diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index 0631d7b1ea4d..ce596586ddc4 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -1953,32 +1953,23 @@ fn register_fn_fuller(ccx: @crate_ctxt, sp: span, path: path, ast_map::path_to_str(path, ccx.sess.parse_sess.interner)); let is_main = is_main_name(path) && !ccx.sess.building_library; - if is_main { create_main_wrapper(ccx, sp, llfn, node_type); } + if is_main { create_main_wrapper(ccx, sp, llfn); } llfn } // Create a _rust_main(args: ~[str]) function which will be called from the // runtime rust_start function -fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef, - main_node_type: ty::t) { +fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef) { if ccx.main_fn != None:: { ccx.sess.span_fatal(sp, ~"multiple 'main' functions"); } - let main_takes_argv = - // invariant! - match ty::get(main_node_type).sty { - ty::ty_fn(ref fn_ty) => fn_ty.sig.inputs.len() != 0u, - _ => ccx.sess.span_fatal(sp, ~"main has a non-function type") - }; - - let llfn = create_main(ccx, main_llfn, main_takes_argv); + let llfn = create_main(ccx, main_llfn); ccx.main_fn = Some(llfn); create_entry_fn(ccx, llfn); - fn create_main(ccx: @crate_ctxt, main_llfn: ValueRef, - takes_argv: bool) -> ValueRef { + fn create_main(ccx: @crate_ctxt, main_llfn: ValueRef) -> ValueRef { let unit_ty = ty::mk_estr(ccx.tcx, ty::vstore_uniq); let vecarg_ty: ty::arg = {mode: ast::expl(ast::by_val), @@ -1998,9 +1989,6 @@ fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef, let lloutputarg = llvm::LLVMGetParam(llfdecl, 0 as c_uint); let llenvarg = llvm::LLVMGetParam(llfdecl, 1 as c_uint); let mut args = ~[lloutputarg, llenvarg]; - if takes_argv { - args.push(llvm::LLVMGetParam(llfdecl, 2 as c_uint)); - } Call(bcx, main_llfn, args); build_return(bcx); diff --git a/src/rustc/middle/typeck.rs b/src/rustc/middle/typeck.rs index e0b2ca5ae642..3a9471139f96 100644 --- a/src/rustc/middle/typeck.rs +++ b/src/rustc/middle/typeck.rs @@ -301,14 +301,12 @@ fn check_main_fn_ty(ccx: @crate_ctxt, } let mut ok = ty::type_is_nil(fn_ty.sig.output); let num_args = vec::len(fn_ty.sig.inputs); - ok &= num_args == 0u || num_args == 1u && - arg_is_argv_ty(tcx, fn_ty.sig.inputs[0]); + ok &= num_args == 0u; if !ok { tcx.sess.span_err( main_span, fmt!("Wrong type in main function: found `%s`, \ - expected `extern fn(++v: ~[~str]) -> ()` \ - or `extern fn() -> ()`", + expected `fn() -> ()`", ty_to_str(tcx, main_t))); } } diff --git a/src/rustdoc/rustdoc.rs b/src/rustdoc/rustdoc.rs index 50ebef05afbe..b79b6ba21899 100755 --- a/src/rustdoc/rustdoc.rs +++ b/src/rustdoc/rustdoc.rs @@ -3,7 +3,8 @@ use doc::Item; use pass::Pass; use config::Config; -fn main(args: ~[~str]) { +fn main() { + let args = os::args(); if args.contains(&~"-h") || args.contains(&~"--help") { config::usage(); diff --git a/src/test/bench/core-map.rs b/src/test/bench/core-map.rs index afd9b2ccc9ca..09a5415823ce 100644 --- a/src/test/bench/core-map.rs +++ b/src/test/bench/core-map.rs @@ -142,7 +142,8 @@ fn empty_results() -> Results { } } -fn main(++args: ~[~str]) { +fn main() { + let args = os::args(); let num_keys = { if args.len() == 2 { uint::from_str(args[1]).get() diff --git a/src/test/bench/core-std.rs b/src/test/bench/core-std.rs index cf44d4783562..6f90a2c99e81 100644 --- a/src/test/bench/core-std.rs +++ b/src/test/bench/core-std.rs @@ -8,7 +8,8 @@ use std::map::{Map, HashMap}; use io::{Reader, ReaderUtil}; -fn main(++argv: ~[~str]) { +fn main() { + let argv = os::args(); #macro[ [#bench[id], maybe_run_test(argv, #stringify(id), id) diff --git a/src/test/bench/core-uint-to-str.rs b/src/test/bench/core-uint-to-str.rs index 05643536dc0a..4b1e9519715e 100644 --- a/src/test/bench/core-uint-to-str.rs +++ b/src/test/bench/core-uint-to-str.rs @@ -1,4 +1,5 @@ -fn main(++args: ~[~str]) { +fn main() { + let args = os::args(); let args = if os::getenv(~"RUST_BENCH").is_some() { ~[~"", ~"10000000"] } else if args.len() <= 1u { diff --git a/src/test/bench/core-vec-append.rs b/src/test/bench/core-vec-append.rs index 2b9216876b42..1adbd20f4cde 100644 --- a/src/test/bench/core-vec-append.rs +++ b/src/test/bench/core-vec-append.rs @@ -20,7 +20,8 @@ fn collect_dvec(num: uint) -> ~[uint] { return dvec::unwrap(move result); } -fn main(++args: ~[~str]) { +fn main() { + let args = os::args(); let args = if os::getenv(~"RUST_BENCH").is_some() { ~[~"", ~"50000000"] } else if args.len() <= 1u { diff --git a/src/test/bench/graph500-bfs.rs b/src/test/bench/graph500-bfs.rs index a34fcc89c048..5acde71c6fd6 100644 --- a/src/test/bench/graph500-bfs.rs +++ b/src/test/bench/graph500-bfs.rs @@ -384,7 +384,8 @@ fn validate(edges: ~[(node_id, node_id)], true } -fn main(++args: ~[~str]) { +fn main() { + let args = os::args(); let args = if os::getenv(~"RUST_BENCH").is_some() { ~[~"", ~"15", ~"48"] } else if args.len() <= 1u { diff --git a/src/test/bench/msgsend-pipes-shared.rs b/src/test/bench/msgsend-pipes-shared.rs index 0a55e7572db9..d60937af13c8 100644 --- a/src/test/bench/msgsend-pipes-shared.rs +++ b/src/test/bench/msgsend-pipes-shared.rs @@ -90,7 +90,8 @@ fn run(args: &[~str]) { assert result == num_bytes * size; } -fn main(++args: ~[~str]) { +fn main() { + let args = os::args(); let args = if os::getenv(~"RUST_BENCH").is_some() { ~[~"", ~"1000000", ~"10000"] } else if args.len() <= 1u { diff --git a/src/test/bench/msgsend-pipes.rs b/src/test/bench/msgsend-pipes.rs index ab67a8c7cb12..e2d115600eff 100644 --- a/src/test/bench/msgsend-pipes.rs +++ b/src/test/bench/msgsend-pipes.rs @@ -87,7 +87,8 @@ fn run(args: &[~str]) { assert result == num_bytes * size; } -fn main(++args: ~[~str]) { +fn main() { + let args = os::args(); let args = if os::getenv(~"RUST_BENCH").is_some() { ~[~"", ~"1000000", ~"8"] } else if args.len() <= 1u { diff --git a/src/test/bench/msgsend-ring-mutex-arcs.rs b/src/test/bench/msgsend-ring-mutex-arcs.rs index ec144b78a10a..f657884eeef8 100644 --- a/src/test/bench/msgsend-ring-mutex-arcs.rs +++ b/src/test/bench/msgsend-ring-mutex-arcs.rs @@ -56,7 +56,8 @@ fn thread_ring(i: uint, }; } -fn main(++args: ~[~str]) { +fn main() { + let args = os::args(); let args = if os::getenv(~"RUST_BENCH").is_some() { ~[~"", ~"100", ~"10000"] } else if args.len() <= 1u { diff --git a/src/test/bench/msgsend-ring-pipes.rs b/src/test/bench/msgsend-ring-pipes.rs index 119c2065d6bc..73942d4ddf8f 100644 --- a/src/test/bench/msgsend-ring-pipes.rs +++ b/src/test/bench/msgsend-ring-pipes.rs @@ -52,7 +52,8 @@ fn thread_ring(i: uint, }; } -fn main(++args: ~[~str]) { +fn main() { + let args = os::args(); let args = if os::getenv(~"RUST_BENCH").is_some() { ~[~"", ~"100", ~"10000"] } else if args.len() <= 1u { diff --git a/src/test/bench/msgsend-ring-rw-arcs.rs b/src/test/bench/msgsend-ring-rw-arcs.rs index 1b857b6caeb8..386496f459d8 100644 --- a/src/test/bench/msgsend-ring-rw-arcs.rs +++ b/src/test/bench/msgsend-ring-rw-arcs.rs @@ -56,7 +56,8 @@ fn thread_ring(i: uint, }; } -fn main(++args: ~[~str]) { +fn main() { + let args = os::args(); let args = if os::getenv(~"RUST_BENCH").is_some() { ~[~"", ~"100", ~"10000"] } else if args.len() <= 1u { diff --git a/src/test/bench/msgsend-ring.rs b/src/test/bench/msgsend-ring.rs index 5533aeeeb41b..2be21d946af2 100644 --- a/src/test/bench/msgsend-ring.rs +++ b/src/test/bench/msgsend-ring.rs @@ -21,7 +21,8 @@ fn thread_ring(i: uint, }; } -fn main(++args: ~[~str]) { +fn main() { + let args = os::args(); let args = if os::getenv(~"RUST_BENCH").is_some() { ~[~"", ~"100", ~"10000"] } else if args.len() <= 1u { diff --git a/src/test/bench/msgsend.rs b/src/test/bench/msgsend.rs index fb1e3ae92262..8564adaab729 100644 --- a/src/test/bench/msgsend.rs +++ b/src/test/bench/msgsend.rs @@ -57,7 +57,8 @@ fn run(args: ~[~str]) { io::stdout().write_str(fmt!("Throughput=%f per sec\n", thruput)); } -fn main(++args: ~[~str]) { +fn main() { + let args = os::args(); let args = if os::getenv(~"RUST_BENCH").is_some() { ~[~"", ~"1000000", ~"10000"] } else if args.len() <= 1u { diff --git a/src/test/bench/shootout-ackermann.rs b/src/test/bench/shootout-ackermann.rs index 03985a22d112..edccf15a4401 100644 --- a/src/test/bench/shootout-ackermann.rs +++ b/src/test/bench/shootout-ackermann.rs @@ -12,7 +12,8 @@ fn ack(m: int, n: int) -> int { } } -fn main(++args: ~[~str]) { +fn main() { + let args = os::args(); let args = if os::getenv(~"RUST_BENCH").is_some() { ~[~"", ~"12"] } else if args.len() <= 1u { diff --git a/src/test/bench/shootout-binarytrees.rs b/src/test/bench/shootout-binarytrees.rs index 2003c16fe6f7..be58bc0595e9 100644 --- a/src/test/bench/shootout-binarytrees.rs +++ b/src/test/bench/shootout-binarytrees.rs @@ -25,7 +25,8 @@ fn bottom_up_tree(arena: &r/arena::Arena, return arena.alloc(|| nil); } -fn main(++args: ~[~str]) { +fn main() { + let args = os::args(); let args = if os::getenv(~"RUST_BENCH").is_some() { ~[~"", ~"17"] } else if args.len() <= 1u { diff --git a/src/test/bench/shootout-chameneos-redux.rs b/src/test/bench/shootout-chameneos-redux.rs index 5c7827f5106d..11c06d45bc88 100644 --- a/src/test/bench/shootout-chameneos-redux.rs +++ b/src/test/bench/shootout-chameneos-redux.rs @@ -178,7 +178,8 @@ fn rendezvous(nn: uint, set: ~[color]) { io::println(show_number(creatures_met)); } -fn main(++args: ~[~str]) { +fn main() { + let args = os::args(); let args = if os::getenv(~"RUST_BENCH").is_some() { ~[~"", ~"200000"] } else if args.len() <= 1u { diff --git a/src/test/bench/shootout-fannkuchredux.rs b/src/test/bench/shootout-fannkuchredux.rs index 19dced9aa183..1fbdaddaead8 100644 --- a/src/test/bench/shootout-fannkuchredux.rs +++ b/src/test/bench/shootout-fannkuchredux.rs @@ -56,7 +56,8 @@ fn fannkuch(n: int) -> int { return flips; } -fn main(++args: ~[~str]) { +fn main() { + let args = os::args(); let args = if os::getenv(~"RUST_BENCH").is_some() { ~[~"", ~"10"] } else if args.len() <= 1u { diff --git a/src/test/bench/shootout-fasta.rs b/src/test/bench/shootout-fasta.rs index 0c742e16bfa5..f230664495f1 100644 --- a/src/test/bench/shootout-fasta.rs +++ b/src/test/bench/shootout-fasta.rs @@ -70,7 +70,8 @@ fn make_repeat_fasta(wr: io::Writer, id: ~str, desc: ~str, s: ~str, n: int) unsa fn acid(ch: char, prob: u32) -> aminoacids { return {ch: ch, prob: prob}; } -fn main(++args: ~[~str]) { +fn main() { + let args = os::args(); let args = if os::getenv(~"RUST_BENCH").is_some() { // alioth tests k-nucleotide with this data at 25,000,000 ~[~"", ~"5000000"] diff --git a/src/test/bench/shootout-fibo.rs b/src/test/bench/shootout-fibo.rs index 9c39ed4aad1d..548dd1e7d79d 100644 --- a/src/test/bench/shootout-fibo.rs +++ b/src/test/bench/shootout-fibo.rs @@ -8,7 +8,8 @@ fn fib(n: int) -> int { } } -fn main(++args: ~[~str]) { +fn main() { + let args = os::args(); let args = if os::getenv(~"RUST_BENCH").is_some() { ~[~"", ~"40"] } else if args.len() <= 1u { diff --git a/src/test/bench/shootout-k-nucleotide-pipes.rs b/src/test/bench/shootout-k-nucleotide-pipes.rs index 4f821a534ab4..2e9f8e98dd37 100644 --- a/src/test/bench/shootout-k-nucleotide-pipes.rs +++ b/src/test/bench/shootout-k-nucleotide-pipes.rs @@ -128,7 +128,8 @@ fn make_sequence_processor(sz: uint, from_parent: pipes::Port<~[u8]>, } // given a FASTA file on stdin, process sequence THREE -fn main(++args: ~[~str]) { +fn main() { + let args = os::args(); let rdr = if os::getenv(~"RUST_BENCH").is_some() { // FIXME: Using this compile-time env variable is a crummy way to // get to this massive data set, but #include_bin chokes on it (#2598) diff --git a/src/test/bench/shootout-k-nucleotide.rs b/src/test/bench/shootout-k-nucleotide.rs index 3b00fd99a553..ae162221503e 100644 --- a/src/test/bench/shootout-k-nucleotide.rs +++ b/src/test/bench/shootout-k-nucleotide.rs @@ -125,7 +125,8 @@ fn make_sequence_processor(sz: uint, from_parent: comm::Port<~[u8]>, } // given a FASTA file on stdin, process sequence THREE -fn main(++args: ~[~str]) { +fn main() { + let args = os::args(); let rdr = if os::getenv(~"RUST_BENCH").is_some() { // FIXME: Using this compile-time env variable is a crummy way to // get to this massive data set, but #include_bin chokes on it (#2598) diff --git a/src/test/bench/shootout-mandelbrot.rs b/src/test/bench/shootout-mandelbrot.rs index ee38b957b0cb..8ab58207fd14 100644 --- a/src/test/bench/shootout-mandelbrot.rs +++ b/src/test/bench/shootout-mandelbrot.rs @@ -151,7 +151,8 @@ fn writer(path: ~str, writech: comm::Chan>, size: uint) } } -fn main(++args: ~[~str]) { +fn main() { + let args = os::args(); let args = if os::getenv(~"RUST_BENCH").is_some() { ~[~"", ~"4000", ~"10"] } else { diff --git a/src/test/bench/shootout-nbody.rs b/src/test/bench/shootout-nbody.rs index e2d3d2a429eb..a1199511907c 100644 --- a/src/test/bench/shootout-nbody.rs +++ b/src/test/bench/shootout-nbody.rs @@ -14,7 +14,8 @@ extern mod libc { fn sqrt(n: float) -> float; } -fn main(++args: ~[~str]) { +fn main() { + let args = os::args(); let args = if os::getenv(~"RUST_BENCH").is_some() { ~[~"", ~"4000000"] } else if args.len() <= 1u { diff --git a/src/test/bench/shootout-pfib.rs b/src/test/bench/shootout-pfib.rs index 90224645f84c..fa97e796bd1c 100644 --- a/src/test/bench/shootout-pfib.rs +++ b/src/test/bench/shootout-pfib.rs @@ -81,7 +81,8 @@ fn stress(num_tasks: int) { for results.each |r| { future::get(r); } } -fn main(++args: ~[~str]) { +fn main() { + let args = os::args(); let args = if os::getenv(~"RUST_BENCH").is_some() { ~[~"", ~"20"] } else if args.len() <= 1u { diff --git a/src/test/bench/shootout-spectralnorm.rs b/src/test/bench/shootout-spectralnorm.rs index 1f00c419de80..781ecce7ff72 100644 --- a/src/test/bench/shootout-spectralnorm.rs +++ b/src/test/bench/shootout-spectralnorm.rs @@ -40,7 +40,8 @@ fn eval_AtA_times_u(u: ~[const float], AtAu: ~[mut float]) { eval_At_times_u(v, AtAu); } -fn main(++args: ~[~str]) { +fn main() { + let args = os::args(); let args = if os::getenv(~"RUST_BENCH").is_some() { ~[~"", ~"2000"] } else if args.len() <= 1u { diff --git a/src/test/bench/shootout-threadring.rs b/src/test/bench/shootout-threadring.rs index 43229d1db133..8bee12b22437 100644 --- a/src/test/bench/shootout-threadring.rs +++ b/src/test/bench/shootout-threadring.rs @@ -37,7 +37,8 @@ fn roundtrip(id: int, p: comm::Port, ch: comm::Chan) { } } -fn main(++args: ~[~str]) { +fn main() { + let args = os::args(); let args = if os::getenv(~"RUST_BENCH").is_some() { ~[~"", ~"2000000"] } else if args.len() <= 1u { diff --git a/src/test/bench/std-smallintmap.rs b/src/test/bench/std-smallintmap.rs index 3fdbe028b708..2ac651862213 100644 --- a/src/test/bench/std-smallintmap.rs +++ b/src/test/bench/std-smallintmap.rs @@ -17,7 +17,8 @@ fn check_sequential(min: uint, max: uint, map: SmallIntMap) { } } -fn main(++args: ~[~str]) { +fn main() { + let args = os::args(); let args = if os::getenv(~"RUST_BENCH").is_some() { ~[~"", ~"100000", ~"100"] } else if args.len() <= 1u { diff --git a/src/test/bench/sudoku.rs b/src/test/bench/sudoku.rs index 8f4e509e6294..2e8ef0bac582 100644 --- a/src/test/bench/sudoku.rs +++ b/src/test/bench/sudoku.rs @@ -126,7 +126,8 @@ fn write_grid(f: io::Writer, g: grid_t) { } } -fn main(++args: ~[~str]) { +fn main() { + let args = os::args(); let grid = if vec::len(args) == 1u { // FIXME create sudoku inline since nested vec consts dont work yet // (#571) diff --git a/src/test/bench/task-perf-jargon-metal-smoke.rs b/src/test/bench/task-perf-jargon-metal-smoke.rs index 53735cdbb16a..2055993d441e 100644 --- a/src/test/bench/task-perf-jargon-metal-smoke.rs +++ b/src/test/bench/task-perf-jargon-metal-smoke.rs @@ -23,7 +23,8 @@ fn child_generation(gens_left: uint, -c: pipes::Chan<()>) { } } -fn main(++args: ~[~str]) { +fn main() { + let args = os::args(); let args = if os::getenv(~"RUST_BENCH").is_some() { ~[~"", ~"100000"] } else if args.len() <= 1u { diff --git a/src/test/bench/task-perf-linked-failure.rs b/src/test/bench/task-perf-linked-failure.rs index 1ba92bfadee8..a59b932f7e12 100644 --- a/src/test/bench/task-perf-linked-failure.rs +++ b/src/test/bench/task-perf-linked-failure.rs @@ -37,7 +37,8 @@ fn spawn_supervised_blocking(myname: &str, +f: fn~()) { assert x == task::Success; } -fn main(++args: ~[~str]) { +fn main() { + let args = os::args(); let args = if os::getenv(~"RUST_BENCH").is_some() { ~[~"", ~"100000"] } else if args.len() <= 1u { diff --git a/src/test/bench/task-perf-one-million.rs b/src/test/bench/task-perf-one-million.rs index c9d4fb6b4d87..39fe02eac799 100644 --- a/src/test/bench/task-perf-one-million.rs +++ b/src/test/bench/task-perf-one-million.rs @@ -48,7 +48,8 @@ fn calc(children: uint, parent_ch: comm::Chan) { comm::send(parent_ch, done(sum + 1)); } -fn main(++args: ~[~str]) { +fn main() { + let args = os::args(); let args = if os::getenv(~"RUST_BENCH").is_some() { ~[~"", ~"100000"] } else if args.len() <= 1u { diff --git a/src/test/bench/task-perf-spawnalot.rs b/src/test/bench/task-perf-spawnalot.rs index 48af1dcd5049..dfa53c3328b5 100644 --- a/src/test/bench/task-perf-spawnalot.rs +++ b/src/test/bench/task-perf-spawnalot.rs @@ -8,7 +8,8 @@ fn f(&&n: uint) { fn g() { } -fn main(++args: ~[~str]) { +fn main() { + let args = os::args(); let args = if os::getenv(~"RUST_BENCH").is_some() { ~[~"", ~"400"] } else if args.len() <= 1u { diff --git a/src/test/bench/task-perf-word-count-generic.rs b/src/test/bench/task-perf-word-count-generic.rs index 626123665243..1002e97497d0 100644 --- a/src/test/bench/task-perf-word-count-generic.rs +++ b/src/test/bench/task-perf-word-count-generic.rs @@ -288,7 +288,8 @@ mod map_reduce { } } -fn main(++argv: ~[~str]) { +fn main() { + let argv = os::args(); if vec::len(argv) < 2u && !os::getenv(~"RUST_BENCH").is_some() { let out = io::stdout(); diff --git a/src/test/compile-fail/bad-main.rs b/src/test/compile-fail/bad-main.rs index 79364a1bb520..3bd1f47307b7 100644 --- a/src/test/compile-fail/bad-main.rs +++ b/src/test/compile-fail/bad-main.rs @@ -1,3 +1,3 @@ -// error-pattern:expected `extern fn(++v: ~[~str]) +// error-pattern:expected `fn() fn main(x: int) { } diff --git a/src/test/run-pass/argv.rs b/src/test/run-pass/argv.rs deleted file mode 100644 index a697e0f73dcb..000000000000 --- a/src/test/run-pass/argv.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn main(++args: ~[~str]) { - let vs: ~[~str] = ~[~"hi", ~"there", ~"this", ~"is", ~"a", ~"vec"]; - let vvs: ~[~[~str]] = ~[args, vs]; - for vvs.each |vs| { for vs.each |s| { log(debug, *s); } } -} diff --git a/src/test/run-pass/command-line-args.rs b/src/test/run-pass/command-line-args.rs deleted file mode 100644 index 242392ccbe17..000000000000 --- a/src/test/run-pass/command-line-args.rs +++ /dev/null @@ -1,3 +0,0 @@ - - -fn main(++args: ~[~str]) { log(debug, args[0]); } diff --git a/src/test/run-pass/main-ivec.rs b/src/test/run-pass/main-ivec.rs deleted file mode 100644 index 39bbd07c66b1..000000000000 --- a/src/test/run-pass/main-ivec.rs +++ /dev/null @@ -1 +0,0 @@ -fn main(++args: ~[~str]) { for args.each |s| { log(debug, *s); } } From 26ed387d7faec2e86289855098f08c56986e2568 Mon Sep 17 00:00:00 2001 From: auREAX Date: Fri, 5 Oct 2012 00:08:34 +0200 Subject: [PATCH 23/80] Rename configure --enable-pax-marks flag to --enable-pax-flags flag. --- configure | 14 +++++++------- mk/stage0.mk | 4 ++-- mk/target.mk | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/configure b/configure index dd734f53a3fd..58fc25eea9e4 100755 --- a/configure +++ b/configure @@ -295,7 +295,7 @@ opt manage-submodules 1 "let the build manage the git submodules" opt mingw-cross 0 "cross-compile for win32 using mingw" opt clang 0 "prefer clang to gcc for building the runtime" opt local-rust 0 "use an installed rustc rather than downloading a snapshot" -opt pax-marks 0 "apply PaX markings to rustc binaries (required for GRSecurity/PaX-patched kernels)" +opt pax-flags 0 "apply PaX flags to rustc binaries (required for GRSecurity/PaX-patched kernels)" valopt prefix "/usr/local" "set installation prefix" valopt local-rust-root "/usr/local" "set prefix for local rust binary" valopt llvm-root "" "set LLVM root" @@ -362,12 +362,12 @@ fi if [ "$CFG_OSTYPE" = "unknown-linux-gnu" ] then - if [ ! -z "$CFG_ENABLE_PAX_MARKS" -a -z "$CFG_PAXCTL" ] + if [ ! -z "$CFG_ENABLE_PAX_FLAGS" -a -z "$CFG_PAXCTL" ] then err "enabled PaX markings but no paxctl binary found" fi - if [ -z "$CFG_DISABLE_PAX_MARKS" ] + if [ -z "$CFG_DISABLE_PAX_FLAGS" ] then # GRSecurity/PaX detection. This can be very flaky. GRSEC_DETECTED= @@ -395,9 +395,9 @@ then step_msg "GRSecurity: yes" if [ ! -z "$CFG_PAXCTL" ] then - CFG_ENABLE_PAX_MARKS=1 + CFG_ENABLE_PAX_FLAGS=1 else - warn "GRSecurity kernel detected but no paxctl binary found: not setting CFG_ENABLE_PAX_MARKS" + warn "GRSecurity kernel detected but no paxctl binary found: not setting CFG_ENABLE_PAX_FLAGS" fi else step_msg "GRSecurity: no" @@ -750,9 +750,9 @@ putvar CFG_C_COMPILER putvar CFG_LIBDIR putvar CFG_DISABLE_MANAGE_SUBMODULES -if [ ! -z "$CFG_ENABLE_PAX_MARKS" ] +if [ ! -z "$CFG_ENABLE_PAX_FLAGS" ] then - putvar CFG_ENABLE_PAX_MARKS + putvar CFG_ENABLE_PAX_FLAGS putvar CFG_PAXCTL fi diff --git a/mk/stage0.mk b/mk/stage0.mk index fae6b3742f81..b64f5df9ca03 100644 --- a/mk/stage0.mk +++ b/mk/stage0.mk @@ -12,8 +12,8 @@ ifdef CFG_ENABLE_LOCAL_RUST $(Q)$(S)src/etc/local_stage0.sh $(CFG_HOST_TRIPLE) $(CFG_LOCAL_RUST_ROOT) else $(Q)$(S)src/etc/get-snapshot.py $(CFG_HOST_TRIPLE) $(SNAPSHOT_FILE) -ifdef CFG_ENABLE_PAX_MARKS - @$(call E, apply PaX markings: $@) +ifdef CFG_ENABLE_PAX_FLAGS + @$(call E, apply PaX flags: $@) @"$(CFG_PAXCTL)" -cm "$@" endif endif diff --git a/mk/target.mk b/mk/target.mk index 458d2a4ac63b..967191ab7450 100644 --- a/mk/target.mk +++ b/mk/target.mk @@ -29,8 +29,8 @@ $$(TBIN$(1)_T_$(2)_H_$(3))/rustc$$(X): \ $$(TLIBRUSTC_DEFAULT$(1)_T_$(2)_H_$(3)) @$$(call E, compile_and_link: $$@) $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< -ifdef CFG_ENABLE_PAX_MARKS - @$$(call E, apply PaX markings: $$@) +ifdef CFG_ENABLE_PAX_FLAGS + @$$(call E, apply PaX flags: $$@) @"$(CFG_PAXCTL)" -cm "$$@" endif From c83218de12748a678e873813a6b8381f46fae590 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 4 Oct 2012 15:14:28 -0700 Subject: [PATCH 24/80] core: Improve option docs a little --- src/libcore/option.rs | 136 ++++++++++++++++++++++++++++++++---------- 1 file changed, 105 insertions(+), 31 deletions(-) diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 6bd326186cb4..1cdd4511e295 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -1,12 +1,35 @@ /*! - * Operations on the ubiquitous `option` type. - * - * Type `option` represents an optional value. - * - * Every `Option` value can either be `Some(T)` or `none`. Where in other - * languages you might use a nullable type, in Rust you would use an option - * type. - */ + +Operations on the ubiquitous `Option` type. + +Type `Option` represents an optional value. + +Every `Option` value can either be `Some(T)` or `None`. Where in other +languages you might use a nullable type, in Rust you would use an option +type. + +Options are most commonly used with pattern matching to query the presence +of a value and take action, always accounting for the `None` case. + +# Example + +~~~ +let msg = Some(~"howdy"); + +// Take a reference to the contained string +match msg { + Some(ref m) => io::println(m), + None => () +} + +// Remove the contained string, destroying the Option +let unwrapped_msg = match move msg { + Some(move m) => m, + None => ~"default message" +}; +~~~ + +*/ // NB: transitionary, de-mode-ing. #[warn(deprecated_mode)]; @@ -22,12 +45,19 @@ pub enum Option { pub pure fn get(opt: &Option) -> T { /*! - * Gets the value out of an option - * - * # Failure - * - * Fails if the value equals `none` - */ + Gets the value out of an option + + # Failure + + Fails if the value equals `None` + + # Safety note + + In general, because this function may fail, its use is discouraged + (calling `get` on `None` is akin to dereferencing a null pointer). + Instead, prefer to use pattern matching and handle the `None` + case explicitly. + */ match *opt { Some(copy x) => return x, @@ -37,11 +67,18 @@ pub pure fn get(opt: &Option) -> T { pub pure fn get_ref(opt: &r/Option) -> &r/T { /*! - * Gets an immutable reference to the value inside an option. - * - * # Failure - * - * Fails if the value equals `none` + Gets an immutable reference to the value inside an option. + + # Failure + + Fails if the value equals `None` + + # Safety note + + In general, because this function may fail, its use is discouraged + (calling `get` on `None` is akin to dereferencing a null pointer). + Instead, prefer to use pattern matching and handle the `None` + case explicitly. */ match *opt { Some(ref x) => x, @@ -154,10 +191,20 @@ pub pure fn iter(opt: &Option, f: fn(x: &T)) { #[inline(always)] pub pure fn unwrap(opt: Option) -> T { /*! - * Moves a value out of an option type and returns it. - * - * Useful primarily for getting strings, vectors and unique pointers out - * of option types without copying them. + Moves a value out of an option type and returns it. + + Useful primarily for getting strings, vectors and unique pointers out + of option types without copying them. + + # Failure + + Fails if the value equals `None`. + + # Safety note + + In general, because this function may fail, its use is discouraged. + Instead, prefer to use pattern matching and handle the `None` + case explicitly. */ match move opt { Some(move x) => move x, @@ -165,9 +212,16 @@ pub pure fn unwrap(opt: Option) -> T { } } -/// The ubiquitous option dance. #[inline(always)] pub fn swap_unwrap(opt: &mut Option) -> T { + /*! + The option dance. Moves a value out of an option type and returns it, + replacing the original with `None`. + + # Failure + + Fails if the value equals `None`. + */ if opt.is_none() { fail ~"option::swap_unwrap none" } unwrap(util::replace(opt, None)) } @@ -201,18 +255,38 @@ impl &Option { 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) } - /// Gets an immutable reference to the value inside a `some`. + /** + Gets an immutable reference to the value inside an option. + + # Failure + + Fails if the value equals `None` + + # Safety note + + In general, because this function may fail, its use is discouraged + (calling `get` on `None` is akin to dereferencing a null pointer). + Instead, prefer to use pattern matching and handle the `None` + case explicitly. + */ pure fn get_ref() -> &self/T { get_ref(self) } } impl Option { /** - * Gets the value out of an option - * - * # Failure - * - * Fails if the value equals `none` - */ + Gets the value out of an option + + # Failure + + Fails if the value equals `None` + + # Safety note + + In general, because this function may fail, its use is discouraged + (calling `get` on `None` is akin to dereferencing a null pointer). + Instead, prefer to use pattern matching and handle the `None` + case explicitly. + */ pure fn get() -> T { get(&self) } pure fn get_default(def: T) -> T { get_default(&self, def) } /** From 2d5cac960d1950a58f8df604183a2c333d6b4d76 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 4 Oct 2012 15:41:14 -0700 Subject: [PATCH 25/80] rt: Remove check_claims from the export list --- src/rt/rustrt.def.in | 1 - 1 file changed, 1 deletion(-) diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index 7412f06d8cd8..890aa352c927 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -1,4 +1,3 @@ -check_claims debug_box debug_fn debug_opaque From c37c243e95df30d22f0dc495312771557e9b2bcc Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Thu, 4 Oct 2012 15:54:50 -0700 Subject: [PATCH 26/80] Remove some residue, core is effectively de-exported now. Close #3583. --- src/libcore/core.rc | 48 +++------------------------------------------ 1 file changed, 3 insertions(+), 45 deletions(-) diff --git a/src/libcore/core.rc b/src/libcore/core.rc index d59eabb22c14..94e6decc4ca8 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -36,54 +36,12 @@ Implicitly, all crates behave as if they included the following prologue: // Don't link to core. We are core. #[no_core]; -//#[legacy_exports]; - #[warn(deprecated_mode)]; #[warn(deprecated_pattern)]; #[warn(vecs_implicitly_copyable)]; #[deny(non_camel_case_types)]; -/* -export int, i8, i16, i32, i64; -export uint, u8, u16, u32, u64; -export float, f32, f64; -export box, char, str, ptr, vec, at_vec, bool; -export either, option, result, iter; -export gc, io, libc, os, run, rand, sys, cast, logging; -export comm, task, future, pipes; -export extfmt; -// The test harness links against core, so don't include runtime in tests. -// FIXME (#2861): Uncomment this after snapshot gets updated. -//#[cfg(notest)] -export rt; -export tuple; -export to_str, to_bytes; -export from_str; -export util; -export dvec, dvec_iter; -export dlist, dlist_iter; -export send_map; -export hash; -export cmp; -export num; -export path; -export mutable; -export flate; -export unit; -export uniq; -export repr; -export cleanup; -export reflect; - -// NDM seems to be necessary for resolve to work -export option_iter; - -// This creates some APIs that I do not want to commit to, but it must be -// exported from core in order for uv to remain in std (see #2648). -export private; -*/ - // Built-in-type support modules /// Operations and constants for `int` @@ -252,10 +210,10 @@ pub mod extfmt; #[legacy_exports] pub mod rt; - -// For internal use, not exported - +// Ideally not exported, but currently is. pub mod private; + +// For internal use, not exported. mod unicode; mod cmath; mod stackwalk; From 777baeb2986aebf32866358c31e4321b594b0742 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Wed, 3 Oct 2012 14:35:14 -0700 Subject: [PATCH 27/80] Remove code that was waiting for a snapshot extfmt is now demoded --- src/libcore/extfmt.rs | 199 +----------------------------------------- 1 file changed, 3 insertions(+), 196 deletions(-) diff --git a/src/libcore/extfmt.rs b/src/libcore/extfmt.rs index 6bcf260a7290..de2e91b2e326 100644 --- a/src/libcore/extfmt.rs +++ b/src/libcore/extfmt.rs @@ -1,4 +1,7 @@ #[doc(hidden)]; +// NB: transitionary, de-mode-ing. +#[forbid(deprecated_mode)]; +#[forbid(deprecated_pattern)]; /* Syntax Extension: fmt @@ -463,202 +466,6 @@ pub mod rt { } } -// Remove after snapshot - -// Functions used by the fmt extension at runtime. For now there are a lot of -// decisions made a runtime. If it proves worthwhile then some of these -// conditions can be evaluated at compile-time. For now though it's cleaner to -// implement it 0this way, I think. -pub mod rt2 { - - pub const flag_none : u32 = 0u32; - pub const flag_left_justify : u32 = 0b00000000000001u32; - pub const flag_left_zero_pad : u32 = 0b00000000000010u32; - pub const flag_space_for_sign : u32 = 0b00000000000100u32; - pub const flag_sign_always : u32 = 0b00000000001000u32; - pub const flag_alternate : u32 = 0b00000000010000u32; - - pub enum Count { CountIs(int), CountImplied, } - pub enum Ty { TyDefault, TyBits, TyHexUpper, TyHexLower, TyOctal, } - - pub type Conv = {flags: u32, width: Count, precision: Count, ty: Ty}; - - pub pure fn conv_int(cv: Conv, i: int) -> ~str { - let radix = 10; - let prec = get_int_precision(cv); - let mut s : ~str = int_to_str_prec(i, radix, prec); - if 0 <= i { - if have_flag(cv.flags, flag_sign_always) { - unsafe { str::unshift_char(&mut s, '+') }; - } else if have_flag(cv.flags, flag_space_for_sign) { - unsafe { str::unshift_char(&mut s, ' ') }; - } - } - return unsafe { pad(cv, s, PadSigned) }; - } - pub pure fn conv_uint(cv: Conv, u: uint) -> ~str { - let prec = get_int_precision(cv); - let mut rs = - match cv.ty { - TyDefault => uint_to_str_prec(u, 10u, prec), - TyHexLower => uint_to_str_prec(u, 16u, prec), - TyHexUpper => str::to_upper(uint_to_str_prec(u, 16u, prec)), - TyBits => uint_to_str_prec(u, 2u, prec), - TyOctal => uint_to_str_prec(u, 8u, prec) - }; - return unsafe { pad(cv, rs, PadUnsigned) }; - } - pub pure fn conv_bool(cv: Conv, b: bool) -> ~str { - let s = if b { ~"true" } else { ~"false" }; - // run the boolean conversion through the string conversion logic, - // giving it the same rules for precision, etc. - return conv_str(cv, s); - } - pub pure fn conv_char(cv: Conv, c: char) -> ~str { - let mut s = str::from_char(c); - return unsafe { pad(cv, s, PadNozero) }; - } - pub pure fn conv_str(cv: Conv, s: &str) -> ~str { - // For strings, precision is the maximum characters - // displayed - let mut unpadded = match cv.precision { - CountImplied => s.to_unique(), - CountIs(max) => if max as uint < str::char_len(s) { - str::substr(s, 0u, max as uint) - } else { - s.to_unique() - } - }; - return unsafe { pad(cv, unpadded, PadNozero) }; - } - pub pure fn conv_float(cv: Conv, f: float) -> ~str { - let (to_str, digits) = match cv.precision { - CountIs(c) => (float::to_str_exact, c as uint), - CountImplied => (float::to_str, 6u) - }; - let mut s = unsafe { to_str(f, digits) }; - if 0.0 <= f { - if have_flag(cv.flags, flag_sign_always) { - s = ~"+" + s; - } else if have_flag(cv.flags, flag_space_for_sign) { - s = ~" " + s; - } - } - return unsafe { pad(cv, s, PadFloat) }; - } - pub pure fn conv_poly(cv: Conv, v: &T) -> ~str { - let s = sys::log_str(v); - return conv_str(cv, s); - } - - // Convert an int to string with minimum number of digits. If precision is - // 0 and num is 0 then the result is the empty string. - pub pure fn int_to_str_prec(num: int, radix: uint, prec: uint) -> ~str { - return if num < 0 { - ~"-" + uint_to_str_prec(-num as uint, radix, prec) - } else { uint_to_str_prec(num as uint, radix, prec) }; - } - - // Convert a uint to string with a minimum number of digits. If precision - // is 0 and num is 0 then the result is the empty string. Could move this - // to uint: but it doesn't seem all that useful. - pub pure fn uint_to_str_prec(num: uint, radix: uint, - prec: uint) -> ~str { - return if prec == 0u && num == 0u { - ~"" - } else { - let s = uint::to_str(num, radix); - let len = str::char_len(s); - if len < prec { - let diff = prec - len; - let pad = str::from_chars(vec::from_elem(diff, '0')); - pad + s - } else { move s } - }; - } - pub pure fn get_int_precision(cv: Conv) -> uint { - return match cv.precision { - CountIs(c) => c as uint, - CountImplied => 1u - }; - } - - pub enum PadMode { PadSigned, PadUnsigned, PadNozero, PadFloat } - - pub impl PadMode : Eq { - pure fn eq(other: &PadMode) -> bool { - match (self, (*other)) { - (PadSigned, PadSigned) => true, - (PadUnsigned, PadUnsigned) => true, - (PadNozero, PadNozero) => true, - (PadFloat, PadFloat) => true, - (PadSigned, _) => false, - (PadUnsigned, _) => false, - (PadNozero, _) => false, - (PadFloat, _) => false - } - } - pure fn ne(other: &PadMode) -> bool { !self.eq(other) } - } - - pub fn pad(cv: Conv, s: ~str, mode: PadMode) -> ~str { - let mut s = move s; // sadtimes - let uwidth : uint = match cv.width { - CountImplied => return s, - CountIs(width) => { - // FIXME: width should probably be uint (see Issue #1996) - width as uint - } - }; - let strlen = str::char_len(s); - if uwidth <= strlen { return s; } - let mut padchar = ' '; - let diff = uwidth - strlen; - if have_flag(cv.flags, flag_left_justify) { - let padstr = str::from_chars(vec::from_elem(diff, padchar)); - return s + padstr; - } - let {might_zero_pad, signed} = match mode { - PadNozero => {might_zero_pad:false, signed:false}, - PadSigned => {might_zero_pad:true, signed:true }, - PadFloat => {might_zero_pad:true, signed:true}, - PadUnsigned => {might_zero_pad:true, signed:false} - }; - pure fn have_precision(cv: Conv) -> bool { - return match cv.precision { CountImplied => false, _ => true }; - } - let zero_padding = { - if might_zero_pad && have_flag(cv.flags, flag_left_zero_pad) && - (!have_precision(cv) || mode == PadFloat) { - padchar = '0'; - true - } else { - false - } - }; - let padstr = str::from_chars(vec::from_elem(diff, padchar)); - // This is completely heinous. If we have a signed value then - // potentially rip apart the intermediate result and insert some - // zeros. It may make sense to convert zero padding to a precision - // instead. - - if signed && zero_padding && s.len() > 0 { - let head = str::shift_char(&mut s); - if head == '+' || head == '-' || head == ' ' { - let headstr = str::from_chars(vec::from_elem(1u, head)); - return headstr + padstr + s; - } - else { - str::unshift_char(&mut s, head); - } - } - return padstr + s; - } - pub pure fn have_flag(flags: u32, f: u32) -> bool { - flags & f != 0 - } -} - #[cfg(test)] mod test { #[test] From fe12da0864ade257eb9b7cffbb96e5cb24af325e Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Wed, 3 Oct 2012 14:38:01 -0700 Subject: [PATCH 28/80] De-mode comm::Chan --- doc/rust.md | 6 +-- src/libcore/comm.rs | 44 +++++++++---------- src/libcore/option.rs | 4 +- src/libcore/os.rs | 6 +-- src/libcore/private.rs | 16 +++---- src/libcore/run.rs | 2 +- src/libcore/task.rs | 42 +++++++++--------- src/libcore/task/spawn.rs | 2 +- src/libstd/net_tcp.rs | 30 ++++++------- src/libstd/sync.rs | 4 +- src/libstd/test.rs | 10 ++--- src/libstd/timer.rs | 10 ++--- src/libstd/uv_global_loop.rs | 10 ++--- src/libstd/uv_iotask.rs | 8 ++-- src/libstd/uv_ll.rs | 6 +-- src/rustc/driver/rustc.rs | 2 +- src/rustdoc/astsrv.rs | 2 +- src/rustdoc/markdown_writer.rs | 8 ++-- src/test/auxiliary/cci_capture_clause.rs | 2 +- src/test/bench/msgsend-ring.rs | 6 +-- src/test/bench/shootout-chameneos-redux.rs | 4 +- src/test/bench/shootout-k-nucleotide.rs | 2 +- src/test/bench/shootout-mandelbrot.rs | 4 +- src/test/bench/shootout-threadring.rs | 2 +- src/test/bench/task-perf-linked-failure.rs | 2 +- src/test/bench/task-perf-one-million.rs | 4 +- .../bench/task-perf-word-count-generic.rs | 6 +-- src/test/compile-fail/issue-3096-2.rs | 2 +- src/test/compile-fail/non-copyable-void.rs | 2 +- src/test/compile-fail/unsendable-class.rs | 2 +- src/test/run-fail/port-type.rs | 2 +- src/test/run-pass/basic-1.rs | 2 +- src/test/run-pass/basic-2.rs | 2 +- src/test/run-pass/basic.rs | 2 +- src/test/run-pass/capture_nil.rs | 2 +- src/test/run-pass/chan-leak.rs | 6 +-- src/test/run-pass/comm.rs | 2 +- src/test/run-pass/decl-with-recv.rs | 2 +- src/test/run-pass/hashmap-memory.rs | 4 +- src/test/run-pass/issue-507.rs | 2 +- src/test/run-pass/issue-687.rs | 6 +-- src/test/run-pass/issue-783.rs | 4 +- src/test/run-pass/ivec-tag.rs | 2 +- src/test/run-pass/lazychan.rs | 2 +- src/test/run-pass/many.rs | 4 +- src/test/run-pass/rt-circular-buffer.rs | 12 ++--- src/test/run-pass/rt-sched-1.rs | 2 +- src/test/run-pass/send-iloop.rs | 2 +- src/test/run-pass/send-resource.rs | 4 +- src/test/run-pass/send-type-inference.rs | 2 +- src/test/run-pass/sendable-class.rs | 2 +- src/test/run-pass/spawn-types.rs | 2 +- src/test/run-pass/task-comm-chan-cleanup.rs | 2 +- src/test/run-pass/task-comm-chan-cleanup2.rs | 2 +- src/test/run-pass/task-comm-chan-cleanup3.rs | 2 +- src/test/run-pass/task-comm-chan-cleanup4.rs | 2 +- src/test/run-pass/task-comm-chan-nil.rs | 2 +- src/test/run-pass/task-comm.rs | 6 +-- src/test/run-pass/task-killjoin-rsrc.rs | 2 +- src/test/run-pass/task-spawn-move-and-copy.rs | 2 +- src/test/run-pass/unique-send-2.rs | 2 +- src/test/run-pass/unique-send.rs | 2 +- src/test/run-pass/unwind-resource.rs | 2 +- 63 files changed, 173 insertions(+), 173 deletions(-) diff --git a/doc/rust.md b/doc/rust.md index 5fd9622046ad..62b3b4409abd 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -2952,7 +2952,7 @@ An example of a `spawn` call: ~~~~ let po = comm::Port(); -let ch = comm::Chan(po); +let ch = comm::Chan(&po); do task::spawn { // let task run, do other things @@ -2974,7 +2974,7 @@ An example of a send: ~~~~ let po = comm::Port(); -let ch = comm::Chan(po); +let ch = comm::Chan(&po); comm::send(ch, ~"hello, world"); ~~~~ @@ -2990,7 +2990,7 @@ An example of a *receive*: ~~~~~~~~ # let po = comm::Port(); -# let ch = comm::Chan(po); +# let ch = comm::Chan(&po); # comm::send(ch, ~""); let s = comm::recv(po); ~~~~~~~~ diff --git a/src/libcore/comm.rs b/src/libcore/comm.rs index 64c38d13e493..c9cd1a21b454 100644 --- a/src/libcore/comm.rs +++ b/src/libcore/comm.rs @@ -32,8 +32,8 @@ will once again be the preferred module for intertask communication. */ -// NB: transitionary, de-mode-ing -// tjc: re-forbid deprecated modes after snapshot +// NB: transitionary, de-mode-ing. +#[forbid(deprecated_mode)]; #[forbid(deprecated_pattern)]; use either::Either; @@ -74,7 +74,7 @@ pub fn Port() -> Port { impl Port { - fn chan() -> Chan { Chan(self) } + fn chan() -> Chan { Chan(&self) } fn send(v: T) { self.chan().send(move v) } fn recv() -> T { recv(self) } fn peek() -> bool { peek(self) } @@ -166,7 +166,7 @@ fn as_raw_port(ch: comm::Chan, f: fn(*rust_port) -> U) -> U { * Constructs a channel. The channel is bound to the port used to * construct it. */ -pub fn Chan(&&p: Port) -> Chan { +pub fn Chan(p: &Port) -> Chan { Chan_(rustrt::get_port_id((**p).po)) } @@ -304,19 +304,19 @@ extern mod rusti { #[test] -fn create_port_and_chan() { let p = Port::(); Chan(p); } +fn create_port_and_chan() { let p = Port::(); Chan(&p); } #[test] fn send_int() { let p = Port::(); - let c = Chan(p); + let c = Chan(&p); send(c, 22); } #[test] fn send_recv_fn() { let p = Port::(); - let c = Chan::(p); + let c = Chan::(&p); send(c, 42); assert (recv(p) == 42); } @@ -324,7 +324,7 @@ fn send_recv_fn() { #[test] fn send_recv_fn_infer() { let p = Port(); - let c = Chan(p); + let c = Chan(&p); send(c, 42); assert (recv(p) == 42); } @@ -332,23 +332,23 @@ fn send_recv_fn_infer() { #[test] fn chan_chan_infer() { let p = Port(), p2 = Port::(); - let c = Chan(p); - send(c, Chan(p2)); + let c = Chan(&p); + send(c, Chan(&p2)); recv(p); } #[test] fn chan_chan() { let p = Port::>(), p2 = Port::(); - let c = Chan(p); - send(c, Chan(p2)); + let c = Chan(&p); + send(c, Chan(&p2)); recv(p); } #[test] fn test_peek() { let po = Port(); - let ch = Chan(po); + let ch = Chan(&po); assert !peek(po); send(ch, ()); assert peek(po); @@ -360,8 +360,8 @@ fn test_peek() { fn test_select2_available() { let po_a = Port(); let po_b = Port(); - let ch_a = Chan(po_a); - let ch_b = Chan(po_b); + let ch_a = Chan(&po_a); + let ch_b = Chan(&po_b); send(ch_a, ~"a"); @@ -376,8 +376,8 @@ fn test_select2_available() { fn test_select2_rendezvous() { let po_a = Port(); let po_b = Port(); - let ch_a = Chan(po_a); - let ch_b = Chan(po_b); + let ch_a = Chan(&po_a); + let ch_b = Chan(&po_b); for iter::repeat(10) { do task::spawn { @@ -400,8 +400,8 @@ fn test_select2_rendezvous() { fn test_select2_stress() { let po_a = Port(); let po_b = Port(); - let ch_a = Chan(po_a); - let ch_b = Chan(po_b); + let ch_a = Chan(&po_a); + let ch_b = Chan(&po_b); let msgs = 100; let times = 4u; @@ -436,7 +436,7 @@ fn test_select2_stress() { #[test] fn test_recv_chan() { let po = Port(); - let ch = Chan(po); + let ch = Chan(&po); send(ch, ~"flower"); assert recv_chan(ch) == ~"flower"; } @@ -445,7 +445,7 @@ fn test_recv_chan() { #[should_fail] #[ignore(cfg(windows))] fn test_recv_chan_dead() { - let ch = Chan(Port()); + let ch = Chan(&Port()); send(ch, ~"flower"); recv_chan(ch); } @@ -454,7 +454,7 @@ fn test_recv_chan_dead() { #[ignore(cfg(windows))] fn test_recv_chan_wrong_task() { let po = Port(); - let ch = Chan(po); + let ch = Chan(&po); send(ch, ~"flower"); assert result::is_err(&task::try(|| recv_chan(ch) diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 1cdd4511e295..c222592a9285 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -326,10 +326,10 @@ impl Option : Eq { #[test] fn test_unwrap_ptr() { let x = ~0; - let addr_x = ptr::p2::addr_of(&(*x)); + let addr_x = ptr::addr_of(&(*x)); let opt = Some(x); let y = unwrap(opt); - let addr_y = ptr::p2::addr_of(&(*y)); + let addr_y = ptr::addr_of(&(*y)); assert addr_x == addr_y; } diff --git a/src/libcore/os.rs b/src/libcore/os.rs index 68571da3a1e9..1a9bd03539e8 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -132,7 +132,7 @@ mod global_env { let env_ch = get_global_env_chan(); let po = comm::Port(); comm::send(env_ch, MsgGetEnv(str::from_slice(n), - comm::Chan(po))); + comm::Chan(&po))); comm::recv(po) } @@ -141,14 +141,14 @@ mod global_env { let po = comm::Port(); comm::send(env_ch, MsgSetEnv(str::from_slice(n), str::from_slice(v), - comm::Chan(po))); + comm::Chan(&po))); comm::recv(po) } pub fn env() -> ~[(~str,~str)] { let env_ch = get_global_env_chan(); let po = comm::Port(); - comm::send(env_ch, MsgEnv(comm::Chan(po))); + comm::send(env_ch, MsgEnv(comm::Chan(&po))); comm::recv(po) } diff --git a/src/libcore/private.rs b/src/libcore/private.rs index c1b2b32edafc..395e63ad30f8 100644 --- a/src/libcore/private.rs +++ b/src/libcore/private.rs @@ -63,7 +63,7 @@ pub unsafe fn chan_from_global_ptr( let (setup_po, setup_ch) = do task_fn().spawn_conversation |move f, setup_po, setup_ch| { let po = comm::Port::(); - let ch = comm::Chan(po); + let ch = comm::Chan(&po); comm::send(setup_ch, ch); // Wait to hear if we are the official instance of @@ -109,7 +109,7 @@ pub fn test_from_global_chan1() { // The global channel let globchan = 0; - let globchanp = ptr::p2::addr_of(&globchan); + let globchanp = ptr::addr_of(&globchan); // Create the global channel, attached to a new task let ch = unsafe { @@ -122,7 +122,7 @@ pub fn test_from_global_chan1() { }; // Talk to it let po = comm::Port(); - comm::send(ch, comm::Chan(po)); + comm::send(ch, comm::Chan(&po)); assert comm::recv(po) == true; // This one just reuses the previous channel @@ -135,7 +135,7 @@ pub fn test_from_global_chan1() { // Talk to the original global task let po = comm::Port(); - comm::send(ch, comm::Chan(po)); + comm::send(ch, comm::Chan(&po)); assert comm::recv(po) == true; } @@ -145,10 +145,10 @@ pub fn test_from_global_chan2() { for iter::repeat(100) { // The global channel let globchan = 0; - let globchanp = ptr::p2::addr_of(&globchan); + let globchanp = ptr::addr_of(&globchan); let resultpo = comm::Port(); - let resultch = comm::Chan(resultpo); + let resultch = comm::Chan(&resultpo); // Spawn a bunch of tasks that all want to compete to // create the global channel @@ -165,7 +165,7 @@ pub fn test_from_global_chan2() { } }; let po = comm::Port(); - comm::send(ch, comm::Chan(po)); + comm::send(ch, comm::Chan(&po)); // We are The winner if our version of the // task was installed let winner = comm::recv(po); @@ -203,7 +203,7 @@ pub fn test_from_global_chan2() { */ pub unsafe fn weaken_task(f: fn(comm::Port<()>)) { let po = comm::Port(); - let ch = comm::Chan(po); + let ch = comm::Chan(&po); unsafe { rustrt::rust_task_weaken(cast::reinterpret_cast(&ch)); } diff --git a/src/libcore/run.rs b/src/libcore/run.rs index f3e98f6ba827..7ebca94f3576 100644 --- a/src/libcore/run.rs +++ b/src/libcore/run.rs @@ -296,7 +296,7 @@ pub fn program_output(prog: &str, args: &[~str]) -> // or the other. FIXME (#2625): Surely there's a much more // clever way to do this. let p = comm::Port(); - let ch = comm::Chan(p); + let ch = comm::Chan(&p); do task::spawn_sched(task::SingleThreaded) { let errput = readclose(pipe_err.in); comm::send(ch, (2, move errput)); diff --git a/src/libcore/task.rs b/src/libcore/task.rs index 5ca35a7f5623..efe6948ecef0 100644 --- a/src/libcore/task.rs +++ b/src/libcore/task.rs @@ -479,10 +479,10 @@ impl TaskBuilder { */ fn spawn_listener(+f: fn~(comm::Port)) -> comm::Chan { let setup_po = comm::Port(); - let setup_ch = comm::Chan(setup_po); + let setup_ch = comm::Chan(&setup_po); do self.spawn |move f| { let po = comm::Port(); - let ch = comm::Chan(po); + let ch = comm::Chan(&po); comm::send(setup_ch, ch); f(move po); } @@ -496,7 +496,7 @@ impl TaskBuilder { (+f: fn~(comm::Port, comm::Chan)) -> (comm::Port, comm::Chan) { let from_child = comm::Port(); - let to_parent = comm::Chan(from_child); + let to_parent = comm::Chan(&from_child); let to_child = do self.spawn_listener |move f, from_parent| { f(from_parent, to_parent) }; @@ -518,7 +518,7 @@ impl TaskBuilder { */ fn try(+f: fn~() -> T) -> Result { let po = comm::Port(); - let ch = comm::Chan(po); + let ch = comm::Chan(&po); let mut result = None; let fr_task_builder = self.future_result(|+r| { @@ -772,7 +772,7 @@ fn test_cant_dup_task_builder() { #[test] #[ignore(cfg(windows))] fn test_spawn_unlinked_unsup_no_fail_down() { // grandchild sends on a port let po = comm::Port(); - let ch = comm::Chan(po); + let ch = comm::Chan(&po); do spawn_unlinked { do spawn_unlinked { // Give middle task a chance to fail-but-not-kill-us. @@ -802,7 +802,7 @@ fn test_spawn_unlinked_sup_fail_down() { #[test] #[should_fail] #[ignore(cfg(windows))] fn test_spawn_linked_sup_fail_up() { // child fails; parent fails let po = comm::Port::<()>(); - let _ch = comm::Chan(po); + let _ch = comm::Chan(&po); // Unidirectional "parenting" shouldn't override bidirectional linked. // We have to cheat with opts - the interface doesn't support them because // they don't make sense (redundant with task().supervised()). @@ -845,7 +845,7 @@ fn test_spawn_linked_sup_fail_down() { // parent fails; child fails #[test] #[should_fail] #[ignore(cfg(windows))] fn test_spawn_linked_unsup_fail_up() { // child fails; parent fails let po = comm::Port::<()>(); - let _ch = comm::Chan(po); + let _ch = comm::Chan(&po); // Default options are to spawn linked & unsupervised. do spawn { fail; } comm::recv(po); // We should get punted awake @@ -917,7 +917,7 @@ fn test_spawn_linked_sup_propagate_sibling() { #[test] fn test_run_basic() { let po = comm::Port(); - let ch = comm::Chan(po); + let ch = comm::Chan(&po); do task().spawn { comm::send(ch, ()); } @@ -927,7 +927,7 @@ fn test_run_basic() { #[test] fn test_add_wrapper() { let po = comm::Port(); - let ch = comm::Chan(po); + let ch = comm::Chan(&po); let b0 = task(); let b1 = do b0.add_wrapper |body| { fn~() { @@ -961,7 +961,7 @@ fn test_back_to_the_future_result() { #[test] fn test_spawn_listiner_bidi() { let po = comm::Port(); - let ch = comm::Chan(po); + let ch = comm::Chan(&po); let ch = do spawn_listener |po| { // Now the child has a port called 'po' to read from and // an environment-captured channel called 'ch'. @@ -1017,7 +1017,7 @@ fn test_spawn_sched_no_threads() { #[test] fn test_spawn_sched() { let po = comm::Port(); - let ch = comm::Chan(po); + let ch = comm::Chan(&po); fn f(i: int, ch: comm::Chan<()>) { let parent_sched_id = rt::rust_get_sched_id(); @@ -1041,7 +1041,7 @@ fn test_spawn_sched() { #[test] fn test_spawn_sched_childs_on_same_sched() { let po = comm::Port(); - let ch = comm::Chan(po); + let ch = comm::Chan(&po); do spawn_sched(SingleThreaded) { let parent_sched_id = rt::rust_get_sched_id(); @@ -1075,9 +1075,9 @@ fn test_spawn_sched_blocking() { for iter::repeat(20u) { let start_po = comm::Port(); - let start_ch = comm::Chan(start_po); + let start_ch = comm::Chan(&start_po); let fin_po = comm::Port(); - let fin_ch = comm::Chan(fin_po); + let fin_ch = comm::Chan(&fin_po); let lock = testrt::rust_dbg_lock_create(); @@ -1105,12 +1105,12 @@ fn test_spawn_sched_blocking() { } let setup_po = comm::Port(); - let setup_ch = comm::Chan(setup_po); + let setup_ch = comm::Chan(&setup_po); let parent_po = comm::Port(); - let parent_ch = comm::Chan(parent_po); + let parent_ch = comm::Chan(&parent_po); do spawn { let child_po = comm::Port(); - comm::send(setup_ch, comm::Chan(child_po)); + comm::send(setup_ch, comm::Chan(&child_po)); pingpong(child_po, parent_ch); }; @@ -1128,13 +1128,13 @@ fn test_spawn_sched_blocking() { #[cfg(test)] fn avoid_copying_the_body(spawnfn: fn(+v: fn~())) { let p = comm::Port::(); - let ch = comm::Chan(p); + let ch = comm::Chan(&p); let x = ~1; - let x_in_parent = ptr::p2::addr_of(&(*x)) as uint; + let x_in_parent = ptr::addr_of(&(*x)) as uint; do spawnfn { - let x_in_child = ptr::p2::addr_of(&(*x)) as uint; + let x_in_child = ptr::addr_of(&(*x)) as uint; comm::send(ch, x_in_child); } @@ -1195,7 +1195,7 @@ fn test_avoid_copying_the_body_unlinked() { #[test] fn test_platform_thread() { let po = comm::Port(); - let ch = comm::Chan(po); + let ch = comm::Chan(&po); do task().sched_mode(PlatformThread).spawn { comm::send(ch, ()); } diff --git a/src/libcore/task/spawn.rs b/src/libcore/task/spawn.rs index ff07150cfa2d..2033db0d58d5 100644 --- a/src/libcore/task/spawn.rs +++ b/src/libcore/task/spawn.rs @@ -636,7 +636,7 @@ pub fn spawn_raw(opts: TaskOpts, +f: fn~()) { #[test] fn test_spawn_raw_simple() { let po = comm::Port(); - let ch = comm::Chan(po); + let ch = comm::Chan(&po); do spawn_raw(default_task_opts()) { comm::send(ch, ()); } diff --git a/src/libstd/net_tcp.rs b/src/libstd/net_tcp.rs index 546231da6333..8c95410d4e83 100644 --- a/src/libstd/net_tcp.rs +++ b/src/libstd/net_tcp.rs @@ -121,8 +121,8 @@ pub fn connect(input_ip: ip::IpAddr, port: uint, let result_po = core::comm::Port::(); let closed_signal_po = core::comm::Port::<()>(); let conn_data = { - result_ch: core::comm::Chan(result_po), - closed_signal_ch: core::comm::Chan(closed_signal_po) + result_ch: core::comm::Chan(&result_po), + closed_signal_ch: core::comm::Chan(&closed_signal_po) }; let conn_data_ptr = ptr::addr_of(&conn_data); let reader_po = core::comm::Port::>(); @@ -130,7 +130,7 @@ pub fn connect(input_ip: ip::IpAddr, port: uint, *(stream_handle_ptr as *mut uv::ll::uv_tcp_t) = uv::ll::tcp_t(); let socket_data = @{ reader_po: reader_po, - reader_ch: core::comm::Chan(reader_po), + reader_ch: core::comm::Chan(&reader_po), stream_handle_ptr: stream_handle_ptr, connect_req: uv::ll::connect_t(), write_req: uv::ll::write_t(), @@ -471,7 +471,7 @@ pub fn accept(new_conn: TcpNewConnection) *(stream_handle_ptr as *mut uv::ll::uv_tcp_t) = uv::ll::tcp_t(); let client_socket_data = @{ reader_po: reader_po, - reader_ch: core::comm::Chan(reader_po), + reader_ch: core::comm::Chan(&reader_po), stream_handle_ptr : stream_handle_ptr, connect_req : uv::ll::connect_t(), write_req : uv::ll::write_t(), @@ -482,7 +482,7 @@ pub fn accept(new_conn: TcpNewConnection) (*client_socket_data_ptr).stream_handle_ptr; let result_po = core::comm::Port::>(); - let result_ch = core::comm::Chan(result_po); + let result_ch = core::comm::Chan(&result_po); // UNSAFE LIBUV INTERACTION BEGIN // .. normally this happens within the context of @@ -580,12 +580,12 @@ fn listen_common(host_ip: ip::IpAddr, port: uint, backlog: uint, -> result::Result<(), TcpListenErrData> unsafe { let stream_closed_po = core::comm::Port::<()>(); let kill_po = core::comm::Port::>(); - let kill_ch = core::comm::Chan(kill_po); + let kill_ch = core::comm::Chan(&kill_po); let server_stream = uv::ll::tcp_t(); let server_stream_ptr = ptr::addr_of(&server_stream); let server_data = { server_stream_ptr: server_stream_ptr, - stream_closed_ch: core::comm::Chan(stream_closed_po), + stream_closed_ch: core::comm::Chan(&stream_closed_po), kill_ch: kill_ch, on_connect_cb: move on_connect_cb, iotask: iotask, @@ -832,7 +832,7 @@ impl TcpSocketBuf: io::Writer { fn tear_down_socket_data(socket_data: @TcpSocketData) unsafe { let closed_po = core::comm::Port::<()>(); - let closed_ch = core::comm::Chan(closed_po); + let closed_ch = core::comm::Chan(&closed_po); let close_data = { closed_ch: closed_ch }; @@ -895,7 +895,7 @@ fn read_stop_common_impl(socket_data: *TcpSocketData) -> result::Result<(), TcpErrData> unsafe { let stream_handle_ptr = (*socket_data).stream_handle_ptr; let stop_po = core::comm::Port::>(); - let stop_ch = core::comm::Chan(stop_po); + let stop_ch = core::comm::Chan(&stop_po); do iotask::interact((*socket_data).iotask) |loop_ptr| unsafe { log(debug, ~"in interact cb for tcp::read_stop"); match uv::ll::read_stop(stream_handle_ptr as *uv::ll::uv_stream_t) { @@ -922,7 +922,7 @@ fn read_start_common_impl(socket_data: *TcpSocketData) result::Result<~[u8], TcpErrData>>, TcpErrData> unsafe { let stream_handle_ptr = (*socket_data).stream_handle_ptr; let start_po = core::comm::Port::>(); - let start_ch = core::comm::Chan(start_po); + let start_ch = core::comm::Chan(&start_po); log(debug, ~"in tcp::read_start before interact loop"); do iotask::interact((*socket_data).iotask) |loop_ptr| unsafe { log(debug, fmt!("in tcp::read_start interact cb %?", loop_ptr)); @@ -961,7 +961,7 @@ fn write_common_impl(socket_data_ptr: *TcpSocketData, let write_buf_vec_ptr = ptr::addr_of(&write_buf_vec); let result_po = core::comm::Port::(); let write_data = { - result_ch: core::comm::Chan(result_po) + result_ch: core::comm::Chan(&result_po) }; let write_data_ptr = ptr::addr_of(&write_data); do iotask::interact((*socket_data_ptr).iotask) |loop_ptr| unsafe { @@ -1277,10 +1277,10 @@ mod test { let expected_resp = ~"pong"; let server_result_po = core::comm::Port::<~str>(); - let server_result_ch = core::comm::Chan(server_result_po); + let server_result_ch = core::comm::Chan(&server_result_po); let cont_po = core::comm::Port::<()>(); - let cont_ch = core::comm::Chan(cont_po); + let cont_ch = core::comm::Chan(&cont_po); // server do task::spawn_sched(task::ManualThreads(1u)) { let actual_req = do comm::listen |server_ch| { @@ -1343,10 +1343,10 @@ mod test { let expected_resp = ~"pong"; let server_result_po = core::comm::Port::<~str>(); - let server_result_ch = core::comm::Chan(server_result_po); + let server_result_ch = core::comm::Chan(&server_result_po); let cont_po = core::comm::Port::<()>(); - let cont_ch = core::comm::Chan(cont_po); + let cont_ch = core::comm::Chan(&cont_po); // server do task::spawn_sched(task::ManualThreads(1u)) { let actual_req = do comm::listen |server_ch| { diff --git a/src/libstd/sync.rs b/src/libstd/sync.rs index f66134d38923..88869773e5de 100644 --- a/src/libstd/sync.rs +++ b/src/libstd/sync.rs @@ -773,7 +773,7 @@ mod tests { let m = ~Mutex(); let m2 = ~m.clone(); let mut sharedstate = ~0; - let ptr = ptr::p2::addr_of(&(*sharedstate)); + let ptr = ptr::addr_of(&(*sharedstate)); do task::spawn { let sharedstate: &mut int = unsafe { cast::reinterpret_cast(&ptr) }; @@ -1045,7 +1045,7 @@ mod tests { let (c,p) = pipes::stream(); let x2 = ~x.clone(); let mut sharedstate = ~0; - let ptr = ptr::p2::addr_of(&(*sharedstate)); + let ptr = ptr::addr_of(&(*sharedstate)); do task::spawn { let sharedstate: &mut int = unsafe { cast::reinterpret_cast(&ptr) }; diff --git a/src/libstd/test.rs b/src/libstd/test.rs index c5d9dd343fa0..2eac3729c229 100644 --- a/src/libstd/test.rs +++ b/src/libstd/test.rs @@ -286,7 +286,7 @@ fn run_tests(opts: &TestOpts, tests: &[TestDesc], let mut done_idx = 0; let p = core::comm::Port(); - let ch = core::comm::Chan(p); + let ch = core::comm::Chan(&p); while done_idx < total { while wait_idx < concurrency && run_idx < total { @@ -421,7 +421,7 @@ mod tests { should_fail: false }; let p = core::comm::Port(); - let ch = core::comm::Chan(p); + let ch = core::comm::Chan(&p); run_test(desc, ch); let (_, res) = core::comm::recv(p); assert res != TrOk; @@ -437,7 +437,7 @@ mod tests { should_fail: false }; let p = core::comm::Port(); - let ch = core::comm::Chan(p); + let ch = core::comm::Chan(&p); run_test(desc, ch); let (_, res) = core::comm::recv(p); assert res == TrIgnored; @@ -454,7 +454,7 @@ mod tests { should_fail: true }; let p = core::comm::Port(); - let ch = core::comm::Chan(p); + let ch = core::comm::Chan(&p); run_test(desc, ch); let (_, res) = core::comm::recv(p); assert res == TrOk; @@ -470,7 +470,7 @@ mod tests { should_fail: true }; let p = core::comm::Port(); - let ch = core::comm::Chan(p); + let ch = core::comm::Chan(&p); run_test(desc, ch); let (_, res) = core::comm::recv(p); assert res == TrFailed; diff --git a/src/libstd/timer.rs b/src/libstd/timer.rs index 2aca87b942ec..821015edd1a9 100644 --- a/src/libstd/timer.rs +++ b/src/libstd/timer.rs @@ -27,7 +27,7 @@ pub fn delayed_send(iotask: IoTask, msecs: uint, ch: comm::Chan, val: T) { unsafe { let timer_done_po = core::comm::Port::<()>(); - let timer_done_ch = core::comm::Chan(timer_done_po); + let timer_done_ch = core::comm::Chan(&timer_done_po); let timer_done_ch_ptr = ptr::addr_of(&timer_done_ch); let timer = uv::ll::timer_t(); let timer_ptr = ptr::addr_of(&timer); @@ -74,7 +74,7 @@ pub fn delayed_send(iotask: IoTask, */ pub fn sleep(iotask: IoTask, msecs: uint) { let exit_po = core::comm::Port::<()>(); - let exit_ch = core::comm::Chan(exit_po); + let exit_ch = core::comm::Chan(&exit_po); delayed_send(iotask, msecs, exit_ch, ()); core::comm::recv(exit_po); } @@ -103,7 +103,7 @@ pub fn recv_timeout(iotask: IoTask, msecs: uint, wait_po: comm::Port) -> Option { let timeout_po = comm::Port::<()>(); - let timeout_ch = comm::Chan(timeout_po); + let timeout_ch = comm::Chan(&timeout_po); delayed_send(iotask, msecs, timeout_ch, ()); // FIXME: This could be written clearer (#2618) either::either( @@ -162,7 +162,7 @@ mod test { #[test] fn test_gl_timer_sleep_stress2() { let po = core::comm::Port(); - let ch = core::comm::Chan(po); + let ch = core::comm::Chan(&po); let hl_loop = uv::global_loop::get(); let repeat = 20u; @@ -240,7 +240,7 @@ mod test { for iter::repeat(times as uint) { let expected = rand::Rng().gen_str(16u); let test_po = core::comm::Port::<~str>(); - let test_ch = core::comm::Chan(test_po); + let test_ch = core::comm::Chan(&test_po); do task::spawn() { delayed_send(hl_loop, 50u, test_ch, expected); diff --git a/src/libstd/uv_global_loop.rs b/src/libstd/uv_global_loop.rs index 869c3efa38f9..79f6bafb4a48 100644 --- a/src/libstd/uv_global_loop.rs +++ b/src/libstd/uv_global_loop.rs @@ -133,12 +133,12 @@ mod test { fn impl_uv_hl_simple_timer(iotask: IoTask) unsafe { let exit_po = core::comm::Port::(); - let exit_ch = core::comm::Chan(exit_po); - let exit_ch_ptr = ptr::p2::addr_of(&exit_ch); + let exit_ch = core::comm::Chan(&exit_po); + let exit_ch_ptr = ptr::addr_of(&exit_ch); log(debug, fmt!("EXIT_CH_PTR newly created exit_ch_ptr: %?", exit_ch_ptr)); let timer_handle = ll::timer_t(); - let timer_ptr = ptr::p2::addr_of(&timer_handle); + let timer_ptr = ptr::addr_of(&timer_handle); do iotask::interact(iotask) |loop_ptr| unsafe { log(debug, ~"user code inside interact loop!!!"); let init_status = ll::timer_init(loop_ptr, timer_ptr); @@ -166,7 +166,7 @@ mod test { fn test_gl_uv_global_loop_high_level_global_timer() unsafe { let hl_loop = get_gl(); let exit_po = comm::Port::<()>(); - let exit_ch = comm::Chan(exit_po); + let exit_ch = comm::Chan(&exit_po); task::spawn_sched(task::ManualThreads(1u), || { impl_uv_hl_simple_timer(hl_loop); core::comm::send(exit_ch, ()); @@ -182,7 +182,7 @@ mod test { fn test_stress_gl_uv_global_loop_high_level_global_timer() unsafe { let hl_loop = get_gl(); let exit_po = core::comm::Port::<()>(); - let exit_ch = core::comm::Chan(exit_po); + let exit_ch = core::comm::Chan(&exit_po); let cycles = 5000u; for iter::repeat(cycles) { task::spawn_sched(task::ManualThreads(1u), || { diff --git a/src/libstd/uv_iotask.rs b/src/libstd/uv_iotask.rs index 4a4a34704be2..ca4d655db59a 100644 --- a/src/libstd/uv_iotask.rs +++ b/src/libstd/uv_iotask.rs @@ -184,7 +184,7 @@ mod test { let async_handle = ll::async_t(); let ah_ptr = ptr::addr_of(&async_handle); let exit_po = core::comm::Port::<()>(); - let exit_ch = core::comm::Chan(exit_po); + let exit_ch = core::comm::Chan(&exit_po); let ah_data = { iotask: iotask, exit_ch: exit_ch @@ -202,7 +202,7 @@ mod test { // high_level_loop unsafe fn spawn_test_loop(exit_ch: comm::Chan<()>) -> IoTask { let iotask_port = comm::Port::(); - let iotask_ch = comm::Chan(iotask_port); + let iotask_ch = comm::Chan(&iotask_port); do task::spawn_sched(task::ManualThreads(1u)) { run_loop(iotask_ch); exit_ch.send(()); @@ -223,7 +223,7 @@ mod test { #[test] fn test_uv_iotask_async() unsafe { let exit_po = core::comm::Port::<()>(); - let exit_ch = core::comm::Chan(exit_po); + let exit_ch = core::comm::Chan(&exit_po); let iotask = spawn_test_loop(exit_ch); // using this handle to manage the lifetime of the high_level_loop, @@ -233,7 +233,7 @@ mod test { // lives until, at least, all of the impl_uv_hl_async() runs have been // called, at least. let work_exit_po = core::comm::Port::<()>(); - let work_exit_ch = core::comm::Chan(work_exit_po); + let work_exit_ch = core::comm::Chan(&work_exit_po); for iter::repeat(7u) { do task::spawn_sched(task::ManualThreads(1u)) { impl_uv_iotask_async(iotask); diff --git a/src/libstd/uv_ll.rs b/src/libstd/uv_ll.rs index f0594475d04e..f8c3882d15eb 100644 --- a/src/libstd/uv_ll.rs +++ b/src/libstd/uv_ll.rs @@ -1466,12 +1466,12 @@ pub mod test { let kill_server_msg = ~"does a dog have buddha nature?"; let server_resp_msg = ~"mu!"; let client_port = core::comm::Port::<~str>(); - let client_chan = core::comm::Chan::<~str>(client_port); + let client_chan = core::comm::Chan::<~str>(&client_port); let server_port = core::comm::Port::<~str>(); - let server_chan = core::comm::Chan::<~str>(server_port); + let server_chan = core::comm::Chan::<~str>(&server_port); let continue_port = core::comm::Port::(); - let continue_chan = core::comm::Chan::(continue_port); + let continue_chan = core::comm::Chan::(&continue_port); let continue_chan_ptr = ptr::addr_of(&continue_chan); do task::spawn_sched(task::ManualThreads(1)) { diff --git a/src/rustc/driver/rustc.rs b/src/rustc/driver/rustc.rs index 5fc48e2b6a2c..c2bca3fc6bec 100644 --- a/src/rustc/driver/rustc.rs +++ b/src/rustc/driver/rustc.rs @@ -229,7 +229,7 @@ bug and need to present an error. */ fn monitor(+f: fn~(diagnostic::emitter)) { let p = comm::Port(); - let ch = comm::Chan(p); + let ch = comm::Chan(&p); match do task::try |move f| { diff --git a/src/rustdoc/astsrv.rs b/src/rustdoc/astsrv.rs index ab6b348c04a2..2e6cbf579c8e 100644 --- a/src/rustdoc/astsrv.rs +++ b/src/rustdoc/astsrv.rs @@ -93,7 +93,7 @@ fn exec( +f: fn~(ctxt: Ctxt) -> T ) -> T { let po = comm::Port(); - let ch = comm::Chan(po); + let ch = comm::Chan(&po); let msg = HandleRequest(fn~(move f, ctxt: Ctxt) { comm::send(ch, f(ctxt)) }); diff --git a/src/rustdoc/markdown_writer.rs b/src/rustdoc/markdown_writer.rs index d0fe7a3840b3..f505f9d0b993 100644 --- a/src/rustdoc/markdown_writer.rs +++ b/src/rustdoc/markdown_writer.rs @@ -109,14 +109,14 @@ fn pandoc_writer( os::close(pipe_in.out); let stdout_po = comm::Port(); - let stdout_ch = comm::Chan(stdout_po); + let stdout_ch = comm::Chan(&stdout_po); do task::spawn_sched(task::SingleThreaded) { comm::send(stdout_ch, readclose(pipe_out.in)); } let stdout = comm::recv(stdout_po); let stderr_po = comm::Port(); - let stderr_ch = comm::Chan(stderr_po); + let stderr_ch = comm::Chan(&stderr_po); do task::spawn_sched(task::SingleThreaded) { comm::send(stderr_ch, readclose(pipe_err.in)); } @@ -268,10 +268,10 @@ fn write_file(path: &Path, s: ~str) { fn future_writer_factory( ) -> (WriterFactory, comm::Port<(doc::Page, ~str)>) { let markdown_po = comm::Port(); - let markdown_ch = comm::Chan(markdown_po); + let markdown_ch = comm::Chan(&markdown_po); let writer_factory = fn~(page: doc::Page) -> Writer { let writer_po = comm::Port(); - let writer_ch = comm::Chan(writer_po); + let writer_ch = comm::Chan(&writer_po); do task::spawn { let (writer, future) = future_writer(); comm::send(writer_ch, writer); diff --git a/src/test/auxiliary/cci_capture_clause.rs b/src/test/auxiliary/cci_capture_clause.rs index 2d7404aa1d2c..b25605852571 100644 --- a/src/test/auxiliary/cci_capture_clause.rs +++ b/src/test/auxiliary/cci_capture_clause.rs @@ -6,7 +6,7 @@ use comm::*; fn foo(x: T) -> Port { let p = Port(); - let c = Chan(p); + let c = Chan(&p); do task::spawn() |copy c, copy x| { c.send(x); } diff --git a/src/test/bench/msgsend-ring.rs b/src/test/bench/msgsend-ring.rs index 2be21d946af2..1dfcd241b83b 100644 --- a/src/test/bench/msgsend-ring.rs +++ b/src/test/bench/msgsend-ring.rs @@ -35,7 +35,7 @@ fn main() { let msg_per_task = uint::from_str(args[2]).get(); let num_port = Port(); - let mut num_chan = Chan(num_port); + let mut num_chan = Chan(&num_port); let start = time::precise_time_s(); @@ -44,12 +44,12 @@ fn main() { for uint::range(1u, num_tasks) |i| { let get_chan = Port(); - let get_chan_chan = Chan(get_chan); + let get_chan_chan = Chan(&get_chan); let new_future = do future::spawn |copy num_chan, move get_chan_chan| { let p = Port(); - get_chan_chan.send(Chan(p)); + get_chan_chan.send(Chan(&p)); thread_ring(i, msg_per_task, num_chan, p) }; futures.push(new_future); diff --git a/src/test/bench/shootout-chameneos-redux.rs b/src/test/bench/shootout-chameneos-redux.rs index 11c06d45bc88..1e3c51d82548 100644 --- a/src/test/bench/shootout-chameneos-redux.rs +++ b/src/test/bench/shootout-chameneos-redux.rs @@ -126,8 +126,8 @@ fn rendezvous(nn: uint, set: ~[color]) { let from_creatures_log: comm::Port<~str> = comm::Port(); // these channels will be passed to the creatures so they can talk to us - let to_rendezvous = comm::Chan(from_creatures); - let to_rendezvous_log = comm::Chan(from_creatures_log); + let to_rendezvous = comm::Chan(&from_creatures); + let to_rendezvous_log = comm::Chan(&from_creatures_log); // these channels will allow us to talk to each creature by 'name'/index let to_creature: ~[comm::Chan>] = diff --git a/src/test/bench/shootout-k-nucleotide.rs b/src/test/bench/shootout-k-nucleotide.rs index ae162221503e..1707c0d991da 100644 --- a/src/test/bench/shootout-k-nucleotide.rs +++ b/src/test/bench/shootout-k-nucleotide.rs @@ -142,7 +142,7 @@ fn main() { // initialize each sequence sorter let sizes = ~[1u,2u,3u,4u,6u,12u,18u]; let from_child = vec::map (sizes, |_sz| comm::Port() ); - let to_parent = vec::mapi(sizes, |ii, _sz| comm::Chan(from_child[ii]) ); + let to_parent = vec::mapi(sizes, |ii, _sz| comm::Chan(&from_child[ii]) ); let to_child = vec::mapi(sizes, |ii, sz| { let ii = ii; let sz = *sz; diff --git a/src/test/bench/shootout-mandelbrot.rs b/src/test/bench/shootout-mandelbrot.rs index 8ab58207fd14..b30e04a4ca7d 100644 --- a/src/test/bench/shootout-mandelbrot.rs +++ b/src/test/bench/shootout-mandelbrot.rs @@ -103,7 +103,7 @@ impl devnull: io::Writer { fn writer(path: ~str, writech: comm::Chan>, size: uint) { let p: comm::Port = comm::Port(); - let ch = comm::Chan(p); + let ch = comm::Chan(&p); comm::send(writech, ch); let cout: io::Writer = match path { ~"" => { @@ -169,7 +169,7 @@ fn main() { else { uint::from_str(args[1]).get() }; let writep = comm::Port(); - let writech = comm::Chan(writep); + let writech = comm::Chan(&writep); do task::spawn { writer(path, writech, size); }; diff --git a/src/test/bench/shootout-threadring.rs b/src/test/bench/shootout-threadring.rs index 8bee12b22437..7ac45863c5b4 100644 --- a/src/test/bench/shootout-threadring.rs +++ b/src/test/bench/shootout-threadring.rs @@ -7,7 +7,7 @@ fn start(+token: int) { use iter::*; let p = comm::Port(); - let mut ch = comm::Chan(p); + let mut ch = comm::Chan(&p); for int::range(2, n_threads + 1) |i| { let id = n_threads + 2 - i; let to_child = do task::spawn_listener:: |p, copy ch| { diff --git a/src/test/bench/task-perf-linked-failure.rs b/src/test/bench/task-perf-linked-failure.rs index a59b932f7e12..a692b2f3011e 100644 --- a/src/test/bench/task-perf-linked-failure.rs +++ b/src/test/bench/task-perf-linked-failure.rs @@ -11,7 +11,7 @@ // Doesn't return until all such tasks are ready, but doesn't block forever itself. fn grandchild_group(num_tasks: uint) { let po = comm::Port(); - let ch = comm::Chan(po); + let ch = comm::Chan(&po); for num_tasks.times { do task::spawn { // linked diff --git a/src/test/bench/task-perf-one-million.rs b/src/test/bench/task-perf-one-million.rs index 39fe02eac799..7a30c5e2325b 100644 --- a/src/test/bench/task-perf-one-million.rs +++ b/src/test/bench/task-perf-one-million.rs @@ -8,7 +8,7 @@ enum msg { fn calc(children: uint, parent_ch: comm::Chan) { let port = comm::Port(); - let chan = comm::Chan(port); + let chan = comm::Chan(&port); let mut child_chs = ~[]; let mut sum = 0; @@ -60,7 +60,7 @@ fn main() { let children = uint::from_str(args[1]).get(); let port = comm::Port(); - let chan = comm::Chan(port); + let chan = comm::Chan(&port); do task::spawn { calc(children, chan); }; diff --git a/src/test/bench/task-perf-word-count-generic.rs b/src/test/bench/task-perf-word-count-generic.rs index 1002e97497d0..168e4b8b1f14 100644 --- a/src/test/bench/task-perf-word-count-generic.rs +++ b/src/test/bench/task-perf-word-count-generic.rs @@ -43,7 +43,7 @@ trait word_reader { type joinable_task = Port<()>; fn spawn_joinable(+f: fn~()) -> joinable_task { let p = Port(); - let c = Chan(p); + let c = Chan(&p); do task::spawn() |move f| { f(); c.send(()); @@ -206,7 +206,7 @@ mod map_reduce { { let p = Port(); - send(out, Chan(p)); + send(out, Chan(&p)); let mut ref_count = 0; let mut is_done = false; @@ -268,7 +268,7 @@ mod map_reduce { None => { // log(error, "creating new reducer for " + k); let p = Port(); - let ch = Chan(p); + let ch = Chan(&p); let r = reduce, kk = k; tasks.push(spawn_joinable(|| reduce_task(r, kk, ch) )); c = recv(p); diff --git a/src/test/compile-fail/issue-3096-2.rs b/src/test/compile-fail/issue-3096-2.rs index 03e13f67a9a9..dd8f341b9355 100644 --- a/src/test/compile-fail/issue-3096-2.rs +++ b/src/test/compile-fail/issue-3096-2.rs @@ -1,6 +1,6 @@ enum bottom { } fn main() { - let x = ptr::p2::addr_of(&()) as *bottom; + let x = ptr::addr_of(&()) as *bottom; match x { } //~ ERROR non-exhaustive patterns } diff --git a/src/test/compile-fail/non-copyable-void.rs b/src/test/compile-fail/non-copyable-void.rs index a00dd7afd6df..eaba1d861196 100644 --- a/src/test/compile-fail/non-copyable-void.rs +++ b/src/test/compile-fail/non-copyable-void.rs @@ -1,5 +1,5 @@ fn main() { - let x : *~[int] = ptr::p2::addr_of(&~[1,2,3]); + let x : *~[int] = ptr::addr_of(&~[1,2,3]); let y : *libc::c_void = x as *libc::c_void; unsafe { let _z = *y; diff --git a/src/test/compile-fail/unsendable-class.rs b/src/test/compile-fail/unsendable-class.rs index a954f6e6e3b2..a47a8b76e56a 100644 --- a/src/test/compile-fail/unsendable-class.rs +++ b/src/test/compile-fail/unsendable-class.rs @@ -16,6 +16,6 @@ fn foo(i:int, j: @~str) -> foo { fn main() { let cat = ~"kitty"; let po = comm::Port(); //~ ERROR missing `send` - let ch = comm::Chan(po); //~ ERROR missing `send` + let ch = comm::Chan(&po); //~ ERROR missing `send` comm::send(ch, foo(42, @cat)); //~ ERROR missing `send` } diff --git a/src/test/run-fail/port-type.rs b/src/test/run-fail/port-type.rs index 7ea778bd1907..30714413c537 100644 --- a/src/test/run-fail/port-type.rs +++ b/src/test/run-fail/port-type.rs @@ -9,7 +9,7 @@ fn echo(c: Chan, oc: Chan>) { // Tests that the type argument in port gets // visited let p = Port::(); - send(oc, Chan(p)); + send(oc, Chan(&p)); let x = recv(p); send(c, x); diff --git a/src/test/run-pass/basic-1.rs b/src/test/run-pass/basic-1.rs index 8f467e24e1b7..1f0bfe93ab28 100644 --- a/src/test/run-pass/basic-1.rs +++ b/src/test/run-pass/basic-1.rs @@ -10,7 +10,7 @@ fn a(c: Chan) { send(c, 10); } fn main() { let p = Port(); - let ch = Chan(p); + let ch = Chan(&p); task::spawn(|| a(ch) ); task::spawn(|| a(ch) ); let mut n: int = 0; diff --git a/src/test/run-pass/basic-2.rs b/src/test/run-pass/basic-2.rs index b5130a100278..7a81bfc3fc52 100644 --- a/src/test/run-pass/basic-2.rs +++ b/src/test/run-pass/basic-2.rs @@ -10,7 +10,7 @@ fn a(c: Chan) { debug!("task a0"); debug!("task a1"); send(c, 10); } fn main() { let p = Port(); - let ch = Chan(p); + let ch = Chan(&p); task::spawn(|| a(ch) ); task::spawn(|| b(ch) ); let mut n: int = 0; diff --git a/src/test/run-pass/basic.rs b/src/test/run-pass/basic.rs index a72c9058d106..6f8fa6e3e70f 100644 --- a/src/test/run-pass/basic.rs +++ b/src/test/run-pass/basic.rs @@ -29,7 +29,7 @@ fn main() { let mut n: int = 2 + 3 * 7; let s: ~str = ~"hello there"; let p = comm::Port(); - let ch = comm::Chan(p); + let ch = comm::Chan(&p); task::spawn(|| a(ch) ); task::spawn(|| b(ch) ); let mut x: int = 10; diff --git a/src/test/run-pass/capture_nil.rs b/src/test/run-pass/capture_nil.rs index 41359ceec185..60f243077096 100644 --- a/src/test/run-pass/capture_nil.rs +++ b/src/test/run-pass/capture_nil.rs @@ -17,7 +17,7 @@ use comm::*; fn foo(&&x: ()) -> Port<()> { let p = Port(); - let c = Chan(p); + let c = Chan(&p); do task::spawn() |copy c, copy x| { c.send(x); } diff --git a/src/test/run-pass/chan-leak.rs b/src/test/run-pass/chan-leak.rs index b0a27a9a97e5..f834b1b35195 100644 --- a/src/test/run-pass/chan-leak.rs +++ b/src/test/run-pass/chan-leak.rs @@ -12,7 +12,7 @@ type ctx = Chan; fn request_task(c: Chan) { let p = Port(); - send(c, Chan(p)); + send(c, Chan(&p)); let mut req: request; req = recv(p); // Need to drop req before receiving it again @@ -21,7 +21,7 @@ fn request_task(c: Chan) { fn new_cx() -> ctx { let p = Port(); - let ch = Chan(p); + let ch = Chan(&p); let t = task::spawn(|| request_task(ch) ); let mut cx: ctx; cx = recv(p); @@ -32,6 +32,6 @@ fn main() { let cx = new_cx(); let p = Port::(); - send(cx, close(Chan(p))); + send(cx, close(Chan(&p))); send(cx, quit); } diff --git a/src/test/run-pass/comm.rs b/src/test/run-pass/comm.rs index b41152f31588..003b7c830934 100644 --- a/src/test/run-pass/comm.rs +++ b/src/test/run-pass/comm.rs @@ -7,7 +7,7 @@ use comm::recv; fn main() { let p = comm::Port(); - let ch = comm::Chan(p); + let ch = comm::Chan(&p); let t = task::spawn(|| child(ch) ); let y = recv(p); error!("received"); diff --git a/src/test/run-pass/decl-with-recv.rs b/src/test/run-pass/decl-with-recv.rs index 07ce5cb63ac6..b594e5334c46 100644 --- a/src/test/run-pass/decl-with-recv.rs +++ b/src/test/run-pass/decl-with-recv.rs @@ -8,7 +8,7 @@ use comm::recv; fn main() { let po = Port(); - let ch = Chan(po); + let ch = Chan(&po); send(ch, 10); let i = recv(po); assert (i == 10); diff --git a/src/test/run-pass/hashmap-memory.rs b/src/test/run-pass/hashmap-memory.rs index 24163cfa5664..50b88693f39f 100644 --- a/src/test/run-pass/hashmap-memory.rs +++ b/src/test/run-pass/hashmap-memory.rs @@ -47,7 +47,7 @@ mod map_reduce { None => { let p = Port(); error!("sending find_reducer"); - send(ctrl, find_reducer(str::to_bytes(key), Chan(p))); + send(ctrl, find_reducer(str::to_bytes(key), Chan(&p))); error!("receiving"); c = recv(p); log(error, c); @@ -70,7 +70,7 @@ mod map_reduce { reducers = map::HashMap(); - start_mappers(Chan(ctrl), inputs); + start_mappers(Chan(&ctrl), inputs); let mut num_mappers = vec::len(inputs) as int; diff --git a/src/test/run-pass/issue-507.rs b/src/test/run-pass/issue-507.rs index 447a892f3390..0baa0aca7ade 100644 --- a/src/test/run-pass/issue-507.rs +++ b/src/test/run-pass/issue-507.rs @@ -20,7 +20,7 @@ fn child(c: Chan) { fn main() { let p = comm::Port(); - let ch = Chan(p); + let ch = Chan(&p); task::spawn(|| child(ch) ); diff --git a/src/test/run-pass/issue-687.rs b/src/test/run-pass/issue-687.rs index 6d9dc8216e1a..4ed94c577849 100644 --- a/src/test/run-pass/issue-687.rs +++ b/src/test/run-pass/issue-687.rs @@ -14,7 +14,7 @@ fn producer(c: Chan<~[u8]>) { fn packager(cb: Chan>, msg: Chan) { let p: Port<~[u8]> = Port(); - send(cb, Chan(p)); + send(cb, Chan(&p)); loop { debug!("waiting for bytes"); let data = recv(p); @@ -35,9 +35,9 @@ fn packager(cb: Chan>, msg: Chan) { fn main() { let p: Port = Port(); - let ch = Chan(p); + let ch = Chan(&p); let recv_reader: Port> = Port(); - let recv_reader_chan = Chan(recv_reader); + let recv_reader_chan = Chan(&recv_reader); let pack = task::spawn(|| packager(recv_reader_chan, ch) ); let source_chan: Chan<~[u8]> = recv(recv_reader); diff --git a/src/test/run-pass/issue-783.rs b/src/test/run-pass/issue-783.rs index a9c6fed8ecae..50fadefa4643 100644 --- a/src/test/run-pass/issue-783.rs +++ b/src/test/run-pass/issue-783.rs @@ -6,10 +6,10 @@ fn a() { fn doit() { fn b(c: Chan>) { let p = Port(); - send(c, Chan(p)); + send(c, Chan(&p)); } let p = Port(); - let ch = Chan(p); + let ch = Chan(&p); spawn(|| b(ch) ); recv(p); } diff --git a/src/test/run-pass/ivec-tag.rs b/src/test/run-pass/ivec-tag.rs index bfcba52790b3..b92d20bbe40c 100644 --- a/src/test/run-pass/ivec-tag.rs +++ b/src/test/run-pass/ivec-tag.rs @@ -13,7 +13,7 @@ fn producer(c: Chan<~[u8]>) { fn main() { let p: Port<~[u8]> = Port(); - let ch = Chan(p); + let ch = Chan(&p); let prod = task::spawn(|| producer(ch) ); let data: ~[u8] = recv(p); diff --git a/src/test/run-pass/lazychan.rs b/src/test/run-pass/lazychan.rs index 1446ebc94935..06e89a298a97 100644 --- a/src/test/run-pass/lazychan.rs +++ b/src/test/run-pass/lazychan.rs @@ -5,7 +5,7 @@ use comm::*; fn main() { let p = Port(); - let ch = Chan(p); + let ch = Chan(&p); let mut y: int; task::spawn(|| child(ch) ); diff --git a/src/test/run-pass/many.rs b/src/test/run-pass/many.rs index 2362f683e5e8..83ebc0ef844b 100644 --- a/src/test/run-pass/many.rs +++ b/src/test/run-pass/many.rs @@ -7,7 +7,7 @@ fn sub(parent: comm::Chan, id: int) { comm::send(parent, 0); } else { let p = comm::Port(); - let ch = comm::Chan(p); + let ch = comm::Chan(&p); let child = task::spawn(|| sub(ch, id - 1) ); let y = comm::recv(p); comm::send(parent, y + 1); @@ -16,7 +16,7 @@ fn sub(parent: comm::Chan, id: int) { fn main() { let p = comm::Port(); - let ch = comm::Chan(p); + let ch = comm::Chan(&p); let child = task::spawn(|| sub(ch, 200) ); let y = comm::recv(p); debug!("transmission complete"); diff --git a/src/test/run-pass/rt-circular-buffer.rs b/src/test/run-pass/rt-circular-buffer.rs index 2f5245f7bc4c..2af5535ad280 100644 --- a/src/test/run-pass/rt-circular-buffer.rs +++ b/src/test/run-pass/rt-circular-buffer.rs @@ -18,7 +18,7 @@ type record = {val1: u32, val2: u32, val3: u32}; // assertions. fn test_init() { let myport = Port(); - let mychan = Chan(myport); + let mychan = Chan(&myport); let val: record = {val1: 0u32, val2: 0u32, val3: 0u32}; send(mychan, val); } @@ -28,7 +28,7 @@ fn test_init() { // Don't trigger any assertions. fn test_grow() { let myport = Port(); - let mychan = Chan(myport); + let mychan = Chan(&myport); for uint::range(0u, 100u) |i| { let val: record = {val1: 0u32, val2: 0u32, val3: 0u32}; comm::send(mychan, val); @@ -39,14 +39,14 @@ fn test_grow() { // Don't allow the buffer to shrink below it's original size fn test_shrink1() { let myport = Port(); - let mychan = Chan(myport); + let mychan = Chan(&myport); send(mychan, 0i8); let x = recv(myport); } fn test_shrink2() { let myport = Port(); - let mychan = Chan(myport); + let mychan = Chan(&myport); for uint::range(0u, 100u) |_i| { let val: record = {val1: 0u32, val2: 0u32, val3: 0u32}; send(mychan, val); @@ -58,7 +58,7 @@ fn test_shrink2() { // Test rotating the buffer when the unit size is not a power of two fn test_rotate() { let myport = Port(); - let mychan = Chan(myport); + let mychan = Chan(&myport); for uint::range(0u, 100u) |i| { let val = {val1: i as u32, val2: i as u32, val3: i as u32}; send(mychan, val); @@ -74,7 +74,7 @@ fn test_rotate() { // the unit size is not a power of two fn test_rotate_grow() { let myport = Port::(); - let mychan = Chan(myport); + let mychan = Chan(&myport); for uint::range(0u, 10u) |j| { for uint::range(0u, 10u) |i| { let val: record = diff --git a/src/test/run-pass/rt-sched-1.rs b/src/test/run-pass/rt-sched-1.rs index 15207b668fef..690d93172ebc 100644 --- a/src/test/run-pass/rt-sched-1.rs +++ b/src/test/run-pass/rt-sched-1.rs @@ -18,7 +18,7 @@ extern mod rustrt { fn main() unsafe { let po = comm::Port(); - let ch = comm::Chan(po); + let ch = comm::Chan(&po); let parent_sched_id = rustrt::rust_get_sched_id(); error!("parent %?", parent_sched_id); let num_threads = 1u; diff --git a/src/test/run-pass/send-iloop.rs b/src/test/run-pass/send-iloop.rs index 9e369d819d41..b0003e8b5b18 100644 --- a/src/test/run-pass/send-iloop.rs +++ b/src/test/run-pass/send-iloop.rs @@ -8,7 +8,7 @@ fn die() { fn iloop() { task::spawn(|| die() ); let p = comm::Port::<()>(); - let c = comm::Chan(p); + let c = comm::Chan(&p); loop { // Sending and receiving here because these actions yield, // at which point our child can kill us diff --git a/src/test/run-pass/send-resource.rs b/src/test/run-pass/send-resource.rs index 3fc3afb12dab..a2ef71b14124 100644 --- a/src/test/run-pass/send-resource.rs +++ b/src/test/run-pass/send-resource.rs @@ -14,11 +14,11 @@ fn test(f: int) -> test { fn main() { let p = Port(); - let c = Chan(p); + let c = Chan(&p); do spawn() { let p = Port(); - c.send(Chan(p)); + c.send(Chan(&p)); let _r = p.recv(); } diff --git a/src/test/run-pass/send-type-inference.rs b/src/test/run-pass/send-type-inference.rs index 4f0b9667524f..8bca78807871 100644 --- a/src/test/run-pass/send-type-inference.rs +++ b/src/test/run-pass/send-type-inference.rs @@ -8,6 +8,6 @@ type command = {key: K, val: V}; fn cache_server(c: Chan>>) { let ctrl = Port(); - send(c, Chan(ctrl)); + send(c, Chan(&ctrl)); } fn main() { } diff --git a/src/test/run-pass/sendable-class.rs b/src/test/run-pass/sendable-class.rs index ecaa9238b277..d9b0ec336432 100644 --- a/src/test/run-pass/sendable-class.rs +++ b/src/test/run-pass/sendable-class.rs @@ -14,6 +14,6 @@ fn foo(i:int, j: char) -> foo { fn main() { let po = comm::Port::(); - let ch = comm::Chan(po); + let ch = comm::Chan(&po); comm::send(ch, foo(42, 'c')); } \ No newline at end of file diff --git a/src/test/run-pass/spawn-types.rs b/src/test/run-pass/spawn-types.rs index 22c20ed7e5e6..043bf125532e 100644 --- a/src/test/run-pass/spawn-types.rs +++ b/src/test/run-pass/spawn-types.rs @@ -15,6 +15,6 @@ fn iotask(cx: ctx, ip: ~str) { fn main() { let p = comm::Port::(); - let ch = comm::Chan(p); + let ch = comm::Chan(&p); task::spawn(|| iotask(ch, ~"localhost") ); } diff --git a/src/test/run-pass/task-comm-chan-cleanup.rs b/src/test/run-pass/task-comm-chan-cleanup.rs index 7149f3079630..b81f001c00d5 100644 --- a/src/test/run-pass/task-comm-chan-cleanup.rs +++ b/src/test/run-pass/task-comm-chan-cleanup.rs @@ -2,6 +2,6 @@ extern mod std; fn main() { let p = comm::Port(); - let c = comm::Chan(p); + let c = comm::Chan(&p); comm::send(c, ~"coffee"); } \ No newline at end of file diff --git a/src/test/run-pass/task-comm-chan-cleanup2.rs b/src/test/run-pass/task-comm-chan-cleanup2.rs index 7149f3079630..b81f001c00d5 100644 --- a/src/test/run-pass/task-comm-chan-cleanup2.rs +++ b/src/test/run-pass/task-comm-chan-cleanup2.rs @@ -2,6 +2,6 @@ extern mod std; fn main() { let p = comm::Port(); - let c = comm::Chan(p); + let c = comm::Chan(&p); comm::send(c, ~"coffee"); } \ No newline at end of file diff --git a/src/test/run-pass/task-comm-chan-cleanup3.rs b/src/test/run-pass/task-comm-chan-cleanup3.rs index 4dc10f867169..14cb272b62f3 100644 --- a/src/test/run-pass/task-comm-chan-cleanup3.rs +++ b/src/test/run-pass/task-comm-chan-cleanup3.rs @@ -3,7 +3,7 @@ extern mod std; fn main() { let c = { let p = comm::Port(); - comm::Chan(p) + comm::Chan(&p) }; comm::send(c, ~"coffee"); } \ No newline at end of file diff --git a/src/test/run-pass/task-comm-chan-cleanup4.rs b/src/test/run-pass/task-comm-chan-cleanup4.rs index 215843fbac71..852f0e5607d8 100644 --- a/src/test/run-pass/task-comm-chan-cleanup4.rs +++ b/src/test/run-pass/task-comm-chan-cleanup4.rs @@ -12,7 +12,7 @@ fn starship(&&ch: comm::Chan<~str>) { fn starbase() { for int::range(0, 10) |_i| { let p = comm::Port(); - let c = comm::Chan(p); + let c = comm::Chan(&p); task::spawn(|| starship(c) ); task::yield(); } diff --git a/src/test/run-pass/task-comm-chan-nil.rs b/src/test/run-pass/task-comm-chan-nil.rs index 87b91889356d..7cbd24844fe5 100644 --- a/src/test/run-pass/task-comm-chan-nil.rs +++ b/src/test/run-pass/task-comm-chan-nil.rs @@ -7,7 +7,7 @@ extern mod std; // or not this is desirable I don't know, but here's a regression test. fn main() { let po = comm::Port(); - let ch = comm::Chan(po); + let ch = comm::Chan(&po); comm::send(ch, ()); let n: () = comm::recv(po); assert (n == ()); diff --git a/src/test/run-pass/task-comm.rs b/src/test/run-pass/task-comm.rs index 8d144b1a3995..c88b556fd53f 100644 --- a/src/test/run-pass/task-comm.rs +++ b/src/test/run-pass/task-comm.rs @@ -32,7 +32,7 @@ fn test00() { debug!("Creating tasks"); let po = Port(); - let ch = Chan(po); + let ch = Chan(&po); let mut i: int = 0; @@ -69,7 +69,7 @@ fn test01() { fn test02() { let p = Port(); - let c = Chan(p); + let c = Chan(&p); debug!("Writing to a local task channel."); send(c, 42); debug!("Reading from a local task port."); @@ -101,7 +101,7 @@ fn test05_start(ch: Chan) { fn test05() { let po = comm::Port(); - let ch = Chan(po); + let ch = Chan(&po); task::spawn(|| test05_start(ch) ); let mut value: int; value = recv(po); diff --git a/src/test/run-pass/task-killjoin-rsrc.rs b/src/test/run-pass/task-killjoin-rsrc.rs index 405ba82b7903..1cea7d61f8c4 100644 --- a/src/test/run-pass/task-killjoin-rsrc.rs +++ b/src/test/run-pass/task-killjoin-rsrc.rs @@ -36,7 +36,7 @@ fn joinable(+f: fn~()) -> comm::Port { *b = true; } let p = comm::Port(); - let c = comm::Chan(p); + let c = comm::Chan(&p); do task::spawn_unlinked { wrapper(c, copy f) }; p } diff --git a/src/test/run-pass/task-spawn-move-and-copy.rs b/src/test/run-pass/task-spawn-move-and-copy.rs index 7316a927751b..09c880d489c2 100644 --- a/src/test/run-pass/task-spawn-move-and-copy.rs +++ b/src/test/run-pass/task-spawn-move-and-copy.rs @@ -1,6 +1,6 @@ fn main() { let p = comm::Port::(); - let ch = comm::Chan(p); + let ch = comm::Chan(&p); let x = ~1; let x_in_parent = ptr::addr_of(&(*x)) as uint; diff --git a/src/test/run-pass/unique-send-2.rs b/src/test/run-pass/unique-send-2.rs index 73cd7adc034e..70d58ea6cc3b 100644 --- a/src/test/run-pass/unique-send-2.rs +++ b/src/test/run-pass/unique-send-2.rs @@ -6,7 +6,7 @@ fn child(c: comm::Chan<~uint>, i: uint) { fn main() { let p = comm::Port(); - let ch = comm::Chan(p); + let ch = comm::Chan(&p); let n = 100u; let mut expected = 0u; for uint::range(0u, n) |i| { diff --git a/src/test/run-pass/unique-send.rs b/src/test/run-pass/unique-send.rs index 3acaa1b59f6e..cf06a55ae7a5 100644 --- a/src/test/run-pass/unique-send.rs +++ b/src/test/run-pass/unique-send.rs @@ -2,7 +2,7 @@ extern mod std; fn main() { let p = comm::Port(); - let c = comm::Chan(p); + let c = comm::Chan(&p); comm::send(c, ~100); let v = comm::recv(p); assert v == ~100; diff --git a/src/test/run-pass/unwind-resource.rs b/src/test/run-pass/unwind-resource.rs index 08d6af273d21..a602a2716026 100644 --- a/src/test/run-pass/unwind-resource.rs +++ b/src/test/run-pass/unwind-resource.rs @@ -22,7 +22,7 @@ fn f(c: comm::Chan) { fn main() { let p = comm::Port(); - let c = comm::Chan(p); + let c = comm::Chan(&p); task::spawn_unlinked(|| f(c) ); error!("hiiiiiiiii"); assert comm::recv(p); From 65c96f849ff1a76d4867c17703c0b384ccd1bb65 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Wed, 3 Oct 2012 14:52:09 -0700 Subject: [PATCH 29/80] Forbid deprecated modes again in core Sadly, there's only one file that requires deprecated modes (stackwalk)... So, forbid them everywhere else. --- src/libcore/at_vec.rs | 2 +- src/libcore/cast.rs | 1 + src/libcore/dlist.rs | 2 +- src/libcore/dvec.rs | 2 +- src/libcore/either.rs | 2 +- src/libcore/future.rs | 3 ++- src/libcore/int-template.rs | 2 +- src/libcore/io.rs | 3 +++ src/libcore/iter-trait.rs | 3 ++- src/libcore/iter.rs | 3 +++ src/libcore/mutable.rs | 2 +- src/libcore/ops.rs | 3 +++ src/libcore/option.rs | 3 +-- src/libcore/os.rs | 2 +- src/libcore/pipes.rs | 3 ++- src/libcore/private.rs | 3 ++- src/libcore/ptr.rs | 3 +++ src/libcore/rand.rs | 4 ++-- src/libcore/reflect.rs | 3 +++ src/libcore/repr.rs | 3 +++ src/libcore/result.rs | 3 ++- src/libcore/run.rs | 2 +- src/libcore/str.rs | 4 ++-- src/libcore/task.rs | 3 ++- src/libcore/task/spawn.rs | 1 + src/libcore/util.rs | 2 +- src/libcore/vec.rs | 4 ++-- 27 files changed, 48 insertions(+), 23 deletions(-) diff --git a/src/libcore/at_vec.rs b/src/libcore/at_vec.rs index 7d410c0337ad..5e1111c20d34 100644 --- a/src/libcore/at_vec.rs +++ b/src/libcore/at_vec.rs @@ -1,7 +1,7 @@ //! Managed vectors // NB: transitionary, de-mode-ing. -// tjc: re-forbid deprecated modes after snapshot +#[forbid(deprecated_mode)]; #[forbid(deprecated_pattern)]; use cast::transmute; diff --git a/src/libcore/cast.rs b/src/libcore/cast.rs index f4f0d7b61044..dce95aa2215f 100644 --- a/src/libcore/cast.rs +++ b/src/libcore/cast.rs @@ -1,4 +1,5 @@ //! Unsafe operations +#[forbid(deprecated_mode)] #[abi = "rust-intrinsic"] extern mod rusti { diff --git a/src/libcore/dlist.rs b/src/libcore/dlist.rs index 17ddd6ea73b7..3bcf486ef7e0 100644 --- a/src/libcore/dlist.rs +++ b/src/libcore/dlist.rs @@ -9,7 +9,7 @@ Do not use ==, !=, <, etc on doubly-linked lists -- it may not terminate. */ // NB: transitionary, de-mode-ing. -// tjc: re-forbid deprecated modes after snapshot +#[forbid(deprecated_mode)]; #[forbid(deprecated_pattern)]; type DListLink = Option>; diff --git a/src/libcore/dvec.rs b/src/libcore/dvec.rs index a2a709087971..1540eb30fe5a 100644 --- a/src/libcore/dvec.rs +++ b/src/libcore/dvec.rs @@ -10,7 +10,7 @@ Note that recursive use is not permitted. */ // NB: transitionary, de-mode-ing. -// tjc: re-forbid deprecated modes after snapshot +#[forbid(deprecated_mode)]; #[forbid(deprecated_pattern)]; use cast::reinterpret_cast; diff --git a/src/libcore/either.rs b/src/libcore/either.rs index c64cd25e4813..7500ff409a41 100644 --- a/src/libcore/either.rs +++ b/src/libcore/either.rs @@ -1,5 +1,5 @@ // NB: transitionary, de-mode-ing. -// tjc: re-forbid deprecated modes after snapshot +#[forbid(deprecated_mode)]; #[forbid(deprecated_pattern)]; //! A type that represents one of two alternatives diff --git a/src/libcore/future.rs b/src/libcore/future.rs index 11b6a2c01354..e07c03cafb68 100644 --- a/src/libcore/future.rs +++ b/src/libcore/future.rs @@ -1,5 +1,6 @@ // NB: transitionary, de-mode-ing. -// tjc: re-forbid deprecated modes after snapshot +// tjc: allowing deprecated modes due to function issue. +// can re-forbid them after snapshot #[forbid(deprecated_pattern)]; /*! diff --git a/src/libcore/int-template.rs b/src/libcore/int-template.rs index 6942d38d5d34..8cb689fd286a 100644 --- a/src/libcore/int-template.rs +++ b/src/libcore/int-template.rs @@ -1,5 +1,5 @@ // NB: transitionary, de-mode-ing. -// tjc: re-forbid deprecated modes after snapshot +#[forbid(deprecated_mode)]; #[forbid(deprecated_pattern)]; use T = inst::T; diff --git a/src/libcore/io.rs b/src/libcore/io.rs index 2efc96933da8..865b8013fb04 100644 --- a/src/libcore/io.rs +++ b/src/libcore/io.rs @@ -4,6 +4,9 @@ Basic input/output */ +#[forbid(deprecated_mode)]; +#[forbid(deprecated_pattern)]; + use result::Result; use cmp::Eq; diff --git a/src/libcore/iter-trait.rs b/src/libcore/iter-trait.rs index 09bfe2eff36a..6de6633f5f8a 100644 --- a/src/libcore/iter-trait.rs +++ b/src/libcore/iter-trait.rs @@ -2,7 +2,8 @@ // workaround our lack of traits and lack of macros. See core.{rc,rs} for // how this file is used. -#[warn(deprecated_mode)]; +#[forbid(deprecated_mode)]; +#[forbid(deprecated_pattern)]; use cmp::{Eq, Ord}; use inst::{IMPL_T, EACH, SIZE_HINT}; diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index bf3e91f70719..322012db135b 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -4,6 +4,9 @@ The iteration traits and common implementation */ +#[forbid(deprecated_mode)]; +#[forbid(deprecated_pattern)]; + use cmp::{Eq, Ord}; /// A function used to initialize the elements of a sequence diff --git a/src/libcore/mutable.rs b/src/libcore/mutable.rs index 5948c630cd85..b314ad61ee2a 100644 --- a/src/libcore/mutable.rs +++ b/src/libcore/mutable.rs @@ -8,7 +8,7 @@ dynamic checks: your program will fail if you attempt to perform mutation when the data structure should be immutable. */ -// tjc: re-forbid deprecated modes after snapshot +#[forbid(deprecated_mode)]; #[forbid(deprecated_pattern)]; use util::with; diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 038c117b8bed..7c6bcf5bd51f 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -1,5 +1,8 @@ // Core operators and kinds. +#[forbid(deprecated_mode)]; +#[forbid(deprecated_pattern)]; + #[lang="const"] pub trait Const { // Empty. diff --git a/src/libcore/option.rs b/src/libcore/option.rs index c222592a9285..c60b7b401cc8 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -31,8 +31,7 @@ let unwrapped_msg = match move msg { */ -// NB: transitionary, de-mode-ing. -#[warn(deprecated_mode)]; +#[forbid(deprecated_mode)]; #[forbid(deprecated_pattern)]; use cmp::Eq; diff --git a/src/libcore/os.rs b/src/libcore/os.rs index 1a9bd03539e8..3fd98e7f2987 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -1,5 +1,5 @@ // NB: transitionary, de-mode-ing. -// tjc: re-forbid +#[forbid(deprecated_mode)]; #[forbid(deprecated_pattern)]; /*! diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs index e34c0db35e9d..c53f069174c3 100644 --- a/src/libcore/pipes.rs +++ b/src/libcore/pipes.rs @@ -73,7 +73,8 @@ bounded and unbounded protocols allows for less code duplication. */ // NB: transitionary, de-mode-ing. -// tjc: re-forbid deprecated modes after snapshot +// tjc: allowing deprecated modes due to function issue, +// re-forbid after snapshot #[forbid(deprecated_pattern)]; use cmp::Eq; diff --git a/src/libcore/private.rs b/src/libcore/private.rs index 395e63ad30f8..992c8e011f7f 100644 --- a/src/libcore/private.rs +++ b/src/libcore/private.rs @@ -1,5 +1,6 @@ // NB: transitionary, de-mode-ing. -// tjc: re-forbid deprecated modes after snapshot +// tjc: Re-forbid deprecated modes once a snapshot fixes the +// function problem #[forbid(deprecated_pattern)]; #[doc(hidden)]; diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index fad7eddd2d8d..608cbdf84a21 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -1,5 +1,8 @@ //! Unsafe pointer utility functions +#[forbid(deprecated_mode)]; +#[forbid(deprecated_pattern)]; + use cmp::{Eq, Ord}; use libc::{c_void, size_t}; diff --git a/src/libcore/rand.rs b/src/libcore/rand.rs index 32f77a533a67..786fed88de97 100644 --- a/src/libcore/rand.rs +++ b/src/libcore/rand.rs @@ -1,7 +1,7 @@ //! Random number generation // NB: transitional, de-mode-ing. -#[warn(deprecated_mode)]; +#[forbid(deprecated_mode)]; #[forbid(deprecated_pattern)]; #[allow(non_camel_case_types)] // runtime type @@ -310,7 +310,7 @@ pub fn seeded_xorshift(x: u32, y: u32, z: u32, w: u32) -> Rng { // used to make space in TLS for a random number generator -fn tls_rng_state(+_v: @RandRes) {} +fn tls_rng_state(_v: @RandRes) {} /** * Gives back a lazily initialized task-local random number generator, diff --git a/src/libcore/reflect.rs b/src/libcore/reflect.rs index 41006e1dfb5e..505804b3da82 100644 --- a/src/libcore/reflect.rs +++ b/src/libcore/reflect.rs @@ -4,6 +4,9 @@ Runtime type reflection */ +#[forbid(deprecated_mode)]; +#[forbid(deprecated_pattern)]; + use intrinsic::{TyDesc, get_tydesc, visit_tydesc, TyVisitor}; use libc::c_void; diff --git a/src/libcore/repr.rs b/src/libcore/repr.rs index ff82ed3fb419..0501b032d2d5 100644 --- a/src/libcore/repr.rs +++ b/src/libcore/repr.rs @@ -4,6 +4,9 @@ More runtime type reflection */ +#[forbid(deprecated_mode)]; +#[forbid(deprecated_pattern)]; + use dvec::DVec; use io::{Writer, WriterUtil}; use libc::c_void; diff --git a/src/libcore/result.rs b/src/libcore/result.rs index e61690d5b2c0..39fae8905f92 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -1,7 +1,8 @@ //! A type representing either success or failure // NB: transitionary, de-mode-ing. -// tjc: re-forbid deprecated modes after snapshot + +#[forbid(deprecated_mode)]; #[forbid(deprecated_pattern)]; use cmp::Eq; diff --git a/src/libcore/run.rs b/src/libcore/run.rs index 7ebca94f3576..0ff917492091 100644 --- a/src/libcore/run.rs +++ b/src/libcore/run.rs @@ -1,5 +1,5 @@ // NB: transitionary, de-mode-ing. -// tjc: re-forbid deprecated modes after snapshot +#[forbid(deprecated_mode)]; #[forbid(deprecated_pattern)]; //! Process spawning diff --git a/src/libcore/str.rs b/src/libcore/str.rs index cf996a8b254c..285b61149577 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -7,8 +7,8 @@ * some heavy-duty uses, try std::rope. */ -#[warn(deprecated_mode)]; -#[warn(deprecated_pattern)]; +#[forbid(deprecated_mode)]; +#[forbid(deprecated_pattern)]; use cmp::{Eq, Ord}; use libc::size_t; diff --git a/src/libcore/task.rs b/src/libcore/task.rs index efe6948ecef0..06150227e950 100644 --- a/src/libcore/task.rs +++ b/src/libcore/task.rs @@ -1,5 +1,6 @@ // NB: transitionary, de-mode-ing. -// tjc: re-forbid deprecated modes after snapshot +// tjc: Deprecated modes allowed because of function arg issue +// in task::spawn. Re-forbid after snapshot. #[forbid(deprecated_pattern)]; /*! diff --git a/src/libcore/task/spawn.rs b/src/libcore/task/spawn.rs index 2033db0d58d5..2db63d20f162 100644 --- a/src/libcore/task/spawn.rs +++ b/src/libcore/task/spawn.rs @@ -61,6 +61,7 @@ ****************************************************************************/ #[doc(hidden)]; // FIXME #3538 +#[warn(deprecated_mode)]; use rt::rust_task; use rt::rust_closure; diff --git a/src/libcore/util.rs b/src/libcore/util.rs index aa1fe14ba882..6c633f16abf2 100644 --- a/src/libcore/util.rs +++ b/src/libcore/util.rs @@ -5,7 +5,7 @@ Miscellaneous helpers for common patterns. */ // NB: transitionary, de-mode-ing. -// tjc: re-forbid deprecated modes after snapshot +#[forbid(deprecated_mode)]; #[forbid(deprecated_pattern)]; use cmp::Eq; diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 0c822bd0a031..7c0b4b516bb5 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -1,7 +1,7 @@ //! Vectors -#[warn(deprecated_mode)]; -#[warn(deprecated_pattern)]; +#[forbid(deprecated_mode)]; +#[forbid(deprecated_pattern)]; #[warn(non_camel_case_types)]; use cmp::{Eq, Ord}; From 202c8fd0eb20ebab07e4da81c96cb147020fb7c9 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Wed, 3 Oct 2012 14:57:02 -0700 Subject: [PATCH 30/80] Kill bootstrapping code in ptr --- src/libcore/ptr.rs | 6 ------ src/libstd/uv_iotask.rs | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 608cbdf84a21..ffa11dcfc754 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -31,12 +31,6 @@ extern mod rusti { #[inline(always)] pub pure fn addr_of(val: &T) -> *T { unsafe { rusti::addr_of(*val) } } -pub mod p2 { - /// Get an unsafe pointer to a value - #[inline(always)] - pub pure fn addr_of(val: &T) -> *T { unsafe { rusti::addr_of(*val) } } -} - /// Get an unsafe mut pointer to a value #[inline(always)] pub pure fn mut_addr_of(val: &T) -> *mut T { diff --git a/src/libstd/uv_iotask.rs b/src/libstd/uv_iotask.rs index ca4d655db59a..2e31e15a70d7 100644 --- a/src/libstd/uv_iotask.rs +++ b/src/libstd/uv_iotask.rs @@ -8,7 +8,7 @@ // tjc: forbid deprecated modes again after a snapshot use libc::c_void; -use ptr::p2::addr_of; +use ptr::addr_of; use comm = core::comm; use comm::{Port, Chan, listen}; use task::TaskBuilder; From 677c7cd7f5574052dadcc1b1c2a9cff8be496c63 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Thu, 4 Oct 2012 17:01:15 -0700 Subject: [PATCH 31/80] Register snapshots --- src/snapshots.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/snapshots.txt b/src/snapshots.txt index 7464d18247d9..cf6fbb242621 100644 --- a/src/snapshots.txt +++ b/src/snapshots.txt @@ -1,3 +1,11 @@ +S 2012-10-02 5585514 + macos-i386 c910d42405e66b444b7870ea66b93e1135776df3 + macos-x86_64 e0dfa93e8d0d25b91c9684d4f6e92dec521e2d74 + freebsd-x86_64 228e68ac17ca104554dd8a39a466d20f1b68de24 + linux-i386 0a2760b24d5bc3cabcc9321b92a08796f95da377 + linux-x86_64 eace8a5c46f7525355e85b3b570dbd7f4b3b6471 + winnt-i386 25680d15a358cf4163e08f4e56e54fb497de5eb4 + S 2012-10-02 4d30b34 macos-i386 2bcce3cde8a7e53df202972cda85b0b59ce4e50d macos-x86_64 fc5592828392f9eabe8b51cc59639be6d709cc26 From 2dfd8229627e39cbef20b2b1663985232082890a Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Thu, 4 Oct 2012 17:03:08 -0700 Subject: [PATCH 32/80] Fix snapshots.txt date --- src/snapshots.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/snapshots.txt b/src/snapshots.txt index cf6fbb242621..0ce74d2d5633 100644 --- a/src/snapshots.txt +++ b/src/snapshots.txt @@ -1,4 +1,4 @@ -S 2012-10-02 5585514 +S 2012-10-03 5585514 macos-i386 c910d42405e66b444b7870ea66b93e1135776df3 macos-x86_64 e0dfa93e8d0d25b91c9684d4f6e92dec521e2d74 freebsd-x86_64 228e68ac17ca104554dd8a39a466d20f1b68de24 From fafce9ae37128f14c890b0805b410527ab81472f Mon Sep 17 00:00:00 2001 From: Kevin Cantu Date: Thu, 4 Oct 2012 12:41:45 -0700 Subject: [PATCH 33/80] More looking at the tutorial, small changes --- doc/tutorial.md | 120 ++++++++++++++++++++++++------------------------ 1 file changed, 61 insertions(+), 59 deletions(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index 4706f47b3d9c..5d1a39078dcf 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -329,7 +329,6 @@ something—in which case you'll have embedded it in a bigger statement. # fn foo() -> bool { true } # fn bar() -> bool { true } # fn baz() -> bool { true } - // `let` is not an expression, so it is semi-colon terminated; let x = foo(); @@ -711,8 +710,8 @@ Structs can be destructured in `match` patterns. The basic syntax is # struct Point { x: float, y: float } # let mypoint = Point { x: 0.0, y: 0.0 }; match mypoint { - Point { x: 0.0, y: y } => { io::println(y.to_str()); } - Point { x: x, y: y } => { io::println(x.to_str() + " " + y.to_str()); } + Point { x: 0.0, y: yy } => { io::println(yy.to_str()); } + Point { x: xx, y: yy } => { io::println(xx.to_str() + " " + yy.to_str()); } } ~~~~ @@ -802,7 +801,7 @@ dereference (`*`) unary operator: ~~~~ # enum GizmoId = int; -let my_gizmo_id = GizmoId(10); +let my_gizmo_id: GizmoId = GizmoId(10); let id_int: int = *my_gizmo_id; ~~~~ @@ -863,12 +862,8 @@ back to [later](#modules-and-crates)). They are introduced with the the return type follows the arrow. ~~~~ -fn repeat(string: &str, count: int) -> ~str { - let mut result = ~""; - for count.times { - result += string; - } - return result; +fn line(a: int, b: int, x: int) -> int { + return a*x + b; } ~~~~ @@ -889,10 +884,8 @@ fn int_to_str(i: int) -> ~str { ~~~~ ~~~~ -# const copernicus: int = 0; -fn int_to_str(i: int) -> ~str { - if i == copernicus { ~"tube sock" } - else { ~"violin" } +fn line(a: int, b: int, x: int) -> int { + a*x + b } ~~~~ @@ -906,6 +899,16 @@ fn do_nothing_the_hard_way() -> () { return (); } fn do_nothing_the_easy_way() { } ~~~~ +Ending the function with a semicolon like so is equivalent to returning `()`. + +~~~~ +fn line(a: int, b: int, x: int) -> int { a*x + b } +fn oops(a: int, b: int, x: int) -> () { a*x + b; } + +assert 8 == line(5,3,1); +assert () == oops(5,3,1); +~~~~ + Methods are like functions, except that they are defined for a specific 'self' type (like 'this' in C++). Calling a method is done with dot notation, as in `my_vec.len()`. Methods may be defined on most @@ -1005,7 +1008,7 @@ easy for programmers to reason about. Heap isolation has the additional benefit that garbage collection must only be done per-heap. Rust never "stops the world" to reclaim memory. -Complete isolation of heaps between tasks implies that any data +Complete isolation of heaps between tasks would, however, mean that any data transferred between tasks must be copied. While this is a fine and useful way to implement communication between tasks, it is also very inefficient for large data structures. Because of this, Rust also @@ -1117,6 +1120,9 @@ If you really want to copy a unique box you must say so explicitly. ~~~~ let x = ~10; let y = copy x; + +let z = *x + *y; +assert z = 20; ~~~~ This is where the 'move' operator comes in. It is similar to @@ -1125,9 +1131,11 @@ from `x` to `y`, without violating the constraint that it only has a single owner (if you used assignment instead of the move operator, the box would, in principle, be copied). -~~~~ +~~~~ {.ignore} let x = ~10; let y = move x; + +let z = *x + *y; // would cause an error: use of moved variable: `x` ~~~~ Owned boxes, when they do not contain any managed boxes, can be sent @@ -1265,7 +1273,7 @@ also done with square brackets (zero-based): # BananaMania, Beaver, Bittersweet }; # fn draw_scene(c: Crayon) { } -let crayons = [BananaMania, Beaver, Bittersweet]; +let crayons: [Crayon] = [BananaMania, Beaver, Bittersweet]; match crayons[0] { Bittersweet => draw_scene(crayons[0]), _ => () @@ -1282,7 +1290,7 @@ elements. Mutable vector literals are written `[mut]` (empty) or `[mut # Aquamarine, Asparagus, AtomicTangerine, # BananaMania, Beaver, Bittersweet }; -let crayons = [mut BananaMania, Beaver, Bittersweet]; +let crayons: [mut Crayon] = [mut BananaMania, Beaver, Bittersweet]; crayons[0] = AtomicTangerine; ~~~~ @@ -1318,8 +1326,8 @@ my_crayons += your_crayons; > not well supported yet, owned vectors are often the most > usable. -Strings are simply vectors of `[u8]`, though they have a distinct -type. They support most of the same allocation aptions as +Strings are implemented with vectors of `[u8]`, though they have a distinct +type. They support most of the same allocation options as vectors, though the string literal without a storage sigil, e.g. `"foo"` is treated differently than a comparable vector (`[foo]`). Where @@ -1328,7 +1336,7 @@ Where // A plain string is a slice to read-only (static) memory let stack_crayons: &str = "Almond, AntiqueBrass, Apricot"; -// The same thing, but without +// The same thing, but with the `&` let stack_crayons: &str = &"Almond, AntiqueBrass, Apricot"; // A local heap (managed) string @@ -1511,9 +1519,12 @@ call_twice(bare_function); ## Do syntax -Closures in Rust are frequently used in combination with higher-order -functions to simulate control structures like `if` and -`loop`. Consider this function that iterates over a vector of +The `do` expression is syntactic sugar for use with functions which +take a closure as a final argument, because closures in Rust +are so frequently used in combination with higher-order +functions. + +Consider this function which iterates over a vector of integers, passing in a pointer to each integer in the vector: ~~~~ @@ -1558,8 +1569,7 @@ do each(&[1, 2, 3]) |n| { The call is prefixed with the keyword `do` and, instead of writing the final closure inside the argument list it is moved outside of the parenthesis where it looks visually more like a typical block of -code. The `do` expression is purely syntactic sugar for a call that -takes a final closure argument. +code. `do` is often used for task spawning. @@ -1653,6 +1663,10 @@ fn contains(v: &[int], elt: int) -> bool { `for` syntax only works with stack closures. +> ***Note:*** This is, essentially, a special loop protocol: +> the keywords `break`, `loop`, and `return` work, in varying degree, +> with `while`, `loop`, `do`, and `for` constructs. + # Generics Throughout this tutorial, we've been defining functions that act only on @@ -2057,6 +2071,9 @@ The compiler will now look for `poultry/chicken.rs` and and `poultry::turkey`. You can also provide a `poultry.rs` to add content to the `poultry` module itself. +The compiler then builds the crate as a platform-specific shared library or +executable which can be distributed. + ## Using other crates Having compiled a crate that contains the `#[crate_type = "lib"]` @@ -2111,22 +2128,22 @@ Now for something that you can actually compile yourself. We have these two files: ~~~~ -// mylib.rs -#[link(name = "mylib", vers = "1.0")]; -fn world() -> ~str { ~"world" } +// world.rs +#[link(name = "world", vers = "1.0")]; +fn explore() -> ~str { ~"world" } ~~~~ ~~~~ {.ignore} // main.rs -extern mod mylib; -fn main() { io::println(~"hello " + mylib::world()); } +extern mod world; +fn main() { io::println(~"hello " + world::explore()); } ~~~~ Now compile and run like this (adjust to your platform if necessary): ~~~~ {.notrust} -> rustc --lib mylib.rs -> rustc main.rs -L . +> rustc --lib world.rs # compiles libworld-94839cbfe144198-1.0.so +> rustc main.rs -L . # compiles main > ./main "hello world" ~~~~ @@ -2146,12 +2163,14 @@ fn main() { } ~~~~ + It is also possible to import just the name of a module (`use std::list;`, then use `list::find`), to import all identifiers exported by a given module (`use io::*`), or to import a specific set of identifiers (`use math::{min, max, pi}`). -You can rename an identifier when importing using the `=` operator: +Rust uses different namespaces for modules, types, and values. You +can also rename an identifier when importing using the `=` operator: ~~~~ use prnt = io::println; @@ -2175,27 +2194,6 @@ This defines a rock-solid encryption algorithm. Code outside of the module can refer to the `enc::encrypt` and `enc::decrypt` identifiers just fine, but it does not have access to `enc::super_secret_number`. -## Namespaces - -Rust uses three different namespaces: one for modules, one for types, -and one for values. This means that this code is valid: - -~~~~ -#[legacy_exports] -mod buffalo { - type buffalo = int; - fn buffalo(+buffalo: buffalo) -> buffalo { buffalo } -} -fn main() { - let buffalo: buffalo::buffalo = 1; - buffalo::buffalo::(buffalo::buffalo(buffalo)); -} -~~~~ - -You don't want to write things like that, but it *is* very practical -to not have to worry about name clashes between types, values, and -modules. - ## Resolution The resolution process in Rust simply goes up the chain of contexts, @@ -2211,7 +2209,7 @@ Identifiers can shadow each other. In this program, `x` is of type type MyType = ~str; fn main() { type MyType = int; - let x: MyType; + let x: MyType = 17; } ~~~~ @@ -2219,13 +2217,17 @@ An `use` directive will only import into the namespaces for which identifiers are actually found. Consider this example: ~~~~ -mod foo { fn bar() {} } -fn baz() { - let bar = 10u; +mod foo { + fn bar() {} +} + +fn main() { + let bar = 10; { use foo::bar; let quux = bar; + assert quux == 10; } } ~~~~ From 8cb3da576deb06a7c298761c01708ea90b18659b Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 4 Oct 2012 17:08:35 -0700 Subject: [PATCH 34/80] docs: Tweaks --- doc/tutorial.md | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index 5d1a39078dcf..0ff048c90196 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -872,17 +872,6 @@ is optionally followed by an expression to return. A function can also return a value by having its top level block produce an expression. -~~~~ -# const copernicus: int = 0; -fn int_to_str(i: int) -> ~str { - if i == copernicus { - return ~"tube sock"; - } else { - return ~"violin"; - } -} -~~~~ - ~~~~ fn line(a: int, b: int, x: int) -> int { a*x + b @@ -1122,7 +1111,7 @@ let x = ~10; let y = copy x; let z = *x + *y; -assert z = 20; +assert z == 20; ~~~~ This is where the 'move' operator comes in. It is similar to @@ -1131,7 +1120,7 @@ from `x` to `y`, without violating the constraint that it only has a single owner (if you used assignment instead of the move operator, the box would, in principle, be copied). -~~~~ {.ignore} +~~~~ {.xfail-test} let x = ~10; let y = move x; @@ -1273,7 +1262,7 @@ also done with square brackets (zero-based): # BananaMania, Beaver, Bittersweet }; # fn draw_scene(c: Crayon) { } -let crayons: [Crayon] = [BananaMania, Beaver, Bittersweet]; +let crayons: [Crayon * 3] = [BananaMania, Beaver, Bittersweet]; match crayons[0] { Bittersweet => draw_scene(crayons[0]), _ => () @@ -1290,7 +1279,7 @@ elements. Mutable vector literals are written `[mut]` (empty) or `[mut # Aquamarine, Asparagus, AtomicTangerine, # BananaMania, Beaver, Bittersweet }; -let crayons: [mut Crayon] = [mut BananaMania, Beaver, Bittersweet]; +let crayons: [mut Crayon * 3] = [mut BananaMania, Beaver, Bittersweet]; crayons[0] = AtomicTangerine; ~~~~ @@ -1330,7 +1319,8 @@ Strings are implemented with vectors of `[u8]`, though they have a distinct type. They support most of the same allocation options as vectors, though the string literal without a storage sigil, e.g. `"foo"` is treated differently than a comparable vector (`[foo]`). -Where +Wheras plain vectors are stack-allocated fixed length vectors, +plain strings are region pointers to read-only memory. ~~~ // A plain string is a slice to read-only (static) memory From 1ee056672bd7b2b73561394a5e949fb4042640c5 Mon Sep 17 00:00:00 2001 From: Andrew Paseltiner Date: Thu, 4 Oct 2012 20:33:06 -0400 Subject: [PATCH 35/80] docs: minor tutorial fixes --- doc/tutorial.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index 0ff048c90196..c8a04349eace 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -358,7 +358,7 @@ This may sound intricate, but it is super-useful and will grow on you. ## Types -The basic types include the usual boolean, integral, and floating point types. +The basic types include the usual boolean, integral, and floating-point types. ------------------------- ----------------------------------------------- `()` Nil, the type that has only a single value @@ -367,8 +367,8 @@ The basic types include the usual boolean, integral, and floating point types. `i8`, `i16`, `i32`, `i64` Signed integers with a specific size (in bits) `u8`, `u16`, `u32`, `u64` Unsigned integers with a specific size `float` The largest floating-point type efficiently supported on the target machine -`f32`, `f64` Floating-point types with a specific size. -`char` A Unicode character (32 bits). +`f32`, `f64` Floating-point types with a specific size +`char` A Unicode character (32 bits) ------------------------- ----------------------------------------------- These can be combined in composite types, which will be described in @@ -378,7 +378,7 @@ while N should be a literal number): ------------------------- ----------------------------------------------- `[T * N]` Vector (like an array in other languages) with N elements `[mut T * N]` Mutable vector with N elements -`(T1, T2)` Tuple type. Any arity above 1 is supported +`(T1, T2)` Tuple type; any arity above 1 is supported `&T`, `~T`, `@T` [Pointer types](#boxes-and-pointers) ------------------------- ----------------------------------------------- @@ -863,7 +863,7 @@ the return type follows the arrow. ~~~~ fn line(a: int, b: int, x: int) -> int { - return a*x + b; + return a * x + b; } ~~~~ @@ -874,7 +874,7 @@ expression. ~~~~ fn line(a: int, b: int, x: int) -> int { - a*x + b + a * x + b } ~~~~ @@ -891,11 +891,11 @@ fn do_nothing_the_easy_way() { } Ending the function with a semicolon like so is equivalent to returning `()`. ~~~~ -fn line(a: int, b: int, x: int) -> int { a*x + b } -fn oops(a: int, b: int, x: int) -> () { a*x + b; } +fn line(a: int, b: int, x: int) -> int { a * x + b } +fn oops(a: int, b: int, x: int) -> () { a * x + b; } -assert 8 == line(5,3,1); -assert () == oops(5,3,1); +assert 8 == line(5, 3, 1); +assert () == oops(5, 3, 1); ~~~~ Methods are like functions, except that they are defined for a specific @@ -1319,7 +1319,7 @@ Strings are implemented with vectors of `[u8]`, though they have a distinct type. They support most of the same allocation options as vectors, though the string literal without a storage sigil, e.g. `"foo"` is treated differently than a comparable vector (`[foo]`). -Wheras plain vectors are stack-allocated fixed length vectors, +Whereas plain vectors are stack-allocated fixed-length vectors, plain strings are region pointers to read-only memory. ~~~ From 88ae10165b42bbd8fbad2d458b64c02e2b66e77b Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Thu, 4 Oct 2012 17:38:55 -0700 Subject: [PATCH 36/80] Add Andrew Paseltiner to AUTHORS --- AUTHORS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.txt b/AUTHORS.txt index e9ff7db43848..8cac3a4df97c 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -9,6 +9,7 @@ Aleksander Balicki Alex Rønne Petersen Alexander Stavonin Andreas Gal +Andrew Paseltiner Arkaitz Jimenez Armin Ronacher Austin Seipp From b4f124e5f810b178d7413f0a9b4db97c83063464 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 4 Oct 2012 17:58:13 -0700 Subject: [PATCH 37/80] docs: Don't talk about mutable vecs in tutorial. Use inherited mutability --- doc/tutorial.md | 117 ++++++++++++++++++++++++++---------------------- 1 file changed, 64 insertions(+), 53 deletions(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index c8a04349eace..7b4c5c5e7b64 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -1237,52 +1237,23 @@ pointers to vectors are also called 'slices'. enum Crayon { Almond, AntiqueBrass, Apricot, Aquamarine, Asparagus, AtomicTangerine, - BananaMania, Beaver, Bittersweet + BananaMania, Beaver, Bittersweet, + Black, BlizzardBlue, Blue } // A fixed-size stack vector let stack_crayons: [Crayon * 3] = [Almond, AntiqueBrass, Apricot]; // A borrowed pointer to stack allocated vector -let stack_crayons: &[Crayon] = &[Almond, AntiqueBrass, Apricot]; +let stack_crayons: &[Crayon] = &[Aquamarine, Asparagus, AtomicTangerine]; // A local heap (managed) vector of crayons -let local_crayons: @[Crayon] = @[Aquamarine, Asparagus, AtomicTangerine]; +let local_crayons: @[Crayon] = @[BananaMania, Beaver, Bittersweet]; // An exchange heap (owned) vector of crayons -let exchange_crayons: ~[Crayon] = ~[BananaMania, Beaver, Bittersweet]; +let exchange_crayons: ~[Crayon] = ~[Black, BlizzardBlue, Blue]; ~~~ -Vector literals are enclosed in square brackets and dereferencing is -also done with square brackets (zero-based): - -~~~~ -# enum Crayon { Almond, AntiqueBrass, Apricot, -# Aquamarine, Asparagus, AtomicTangerine, -# BananaMania, Beaver, Bittersweet }; -# fn draw_scene(c: Crayon) { } - -let crayons: [Crayon * 3] = [BananaMania, Beaver, Bittersweet]; -match crayons[0] { - Bittersweet => draw_scene(crayons[0]), - _ => () -} -~~~~ - -By default, vectors are immutable—you can not replace their elements. -The type written as `[mut T]` is a vector with mutable -elements. Mutable vector literals are written `[mut]` (empty) or `[mut -1, 2, 3]` (with elements). - -~~~~ -# enum Crayon { Almond, AntiqueBrass, Apricot, -# Aquamarine, Asparagus, AtomicTangerine, -# BananaMania, Beaver, Bittersweet }; - -let crayons: [mut Crayon * 3] = [mut BananaMania, Beaver, Bittersweet]; -crayons[0] = AtomicTangerine; -~~~~ - The `+` operator means concatenation when applied to vector types. ~~~~ @@ -1293,20 +1264,12 @@ The `+` operator means concatenation when applied to vector types. let my_crayons = ~[Almond, AntiqueBrass, Apricot]; let your_crayons = ~[BananaMania, Beaver, Bittersweet]; +// Add two vectors to create a new one let our_crayons = my_crayons + your_crayons; -~~~~ - -The `+=` operator also works as expected, provided the assignee -lives in a mutable slot. - -~~~~ -# enum Crayon { Almond, AntiqueBrass, Apricot, -# Aquamarine, Asparagus, AtomicTangerine, -# BananaMania, Beaver, Bittersweet }; - -let mut my_crayons = ~[Almond, AntiqueBrass, Apricot]; -let your_crayons = ~[BananaMania, Beaver, Bittersweet]; +// += will append to a vector, provided it leves +// in a mutable slot +let mut my_crayons = move my_crayons; my_crayons += your_crayons; ~~~~ @@ -1315,31 +1278,79 @@ my_crayons += your_crayons; > not well supported yet, owned vectors are often the most > usable. +Indexing into vectors is done with square brackets: + +~~~~ +# enum Crayon { Almond, AntiqueBrass, Apricot, +# Aquamarine, Asparagus, AtomicTangerine, +# BananaMania, Beaver, Bittersweet }; +# fn draw_scene(c: Crayon) { } +let crayons: [Crayon * 3] = [BananaMania, Beaver, Bittersweet]; +match crayons[0] { + Bittersweet => draw_scene(crayons[0]), + _ => () +} +~~~~ + +The elements of a vector _inherit the mutability of the vector_, +and as such individual elements may not be reassigned when the +vector lives in an immutable slot. + +~~~ {.xfail-test} +# enum Crayon { Almond, AntiqueBrass, Apricot, +# Aquamarine, Asparagus, AtomicTangerine, +# BananaMania, Beaver, Bittersweet }; +let crayons: ~[Crayon] = ~[BananaMania, Beaver, Bittersweet]; + +crayons[0] = Apricot; // ERROR: Can't assign to immutable vector +~~~ + +Moving it into a mutable slot makes the elements assignable. + +~~~ +# enum Crayon { Almond, AntiqueBrass, Apricot, +# Aquamarine, Asparagus, AtomicTangerine, +# BananaMania, Beaver, Bittersweet }; +let crayons: ~[Crayon] = ~[BananaMania, Beaver, Bittersweet]; + +// Put the vector into a mutable slot +let mut mutable_crayons = move crayons; + +// Now it's mutable to the bone +mutable_crayons[0] = Apricot; +~~~ + +This is a simple example of Rust's _dual-mode data structures_, also +referred to as _freezing and thawing_. + Strings are implemented with vectors of `[u8]`, though they have a distinct type. They support most of the same allocation options as vectors, though the string literal without a storage sigil, e.g. `"foo"` is treated differently than a comparable vector (`[foo]`). Whereas plain vectors are stack-allocated fixed-length vectors, -plain strings are region pointers to read-only memory. +plain strings are region pointers to read-only memory. Strings +are always immutable. ~~~ // A plain string is a slice to read-only (static) memory let stack_crayons: &str = "Almond, AntiqueBrass, Apricot"; // The same thing, but with the `&` -let stack_crayons: &str = &"Almond, AntiqueBrass, Apricot"; +let stack_crayons: &str = &"Aquamarine, Asparagus, AtomicTangerine"; // A local heap (managed) string -let local_crayons: @str = @"Aquamarine, Asparagus, AtomicTangerine"; +let local_crayons: @str = @"BananMania, Beaver, Bittersweet"; // An exchange heap (owned) string -let exchange_crayons: ~str = ~"BananaMania, Beaver, Bittersweet"; +let exchange_crayons: ~str = ~"Black, BlizzardBlue, Blue"; ~~~ Both vectors and strings support a number of useful -[methods](#implementation). While we haven't covered methods yet, -most vector functionality is provided by methods, so let's have a -brief look at a few common ones. +[methods](#functions-and-methods), defined in [`core::vec`] +and [`core::str`]. Here are some examples. + +[`core::vec`]: core/vec.html +[`core::str`]: core/str.html ~~~ # use io::println; From aca2419d55c6c5defcaa97d047da5ed7d7c8147e Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 4 Oct 2012 18:04:31 -0700 Subject: [PATCH 38/80] docs: Minor tutorial tweaks --- doc/tutorial.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index 7b4c5c5e7b64..7ed93e47a68b 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -1509,7 +1509,7 @@ fn call_twice(f: fn()) { f(); f(); } call_twice(|| { ~"I am an inferred stack closure"; } ); call_twice(fn&() { ~"I am also a stack closure"; } ); call_twice(fn@() { ~"I am a managed closure"; }); -call_twice(fn~() { ~"I am a owned closure"; }); +call_twice(fn~() { ~"I am an owned closure"; }); fn bare_function() { ~"I am a plain function"; } call_twice(bare_function); ~~~~ @@ -2121,7 +2121,7 @@ Rust program. This library is documented [here][core]. -[core]: http://doc.rust-lang.org/doc/core +[core]: core/index.html ## A minimal example From 213725407b8f70dfe9f45d636f759a8ccd9451ca Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 4 Oct 2012 19:36:56 -0700 Subject: [PATCH 39/80] docs: Add section on constants to tutorial --- doc/tutorial.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/doc/tutorial.md b/doc/tutorial.md index 7ed93e47a68b..a7e627fa08e6 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -463,6 +463,41 @@ character, such as `\n`, `\r`, and `\t`. String literals, written between double quotes, allow the same escape sequences. Rust strings may contain newlines. +## Constants + +Compile-time constants are declared with `const`. All scalar types, +like integers and floats, may be declared `const`, as well as fixed +length vectors, static strings (more on this later), and structs. +Constants may be declared in any scope and may refer to other +constants. Constant declarations are not type inferred, so must always +have a type annotation. By convention they are written in all capital +letters. + +~~~ +// Scalars can be constants +const MY_PASSWORD: int = 12345; + +// Scalar constants can be combined with other constants +const MY_DOGGIES_PASSWORD: int = MY_PASSWORD + 1; + +// Fixed-length vectors +const MY_VECTORY_PASSWORD: [int * 5] = [1, 2, 3, 4, 5]; + +// Static strings +const MY_STRINGY_PASSWORD: &static/str = "12345"; + +// Structs +struct Password { + value: int +} + +const MY_STRUCTY_PASSWORD: Password = Password { value: MY_PASSWORD }; +~~~ + +> ***Note:*** Support for compile-time constants and constant +> evaluation is essentially added 'as needed'. You may find that +> things you expect to work do not. + ## Operators Rust's set of operators contains very few surprises. Arithmetic is done with From 4155a60c75fbfe322207e99b7bd541bedf088ada Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Thu, 4 Oct 2012 19:43:10 -0700 Subject: [PATCH 40/80] Fix FIXME that's no longer blocked by #2611 --- src/libcore/vec.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 7c0b4b516bb5..a157071c9557 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -1918,10 +1918,9 @@ impl &[A]: iter::CopyableIter { } pure fn to_vec() -> ~[A] { iter::to_vec(&self) } - // FIXME--bug in resolve prevents this from working (#2611) - // fn flat_map_to_vec>(op: fn(A) -> IB) -> ~[B] { - // iter::flat_map_to_vec(self, op) - // } + pure fn flat_map_to_vec>(op: fn(A) -> IB) -> ~[B] { + iter::flat_map_to_vec(&self, op) + } pub pure fn find(p: fn(a: A) -> bool) -> Option { iter::find(&self, p) From f5dfd9b3ce5dd6fbe567ba07e89c70a4db2c4cd4 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 4 Oct 2012 19:47:09 -0700 Subject: [PATCH 41/80] docs: Tweaks to section on constants --- doc/tutorial.md | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index a7e627fa08e6..3393964b845d 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -487,17 +487,10 @@ const MY_VECTORY_PASSWORD: [int * 5] = [1, 2, 3, 4, 5]; const MY_STRINGY_PASSWORD: &static/str = "12345"; // Structs -struct Password { - value: int -} - +struct Password { value: int } const MY_STRUCTY_PASSWORD: Password = Password { value: MY_PASSWORD }; ~~~ -> ***Note:*** Support for compile-time constants and constant -> evaluation is essentially added 'as needed'. You may find that -> things you expect to work do not. - ## Operators Rust's set of operators contains very few surprises. Arithmetic is done with From 8fc60af441a1375ee73a0efe4524b54ff039e69a Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Thu, 4 Oct 2012 19:58:31 -0700 Subject: [PATCH 42/80] Remove by-copy mode from std, mostly One instance remains in net_tcp due to a foreign fn. Lots of instances remain in serialization.rs, but IIRC that is being removed. I had to do unholy things to task-perf-word-count-generic to get it to compile after demoding pipes. I may well have messed up its performance, but it passes. --- src/libcore/future.rs | 4 +- src/libcore/pipes.rs | 4 +- src/libcore/private.rs | 2 +- src/libcore/task.rs | 38 ++++++++--------- src/libcore/task/spawn.rs | 4 +- src/libstd/arc.rs | 2 +- src/libstd/bitv.rs | 4 +- src/libstd/c_vec.rs | 3 +- src/libstd/cell.rs | 2 +- src/libstd/comm.rs | 4 +- src/libstd/dbg.rs | 2 +- src/libstd/deque.rs | 4 +- src/libstd/ebml.rs | 15 +++---- src/libstd/ebml2.rs | 3 +- src/libstd/fun_treemap.rs | 6 +-- src/libstd/getopts.rs | 7 ++-- src/libstd/json.rs | 4 +- src/libstd/list.rs | 6 +-- src/libstd/map.rs | 15 ++++--- src/libstd/net_tcp.rs | 21 +++++----- src/libstd/net_url.rs | 12 +++--- src/libstd/par.rs | 10 +++-- src/libstd/smallintmap.rs | 6 +-- src/libstd/std.rc | 1 + src/libstd/sync.rs | 2 +- src/libstd/test.rs | 2 +- src/libstd/time.rs | 2 +- src/libstd/timer.rs | 2 +- src/libstd/treemap.rs | 8 ++-- src/libstd/uv_iotask.rs | 7 ++-- src/libstd/uv_ll.rs | 12 +++--- src/libsyntax/ext/pipes/ast_builder.rs | 8 ---- src/libsyntax/ext/pipes/pipec.rs | 14 +++---- src/rustc/driver/rustc.rs | 20 ++++----- .../bench/task-perf-word-count-generic.rs | 41 ++++++++++--------- 35 files changed, 146 insertions(+), 151 deletions(-) diff --git a/src/libcore/future.rs b/src/libcore/future.rs index e07c03cafb68..efd5ff65aa5f 100644 --- a/src/libcore/future.rs +++ b/src/libcore/future.rs @@ -87,7 +87,7 @@ pub fn from_port(port: future_pipe::client::waiting) -> } } -pub fn from_fn(+f: ~fn() -> A) -> Future { +pub fn from_fn(f: ~fn() -> A) -> Future { /*! * Create a future from a function. * @@ -99,7 +99,7 @@ pub fn from_fn(+f: ~fn() -> A) -> Future { Future {state: Pending(move f)} } -pub fn spawn(+blk: fn~() -> A) -> Future { +pub fn spawn(blk: fn~() -> A) -> Future { /*! * Create a future from a unique closure. * diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs index c53f069174c3..791c6bccde8c 100644 --- a/src/libcore/pipes.rs +++ b/src/libcore/pipes.rs @@ -860,7 +860,7 @@ endpoint is passed to the new task. pub fn spawn_service( init: extern fn() -> (SendPacketBuffered, RecvPacketBuffered), - +service: fn~(v: RecvPacketBuffered)) + service: fn~(v: RecvPacketBuffered)) -> SendPacketBuffered { let (client, server) = init(); @@ -884,7 +884,7 @@ receive state. pub fn spawn_service_recv( init: extern fn() -> (RecvPacketBuffered, SendPacketBuffered), - +service: fn~(v: SendPacketBuffered)) + service: fn~(v: SendPacketBuffered)) -> RecvPacketBuffered { let (client, server) = init(); diff --git a/src/libcore/private.rs b/src/libcore/private.rs index 992c8e011f7f..c4ef136a592e 100644 --- a/src/libcore/private.rs +++ b/src/libcore/private.rs @@ -46,7 +46,7 @@ type GlobalPtr = *libc::uintptr_t; pub unsafe fn chan_from_global_ptr( global: GlobalPtr, task_fn: fn() -> task::TaskBuilder, - +f: fn~(comm::Port) + f: fn~(comm::Port) ) -> comm::Chan { enum Msg { diff --git a/src/libcore/task.rs b/src/libcore/task.rs index 06150227e950..8d7791d18d90 100644 --- a/src/libcore/task.rs +++ b/src/libcore/task.rs @@ -220,7 +220,7 @@ pub type TaskOpts = { // FIXME (#2585): Replace the 'consumed' bit with move mode on self pub enum TaskBuilder = { opts: TaskOpts, - gen_body: fn@(+v: fn~()) -> fn~(), + gen_body: fn@(v: fn~()) -> fn~(), can_not_copy: Option, mut consumed: bool, }; @@ -233,7 +233,7 @@ pub enum TaskBuilder = { pub fn task() -> TaskBuilder { TaskBuilder({ opts: default_task_opts(), - gen_body: |+body| move body, // Identity function + gen_body: |body| move body, // Identity function can_not_copy: None, mut consumed: false, }) @@ -410,7 +410,7 @@ impl TaskBuilder { * generator by applying the task body which results from the * existing body generator to the new body generator. */ - fn add_wrapper(wrapper: fn@(+v: fn~()) -> fn~()) -> TaskBuilder { + fn add_wrapper(wrapper: fn@(v: fn~()) -> fn~()) -> TaskBuilder { let prev_gen_body = self.gen_body; let notify_chan = if self.opts.notify_chan.is_none() { None @@ -442,7 +442,7 @@ impl TaskBuilder { * When spawning into a new scheduler, the number of threads requested * must be greater than zero. */ - fn spawn(+f: fn~()) { + fn spawn(f: fn~()) { let notify_chan = if self.opts.notify_chan.is_none() { None } else { @@ -460,7 +460,7 @@ impl TaskBuilder { spawn::spawn_raw(move opts, x.gen_body(move f)); } /// Runs a task, while transfering ownership of one argument to the child. - fn spawn_with(arg: A, +f: fn~(+v: A)) { + fn spawn_with(arg: A, f: fn~(v: A)) { let arg = ~mut Some(move arg); do self.spawn |move arg, move f| { f(option::swap_unwrap(arg)) @@ -478,7 +478,7 @@ impl TaskBuilder { * otherwise be required to establish communication from the parent * to the child. */ - fn spawn_listener(+f: fn~(comm::Port)) -> comm::Chan { + fn spawn_listener(f: fn~(comm::Port)) -> comm::Chan { let setup_po = comm::Port(); let setup_ch = comm::Chan(&setup_po); do self.spawn |move f| { @@ -494,7 +494,7 @@ impl TaskBuilder { * Runs a new task, setting up communication in both directions */ fn spawn_conversation - (+f: fn~(comm::Port, comm::Chan)) + (f: fn~(comm::Port, comm::Chan)) -> (comm::Port, comm::Chan) { let from_child = comm::Port(); let to_parent = comm::Chan(&from_child); @@ -517,7 +517,7 @@ impl TaskBuilder { * # Failure * Fails if a future_result was already set for this task. */ - fn try(+f: fn~() -> T) -> Result { + fn try(f: fn~() -> T) -> Result { let po = comm::Port(); let ch = comm::Chan(&po); let mut result = None; @@ -556,7 +556,7 @@ pub fn default_task_opts() -> TaskOpts { /* Spawn convenience functions */ -pub fn spawn(+f: fn~()) { +pub fn spawn(f: fn~()) { /*! * Creates and executes a new child task * @@ -569,7 +569,7 @@ pub fn spawn(+f: fn~()) { task().spawn(move f) } -pub fn spawn_unlinked(+f: fn~()) { +pub fn spawn_unlinked(f: fn~()) { /*! * Creates a child task unlinked from the current one. If either this * task or the child task fails, the other will not be killed. @@ -578,7 +578,7 @@ pub fn spawn_unlinked(+f: fn~()) { task().unlinked().spawn(move f) } -pub fn spawn_supervised(+f: fn~()) { +pub fn spawn_supervised(f: fn~()) { /*! * Creates a child task unlinked from the current one. If either this * task or the child task fails, the other will not be killed. @@ -587,7 +587,7 @@ pub fn spawn_supervised(+f: fn~()) { task().supervised().spawn(move f) } -pub fn spawn_with(+arg: A, +f: fn~(+v: A)) { +pub fn spawn_with(arg: A, f: fn~(v: A)) { /*! * Runs a task, while transfering ownership of one argument to the * child. @@ -601,7 +601,7 @@ pub fn spawn_with(+arg: A, +f: fn~(+v: A)) { task().spawn_with(move arg, move f) } -pub fn spawn_listener(+f: fn~(comm::Port)) -> comm::Chan { +pub fn spawn_listener(f: fn~(comm::Port)) -> comm::Chan { /*! * Runs a new task while providing a channel from the parent to the child * @@ -612,7 +612,7 @@ pub fn spawn_listener(+f: fn~(comm::Port)) -> comm::Chan { } pub fn spawn_conversation - (+f: fn~(comm::Port, comm::Chan)) + (f: fn~(comm::Port, comm::Chan)) -> (comm::Port, comm::Chan) { /*! * Runs a new task, setting up communication in both directions @@ -623,7 +623,7 @@ pub fn spawn_conversation task().spawn_conversation(move f) } -pub fn spawn_sched(mode: SchedMode, +f: fn~()) { +pub fn spawn_sched(mode: SchedMode, f: fn~()) { /*! * Creates a new scheduler and executes a task on it * @@ -640,7 +640,7 @@ pub fn spawn_sched(mode: SchedMode, +f: fn~()) { task().sched_mode(mode).spawn(move f) } -pub fn try(+f: fn~() -> T) -> Result { +pub fn try(f: fn~() -> T) -> Result { /*! * Execute a function in another task and return either the return value * of the function or result::err. @@ -1127,7 +1127,7 @@ fn test_spawn_sched_blocking() { } #[cfg(test)] -fn avoid_copying_the_body(spawnfn: fn(+v: fn~())) { +fn avoid_copying_the_body(spawnfn: fn(v: fn~())) { let p = comm::Port::(); let ch = comm::Chan(&p); @@ -1150,7 +1150,7 @@ fn test_avoid_copying_the_body_spawn() { #[test] fn test_avoid_copying_the_body_spawn_listener() { - do avoid_copying_the_body |+f| { + do avoid_copying_the_body |f| { spawn_listener(fn~(move f, _po: comm::Port) { f(); }); @@ -1168,7 +1168,7 @@ fn test_avoid_copying_the_body_task_spawn() { #[test] fn test_avoid_copying_the_body_spawn_listener_1() { - do avoid_copying_the_body |+f| { + do avoid_copying_the_body |f| { task().spawn_listener(fn~(move f, _po: comm::Port) { f(); }); diff --git a/src/libcore/task/spawn.rs b/src/libcore/task/spawn.rs index 2db63d20f162..6eaace1fa1a1 100644 --- a/src/libcore/task/spawn.rs +++ b/src/libcore/task/spawn.rs @@ -488,7 +488,7 @@ fn gen_child_taskgroup(linked: bool, supervised: bool) } } -pub fn spawn_raw(opts: TaskOpts, +f: fn~()) { +pub fn spawn_raw(opts: TaskOpts, f: fn~()) { let (child_tg, ancestors, is_main) = gen_child_taskgroup(opts.linked, opts.supervised); @@ -533,7 +533,7 @@ pub fn spawn_raw(opts: TaskOpts, +f: fn~()) { fn make_child_wrapper(child: *rust_task, child_arc: TaskGroupArc, ancestors: AncestorList, is_main: bool, notify_chan: Option>, - +f: fn~()) -> fn~() { + f: fn~()) -> fn~() { let child_data = ~mut Some((move child_arc, move ancestors)); return fn~(move notify_chan, move child_data, move f) { // Agh. Get move-mode items into the closure. FIXME (#2829) diff --git a/src/libstd/arc.rs b/src/libstd/arc.rs index 60db62ce01ae..addabb2ddb9b 100644 --- a/src/libstd/arc.rs +++ b/src/libstd/arc.rs @@ -1,5 +1,5 @@ // NB: transitionary, de-mode-ing. -// tjc: forbid deprecated modes again after snap +#[forbid(deprecated_mode)]; /** * Concurrency-enabled mechanisms for sharing mutable and/or immutable state * between tasks. diff --git a/src/libstd/bitv.rs b/src/libstd/bitv.rs index 77f0d39c338e..91af4a3d6531 100644 --- a/src/libstd/bitv.rs +++ b/src/libstd/bitv.rs @@ -1,4 +1,4 @@ -// tjc: forbid deprecated modes again after snap +#[forbid(deprecated_mode)]; use vec::{to_mut, from_elem}; @@ -553,7 +553,7 @@ pure fn land(w0: uint, w1: uint) -> uint { return w0 & w1; } pure fn right(_w0: uint, w1: uint) -> uint { return w1; } impl Bitv: ops::Index { - pure fn index(+i: uint) -> bool { + pure fn index(i: uint) -> bool { self.get(i) } } diff --git a/src/libstd/c_vec.rs b/src/libstd/c_vec.rs index 1ff5b63ee12f..06d56ed1ae52 100644 --- a/src/libstd/c_vec.rs +++ b/src/libstd/c_vec.rs @@ -25,6 +25,7 @@ * great care must be taken to ensure that a reference to the c_vec::t is * still held if needed. */ +#[forbid(deprecated_mode)]; /** * The type representing a foreign chunk of memory @@ -111,7 +112,7 @@ pub fn get(t: CVec, ofs: uint) -> T { * * Fails if `ofs` is greater or equal to the length of the vector */ -pub fn set(t: CVec, ofs: uint, +v: T) { +pub fn set(t: CVec, ofs: uint, v: T) { assert ofs < len(t); unsafe { *ptr::mut_offset((*t).base, ofs) = v }; } diff --git a/src/libstd/cell.rs b/src/libstd/cell.rs index 866dbce1c085..c888957728a3 100644 --- a/src/libstd/cell.rs +++ b/src/libstd/cell.rs @@ -1,4 +1,4 @@ -// tjc: forbid deprecated modes again after snap +#[forbid(deprecated_mode)]; /// A dynamic, mutable location. /// /// Similar to a mutable option type, but friendlier. diff --git a/src/libstd/comm.rs b/src/libstd/comm.rs index 4d87ebeac99d..1a897a2c2fa9 100644 --- a/src/libstd/comm.rs +++ b/src/libstd/comm.rs @@ -16,11 +16,11 @@ pub struct DuplexStream { } impl DuplexStream : Channel { - fn send(+x: T) { + fn send(x: T) { self.chan.send(move x) } - fn try_send(+x: T) -> bool { + fn try_send(x: T) -> bool { self.chan.try_send(move x) } } diff --git a/src/libstd/dbg.rs b/src/libstd/dbg.rs index f85d4655ad14..f141a028e652 100644 --- a/src/libstd/dbg.rs +++ b/src/libstd/dbg.rs @@ -1,4 +1,4 @@ -// tjc: forbid deprecated modes again after snap +#[forbid(deprecated_mode)]; //! Unsafe debugging functions for inspecting values. use cast::reinterpret_cast; diff --git a/src/libstd/deque.rs b/src/libstd/deque.rs index f4fbc11c4f71..37798d9a6273 100644 --- a/src/libstd/deque.rs +++ b/src/libstd/deque.rs @@ -1,5 +1,5 @@ //! A deque. Untested as of yet. Likely buggy -// tjc: forbid deprecated modes again after snap +#[forbid(deprecated_mode)]; #[forbid(non_camel_case_types)]; use option::{Some, None}; @@ -200,7 +200,7 @@ mod tests { assert (deq.get(3) == d); } - fn test_parameterized(a: T, +b: T, +c: T, +d: T) { + fn test_parameterized(a: T, b: T, c: T, d: T) { let deq: deque::Deque = deque::create::(); assert (deq.size() == 0u); deq.add_front(a); diff --git a/src/libstd/ebml.rs b/src/libstd/ebml.rs index 238e9d77a771..3df5a70a0c1f 100644 --- a/src/libstd/ebml.rs +++ b/src/libstd/ebml.rs @@ -1,3 +1,4 @@ +#[forbid(deprecated_mode)]; // Simple Extensible Binary Markup Language (ebml) reader and writer on a // cursor model. See the specification here: // http://www.matroska.org/technical/specs/rfc/index.html @@ -17,7 +18,7 @@ pub type Doc = {data: @~[u8], start: uint, end: uint}; type TaggedDoc = {tag: uint, doc: Doc}; impl Doc: ops::Index { - pure fn index(+tag: uint) -> Doc { + pure fn index(tag: uint) -> Doc { unsafe { get_doc(self, tag) } @@ -563,11 +564,11 @@ impl EbmlDeserializer: serialization::Deserializer { #[test] fn test_option_int() { - fn serialize_1(&&s: S, v: int) { + fn serialize_1(s: &S, v: int) { s.emit_i64(v as i64); } - fn serialize_0(&&s: S, v: Option) { + fn serialize_0(s: &S, v: Option) { do s.emit_enum(~"core::option::t") { match v { None => s.emit_enum_variant( @@ -581,11 +582,11 @@ fn test_option_int() { } } - fn deserialize_1(&&s: S) -> int { + fn deserialize_1(s: &S) -> int { s.read_i64() as int } - fn deserialize_0(&&s: S) -> Option { + fn deserialize_0(s: &S) -> Option { do s.read_enum(~"core::option::t") { do s.read_enum_variant |i| { match i { @@ -608,11 +609,11 @@ fn test_option_int() { debug!("v == %?", v); let bytes = do io::with_bytes_writer |wr| { let ebml_w = ebml::Writer(wr); - serialize_0(ebml_w, v); + serialize_0(&ebml_w, v); }; let ebml_doc = ebml::Doc(@bytes); let deser = ebml_deserializer(ebml_doc); - let v1 = deserialize_0(deser); + let v1 = deserialize_0(&deser); debug!("v1 == %?", v1); assert v == v1; } diff --git a/src/libstd/ebml2.rs b/src/libstd/ebml2.rs index 30d68da06f56..f88aad1ac633 100644 --- a/src/libstd/ebml2.rs +++ b/src/libstd/ebml2.rs @@ -1,3 +1,4 @@ +#[forbid(deprecated_mode)]; use serialization2; // Simple Extensible Binary Markup Language (ebml) reader and writer on a @@ -31,7 +32,7 @@ struct TaggedDoc { } impl Doc: ops::Index { - pure fn index(+tag: uint) -> Doc { + pure fn index(tag: uint) -> Doc { unsafe { get_doc(self, tag) } diff --git a/src/libstd/fun_treemap.rs b/src/libstd/fun_treemap.rs index 2973c8cc9f78..a1e29b03b455 100644 --- a/src/libstd/fun_treemap.rs +++ b/src/libstd/fun_treemap.rs @@ -1,4 +1,4 @@ -#[warn(deprecated_mode)]; +#[forbid(deprecated_mode)]; /*! * A functional key,value store that works on anything. @@ -26,7 +26,7 @@ enum TreeNode { pub fn init() -> Treemap { @Empty } /// Insert a value into the map -pub fn insert(m: Treemap, +k: K, +v: V) +pub fn insert(m: Treemap, k: K, v: V) -> Treemap { @match m { @Empty => Node(@k, @v, @Empty, @Empty), @@ -41,7 +41,7 @@ pub fn insert(m: Treemap, +k: K, +v: V) } /// Find a value based on the key -pub fn find(m: Treemap, +k: K) -> Option { +pub fn find(m: Treemap, k: K) -> Option { match *m { Empty => None, Node(@ref kk, @copy v, left, right) => { diff --git a/src/libstd/getopts.rs b/src/libstd/getopts.rs index 771eaaeca7fa..6da51571e34a 100644 --- a/src/libstd/getopts.rs +++ b/src/libstd/getopts.rs @@ -61,8 +61,7 @@ * do_work(input, output); * } */ - -// tjc: forbid deprecated modes again after snap +#[forbid(deprecated_mode)]; use core::cmp::Eq; use core::result::{Err, Ok}; @@ -162,7 +161,7 @@ fn name_str(nm: &Name) -> ~str { }; } -fn find_opt(opts: &[Opt], +nm: Name) -> Option { +fn find_opt(opts: &[Opt], nm: Name) -> Option { vec::position(opts, |opt| opt.name == nm) } @@ -214,7 +213,7 @@ pub type Result = result::Result; */ pub fn getopts(args: &[~str], opts: &[Opt]) -> Result unsafe { let n_opts = vec::len::(opts); - fn f(+_x: uint) -> ~[Optval] { return ~[]; } + fn f(_x: uint) -> ~[Optval] { return ~[]; } let vals = vec::to_mut(vec::from_fn(n_opts, f)); let mut free: ~[~str] = ~[]; let l = vec::len(args); diff --git a/src/libstd/json.rs b/src/libstd/json.rs index f244f2869a60..09d002162093 100644 --- a/src/libstd/json.rs +++ b/src/libstd/json.rs @@ -1,6 +1,6 @@ // Rust JSON serialization library // Copyright (c) 2011 Google Inc. -// tjc: forbid deprecated modes again after snap +#[forbid(deprecated_mode)]; #[forbid(non_camel_case_types)]; //! json serialization @@ -399,7 +399,7 @@ priv impl Parser { while char::is_whitespace(self.ch) { self.bump(); } } - fn parse_ident(ident: &str, +value: Json) -> Result { + fn parse_ident(ident: &str, value: Json) -> Result { if str::all(ident, |c| c == self.next_char()) { self.bump(); Ok(move value) diff --git a/src/libstd/list.rs b/src/libstd/list.rs index 4ff493f5ab91..396edb548850 100644 --- a/src/libstd/list.rs +++ b/src/libstd/list.rs @@ -1,5 +1,5 @@ //! A standard linked list -#[warn(deprecated_mode)]; +#[forbid(deprecated_mode)]; use core::cmp::Eq; use core::option; @@ -56,7 +56,7 @@ pub fn find(ls: @List, f: fn((&T)) -> bool) -> Option { } /// Returns true if a list contains an element with the given value -pub fn has(ls: @List, +elt: T) -> bool { +pub fn has(ls: @List, elt: T) -> bool { for each(ls) |e| { if *e == elt { return true; } } @@ -114,7 +114,7 @@ pub pure fn append(l: @List, m: @List) -> @List { /* /// Push one element into the front of a list, returning a new list /// THIS VERSION DOESN'T ACTUALLY WORK -pure fn push(ll: &mut @list, +vv: T) { +pure fn push(ll: &mut @list, vv: T) { ll = &mut @cons(vv, *ll) } */ diff --git a/src/libstd/map.rs b/src/libstd/map.rs index 90476ea101a5..765d40339d3c 100644 --- a/src/libstd/map.rs +++ b/src/libstd/map.rs @@ -1,6 +1,5 @@ //! A map type - -// tjc: forbid deprecated modes again after snap +#[forbid(deprecated_mode)]; use io::WriterUtil; use to_str::ToStr; @@ -28,7 +27,7 @@ pub trait Map { * * Returns true if the key did not already exist in the map */ - fn insert(v: K, +v: V) -> bool; + fn insert(v: K, v: V) -> bool; /// Returns true if the map contains a value for the specified key fn contains_key(key: K) -> bool; @@ -59,7 +58,7 @@ pub trait Map { fn clear(); /// Iterate over all the key/value pairs in the map by value - pure fn each(fn(key: K, +value: V) -> bool); + pure fn each(fn(key: K, value: V) -> bool); /// Iterate over all the keys in the map by value pure fn each_key(fn(key: K) -> bool); @@ -213,7 +212,7 @@ pub mod chained { } } - fn insert(k: K, +v: V) -> bool { + fn insert(k: K, v: V) -> bool { let hash = k.hash_keyed(0,0) as uint; match self.search_tbl(&k, hash) { NotFound => { @@ -294,7 +293,7 @@ pub mod chained { self.chains = chains(initial_capacity); } - pure fn each(blk: fn(key: K, +value: V) -> bool) { + pure fn each(blk: fn(key: K, value: V) -> bool) { self.each_ref(|k, v| blk(*k, *v)) } @@ -348,7 +347,7 @@ pub mod chained { } impl T: ops::Index { - pure fn index(+k: K) -> V { + pure fn index(k: K) -> V { unsafe { self.get(k) } @@ -459,7 +458,7 @@ impl @Mut>: } } - pure fn each(op: fn(key: K, +value: V) -> bool) { + pure fn each(op: fn(key: K, value: V) -> bool) { unsafe { do self.borrow_imm |p| { p.each(|k, v| op(*k, *v)) diff --git a/src/libstd/net_tcp.rs b/src/libstd/net_tcp.rs index 8c95410d4e83..1027acfb569c 100644 --- a/src/libstd/net_tcp.rs +++ b/src/libstd/net_tcp.rs @@ -1,4 +1,5 @@ //! High-level interface to libuv's TCP functionality +#[warn(deprecated_mode)]; use ip = net_ip; use uv::iotask; @@ -324,7 +325,7 @@ pub fn read_start(sock: &TcpSocket) * * `sock` - a `net::tcp::tcp_socket` that you wish to stop reading on */ pub fn read_stop(sock: &TcpSocket, - +read_port: comm::Port>) -> + read_port: comm::Port>) -> result::Result<(), TcpErrData> unsafe { log(debug, fmt!("taking the read_port out of commission %?", read_port)); let socket_data = ptr::addr_of(&(*sock.socket_data)); @@ -558,8 +559,8 @@ pub fn accept(new_conn: TcpNewConnection) */ pub fn listen(host_ip: ip::IpAddr, port: uint, backlog: uint, iotask: IoTask, - +on_establish_cb: fn~(comm::Chan>), - +new_connect_cb: fn~(TcpNewConnection, + on_establish_cb: fn~(comm::Chan>), + new_connect_cb: fn~(TcpNewConnection, comm::Chan>)) -> result::Result<(), TcpListenErrData> unsafe { do listen_common(move host_ip, port, backlog, iotask, on_establish_cb) @@ -575,8 +576,8 @@ pub fn listen(host_ip: ip::IpAddr, port: uint, backlog: uint, fn listen_common(host_ip: ip::IpAddr, port: uint, backlog: uint, iotask: IoTask, - +on_establish_cb: fn~(comm::Chan>), - +on_connect_cb: fn~(*uv::ll::uv_tcp_t)) + on_establish_cb: fn~(comm::Chan>), + on_connect_cb: fn~(*uv::ll::uv_tcp_t)) -> result::Result<(), TcpListenErrData> unsafe { let stream_closed_po = core::comm::Port::<()>(); let kill_po = core::comm::Port::>(); @@ -749,7 +750,7 @@ impl TcpSocket { /// Implementation of `io::reader` trait for a buffered `net::tcp::tcp_socket` impl TcpSocketBuf: io::Reader { - fn read(buf: &[mut u8], +len: uint) -> uint { + fn read(buf: &[mut u8], len: uint) -> uint { // Loop until our buffer has enough data in it for us to read from. while self.data.buf.len() < len { let read_result = read(&self.data.sock, 0u); @@ -785,13 +786,13 @@ impl TcpSocketBuf: io::Reader { let mut bytes = ~[0]; if self.read(bytes, 1u) == 0 { fail } else { bytes[0] as int } } - fn unread_byte(+amt: int) { + fn unread_byte(amt: int) { self.data.buf.unshift(amt as u8); } fn eof() -> bool { false // noop } - fn seek(+dist: int, +seek: io::SeekStyle) { + fn seek(dist: int, seek: io::SeekStyle) { log(debug, fmt!("tcp_socket_buf seek stub %? %?", dist, seek)); // noop } @@ -813,7 +814,7 @@ impl TcpSocketBuf: io::Writer { err_data.err_name, err_data.err_msg)); } } - fn seek(+dist: int, +seek: io::SeekStyle) { + fn seek(dist: int, seek: io::SeekStyle) { log(debug, fmt!("tcp_socket_buf seek stub %? %?", dist, seek)); // noop } @@ -1474,7 +1475,7 @@ mod test { str::from_bytes(new_bytes) } - fn run_tcp_test_server(server_ip: &str, server_port: uint, +resp: ~str, + fn run_tcp_test_server(server_ip: &str, server_port: uint, resp: ~str, server_ch: comm::Chan<~str>, cont_ch: comm::Chan<()>, iotask: IoTask) -> ~str { diff --git a/src/libstd/net_url.rs b/src/libstd/net_url.rs index 40c9f96f5e84..0ab4d89f3635 100644 --- a/src/libstd/net_url.rs +++ b/src/libstd/net_url.rs @@ -1,5 +1,5 @@ //! Types/fns concerning URLs (see RFC 3986) -// tjc: forbid deprecated modes again after a snapshot +#[forbid(deprecated_mode)]; use core::cmp::Eq; use map::HashMap; @@ -27,15 +27,15 @@ type UserInfo = { pub type Query = ~[(~str, ~str)]; -pub fn Url(scheme: ~str, +user: Option, +host: ~str, - +port: Option<~str>, +path: ~str, +query: Query, - +fragment: Option<~str>) -> Url { +pub fn Url(scheme: ~str, user: Option, host: ~str, + port: Option<~str>, path: ~str, query: Query, + fragment: Option<~str>) -> Url { Url { scheme: move scheme, user: move user, host: move host, port: move port, path: move path, query: move query, fragment: move fragment } } -fn UserInfo(user: ~str, +pass: Option<~str>) -> UserInfo { +fn UserInfo(user: ~str, pass: Option<~str>) -> UserInfo { {user: move user, pass: move pass} } @@ -726,7 +726,7 @@ impl Url : Eq { } impl Url: IterBytes { - pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { unsafe { self.to_str() }.iter_bytes(lsb0, f) } } diff --git a/src/libstd/par.rs b/src/libstd/par.rs index 65e41dba5d83..e5336b7204d2 100644 --- a/src/libstd/par.rs +++ b/src/libstd/par.rs @@ -1,3 +1,5 @@ +#[forbid(deprecated_mode)]; + use future_spawn = future::spawn; @@ -72,7 +74,7 @@ fn map_slices( } /// A parallel version of map. -pub fn map(xs: &[A], +f: fn~((&A)) -> B) -> ~[B] { +pub fn map(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)) @@ -82,7 +84,7 @@ pub fn map(xs: &[A], +f: fn~((&A)) -> B) -> ~[B] { /// 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| { @@ -119,7 +121,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| { @@ -130,7 +132,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/smallintmap.rs b/src/libstd/smallintmap.rs index 58ecbb0d6c3a..1582d90ce2d6 100644 --- a/src/libstd/smallintmap.rs +++ b/src/libstd/smallintmap.rs @@ -2,7 +2,7 @@ * A simple map based on a vector for small integer keys. Space requirements * are O(highest integer key). */ -// tjc: forbid deprecated modes again after snap +#[forbid(deprecated_mode)]; use core::option; use core::option::{Some, None}; @@ -103,7 +103,7 @@ impl SmallIntMap: map::Map { pure fn find(key: uint) -> Option { find(self, key) } fn rehash() { fail } - pure fn each(it: fn(key: uint, +value: V) -> bool) { + pure fn each(it: fn(key: uint, value: V) -> bool) { self.each_ref(|k, v| it(*k, *v)) } pure fn each_key(it: fn(key: uint) -> bool) { @@ -131,7 +131,7 @@ impl SmallIntMap: map::Map { } impl SmallIntMap: ops::Index { - pure fn index(+key: uint) -> V { + pure fn index(key: uint) -> V { unsafe { get(self, key) } diff --git a/src/libstd/std.rc b/src/libstd/std.rc index 7622f1b8de6b..cc076772e6eb 100644 --- a/src/libstd/std.rc +++ b/src/libstd/std.rc @@ -20,6 +20,7 @@ not required in or otherwise suitable for the core library. #[allow(vecs_implicitly_copyable)]; #[deny(non_camel_case_types)]; +#[warn(deprecated_mode)]; #[forbid(deprecated_pattern)]; extern mod core(vers = "0.4"); diff --git a/src/libstd/sync.rs b/src/libstd/sync.rs index 88869773e5de..908f3936f4e1 100644 --- a/src/libstd/sync.rs +++ b/src/libstd/sync.rs @@ -1,5 +1,5 @@ // NB: transitionary, de-mode-ing. -// tjc: forbid deprecated modes again after snap +#[forbid(deprecated_mode)]; /** * The concurrency primitives you know and love. * diff --git a/src/libstd/test.rs b/src/libstd/test.rs index 2eac3729c229..162a5ecc5fcf 100644 --- a/src/libstd/test.rs +++ b/src/libstd/test.rs @@ -5,7 +5,7 @@ // simplest interface possible for representing and running tests // while providing a base that other test frameworks may build off of. -#[warn(deprecated_mode)]; +#[forbid(deprecated_mode)]; use core::cmp::Eq; use either::Either; diff --git a/src/libstd/time.rs b/src/libstd/time.rs index aef3bb2ac0ad..627a3b8eeae0 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -1,4 +1,4 @@ -// tjc: forbid deprecated modes again after snap +#[forbid(deprecated_mode)]; use core::cmp::Eq; use libc::{c_char, c_int, c_long, size_t, time_t}; diff --git a/src/libstd/timer.rs b/src/libstd/timer.rs index 821015edd1a9..c9c28c4e1f08 100644 --- a/src/libstd/timer.rs +++ b/src/libstd/timer.rs @@ -1,6 +1,6 @@ //! Utilities that leverage libuv's `uv_timer_*` API -// tjc: forbid deprecated modes again after snap +#[forbid(deprecated_mode)]; use uv = uv; use uv::iotask; diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs index 184dfd362796..8ab0dc7f2e7d 100644 --- a/src/libstd/treemap.rs +++ b/src/libstd/treemap.rs @@ -5,7 +5,7 @@ * very naive algorithm, but it will probably be updated to be a * red-black tree or something else. */ -#[warn(deprecated_mode)]; +#[forbid(deprecated_mode)]; use core::cmp::{Eq, Ord}; use core::option::{Some, None}; @@ -26,7 +26,7 @@ enum TreeNode = { pub fn TreeMap() -> TreeMap { @mut None } /// Insert a value into the map -pub fn insert(m: &mut TreeEdge, +k: K, +v: V) { +pub fn insert(m: &mut TreeEdge, k: K, v: V) { match copy *m { None => { *m = Some(@TreeNode({key: k, @@ -48,7 +48,7 @@ pub fn insert(m: &mut TreeEdge, +k: K, +v: V) { } /// Find a value based on the key -pub fn find(m: &const TreeEdge, +k: K) +pub fn find(m: &const TreeEdge, k: K) -> Option { match copy *m { None => None, @@ -121,7 +121,7 @@ mod tests { insert(m, 1, ()); let n = @mut 0; - fn t(n: @mut int, +k: int, +_v: ()) { + fn t(n: @mut int, k: int, _v: ()) { assert (*n == k); *n += 1; } traverse(m, |x,y| t(n, *x, *y)); diff --git a/src/libstd/uv_iotask.rs b/src/libstd/uv_iotask.rs index 2e31e15a70d7..ad40d96e4f77 100644 --- a/src/libstd/uv_iotask.rs +++ b/src/libstd/uv_iotask.rs @@ -4,8 +4,7 @@ * The I/O task runs in its own single-threaded scheduler. By using the * `interact` function you can execute code in a uv callback. */ - -// tjc: forbid deprecated modes again after a snapshot +#[forbid(deprecated_mode)]; use libc::c_void; use ptr::addr_of; @@ -60,7 +59,7 @@ pub fn spawn_iotask(task: task::TaskBuilder) -> IoTask { * via ports/chans. */ pub unsafe fn interact(iotask: IoTask, - +cb: fn~(*c_void)) { + cb: fn~(*c_void)) { send_msg(iotask, Interaction(move cb)); } @@ -125,7 +124,7 @@ type IoTaskLoopData = { }; fn send_msg(iotask: IoTask, - +msg: IoTaskMsg) unsafe { + msg: IoTaskMsg) unsafe { iotask.op_chan.send(move msg); ll::async_send(iotask.async_handle); } diff --git a/src/libstd/uv_ll.rs b/src/libstd/uv_ll.rs index f8c3882d15eb..8b428d8d6d8a 100644 --- a/src/libstd/uv_ll.rs +++ b/src/libstd/uv_ll.rs @@ -19,7 +19,7 @@ * This module's implementation will hopefully be, eventually, replaced * with per-platform, generated source files from rust-bindgen. */ - +#[warn(deprecated_mode)]; #[allow(non_camel_case_types)]; // C types use libc::size_t; @@ -642,7 +642,7 @@ extern mod rustrt { fn rust_uv_addrinfo_as_sockaddr_in(input: *addrinfo) -> *sockaddr_in; fn rust_uv_addrinfo_as_sockaddr_in6(input: *addrinfo) -> *sockaddr_in6; fn rust_uv_malloc_buf_base_of(sug_size: libc::size_t) -> *u8; - fn rust_uv_free_base_of_buf(++buf: uv_buf_t); + fn rust_uv_free_base_of_buf(+buf: uv_buf_t); fn rust_uv_get_stream_handle_from_connect_req( connect_req: *uv_connect_t) -> *uv_stream_t; @@ -661,8 +661,8 @@ extern mod rustrt { fn rust_uv_get_data_for_req(req: *libc::c_void) -> *libc::c_void; fn rust_uv_set_data_for_req(req: *libc::c_void, data: *libc::c_void); - fn rust_uv_get_base_from_buf(++buf: uv_buf_t) -> *u8; - fn rust_uv_get_len_from_buf(++buf: uv_buf_t) -> libc::size_t; + fn rust_uv_get_base_from_buf(+buf: uv_buf_t) -> *u8; + fn rust_uv_get_len_from_buf(+buf: uv_buf_t) -> libc::size_t; // sizeof testing helpers fn rust_uv_helper_uv_tcp_t_size() -> libc::c_uint; @@ -1357,8 +1357,8 @@ pub mod test { fn impl_uv_tcp_server(server_ip: &str, server_port: int, - +kill_server_msg: ~str, - +server_resp_msg: ~str, + kill_server_msg: ~str, + server_resp_msg: ~str, server_chan: *comm::Chan<~str>, continue_chan: *comm::Chan) unsafe { let test_loop = loop_new(); diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs index bfe0f4dd0e64..4da9992b0dd3 100644 --- a/src/libsyntax/ext/pipes/ast_builder.rs +++ b/src/libsyntax/ext/pipes/ast_builder.rs @@ -48,7 +48,6 @@ trait ext_ctxt_ast_builder { fn ty_param(id: ast::ident, +bounds: ~[ast::ty_param_bound]) -> ast::ty_param; fn arg(name: ident, ty: @ast::ty) -> ast::arg; - fn arg_mode(name: ident, ty: @ast::ty, mode: ast::rmode) -> ast::arg; fn expr_block(e: @ast::expr) -> ast::blk; fn fn_decl(+inputs: ~[ast::arg], output: @ast::ty) -> ast::fn_decl; fn item(name: ident, span: span, +node: ast::item_) -> @ast::item; @@ -177,13 +176,6 @@ impl ext_ctxt: ext_ctxt_ast_builder { id: self.next_id()} } - fn arg_mode(name: ident, ty: @ast::ty, mode: ast::rmode) -> ast::arg { - {mode: ast::expl(mode), - ty: ty, - ident: name, - id: self.next_id()} - } - fn block(+stmts: ~[@ast::stmt], e: @ast::expr) -> ast::blk { let blk = {view_items: ~[], stmts: stmts, diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs index 9c10d228a23f..874ea01e9b01 100644 --- a/src/libsyntax/ext/pipes/pipec.rs +++ b/src/libsyntax/ext/pipes/pipec.rs @@ -47,16 +47,15 @@ impl message: gen_send { let arg_names = tys.mapi(|i, _ty| cx.ident_of(~"x_"+i.to_str())); let args_ast = (arg_names, tys).map( - |n, t| cx.arg_mode(*n, *t, ast::by_copy) + |n, t| cx.arg(*n, *t) ); let pipe_ty = cx.ty_path_ast_builder( path(~[this.data_name()], span) .add_tys(cx.ty_vars(this.ty_params))); let args_ast = vec::append( - ~[cx.arg_mode(cx.ident_of(~"pipe"), - pipe_ty, - ast::by_copy)], + ~[cx.arg(cx.ident_of(~"pipe"), + pipe_ty)], args_ast); let mut body = ~"{\n"; @@ -129,15 +128,14 @@ impl message: gen_send { let arg_names = tys.mapi(|i, _ty| (~"x_" + i.to_str())); let args_ast = (arg_names, tys).map( - |n, t| cx.arg_mode(cx.ident_of(*n), *t, ast::by_copy) + |n, t| cx.arg(cx.ident_of(*n), *t) ); let args_ast = vec::append( - ~[cx.arg_mode(cx.ident_of(~"pipe"), + ~[cx.arg(cx.ident_of(~"pipe"), cx.ty_path_ast_builder( path(~[this.data_name()], span) - .add_tys(cx.ty_vars(this.ty_params))), - ast::by_copy)], + .add_tys(cx.ty_vars(this.ty_params))))], args_ast); let message_args = if arg_names.len() == 0 { diff --git a/src/rustc/driver/rustc.rs b/src/rustc/driver/rustc.rs index c2bca3fc6bec..c60904419d5f 100644 --- a/src/rustc/driver/rustc.rs +++ b/src/rustc/driver/rustc.rs @@ -22,15 +22,15 @@ use syntax::diagnostic; use rustc::driver::session; use rustc::middle::lint; -fn version(argv0: ~str) { +fn version(argv0: &str) { let mut vers = ~"unknown version"; let env_vers = env!("CFG_VERSION"); - if str::len(env_vers) != 0u { vers = env_vers; } + if env_vers.len() != 0 { vers = env_vers; } io::println(fmt!("%s %s", argv0, vers)); io::println(fmt!("host: %s", host_triple())); } -fn usage(argv0: ~str) { +fn usage(argv0: &str) { io::println(fmt!("Usage: %s [options] \n", argv0) + ~" Options: @@ -86,7 +86,7 @@ fn describe_warnings() { let lint_dict = lint::get_lint_dict(); let mut max_key = 0; for lint_dict.each_key |k| { max_key = uint::max(k.len(), max_key); } - fn padded(max: uint, s: ~str) -> ~str { + fn padded(max: uint, s: &str) -> ~str { str::from_bytes(vec::from_elem(max - s.len(), ' ' as u8)) + s } io::println(fmt!("\nAvailable lint checks:\n")); @@ -117,14 +117,14 @@ fn describe_debug_flags() { } } -fn run_compiler(args: ~[~str], demitter: diagnostic::emitter) { +fn run_compiler(args: &~[~str], demitter: diagnostic::emitter) { // Don't display log spew by default. Can override with RUST_LOG. logging::console_off(); - let mut args = args; + let mut args = *args; let binary = args.shift(); - if vec::len(args) == 0u { usage(binary); return; } + if args.is_empty() { usage(binary); return; } let matches = match getopts::getopts(args, opts()) { @@ -278,9 +278,9 @@ fn monitor(+f: fn~(diagnostic::emitter)) { } fn main() { - let args = os::args(); - do monitor |demitter| { - run_compiler(args, demitter); + let mut args = os::args(); + do monitor |move args, demitter| { + run_compiler(&args, demitter); } } diff --git a/src/test/bench/task-perf-word-count-generic.rs b/src/test/bench/task-perf-word-count-generic.rs index 168e4b8b1f14..97b031c6024a 100644 --- a/src/test/bench/task-perf-word-count-generic.rs +++ b/src/test/bench/task-perf-word-count-generic.rs @@ -10,8 +10,6 @@ // xfail-pretty -#[legacy_modes]; - extern mod std; use option = option; @@ -70,18 +68,18 @@ fn map(f: fn~() -> word_reader, emit: map_reduce::putter<~str, int>) { let f = f(); loop { match f.read_word() { - Some(w) => { emit(w, 1); } + Some(w) => { emit(&w, 1); } None => { break; } } } } -fn reduce(&&word: ~str, get: map_reduce::getter) { +fn reduce(word: &~str, get: map_reduce::getter) { let mut count = 0; loop { match get() { Some(_) => { count += 1; } None => { break; } } } - io::println(fmt!("%s\t%?", word, count)); + io::println(fmt!("%s\t%?", *word, count)); } struct box { @@ -116,13 +114,13 @@ mod map_reduce { export reducer; export map_reduce; - type putter = fn(K, V); + type putter = fn(&K, V); type mapper = fn~(K1, putter); type getter = fn() -> Option; - type reducer = fn~(K, getter); + type reducer = fn~(&K, getter); enum ctrl_proto { find_reducer(K, Chan>>), @@ -145,9 +143,9 @@ mod map_reduce { fn start_mappers( - map: mapper, + map: &mapper, &ctrls: ~[ctrl_proto::server::open], - inputs: ~[K1]) + inputs: &~[K1]) -> ~[joinable_task] { let mut tasks = ~[]; @@ -155,7 +153,8 @@ mod map_reduce { let (ctrl, ctrl_server) = ctrl_proto::init(); let ctrl = box(ctrl); let i = copy *i; - tasks.push(spawn_joinable(|move i| map_task(map, ctrl, i))); + let m = copy *map; + tasks.push(spawn_joinable(|move i| map_task(m, &ctrl, i))); ctrls.push(ctrl_server); } return tasks; @@ -163,20 +162,22 @@ mod map_reduce { fn map_task( map: mapper, - ctrl: box>, + ctrl: &box>, input: K1) { // log(error, "map_task " + input); - let intermediates = map::HashMap(); + let intermediates: HashMap>> + = map::HashMap(); - do map(input) |key, val| { + do map(input) |key: &K2, val| { let mut c = None; - let found = intermediates.find(key); + let found: Option>> + = intermediates.find(*key); match found { Some(_c) => { c = Some(_c); } None => { do ctrl.swap |ctrl| { - let ctrl = ctrl_proto::client::find_reducer(ctrl, key); + let ctrl = ctrl_proto::client::find_reducer(ctrl, *key); match pipes::recv(ctrl) { ctrl_proto::reducer(c_, ctrl) => { c = Some(c_); @@ -184,7 +185,7 @@ mod map_reduce { } } } - intermediates.insert(key, c.get()); + intermediates.insert(*key, c.get()); send(c.get(), addref); } } @@ -200,7 +201,7 @@ mod map_reduce { } fn reduce_task( - reduce: reducer, + reduce: ~reducer, key: K, out: Chan>>) { @@ -231,7 +232,7 @@ mod map_reduce { return None; } - reduce(key, || get(p, ref_count, is_done) ); + (*reduce)(&key, || get(p, ref_count, is_done) ); } fn map_reduce( @@ -245,7 +246,7 @@ mod map_reduce { // to do the rest. let reducers = map::HashMap(); - let mut tasks = start_mappers(map, ctrl, inputs); + let mut tasks = start_mappers(&map, ctrl, &inputs); let mut num_mappers = vec::len(inputs) as int; while num_mappers > 0 { @@ -270,7 +271,7 @@ mod map_reduce { let p = Port(); let ch = Chan(&p); let r = reduce, kk = k; - tasks.push(spawn_joinable(|| reduce_task(r, kk, ch) )); + tasks.push(spawn_joinable(|| reduce_task(~r, kk, ch) )); c = recv(p); reducers.insert(k, c); } From 09df3ed8f1abdbeaf6b6ae9c08c9446341965918 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 4 Oct 2012 20:03:40 -0700 Subject: [PATCH 43/80] docs: Explain a little bit about dtors --- doc/tutorial.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/doc/tutorial.md b/doc/tutorial.md index 3393964b845d..dd16e88329f5 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -734,6 +734,7 @@ omitted from the type, such an assignment would result in a type error. Structs can be destructured in `match` patterns. The basic syntax is `Name {fieldname: pattern, ...}`: + ~~~~ # struct Point { x: float, y: float } # let mypoint = Point { x: 0.0, y: 0.0 }; @@ -747,6 +748,35 @@ In general, the field names of a struct do not have to appear in the same order they appear in the type. When you are not interested in all the fields of a struct, a struct pattern may end with `, _` (as in `Name {field1, _}`) to indicate that you're ignoring all other fields. +Additionally, struct fields have a shorthand matching form that simply +reuses the field name as the binding name. + +~~~ +# struct Point { x: float, y: float } +# let mypoint = Point { x: 0.0, y: 0.0 }; +match mypoint { + Point { x, _ } => { io::println(x.to_str()) } +} +~~~ + +Structs are the only type in Rust that may have user-defined destructors, +using `drop` blocks, inside of which the struct's value may be referred +to with the name `self`. + +~~~ +struct TimeBomb { + explosivity: uint, + + drop { + for iter::repeat(explosivity) { + io::println(fmt!("blam!")); + } + } +} +~~~ + +> ***Note***: This destructor syntax is temporary. Eventually destructors +> will be defined for any type using [traits](#traits). ## Enums From 8b56287d607a7445a33099f852969099d1cfd790 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 4 Oct 2012 20:13:50 -0700 Subject: [PATCH 44/80] docs: Fix example --- doc/tutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index dd16e88329f5..952fcd30f4c3 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -768,7 +768,7 @@ struct TimeBomb { explosivity: uint, drop { - for iter::repeat(explosivity) { + for iter::repeat(self.explosivity) { io::println(fmt!("blam!")); } } From 2f6f0b55fc438764e4e11fb90ecf41ac3a739a67 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 5 Oct 2012 01:59:37 -0600 Subject: [PATCH 45/80] core: Correct description of cast::forget 'managed' means something different now --- src/libcore/cast.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/cast.rs b/src/libcore/cast.rs index dce95aa2215f..030f05c6eeae 100644 --- a/src/libcore/cast.rs +++ b/src/libcore/cast.rs @@ -19,7 +19,7 @@ pub unsafe fn reinterpret_cast(src: &T) -> U { * The forget function will take ownership of the provided value but neglect * to run any required cleanup or memory-management operations on it. This * can be used for various acts of magick, particularly when using - * reinterpret_cast on managed pointer types. + * reinterpret_cast on pointer types. */ #[inline(always)] pub unsafe fn forget(thing: T) { rusti::forget(move thing); } From 8574766033d3b5e3925e3807d13f9dcc639e5d1b Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 5 Oct 2012 04:18:11 -0600 Subject: [PATCH 46/80] Update src/README.txt --- src/README.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/README.txt b/src/README.txt index 2086765b6f9e..5e0d9bd0e841 100644 --- a/src/README.txt +++ b/src/README.txt @@ -1,4 +1,4 @@ -This is preliminary version of the Rust compiler, libraries and tools +This is a preliminary version of the Rust compiler, libraries and tools Source layout: From ba75a3e14c8ffe85c0ac0a81a31affff1d678834 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 5 Oct 2012 11:32:00 -0700 Subject: [PATCH 47/80] std: Revert demoding of uv_ll. It can't be done without FFI changes --- src/libstd/uv_ll.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libstd/uv_ll.rs b/src/libstd/uv_ll.rs index 8b428d8d6d8a..f8c3882d15eb 100644 --- a/src/libstd/uv_ll.rs +++ b/src/libstd/uv_ll.rs @@ -19,7 +19,7 @@ * This module's implementation will hopefully be, eventually, replaced * with per-platform, generated source files from rust-bindgen. */ -#[warn(deprecated_mode)]; + #[allow(non_camel_case_types)]; // C types use libc::size_t; @@ -642,7 +642,7 @@ extern mod rustrt { fn rust_uv_addrinfo_as_sockaddr_in(input: *addrinfo) -> *sockaddr_in; fn rust_uv_addrinfo_as_sockaddr_in6(input: *addrinfo) -> *sockaddr_in6; fn rust_uv_malloc_buf_base_of(sug_size: libc::size_t) -> *u8; - fn rust_uv_free_base_of_buf(+buf: uv_buf_t); + fn rust_uv_free_base_of_buf(++buf: uv_buf_t); fn rust_uv_get_stream_handle_from_connect_req( connect_req: *uv_connect_t) -> *uv_stream_t; @@ -661,8 +661,8 @@ extern mod rustrt { fn rust_uv_get_data_for_req(req: *libc::c_void) -> *libc::c_void; fn rust_uv_set_data_for_req(req: *libc::c_void, data: *libc::c_void); - fn rust_uv_get_base_from_buf(+buf: uv_buf_t) -> *u8; - fn rust_uv_get_len_from_buf(+buf: uv_buf_t) -> libc::size_t; + fn rust_uv_get_base_from_buf(++buf: uv_buf_t) -> *u8; + fn rust_uv_get_len_from_buf(++buf: uv_buf_t) -> libc::size_t; // sizeof testing helpers fn rust_uv_helper_uv_tcp_t_size() -> libc::c_uint; @@ -1357,8 +1357,8 @@ pub mod test { fn impl_uv_tcp_server(server_ip: &str, server_port: int, - kill_server_msg: ~str, - server_resp_msg: ~str, + +kill_server_msg: ~str, + +server_resp_msg: ~str, server_chan: *comm::Chan<~str>, continue_chan: *comm::Chan) unsafe { let test_loop = loop_new(); From f8179b6d4d6c290db57d3cdc8c340655ba5f5619 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 4 Oct 2012 20:51:41 -0700 Subject: [PATCH 48/80] Hack around llvm 14013 --- src/llvm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm b/src/llvm index c51053bf71de..dc4cdbf05228 160000 --- a/src/llvm +++ b/src/llvm @@ -1 +1 @@ -Subproject commit c51053bf71de475df6a91204acd9ad78f4747c38 +Subproject commit dc4cdbf052288794ac418f310e7f5cfa609f5902 From 2d903abeab00cea395980535a200c523630771c7 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Fri, 5 Oct 2012 07:16:56 -0700 Subject: [PATCH 49/80] configure should recursively sync submodules --- configure | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/configure b/configure index 58fc25eea9e4..60de25809c28 100755 --- a/configure +++ b/configure @@ -583,6 +583,10 @@ then "${CFG_GIT}" submodule --quiet update --init --recursive need_ok "git failed" + msg "git: submodule foreach sync" + "${CFG_GIT}" submodule --quiet foreach --recursive git submodule sync + need_ok "git failed" + msg "git: submodule clobber" "${CFG_GIT}" submodule --quiet foreach --recursive git clean -dxf need_ok "git failed" From c56a7e5c25c2a411ba119f3a17bfa6db0b1722ed Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 5 Oct 2012 11:04:45 -0700 Subject: [PATCH 50/80] Reorder the submodule ops in configure --- configure | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/configure b/configure index 60de25809c28..e67ea3af5f38 100755 --- a/configure +++ b/configure @@ -574,19 +574,23 @@ then msg "git: submodule sync" "${CFG_GIT}" submodule --quiet sync - # NB: this is just for the sake of getting the submodule SHA1 values - # and status written into the build log. - msg "git: submodule status" - "${CFG_GIT}" submodule status --recursive - msg "git: submodule update" - "${CFG_GIT}" submodule --quiet update --init --recursive + "${CFG_GIT}" submodule --quiet update --init need_ok "git failed" msg "git: submodule foreach sync" "${CFG_GIT}" submodule --quiet foreach --recursive git submodule sync need_ok "git failed" + msg "git: submodule foreach update" + "${CFG_GIT}" submodule --quiet update --init --recursive + need_ok "git failed" + + # NB: this is just for the sake of getting the submodule SHA1 values + # and status written into the build log. + msg "git: submodule status" + "${CFG_GIT}" submodule status --recursive + msg "git: submodule clobber" "${CFG_GIT}" submodule --quiet foreach --recursive git clean -dxf need_ok "git failed" From 1b732145ec569cd67e2a5d0cc4dd37d5cd60c961 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 5 Oct 2012 11:50:53 -0700 Subject: [PATCH 51/80] rustc: Implement simple trait inheritance. Generic trait inheritance, cross-crate trait inheritance, and vtable-based trait inheritance don't work yet. --- src/rustc/middle/resolve.rs | 6 +- src/rustc/middle/typeck/check/vtable.rs | 102 +++++++++++++----- src/rustc/middle/typeck/coherence.rs | 37 ++++++- src/test/run-pass/trait-inheritance-simple.rs | 26 +++++ 4 files changed, 136 insertions(+), 35 deletions(-) create mode 100644 src/test/run-pass/trait-inheritance-simple.rs diff --git a/src/rustc/middle/resolve.rs b/src/rustc/middle/resolve.rs index eca0687f2fda..5f30346a28e8 100644 --- a/src/rustc/middle/resolve.rs +++ b/src/rustc/middle/resolve.rs @@ -4181,9 +4181,9 @@ impl Resolver { } return self.resolve_identifier(path.idents.last(), - namespace, - check_ribs, - path.span); + namespace, + check_ribs, + path.span); } fn resolve_identifier(identifier: ident, diff --git a/src/rustc/middle/typeck/check/vtable.rs b/src/rustc/middle/typeck/check/vtable.rs index e8595b2f50a1..e8926468b3a8 100644 --- a/src/rustc/middle/typeck/check/vtable.rs +++ b/src/rustc/middle/typeck/check/vtable.rs @@ -51,8 +51,8 @@ fn lookup_vtables(fcx: @fn_ctxt, match *bound { ty::bound_trait(i_ty) => { let i_ty = ty::subst(tcx, substs, i_ty); - match lookup_vtable(fcx, expr, *ty, i_ty, allow_unsafe, - is_early) { + match lookup_vtable_covariant(fcx, expr, *ty, i_ty, + allow_unsafe, is_early) { Some(vtable) => result.push(vtable), None => { fcx.tcx().sess.span_fatal( @@ -91,20 +91,67 @@ fn relate_trait_tys(fcx: @fn_ctxt, expr: @ast::expr, demand::suptype(fcx, expr.span, exp_trait_ty, act_trait_ty) } -/* -Look up the vtable to use when treating an item of type -as if it has type -*/ -fn lookup_vtable(fcx: @fn_ctxt, - expr: @ast::expr, - ty: ty::t, - trait_ty: ty::t, - allow_unsafe: bool, - is_early: bool) - -> Option -{ +// Look up the vtable to use when treating an item of type `t` as if it has +// type `trait_ty`. This does allow subtraits. +fn lookup_vtable_covariant(fcx: @fn_ctxt, + expr: @ast::expr, + ty: ty::t, + trait_ty: ty::t, + allow_unsafe: bool, + is_early: bool) + -> Option { + let worklist = dvec::DVec(); + worklist.push(trait_ty); + while worklist.len() > 0 { + let trait_ty = worklist.pop(); + let result = lookup_vtable_invariant(fcx, expr, ty, trait_ty, + allow_unsafe, is_early); + if result.is_some() { + return result; + } - debug!("lookup_vtable(ty=%s, trait_ty=%s)", + // Add subtraits to the worklist, if applicable. + match ty::get(trait_ty).sty { + ty::ty_trait(trait_id, _, _) => { + let table = fcx.ccx.coherence_info.supertrait_to_subtraits; + match table.find(trait_id) { + None => {} + Some(subtraits) => { + for subtraits.each |subtrait_id| { + // XXX: This is wrong; subtraits should themselves + // have substs. + let substs = + { self_r: None, self_ty: None, tps: ~[] }; + let trait_ty = ty::mk_trait(fcx.ccx.tcx, + *subtrait_id, + substs, + ty::vstore_box); + worklist.push(trait_ty); + } + } + } + } + _ => { + fcx.ccx.tcx.sess.impossible_case(expr.span, + "lookup_vtable_covariant: \ + non-trait in worklist"); + } + } + } + + return None; +} + +// Look up the vtable to use when treating an item of type `t` as if it has +// type `trait_ty`. This does not allow subtraits. +fn lookup_vtable_invariant(fcx: @fn_ctxt, + expr: @ast::expr, + ty: ty::t, + trait_ty: ty::t, + allow_unsafe: bool, + is_early: bool) + -> Option { + debug!("lookup_vtable_invariant(ty=%s, trait_ty=%s)", fcx.infcx().ty_to_str(ty), fcx.inh.infcx.ty_to_str(trait_ty)); let _i = indenter(); @@ -112,7 +159,7 @@ fn lookup_vtable(fcx: @fn_ctxt, let (trait_id, trait_substs) = match ty::get(trait_ty).sty { ty::ty_trait(did, substs, _) => (did, substs), _ => tcx.sess.impossible_case(expr.span, - "lookup_vtable: \ + "lookup_vtable_invariant: \ don't know how to handle a non-trait") }; let ty = match fixup_ty(fcx, expr, ty, is_early) { @@ -150,7 +197,7 @@ fn lookup_vtable(fcx: @fn_ctxt, } _ => tcx.sess.impossible_case( expr.span, - "lookup_vtable: in loop, \ + "lookup_vtable_invariant: in loop, \ don't know how to handle a non-trait ity") } n_bound += 1u; @@ -462,13 +509,14 @@ fn early_resolve_expr(ex: @ast::expr, &&fcx: @fn_ctxt, is_early: bool) { let target_ty = fcx.expr_ty(ex); match ty::get(target_ty).sty { ty::ty_trait(*) => { - /* - Look up vtables for the type we're casting to, - passing in the source and target type - */ + // Look up vtables for the type we're casting to, passing in the + // source and target type. + // + // XXX: This is invariant and shouldn't be. --pcw + let ty = fcx.expr_ty(src); - let vtable_opt = lookup_vtable(fcx, ex, ty, target_ty, true, - is_early); + let vtable_opt = lookup_vtable_invariant(fcx, ex, ty, target_ty, + true, is_early); match vtable_opt { None => { // Try the new-style boxed trait; "@int as @Trait". @@ -476,10 +524,10 @@ fn early_resolve_expr(ex: @ast::expr, &&fcx: @fn_ctxt, is_early: bool) { let ty = structurally_resolved_type(fcx, ex.span, ty); match ty::get(ty).sty { ty::ty_box(boxed_ty) => { - let vtable_opt = lookup_vtable(fcx, ex, - boxed_ty.ty, - target_ty, true, - is_early); + let vtable_opt = + lookup_vtable_invariant(fcx, ex, boxed_ty.ty, + target_ty, true, + is_early); match vtable_opt { Some(vtable) => { /* diff --git a/src/rustc/middle/typeck/coherence.rs b/src/rustc/middle/typeck/coherence.rs index e9238e30c663..89cd696eb6fb 100644 --- a/src/rustc/middle/typeck/coherence.rs +++ b/src/rustc/middle/typeck/coherence.rs @@ -126,12 +126,16 @@ struct CoherenceInfo { // Contains implementations of methods associated with a trait. For these, // the associated trait must be imported at the call site. extension_methods: HashMap>, + + // A mapping from a supertrait to its subtraits. + supertrait_to_subtraits: HashMap> } fn CoherenceInfo() -> CoherenceInfo { CoherenceInfo { inherent_methods: HashMap(), - extension_methods: HashMap() + extension_methods: HashMap(), + supertrait_to_subtraits: HashMap() } } @@ -161,7 +165,6 @@ struct CoherenceChecker { } impl CoherenceChecker { - // Create a mapping containing a MethodInfo for every provided // method in every trait. fn build_provided_methods_map(crate: @crate) { @@ -225,9 +228,9 @@ impl CoherenceChecker { } fn check_coherence(crate: @crate) { - - // Check implementations. This populates the tables containing the - // inherent methods and extension methods. + // Check implementations and traits. This populates the tables + // containing the inherent methods and extension methods. It also + // builds up the trait inheritance table. visit_crate(*crate, (), mk_simple_visitor(@{ visit_item: |item| { debug!("(checking coherence) item '%s'", @@ -240,6 +243,9 @@ impl CoherenceChecker { item_class(struct_def, _) => { self.check_implementation(item, struct_def.traits); } + item_trait(_, supertraits, _) => { + self.register_inherited_trait(item, supertraits); + } _ => { // Nothing to do. } @@ -324,6 +330,27 @@ impl CoherenceChecker { } } + fn register_inherited_trait(item: @item, supertraits: ~[@trait_ref]) { + // XXX: This is wrong. We need to support substitutions; e.g. + // trait Foo : Bar. + let supertrait_to_subtraits = + self.crate_context.coherence_info.supertrait_to_subtraits; + let subtrait_id = local_def(item.id); + for supertraits.each |supertrait| { + let supertrait_id = self.trait_ref_to_trait_def_id(*supertrait); + match supertrait_to_subtraits.find(supertrait_id) { + None => { + let new_vec = @dvec::DVec(); + new_vec.push(subtrait_id); + supertrait_to_subtraits.insert(supertrait_id, new_vec); + } + Some(existing_vec) => { + existing_vec.push(subtrait_id); + } + } + } + } + fn add_inherent_method(base_def_id: def_id, implementation: @Impl) { let implementation_list; match self.crate_context.coherence_info.inherent_methods diff --git a/src/test/run-pass/trait-inheritance-simple.rs b/src/test/run-pass/trait-inheritance-simple.rs new file mode 100644 index 000000000000..fcd4cf1de6b3 --- /dev/null +++ b/src/test/run-pass/trait-inheritance-simple.rs @@ -0,0 +1,26 @@ +trait Foo { + fn f(); +} + +trait Bar : Foo { + fn g(); +} + +struct A { + x: int +} + +impl A : Bar { + fn g() { io::println("in g"); } + fn f() { io::println("in f"); } +} + +fn h(a: &T) { + a.f(); +} + +fn main() { + let a = A { x: 3 }; + h(&a); +} + From e46e97fc9a6bb6485e87659ea968fac8c4d05a9f Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 5 Oct 2012 11:53:09 -0700 Subject: [PATCH 52/80] Silence most of the remaining warnings --- src/libcore/stackwalk.rs | 4 ++-- src/libstd/net_tcp.rs | 3 ++- src/libstd/serialization.rs | 2 ++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/libcore/stackwalk.rs b/src/libcore/stackwalk.rs index 09973148c8c8..a88a44701ce8 100644 --- a/src/libcore/stackwalk.rs +++ b/src/libcore/stackwalk.rs @@ -3,8 +3,8 @@ #[legacy_modes]; // tjc: remove after snapshot // NB: transitionary, de-mode-ing. -// XXX: Can't do this because frame_address needs a deprecated mode. -//#[forbid(deprecated_mode)]; +// XXX: Can't forbid this because frame_address needs a deprecated mode. +#[allow(deprecated_mode)]; #[forbid(deprecated_pattern)]; use cast::reinterpret_cast; diff --git a/src/libstd/net_tcp.rs b/src/libstd/net_tcp.rs index 1027acfb569c..249551fbb7df 100644 --- a/src/libstd/net_tcp.rs +++ b/src/libstd/net_tcp.rs @@ -1,5 +1,6 @@ //! High-level interface to libuv's TCP functionality -#[warn(deprecated_mode)]; +// XXX Need FFI fixes +#[allow(deprecated_mode)]; use ip = net_ip; use uv::iotask; diff --git a/src/libstd/serialization.rs b/src/libstd/serialization.rs index 269027a80e51..8ba00e65dec9 100644 --- a/src/libstd/serialization.rs +++ b/src/libstd/serialization.rs @@ -1,5 +1,7 @@ //! Support code for serialization. +#[allow(deprecated_mode)]; + /* Core serialization interfaces. */ From 016875b1b18b8d96a9e48ade55ce6d3ae7fd3680 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 5 Oct 2012 11:59:51 -0700 Subject: [PATCH 53/80] std: Silence remaining warnings --- src/libstd/std.rc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libstd/std.rc b/src/libstd/std.rc index cc076772e6eb..7fc3004bbcfa 100644 --- a/src/libstd/std.rc +++ b/src/libstd/std.rc @@ -20,7 +20,9 @@ not required in or otherwise suitable for the core library. #[allow(vecs_implicitly_copyable)]; #[deny(non_camel_case_types)]; -#[warn(deprecated_mode)]; +// XXX this is set to allow because there are two methods in serialization +// that can't be silenced otherwise. Most every module is set to forbid +#[allow(deprecated_mode)]; #[forbid(deprecated_pattern)]; extern mod core(vers = "0.4"); From cc51b6b57649986c209e5316234471cb7839d2e6 Mon Sep 17 00:00:00 2001 From: Yasuhiro Fujii Date: Fri, 5 Oct 2012 19:55:42 +0900 Subject: [PATCH 54/80] fix escape --- doc/prep.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/prep.js b/doc/prep.js index 1cd5bec81b2b..3a1e60ec4231 100755 --- a/doc/prep.js +++ b/doc/prep.js @@ -60,9 +60,10 @@ while ((line = lines[cur++]) != null) { var html = '
', curstr = "", curstyle = null;
       function add(str, style) {
         if (style != curstyle) {
-          if (curstyle) html += '' + curstr
-            + "";
-          else if (curstr) html += curstr;
+          if (curstyle) html +=
+            '' +
+            CodeMirror.htmlEscape(curstr) + "";
+          else if (curstr) html += CodeMirror.htmlEscape(curstr);
           curstr = str; curstyle = style;
         } else curstr += str;
       }

From e3cb70fa8a6f9163352f26ae2614ab4c9a261838 Mon Sep 17 00:00:00 2001
From: Brian Anderson 
Date: Fri, 5 Oct 2012 12:42:41 -0700
Subject: [PATCH 55/80] Add Yasuhiro Fujii to AUTHORS.txt

---
 AUTHORS.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/AUTHORS.txt b/AUTHORS.txt
index 8cac3a4df97c..4a0bd86b5441 100644
--- a/AUTHORS.txt
+++ b/AUTHORS.txt
@@ -106,4 +106,5 @@ Tomoki Aonuma 
 Tycho Sci 
 Vincent Belliard 
 Wade Mealing 
+Yasuhiro Fujii 
 Zack Corr 

From e16dbb7888504ef5d0de0c14493fc8ecc492ee30 Mon Sep 17 00:00:00 2001
From: Tim Chevalier 
Date: Fri, 5 Oct 2012 14:58:42 -0700
Subject: [PATCH 56/80] Demode some code using by-mutbl-ref; warn about
 by-mutbl-ref

The parser now warns about use of mutbl-ref mode, though it's kind
of a lie since this commit doesn't remove support for the mode.

Changed move_val_init to have stage0 and stage1/2 versions, the latter of
which is demoded.

Changed the type that the typechecker expects the move_val_init
intrinsic to have. After this is pushed, I can make a new snapshot,
which will remove the need for the stage0 versions.
---
 src/libcore/at_vec.rs                         |  18 +++
 src/libcore/vec.rs                            |  49 +++++++-
 src/libstd/arena.rs                           | 115 ++++++++++++++++++
 src/libsyntax/parse/parser.rs                 |   1 +
 src/rustc/middle/typeck/check.rs              |   4 +-
 src/test/compile-fail/borrowck-lend-args.rs   |   4 +-
 .../compile-fail/deprecated-mode-fn-arg.rs    |   2 +
 src/test/compile-fail/issue-511.rs            |   6 +-
 src/test/compile-fail/liveness-dead.rs        |   4 +-
 .../compile-fail/liveness-move-from-args.rs   |   4 -
 src/test/compile-fail/liveness-unused.rs      |   2 +-
 src/test/compile-fail/mutable-arguments.rs    |  12 +-
 src/test/run-pass/intrinsic-move-val.rs       |   6 +-
 13 files changed, 204 insertions(+), 23 deletions(-)

diff --git a/src/libcore/at_vec.rs b/src/libcore/at_vec.rs
index 5e1111c20d34..8c023a7cb4c0 100644
--- a/src/libcore/at_vec.rs
+++ b/src/libcore/at_vec.rs
@@ -21,7 +21,11 @@ extern mod rustrt {
 #[abi = "rust-intrinsic"]
 extern mod rusti {
     #[legacy_exports];
+    #[cfg(stage0)]
     fn move_val_init(&dst: T, -src: T);
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    fn move_val_init(dst: &mut T, -src: T);
 }
 
 /// Returns the number of elements the vector can hold without reallocating
@@ -176,7 +180,9 @@ pub mod raw {
             push_slow(v, move initval);
         }
     }
+
     // This doesn't bother to make sure we have space.
+    #[cfg(stage0)]
     #[inline(always)] // really pretty please
     pub unsafe fn push_fast(v: &mut @[const T], initval: T) {
         let repr: **VecRepr = ::cast::reinterpret_cast(&v);
@@ -186,6 +192,18 @@ pub mod raw {
         let p = ptr::offset(p, fill) as *mut T;
         rusti::move_val_init(*p, move initval);
     }
+    // This doesn't bother to make sure we have space.
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[inline(always)] // really pretty please
+    pub unsafe fn push_fast(v: &mut @[const T], initval: T) {
+        let repr: **VecRepr = ::cast::reinterpret_cast(&v);
+        let fill = (**repr).unboxed.fill;
+        (**repr).unboxed.fill += sys::size_of::();
+        let p = addr_of(&((**repr).unboxed.data));
+        let p = ptr::offset(p, fill) as *mut T;
+        rusti::move_val_init(&mut(*p), move initval);
+    }
 
     pub unsafe fn push_slow(v: &mut @[const T], initval: T) {
         reserve_at_least(v, v.len() + 1u);
diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs
index a157071c9557..ce1193aa730e 100644
--- a/src/libcore/vec.rs
+++ b/src/libcore/vec.rs
@@ -18,9 +18,14 @@ extern mod rustrt {
 
 #[abi = "rust-intrinsic"]
 extern mod rusti {
+    #[cfg(stage0)]
     fn move_val_init(&dst: T, -src: T);
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    fn move_val_init(dst: &mut T, -src: T);
 }
 
+
 /// Returns true if a vector contains no elements
 pub pure fn is_empty(v: &[const T]) -> bool {
     as_const_buf(v, |_p, len| len == 0u)
@@ -98,6 +103,7 @@ pub pure fn len(v: &[const T]) -> uint {
  * Creates an immutable vector of size `n_elts` and initializes the elements
  * to the value returned by the function `op`.
  */
+#[cfg(stage0)]
 pub pure fn from_fn(n_elts: uint, op: iter::InitOp) -> ~[T] {
     unsafe {
         let mut v = with_capacity(n_elts);
@@ -112,6 +118,22 @@ pub pure fn from_fn(n_elts: uint, op: iter::InitOp) -> ~[T] {
         return move v;
     }
 }
+#[cfg(stage1)]
+#[cfg(stage2)]
+pub pure fn from_fn(n_elts: uint, op: iter::InitOp) -> ~[T] {
+    unsafe {
+        let mut v = with_capacity(n_elts);
+        do as_mut_buf(v) |p, _len| {
+            let mut i: uint = 0u;
+            while i < n_elts {
+                rusti::move_val_init(&mut(*ptr::mut_offset(p, i)), op(i));
+                i += 1u;
+            }
+        }
+        raw::set_len(&mut v, n_elts);
+        return move v;
+    }
+}
 
 /**
  * Creates and initializes an immutable vector.
@@ -481,6 +503,7 @@ pub fn push(v: &mut ~[T], initval: T) {
     }
 }
 
+#[cfg(stage0)]
 // This doesn't bother to make sure we have space.
 #[inline(always)] // really pretty please
 unsafe fn push_fast(v: &mut ~[T], initval: T) {
@@ -491,6 +514,18 @@ unsafe fn push_fast(v: &mut ~[T], initval: T) {
     let p = ptr::offset(p, fill) as *mut T;
     rusti::move_val_init(*p, move initval);
 }
+#[cfg(stage1)]
+#[cfg(stage2)]
+// This doesn't bother to make sure we have space.
+#[inline(always)] // really pretty please
+unsafe fn push_fast(v: &mut ~[T], initval: T) {
+    let repr: **raw::VecRepr = ::cast::transmute(v);
+    let fill = (**repr).unboxed.fill;
+    (**repr).unboxed.fill += sys::size_of::();
+    let p = addr_of(&((**repr).unboxed.data));
+    let p = ptr::offset(p, fill) as *mut T;
+    rusti::move_val_init(&mut(*p), move initval);
+}
 
 #[inline(never)]
 fn push_slow(v: &mut ~[T], initval: T) {
@@ -1758,6 +1793,18 @@ pub mod raw {
         as_const_buf(v, |p, _len| *ptr::const_offset(p, i))
     }
 
+    #[cfg(stage0)]
+    #[inline(always)]
+    pub unsafe fn init_elem(v: &[mut T], i: uint, val: T) {
+        let mut box = Some(move val);
+        do as_mut_buf(v) |p, _len| {
+            let mut box2 = None;
+            box2 <-> box;
+            rusti::move_val_init(*ptr::mut_offset(p, i),
+                                 option::unwrap(move box2));
+        }
+    }
+    #[cfg(stage1)]
     /**
      * Unchecked vector index assignment.  Does not drop the
      * old value and hence is only suitable when the vector
@@ -1769,7 +1816,7 @@ pub mod raw {
         do as_mut_buf(v) |p, _len| {
             let mut box2 = None;
             box2 <-> box;
-            rusti::move_val_init(*ptr::mut_offset(p, i),
+            rusti::move_val_init(&mut(*ptr::mut_offset(p, i)),
                                  option::unwrap(move box2));
         }
     }
diff --git a/src/libstd/arena.rs b/src/libstd/arena.rs
index 4d2b910fa851..69478b3e731f 100644
--- a/src/libstd/arena.rs
+++ b/src/libstd/arena.rs
@@ -31,9 +31,14 @@ use libc::size_t;
 
 #[abi = "rust-intrinsic"]
 extern mod rusti {
+    #[cfg(stage0)]
     fn move_val_init(&dst: T, -src: T);
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    fn move_val_init(dst: &mut T, -src: T);
     fn needs_drop() -> bool;
 }
+
 extern mod rustrt {
     #[rust_stack]
     fn rust_call_tydesc_glue(root: *u8, tydesc: *TypeDesc, field: size_t);
@@ -127,6 +132,8 @@ unsafe fn un_bitpack_tydesc_ptr(p: uint) -> (*TypeDesc, bool) {
     (reinterpret_cast(&(p & !1)), p & 1 == 1)
 }
 
+// tjc: Can get rid of the duplication post-snapshot
+#[cfg(stage0)]
 // The duplication between the POD and non-POD functions is annoying.
 impl &Arena {
     // Functions for the POD part of the arena
@@ -234,6 +241,114 @@ impl &Arena {
         } else { self.alloc_nonpod(op) }
     }
 }
+#[cfg(stage1)]
+#[cfg(stage2)]
+impl &Arena {
+    // Functions for the POD part of the arena
+    fn alloc_pod_grow(n_bytes: uint, align: uint) -> *u8 {
+        // Allocate a new chunk.
+        let chunk_size = at_vec::capacity(self.pod_head.data);
+        let new_min_chunk_size = uint::max(n_bytes, chunk_size);
+        self.chunks = @Cons(copy self.pod_head, self.chunks);
+        self.pod_head =
+            chunk(uint::next_power_of_two(new_min_chunk_size + 1u), true);
+
+        return self.alloc_pod_inner(n_bytes, align);
+    }
+
+    #[inline(always)]
+    fn alloc_pod_inner(n_bytes: uint, align: uint) -> *u8 {
+        let head = &mut self.pod_head;
+
+        let start = round_up_to(head.fill, align);
+        let end = start + n_bytes;
+        if end > at_vec::capacity(head.data) {
+            return self.alloc_pod_grow(n_bytes, align);
+        }
+        head.fill = end;
+
+        //debug!("idx = %u, size = %u, align = %u, fill = %u",
+        //       start, n_bytes, align, head.fill);
+
+        unsafe {
+            ptr::offset(vec::raw::to_ptr(head.data), start)
+        }
+    }
+
+    #[inline(always)]
+    fn alloc_pod(op: fn() -> T) -> &self/T {
+        unsafe {
+            let tydesc = sys::get_type_desc::();
+            let ptr = self.alloc_pod_inner((*tydesc).size, (*tydesc).align);
+            let ptr: *mut T = reinterpret_cast(&ptr);
+            rusti::move_val_init(&mut (*ptr), op());
+            return reinterpret_cast(&ptr);
+        }
+    }
+
+    // Functions for the non-POD part of the arena
+    fn alloc_nonpod_grow(n_bytes: uint, align: uint) -> (*u8, *u8) {
+        // Allocate a new chunk.
+        let chunk_size = at_vec::capacity(self.head.data);
+        let new_min_chunk_size = uint::max(n_bytes, chunk_size);
+        self.chunks = @Cons(copy self.head, self.chunks);
+        self.head =
+            chunk(uint::next_power_of_two(new_min_chunk_size + 1u), false);
+
+        return self.alloc_nonpod_inner(n_bytes, align);
+    }
+
+    #[inline(always)]
+    fn alloc_nonpod_inner(n_bytes: uint, align: uint) -> (*u8, *u8) {
+        let head = &mut self.head;
+
+        let tydesc_start = head.fill;
+        let after_tydesc = head.fill + sys::size_of::<*TypeDesc>();
+        let start = round_up_to(after_tydesc, align);
+        let end = start + n_bytes;
+        if end > at_vec::capacity(head.data) {
+            return self.alloc_nonpod_grow(n_bytes, align);
+        }
+        head.fill = round_up_to(end, sys::pref_align_of::<*TypeDesc>());
+
+        //debug!("idx = %u, size = %u, align = %u, fill = %u",
+        //       start, n_bytes, align, head.fill);
+
+        unsafe {
+            let buf = vec::raw::to_ptr(head.data);
+            return (ptr::offset(buf, tydesc_start), ptr::offset(buf, start));
+        }
+    }
+
+    #[inline(always)]
+    fn alloc_nonpod(op: fn() -> T) -> &self/T {
+        unsafe {
+            let tydesc = sys::get_type_desc::();
+            let (ty_ptr, ptr) =
+                self.alloc_nonpod_inner((*tydesc).size, (*tydesc).align);
+            let ty_ptr: *mut uint = reinterpret_cast(&ty_ptr);
+            let ptr: *mut T = reinterpret_cast(&ptr);
+            // Write in our tydesc along with a bit indicating that it
+            // has *not* been initialized yet.
+            *ty_ptr = reinterpret_cast(&tydesc);
+            // Actually initialize it
+            rusti::move_val_init(&mut(*ptr), op());
+            // Now that we are done, update the tydesc to indicate that
+            // the object is there.
+            *ty_ptr = bitpack_tydesc_ptr(tydesc, true);
+
+            return reinterpret_cast(&ptr);
+        }
+    }
+
+    // The external interface
+    #[inline(always)]
+    fn alloc(op: fn() -> T) -> &self/T {
+        if !rusti::needs_drop::() {
+            self.alloc_pod(op)
+        } else { self.alloc_nonpod(op) }
+    }
+}
 
 #[test]
 fn test_arena_destructors() {
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 8860d1b5cea8..1a87d7fed695 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -570,6 +570,7 @@ impl parser {
 
     fn parse_arg_mode() -> mode {
         if self.eat(token::BINOP(token::AND)) {
+            self.warn(~"Obsolete syntax has no effect");
             expl(by_mutbl_ref)
         } else if self.eat(token::BINOP(token::MINUS)) {
             expl(by_move)
diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs
index 368b69cafaba..7cc2c8b0ad76 100644
--- a/src/rustc/middle/typeck/check.rs
+++ b/src/rustc/middle/typeck/check.rs
@@ -2601,7 +2601,9 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::foreign_item) {
       ~"addr_of" => (1u, ~[arg(ast::by_ref, param(ccx, 0u))],
                       ty::mk_imm_ptr(tcx, param(ccx, 0u))),
       ~"move_val" | ~"move_val_init" => {
-        (1u, ~[arg(ast::by_mutbl_ref, param(ccx, 0u)),
+          (1u, ~[arg(ast::by_copy,
+                     ty::mk_mut_rptr(tcx, ty::re_bound(ty::br_anon(0)),
+                                     param(ccx, 0u))),
                arg(ast::by_move, param(ccx, 0u))],
          ty::mk_nil(tcx))
       }
diff --git a/src/test/compile-fail/borrowck-lend-args.rs b/src/test/compile-fail/borrowck-lend-args.rs
index 3cb7009ee270..79f52b93612a 100644
--- a/src/test/compile-fail/borrowck-lend-args.rs
+++ b/src/test/compile-fail/borrowck-lend-args.rs
@@ -4,8 +4,8 @@ fn borrow_from_arg_imm_ref(&&v: ~int) {
     borrow(v);
 }
 
-fn borrow_from_arg_mut_ref(&v: ~int) {
-    borrow(v); //~ ERROR illegal borrow unless pure
+fn borrow_from_arg_mut_ref(v: &mut ~int) {
+    borrow(*v); //~ ERROR illegal borrow unless pure
     //~^ NOTE impure due to access to impure function
 }
 
diff --git a/src/test/compile-fail/deprecated-mode-fn-arg.rs b/src/test/compile-fail/deprecated-mode-fn-arg.rs
index 5afffb59dfc3..2c20e604f502 100644
--- a/src/test/compile-fail/deprecated-mode-fn-arg.rs
+++ b/src/test/compile-fail/deprecated-mode-fn-arg.rs
@@ -1,9 +1,11 @@
 #[forbid(deprecated_mode)];
 
 fn foo(_f: fn(&i: int)) { //~ ERROR explicit mode
+    //~^ WARNING Obsolete syntax has no effect
 }
 
 type Bar = fn(&i: int); //~ ERROR explicit mode
+    //~^ WARNING Obsolete syntax has no effect
 
 fn main() {
 }
\ No newline at end of file
diff --git a/src/test/compile-fail/issue-511.rs b/src/test/compile-fail/issue-511.rs
index a3498dd19686..02a3082dc10d 100644
--- a/src/test/compile-fail/issue-511.rs
+++ b/src/test/compile-fail/issue-511.rs
@@ -1,11 +1,11 @@
 extern mod std;
 use cmp::Eq;
 
-fn f(&o: Option) {
-    assert o == option::None;
+fn f(o: &mut Option) {
+    assert *o == option::None;
 }
 
 fn main() {
-    f::(option::None);
+    f::(&mut option::None);
     //~^ ERROR illegal borrow: creating mutable alias to static item
 }
diff --git a/src/test/compile-fail/liveness-dead.rs b/src/test/compile-fail/liveness-dead.rs
index a115d7c4e340..834457940bec 100644
--- a/src/test/compile-fail/liveness-dead.rs
+++ b/src/test/compile-fail/liveness-dead.rs
@@ -1,5 +1,5 @@
-fn f1(&x: int) {
-    x = 1; // no error
+fn f1(x: &mut int) {
+    *x = 1; // no error
 }
 
 fn f2() {
diff --git a/src/test/compile-fail/liveness-move-from-args.rs b/src/test/compile-fail/liveness-move-from-args.rs
index 27e7e51b4054..27e9d3b60dc9 100644
--- a/src/test/compile-fail/liveness-move-from-args.rs
+++ b/src/test/compile-fail/liveness-move-from-args.rs
@@ -4,10 +4,6 @@ fn from_by_value_arg(++x: int) {
     take(x);  //~ ERROR illegal move from argument `x`, which is not copy or move mode
 }
 
-fn from_by_mut_ref_arg(&x: int) {
-    take(x);  //~ ERROR illegal move from argument `x`, which is not copy or move mode
-}
-
 fn from_by_ref_arg(&&x: int) {
     take(x);  //~ ERROR illegal move from argument `x`, which is not copy or move mode
 }
diff --git a/src/test/compile-fail/liveness-unused.rs b/src/test/compile-fail/liveness-unused.rs
index 7db02897112d..8b2fef7cd350 100644
--- a/src/test/compile-fail/liveness-unused.rs
+++ b/src/test/compile-fail/liveness-unused.rs
@@ -2,7 +2,7 @@ fn f1(x: int) {
     //~^ WARNING unused variable: `x`
 }
 
-fn f1b(&x: int) {
+fn f1b(x: &mut int) {
     //~^ WARNING unused variable: `x`
 }
 
diff --git a/src/test/compile-fail/mutable-arguments.rs b/src/test/compile-fail/mutable-arguments.rs
index 4fcb73e8516c..d84c9401e257 100644
--- a/src/test/compile-fail/mutable-arguments.rs
+++ b/src/test/compile-fail/mutable-arguments.rs
@@ -1,28 +1,28 @@
 // Note: it would be nice to give fewer warnings in these cases.
 
-fn mutate_by_mut_ref(&x: uint) {
-    x = 0u;
+fn mutate_by_mut_ref(x: &mut uint) {
+    *x = 0;
 }
 
 fn mutate_by_ref(&&x: uint) {
     //~^ WARNING unused variable: `x`
-    x = 0u; //~ ERROR assigning to argument
+    x = 0; //~ ERROR assigning to argument
 }
 
 fn mutate_by_val(++x: uint) {
     //~^ WARNING unused variable: `x`
-    x = 0u; //~ ERROR assigning to argument
+    x = 0; //~ ERROR assigning to argument
 }
 
 fn mutate_by_copy(+x: uint) {
     //~^ WARNING unused variable: `x`
-    x = 0u; //~ ERROR assigning to argument
+    x = 0; //~ ERROR assigning to argument
     //~^ WARNING value assigned to `x` is never read
 }
 
 fn mutate_by_move(-x: uint) {
     //~^ WARNING unused variable: `x`
-    x = 0u; //~ ERROR assigning to argument
+    x = 0; //~ ERROR assigning to argument
     //~^ WARNING value assigned to `x` is never read
 }
 
diff --git a/src/test/run-pass/intrinsic-move-val.rs b/src/test/run-pass/intrinsic-move-val.rs
index b7f2115f45da..683321aac3d0 100644
--- a/src/test/run-pass/intrinsic-move-val.rs
+++ b/src/test/run-pass/intrinsic-move-val.rs
@@ -1,13 +1,13 @@
 #[abi = "rust-intrinsic"]
 extern mod rusti {
     #[legacy_exports];
-    fn move_val_init(&dst: T, -src: T);
-    fn move_val(&dst: T, -src: T);
+    fn move_val_init(dst: &mut T, -src: T);
+    fn move_val(dst: &mut T, -src: T);
 }
 
 fn main() {
     let mut x = @1;
     let mut y = @2;
-    rusti::move_val(y, x);
+    rusti::move_val(&mut y, x);
     assert *y == 1;
 }
\ No newline at end of file

From ca49fd402af8e7bf613c43e996274b5a017958d2 Mon Sep 17 00:00:00 2001
From: Tim Chevalier 
Date: Fri, 5 Oct 2012 14:27:56 -0700
Subject: [PATCH 57/80] wip

---
 src/libcore/cmath.rs                      | 16 ++++++------
 src/libstd/time.rs                        | 30 ++++++++++++++++++++++-
 src/libsyntax/ast.rs                      |  2 +-
 src/libsyntax/parse/comments.rs           | 28 ++++++++++-----------
 src/libsyntax/parse/eval.rs               | 10 ++++----
 src/libsyntax/parse/parser.rs             | 10 +++++---
 src/libsyntax/parse/token.rs              |  2 +-
 src/libsyntax/print/pprust.rs             |  1 -
 src/rustc/metadata/encoder.rs             |  2 +-
 src/rustc/metadata/tydecode.rs            |  1 -
 src/rustc/metadata/tyencode.rs            |  1 -
 src/rustc/middle/borrowck.rs              |  6 ++---
 src/rustc/middle/borrowck/check_loans.rs  | 11 ++++-----
 src/rustc/middle/borrowck/gather_loans.rs |  4 ---
 src/rustc/middle/kind.rs                  | 18 ++++----------
 src/rustc/middle/liveness.rs              | 29 ++++++----------------
 src/rustc/middle/mem_categorization.rs    |  3 ---
 src/rustc/middle/trans/base.rs            |  2 +-
 src/rustc/middle/trans/callee.rs          |  2 +-
 src/rustc/middle/trans/reflect.rs         |  1 -
 src/rustc/middle/trans/shape.rs           |  8 +++---
 src/rustc/middle/trans/type_use.rs        |  2 +-
 src/rustc/middle/trans/uniq.rs            |  1 -
 23 files changed, 93 insertions(+), 97 deletions(-)

diff --git a/src/libcore/cmath.rs b/src/libcore/cmath.rs
index 9a9a7cb31121..b0aeb78afaa8 100644
--- a/src/libcore/cmath.rs
+++ b/src/libcore/cmath.rs
@@ -40,15 +40,15 @@ pub extern mod c_double {
     #[link_name="fmax"] pure fn fmax(a: c_double, b: c_double) -> c_double;
     #[link_name="fmin"] pure fn fmin(a: c_double, b: c_double) -> c_double;
     pure fn nextafter(x: c_double, y: c_double) -> c_double;
-    pure fn frexp(n: c_double, &value: c_int) -> c_double;
+    pure fn frexp(n: c_double, value: &mut c_int) -> c_double;
     pure fn hypot(x: c_double, y: c_double) -> c_double;
     pure fn ldexp(x: c_double, n: c_int) -> c_double;
     #[cfg(unix)]
     #[link_name="lgamma_r"] pure fn lgamma(n: c_double,
-                                           &sign: c_int) -> c_double;
+                                           sign: &mut c_int) -> c_double;
     #[cfg(windows)]
     #[link_name="__lgamma_r"] pure fn lgamma(n: c_double,
-                                             &sign: c_int) -> c_double;
+                                             sign: &mut c_int) -> c_double;
     // renamed: log is a reserved keyword; ln seems more natural, too
     #[link_name="log"] pure fn ln(n: c_double) -> c_double;
     // renamed: "logb" /often/ is confused for log2 by beginners
@@ -58,7 +58,7 @@ pub extern mod c_double {
     pure fn log10(n: c_double) -> c_double;
     pure fn log2(n: c_double) -> c_double;
     #[link_name="ilogb"] pure fn ilog_radix(n: c_double) -> c_int;
-    pure fn modf(n: c_double, &iptr: c_double) -> c_double;
+    pure fn modf(n: c_double, iptr: &mut c_double) -> c_double;
     pure fn pow(n: c_double, e: c_double) -> c_double;
 // FIXME (#1379): enable when rounding modes become available
 //    pure fn rint(n: c_double) -> c_double;
@@ -110,7 +110,7 @@ pub extern mod c_float {
     #[link_name="fdimf"] pure fn abs_sub(a: c_float, b: c_float) -> c_float;
     #[link_name="floorf"] pure fn floor(n: c_float) -> c_float;
     #[link_name="frexpf"] pure fn frexp(n: c_float,
-                                        &value: c_int) -> c_float;
+                                        value: &mut c_int) -> c_float;
     #[link_name="fmaf"] pure fn mul_add(a: c_float,
                                         b: c_float, c: c_float) -> c_float;
     #[link_name="fmaxf"] pure fn fmax(a: c_float, b: c_float) -> c_float;
@@ -122,11 +122,11 @@ pub extern mod c_float {
 
     #[cfg(unix)]
     #[link_name="lgammaf_r"] pure fn lgamma(n: c_float,
-                                            &sign: c_int) -> c_float;
+                                            sign: &mut c_int) -> c_float;
 
     #[cfg(windows)]
     #[link_name="__lgammaf_r"] pure fn lgamma(n: c_float,
-                                              &sign: c_int) -> c_float;
+                                              sign: &mut c_int) -> c_float;
 
     #[link_name="logf"] pure fn ln(n: c_float) -> c_float;
     #[link_name="logbf"] pure fn log_radix(n: c_float) -> c_float;
@@ -135,7 +135,7 @@ pub extern mod c_float {
     #[link_name="log10f"] pure fn log10(n: c_float) -> c_float;
     #[link_name="ilogbf"] pure fn ilog_radix(n: c_float) -> c_int;
     #[link_name="modff"] pure fn modf(n: c_float,
-                                      &iptr: c_float) -> c_float;
+                                      iptr: &mut c_float) -> c_float;
     #[link_name="powf"] pure fn pow(n: c_float, e: c_float) -> c_float;
 // FIXME (#1379): enable when rounding modes become available
 //    #[link_name="rintf"] pure fn rint(n: c_float) -> c_float;
diff --git a/src/libstd/time.rs b/src/libstd/time.rs
index 627a3b8eeae0..8fa1e0cf3f0a 100644
--- a/src/libstd/time.rs
+++ b/src/libstd/time.rs
@@ -7,9 +7,18 @@ use result::{Result, Ok, Err};
 
 #[abi = "cdecl"]
 extern mod rustrt {
-    #[legacy_exports];
+    #[legacy_exports]
+    #[cfg(stage0)]
     fn get_time(&sec: i64, &nsec: i32);
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    fn get_time(sec: &mut i64, nsec: &mut i32);
+
+    #[cfg(stage0)]
     fn precise_time_ns(&ns: u64);
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    fn precise_time_ns(ns: &mut u64);
 
     fn rust_tzset();
     // FIXME: The i64 values can be passed by-val when #2064 is fixed.
@@ -33,22 +42,41 @@ impl Timespec : Eq {
  * Returns the current time as a `timespec` containing the seconds and
  * nanoseconds since 1970-01-01T00:00:00Z.
  */
+#[cfg(stage0)]
 pub fn get_time() -> Timespec {
     let mut sec = 0i64;
     let mut nsec = 0i32;
     rustrt::get_time(sec, nsec);
     return {sec: sec, nsec: nsec};
 }
+#[cfg(stage1)]
+#[cfg(stage2)]
+pub fn get_time() -> Timespec {
+    let mut sec = 0i64;
+    let mut nsec = 0i32;
+    rustrt::get_time(&mut sec, &mut nsec);
+    return {sec: sec, nsec: nsec};
+}
+
 
 /**
  * Returns the current value of a high-resolution performance counter
  * in nanoseconds since an unspecified epoch.
  */
+#[cfg(stage0)]
 pub fn precise_time_ns() -> u64 {
     let mut ns = 0u64;
     rustrt::precise_time_ns(ns);
     ns
 }
+#[cfg(stage1)]
+#[cfg(stage2)]
+pub fn precise_time_ns() -> u64 {
+    let mut ns = 0u64;
+    rustrt::precise_time_ns(&mut ns);
+    ns
+}
+
 
 /**
  * Returns the current value of a high-resolution performance counter
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index e17b52fb27d1..a50189cf5989 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -574,7 +574,7 @@ impl inferable : cmp::Eq {
 
 // "resolved" mode: the real modes.
 #[auto_serialize]
-enum rmode { by_ref, by_val, by_mutbl_ref, by_move, by_copy }
+enum rmode { by_ref, by_val, by_move, by_copy }
 
 impl rmode : to_bytes::IterBytes {
     pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) {
diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs
index cb8416501b37..4f265e1919c2 100644
--- a/src/libsyntax/parse/comments.rs
+++ b/src/libsyntax/parse/comments.rs
@@ -127,14 +127,14 @@ fn consume_non_eol_whitespace(rdr: string_reader) {
     }
 }
 
-fn push_blank_line_comment(rdr: string_reader, &comments: ~[cmnt]) {
+fn push_blank_line_comment(rdr: string_reader, comments: &mut ~[cmnt]) {
     debug!(">>> blank-line comment");
     let v: ~[~str] = ~[];
     comments.push({style: blank_line, lines: v, pos: rdr.chpos});
 }
 
 fn consume_whitespace_counting_blank_lines(rdr: string_reader,
-                                           &comments: ~[cmnt]) {
+                                           comments: &mut ~[cmnt]) {
     while is_whitespace(rdr.curr) && !is_eof(rdr) {
         if rdr.col == 0u && rdr.curr == '\n' {
             push_blank_line_comment(rdr, comments);
@@ -145,7 +145,7 @@ fn consume_whitespace_counting_blank_lines(rdr: string_reader,
 
 
 fn read_shebang_comment(rdr: string_reader, code_to_the_left: bool,
-                                                        &comments: ~[cmnt]) {
+                                            comments: &mut ~[cmnt]) {
     debug!(">>> shebang comment");
     let p = rdr.chpos;
     debug!("<<< shebang comment");
@@ -157,7 +157,7 @@ fn read_shebang_comment(rdr: string_reader, code_to_the_left: bool,
 }
 
 fn read_line_comments(rdr: string_reader, code_to_the_left: bool,
-                                                        &comments: ~[cmnt]) {
+                                          comments: &mut ~[cmnt]) {
     debug!(">>> line comments");
     let p = rdr.chpos;
     let mut lines: ~[~str] = ~[];
@@ -188,8 +188,8 @@ fn all_whitespace(s: ~str, begin: uint, end: uint) -> bool {
     return true;
 }
 
-fn trim_whitespace_prefix_and_push_line(&lines: ~[~str],
-                                        s: ~str, col: uint) unsafe {
+fn trim_whitespace_prefix_and_push_line(lines: &mut ~[~str],
+                                        s: ~str, col: uint) {
     let mut s1;
     let len = str::len(s);
     if all_whitespace(s, 0u, uint::min(len, col)) {
@@ -202,7 +202,7 @@ fn trim_whitespace_prefix_and_push_line(&lines: ~[~str],
 }
 
 fn read_block_comment(rdr: string_reader, code_to_the_left: bool,
-                                                        &comments: ~[cmnt]) {
+                                          comments: &mut ~[cmnt]) {
     debug!(">>> block comment");
     let p = rdr.chpos;
     let mut lines: ~[~str] = ~[];
@@ -228,7 +228,7 @@ fn read_block_comment(rdr: string_reader, code_to_the_left: bool,
         debug!("=== block comment level %d", level);
         if is_eof(rdr) {(rdr as reader).fatal(~"unterminated block comment");}
         if rdr.curr == '\n' {
-            trim_whitespace_prefix_and_push_line(lines, curr_line, col);
+            trim_whitespace_prefix_and_push_line(&mut lines, curr_line, col);
             curr_line = ~"";
             bump(rdr);
         } else {
@@ -248,8 +248,8 @@ fn read_block_comment(rdr: string_reader, code_to_the_left: bool,
             }
         }
     }
-    if str::len(curr_line) != 0u {
-        trim_whitespace_prefix_and_push_line(lines, curr_line, col);
+    if str::len(curr_line) != 0 {
+        trim_whitespace_prefix_and_push_line(&mut lines, curr_line, col);
     }
     let mut style = if code_to_the_left { trailing } else { isolated };
     consume_non_eol_whitespace(rdr);
@@ -267,7 +267,7 @@ fn peeking_at_comment(rdr: string_reader) -> bool {
 }
 
 fn consume_comment(rdr: string_reader, code_to_the_left: bool,
-                   &comments: ~[cmnt]) {
+                   comments: &mut ~[cmnt]) {
     debug!(">>> consume comment");
     if rdr.curr == '/' && nextch(rdr) == '/' {
         read_line_comments(rdr, code_to_the_left, comments);
@@ -299,11 +299,11 @@ fn gather_comments_and_literals(span_diagnostic: diagnostic::span_handler,
             consume_non_eol_whitespace(rdr);
             if rdr.curr == '\n' {
                 code_to_the_left = false;
-                consume_whitespace_counting_blank_lines(rdr, comments);
+                consume_whitespace_counting_blank_lines(rdr, &mut comments);
             }
             while peeking_at_comment(rdr) {
-                consume_comment(rdr, code_to_the_left, comments);
-                consume_whitespace_counting_blank_lines(rdr, comments);
+                consume_comment(rdr, code_to_the_left, &mut comments);
+                consume_whitespace_counting_blank_lines(rdr, &mut comments);
             }
             break;
         }
diff --git a/src/libsyntax/parse/eval.rs b/src/libsyntax/parse/eval.rs
index 14dc490346eb..c91060284910 100644
--- a/src/libsyntax/parse/eval.rs
+++ b/src/libsyntax/parse/eval.rs
@@ -10,8 +10,8 @@ type ctx =
 fn eval_crate_directives(cx: ctx,
                          cdirs: ~[@ast::crate_directive],
                          prefix: &Path,
-                         &view_items: ~[@ast::view_item],
-                         &items: ~[@ast::item]) {
+                         view_items: &mut~[@ast::view_item],
+                         items: &mut~[@ast::item]) {
     for cdirs.each |sub_cdir| {
         eval_crate_directive(cx, *sub_cdir, prefix, view_items, items);
     }
@@ -24,7 +24,7 @@ fn eval_crate_directives_to_mod(cx: ctx, cdirs: ~[@ast::crate_directive],
         = parse_companion_mod(cx, prefix, suffix);
     let mut view_items: ~[@ast::view_item] = ~[];
     let mut items: ~[@ast::item] = ~[];
-    eval_crate_directives(cx, cdirs, prefix, view_items, items);
+    eval_crate_directives(cx, cdirs, prefix, &mut view_items, &mut items);
     return ({view_items: vec::append(view_items, cview_items),
           items: vec::append(items, citems)},
          cattrs);
@@ -82,8 +82,8 @@ fn cdir_path_opt(default: ~str, attrs: ~[ast::attribute]) -> ~str {
 }
 
 fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: &Path,
-                        &view_items: ~[@ast::view_item],
-                        &items: ~[@ast::item]) {
+                        view_items: &mut ~[@ast::view_item],
+                        items: &mut ~[@ast::item]) {
     match cdir.node {
       ast::cdir_src_mod(vis, id, attrs) => {
         let file_path = Path(cdir_path_opt(
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 1a87d7fed695..79f7d72d2a56 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -26,7 +26,7 @@ use ast::{_mod, add, alt_check, alt_exhaustive, arg, arm, attribute,
              bind_by_ref, bind_by_implicit_ref, bind_by_value, bind_by_move,
              bitand, bitor, bitxor, blk, blk_check_mode, bound_const,
              bound_copy, bound_send, bound_trait, bound_owned, box, by_copy,
-             by_move, by_mutbl_ref, by_ref, by_val, capture_clause,
+             by_move, by_ref, by_val, capture_clause,
              capture_item, cdir_dir_mod, cdir_src_mod, cdir_view_item,
              class_immutable, class_mutable,
              crate, crate_cfg, crate_directive, decl, decl_item, decl_local,
@@ -571,7 +571,7 @@ impl parser {
     fn parse_arg_mode() -> mode {
         if self.eat(token::BINOP(token::AND)) {
             self.warn(~"Obsolete syntax has no effect");
-            expl(by_mutbl_ref)
+            expl(by_val)
         } else if self.eat(token::BINOP(token::MINUS)) {
             expl(by_move)
         } else if self.eat(token::ANDAND) {
@@ -1276,7 +1276,8 @@ impl parser {
 
         return match self.token {
           token::LPAREN | token::LBRACE | token::LBRACKET => {
-            let ket = token::flip_delimiter(self.token);
+              // tjc: ??????
+            let ket = token::flip_delimiter(copy self.token);
             tt_delim(vec::append(
                 ~[parse_tt_tok(self, true)],
                 vec::append(
@@ -1297,7 +1298,8 @@ impl parser {
         return match self.token {
           token::LBRACE | token::LPAREN | token::LBRACKET => {
             self.parse_matcher_subseq(name_idx, copy self.token,
-                                      token::flip_delimiter(self.token))
+                                      // tjc: not sure why we need a copy
+                                      token::flip_delimiter(copy self.token))
           }
           _ => self.fatal(~"expected open delimiter")
         }
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index a328ff1bdf64..99b789cf63fc 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -230,7 +230,7 @@ pure fn can_begin_expr(t: token) -> bool {
 }
 
 /// what's the opposite delimiter?
-fn flip_delimiter(&t: token::token) -> token::token {
+fn flip_delimiter(t: token::token) -> token::token {
     match t {
       token::LPAREN => token::RPAREN,
       token::LBRACE => token::RBRACE,
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index d08b20eed843..bff356e5cb72 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1688,7 +1688,6 @@ fn print_fn_block_args(s: ps, decl: ast::fn_decl,
 
 fn mode_to_str(m: ast::mode) -> ~str {
     match m {
-      ast::expl(ast::by_mutbl_ref) => ~"&",
       ast::expl(ast::by_move) => ~"-",
       ast::expl(ast::by_ref) => ~"&&",
       ast::expl(ast::by_val) => ~"++",
diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs
index 87ef3b4749c3..47d91c10818c 100644
--- a/src/rustc/metadata/encoder.rs
+++ b/src/rustc/metadata/encoder.rs
@@ -116,7 +116,7 @@ fn encode_mutability(ebml_w: ebml::Writer, mt: class_mutability) {
 type entry = {val: T, pos: uint};
 
 fn add_to_index(ecx: @encode_ctxt, ebml_w: ebml::Writer, path: &[ident],
-                &index: ~[entry<~str>], name: ident) {
+                index: &mut ~[entry<~str>], name: ident) {
     let mut full_path = ~[];
     full_path.push_all(path);
     full_path.push(name);
diff --git a/src/rustc/metadata/tydecode.rs b/src/rustc/metadata/tydecode.rs
index f3fa0e3f3507..1375ff2d0be0 100644
--- a/src/rustc/metadata/tydecode.rs
+++ b/src/rustc/metadata/tydecode.rs
@@ -394,7 +394,6 @@ fn parse_arg(st: @pstate, conv: conv_did) -> ty::arg {
 
 fn parse_mode(st: @pstate) -> ast::mode {
     let m = ast::expl(match next(st) {
-        '&' => ast::by_mutbl_ref,
         '-' => ast::by_move,
         '+' => ast::by_copy,
         '=' => ast::by_ref,
diff --git a/src/rustc/metadata/tyencode.rs b/src/rustc/metadata/tyencode.rs
index 88d83ca23f4c..83f92b44fe8f 100644
--- a/src/rustc/metadata/tyencode.rs
+++ b/src/rustc/metadata/tyencode.rs
@@ -332,7 +332,6 @@ fn enc_arg(w: io::Writer, cx: @ctxt, arg: ty::arg) {
 
 fn enc_mode(w: io::Writer, cx: @ctxt, m: mode) {
     match ty::resolved_mode(cx.tcx, m) {
-      by_mutbl_ref => w.write_char('&'),
       by_move => w.write_char('-'),
       by_copy => w.write_char('+'),
       by_ref => w.write_char('='),
diff --git a/src/rustc/middle/borrowck.rs b/src/rustc/middle/borrowck.rs
index 414890cbd7c6..e2f7ba20642a 100644
--- a/src/rustc/middle/borrowck.rs
+++ b/src/rustc/middle/borrowck.rs
@@ -396,10 +396,10 @@ type req_maps = {
     pure_map: HashMap
 };
 
-fn save_and_restore(&save_and_restore_t: T, f: fn() -> U) -> U {
-    let old_save_and_restore_t = save_and_restore_t;
+fn save_and_restore(save_and_restore_t: &mut T, f: fn() -> U) -> U {
+    let old_save_and_restore_t = *save_and_restore_t;
     let u <- f();
-    save_and_restore_t = old_save_and_restore_t;
+    *save_and_restore_t = old_save_and_restore_t;
     move u
 }
 
diff --git a/src/rustc/middle/borrowck/check_loans.rs b/src/rustc/middle/borrowck/check_loans.rs
index 0c79c0fcd7f3..51beff021fa7 100644
--- a/src/rustc/middle/borrowck/check_loans.rs
+++ b/src/rustc/middle/borrowck/check_loans.rs
@@ -529,8 +529,7 @@ impl check_loan_ctxt {
                 ast::by_move => {
                     self.check_move_out(*arg);
                 }
-                ast::by_mutbl_ref | ast::by_ref |
-                ast::by_copy | ast::by_val => {
+                ast::by_ref | ast::by_copy | ast::by_val => {
                 }
             }
         }
@@ -542,9 +541,9 @@ fn check_loans_in_fn(fk: visit::fn_kind, decl: ast::fn_decl, body: ast::blk,
                      visitor: visit::vt) {
 
     debug!("purity on entry=%?", copy self.declared_purity);
-    do save_and_restore(self.in_ctor) {
-        do save_and_restore(self.declared_purity) {
-            do save_and_restore(self.fn_args) {
+    do save_and_restore(&mut(self.in_ctor)) {
+        do save_and_restore(&mut(self.declared_purity)) {
+            do save_and_restore(&mut(self.fn_args)) {
                 let is_stack_closure = self.is_stack_closure(id);
                 let fty = ty::node_id_to_type(self.tcx(), id);
                 self.declared_purity = ty::determine_inherited_purity(
@@ -667,7 +666,7 @@ fn check_loans_in_expr(expr: @ast::expr,
 fn check_loans_in_block(blk: ast::blk,
                         &&self: check_loan_ctxt,
                         vt: visit::vt) {
-    do save_and_restore(self.declared_purity) {
+    do save_and_restore(&mut(self.declared_purity)) {
         self.check_for_conflicting_loans(blk.node.id);
 
         match blk.node.rules {
diff --git a/src/rustc/middle/borrowck/gather_loans.rs b/src/rustc/middle/borrowck/gather_loans.rs
index 327db51518be..5dfde8c9af64 100644
--- a/src/rustc/middle/borrowck/gather_loans.rs
+++ b/src/rustc/middle/borrowck/gather_loans.rs
@@ -115,10 +115,6 @@ fn req_loans_in_expr(ex: @ast::expr,
         let scope_r = ty::re_scope(ex.id);
         for vec::each2(args, arg_tys) |arg, arg_ty| {
             match ty::resolved_mode(self.tcx(), arg_ty.mode) {
-              ast::by_mutbl_ref => {
-                let arg_cmt = self.bccx.cat_expr(*arg);
-                self.guarantee_valid(arg_cmt, m_mutbl, scope_r);
-              }
               ast::by_ref => {
                 let arg_cmt = self.bccx.cat_expr(*arg);
                 self.guarantee_valid(arg_cmt, m_imm,  scope_r);
diff --git a/src/rustc/middle/kind.rs b/src/rustc/middle/kind.rs
index 9aff382775c8..1da145cabc9f 100644
--- a/src/rustc/middle/kind.rs
+++ b/src/rustc/middle/kind.rs
@@ -319,13 +319,13 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt) {
         for exprs.each |expr| { maybe_copy(cx, *expr, None); }
       }
       expr_call(f, args, _) => {
-        let mut i = 0u;
+        let mut i = 0;
         for ty::ty_fn_args(ty::expr_ty(cx.tcx, f)).each |arg_t| {
             match ty::arg_mode(cx.tcx, *arg_t) {
               by_copy => maybe_copy(cx, args[i], None),
-              by_ref | by_val | by_mutbl_ref | by_move => ()
+              by_ref | by_val | by_move => ()
             }
-            i += 1u;
+            i += 1;
         }
       }
       expr_field(lhs, _, _) => {
@@ -335,7 +335,7 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt) {
             Some(ref mme) => {
                 match ty::arg_mode(cx.tcx, mme.self_arg) {
                     by_copy => maybe_copy(cx, lhs, None),
-                    by_ref | by_val | by_mutbl_ref | by_move => ()
+                    by_ref | by_val | by_move => ()
                 }
             }
             _ => ()
@@ -465,18 +465,10 @@ fn check_imm_free_var(cx: ctx, def: def, sp: span) {
             cx.tcx.sess.span_err(sp, msg);
         }
       }
-      def_arg(_, mode) => {
-        match ty::resolved_mode(cx.tcx, mode) {
-          by_ref | by_val | by_move | by_copy => { /* ok */ }
-          by_mutbl_ref => {
-            cx.tcx.sess.span_err(sp, msg);
-          }
-        }
-      }
       def_upvar(_, def1, _, _) => {
         check_imm_free_var(cx, *def1, sp);
       }
-      def_binding(*) | def_self(*) => { /*ok*/ }
+      def_arg(*) | def_binding(*) | def_self(*) => { /*ok*/ }
       _ => {
         cx.tcx.sess.span_bug(
             sp,
diff --git a/src/rustc/middle/liveness.rs b/src/rustc/middle/liveness.rs
index 69b325b03a4a..bdf808e8568f 100644
--- a/src/rustc/middle/liveness.rs
+++ b/src/rustc/middle/liveness.rs
@@ -398,8 +398,8 @@ impl IrMaps {
 
             (*v).push(id);
           }
-          Arg(_, _, by_ref) | Arg(_, _, by_mutbl_ref) |
-          Arg(_, _, by_val) | Self | Field(_) | ImplicitRet |
+          Arg(_, _, by_ref) | Arg(_, _, by_val) | Self | Field(_) |
+          ImplicitRet |
           Local(LocalInfo {kind: FromMatch(bind_by_implicit_ref), _}) => {
             debug!("--but it is not owned");
           }
@@ -831,9 +831,9 @@ impl Liveness {
         let mut changed = false;
         do self.indices2(ln, succ_ln) |idx, succ_idx| {
             changed |= copy_if_invalid(copy self.users[succ_idx].reader,
-                                       self.users[idx].reader);
+                                       &mut self.users[idx].reader);
             changed |= copy_if_invalid(copy self.users[succ_idx].writer,
-                                       self.users[idx].writer);
+                                       &mut self.users[idx].writer);
             if self.users[succ_idx].used && !self.users[idx].used {
                 self.users[idx].used = true;
                 changed = true;
@@ -844,10 +844,10 @@ impl Liveness {
                ln.to_str(), self.ln_str(succ_ln), first_merge, changed);
         return changed;
 
-        fn copy_if_invalid(src: LiveNode, &dst: LiveNode) -> bool {
+        fn copy_if_invalid(src: LiveNode, dst: &mut LiveNode) -> bool {
             if src.is_valid() {
                 if !dst.is_valid() {
-                    dst = src;
+                    *dst = src;
                     return true;
                 }
             }
@@ -919,7 +919,7 @@ impl Liveness {
         // inputs passed by & mode should be considered live on exit:
         for decl.inputs.each |arg| {
             match ty::resolved_mode(self.tcx, arg.mode) {
-              by_mutbl_ref | by_ref | by_val => {
+              by_ref | by_val => {
                 // These are "non-owned" modes, so register a read at
                 // the end.  This will prevent us from moving out of
                 // such variables but also prevent us from registering
@@ -1573,7 +1573,7 @@ fn check_expr(expr: @expr, &&self: @Liveness, vt: vt<@Liveness>) {
         let targs = ty::ty_fn_args(ty::expr_ty(self.tcx, f));
         for vec::each2(args, targs) |arg_expr, arg_ty| {
             match ty::resolved_mode(self.tcx, arg_ty.mode) {
-                by_val | by_copy | by_ref | by_mutbl_ref => {}
+                by_val | by_copy | by_ref => {}
                 by_move => {
                     self.check_move_from_expr(*arg_expr, vt);
                 }
@@ -1866,19 +1866,6 @@ impl @Liveness {
         for decl.inputs.each |arg| {
             let var = self.variable(arg.id, arg.ty.span);
             match ty::resolved_mode(self.tcx, arg.mode) {
-              by_mutbl_ref => {
-                // for mutable reference arguments, something like
-                //    x = 1;
-                // is not worth warning about, as it has visible
-                // side effects outside the fn.
-                match self.assigned_on_entry(entry_ln, var) {
-                  Some(_) => { /*ok*/ }
-                  None => {
-                    // but if it is not written, it ought to be used
-                    self.warn_about_unused(sp, entry_ln, var);
-                  }
-                }
-              }
               by_val | by_ref | by_move | by_copy => {
                 self.warn_about_unused(sp, entry_ln, var);
               }
diff --git a/src/rustc/middle/mem_categorization.rs b/src/rustc/middle/mem_categorization.rs
index fe465db1312c..dc5874ea2cfa 100644
--- a/src/rustc/middle/mem_categorization.rs
+++ b/src/rustc/middle/mem_categorization.rs
@@ -523,9 +523,6 @@ impl &mem_categorization_ctxt {
             // m: mutability of the argument
             // lp: loan path, must be none for aliasable things
             let {m,lp} = match ty::resolved_mode(self.tcx, mode) {
-              ast::by_mutbl_ref => {
-                {m: m_mutbl, lp: None}
-              }
               ast::by_move | ast::by_copy => {
                 {m: m_imm, lp: Some(@lp_arg(vid))}
               }
diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs
index ce596586ddc4..368a523306e0 100644
--- a/src/rustc/middle/trans/base.rs
+++ b/src/rustc/middle/trans/base.rs
@@ -1503,7 +1503,7 @@ fn copy_args_to_allocas(fcx: fn_ctxt,
         // the event it's not truly needed.
         let llarg;
         match ty::resolved_mode(tcx, arg_ty.mode) {
-            ast::by_ref | ast::by_mutbl_ref => {
+            ast::by_ref => {
                 llarg = raw_llarg;
             }
             ast::by_move | ast::by_copy => {
diff --git a/src/rustc/middle/trans/callee.rs b/src/rustc/middle/trans/callee.rs
index e7b4dd171e31..c851c5bc7250 100644
--- a/src/rustc/middle/trans/callee.rs
+++ b/src/rustc/middle/trans/callee.rs
@@ -592,7 +592,7 @@ fn trans_arg_expr(bcx: block,
             DoAutorefArg => { val = arg_datum.to_ref_llval(bcx); }
             DontAutorefArg => {
                 match arg_mode {
-                    ast::by_ref | ast::by_mutbl_ref => {
+                    ast::by_ref => {
                         val = arg_datum.to_ref_llval(bcx);
                     }
 
diff --git a/src/rustc/middle/trans/reflect.rs b/src/rustc/middle/trans/reflect.rs
index cdd11ee85c57..ef1cc15f5c0e 100644
--- a/src/rustc/middle/trans/reflect.rs
+++ b/src/rustc/middle/trans/reflect.rs
@@ -208,7 +208,6 @@ impl reflector {
                   ast::expl(e) => match e {
                     ast::by_ref => 1u,
                     ast::by_val => 2u,
-                    ast::by_mutbl_ref => 3u,
                     ast::by_move => 4u,
                     ast::by_copy => 5u
                   }
diff --git a/src/rustc/middle/trans/shape.rs b/src/rustc/middle/trans/shape.rs
index cf58b5b51c4c..e7dfac42becc 100644
--- a/src/rustc/middle/trans/shape.rs
+++ b/src/rustc/middle/trans/shape.rs
@@ -49,12 +49,12 @@ fn mk_ctxt(llmod: ModuleRef) -> ctxt {
     return {mut next_tag_id: 0u16, pad: 0u16, pad2: 0u32};
 }
 
-fn add_u16(&dest: ~[u8], val: u16) {
-    dest += ~[(val & 0xffu16) as u8, (val >> 8u16) as u8];
+fn add_u16(dest: &mut ~[u8], val: u16) {
+    *dest += ~[(val & 0xffu16) as u8, (val >> 8u16) as u8];
 }
 
-fn add_substr(&dest: ~[u8], src: ~[u8]) {
+fn add_substr(dest: &mut ~[u8], src: ~[u8]) {
     add_u16(dest, vec::len(src) as u16);
-    dest += src;
+    *dest += src;
 }
 
diff --git a/src/rustc/middle/trans/type_use.rs b/src/rustc/middle/trans/type_use.rs
index 6bd3c22f626a..9140ea94e9ca 100644
--- a/src/rustc/middle/trans/type_use.rs
+++ b/src/rustc/middle/trans/type_use.rs
@@ -53,7 +53,7 @@ fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint)
                     by_val | by_move | by_copy => {
                         type_needs(cx, use_repr, arg.ty);
                     }
-                    by_ref | by_mutbl_ref => {}
+                    by_ref => {}
                 }
             }
         }
diff --git a/src/rustc/middle/trans/uniq.rs b/src/rustc/middle/trans/uniq.rs
index 6ab91c4a1d79..50ea363ace2a 100644
--- a/src/rustc/middle/trans/uniq.rs
+++ b/src/rustc/middle/trans/uniq.rs
@@ -3,7 +3,6 @@ use lib::llvm::ValueRef;
 use common::*;
 use build::*;
 use base::*;
-use shape::llsize_of;
 use datum::immediate_rvalue;
 
 export make_free_glue, autoderef, duplicate;

From f8bc0d25455d7bfb299cd0e7693ee575f5dbce21 Mon Sep 17 00:00:00 2001
From: Tim Chevalier 
Date: Fri, 5 Oct 2012 16:10:08 -0700
Subject: [PATCH 58/80] Revert "wip"

This reverts commit ca49fd402af8e7bf613c43e996274b5a017958d2.
---
 src/libcore/cmath.rs                      | 16 ++++++------
 src/libstd/time.rs                        | 30 +----------------------
 src/libsyntax/ast.rs                      |  2 +-
 src/libsyntax/parse/comments.rs           | 28 ++++++++++-----------
 src/libsyntax/parse/eval.rs               | 10 ++++----
 src/libsyntax/parse/parser.rs             | 10 +++-----
 src/libsyntax/parse/token.rs              |  2 +-
 src/libsyntax/print/pprust.rs             |  1 +
 src/rustc/metadata/encoder.rs             |  2 +-
 src/rustc/metadata/tydecode.rs            |  1 +
 src/rustc/metadata/tyencode.rs            |  1 +
 src/rustc/middle/borrowck.rs              |  6 ++---
 src/rustc/middle/borrowck/check_loans.rs  | 11 +++++----
 src/rustc/middle/borrowck/gather_loans.rs |  4 +++
 src/rustc/middle/kind.rs                  | 18 ++++++++++----
 src/rustc/middle/liveness.rs              | 29 ++++++++++++++++------
 src/rustc/middle/mem_categorization.rs    |  3 +++
 src/rustc/middle/trans/base.rs            |  2 +-
 src/rustc/middle/trans/callee.rs          |  2 +-
 src/rustc/middle/trans/reflect.rs         |  1 +
 src/rustc/middle/trans/shape.rs           |  8 +++---
 src/rustc/middle/trans/type_use.rs        |  2 +-
 src/rustc/middle/trans/uniq.rs            |  1 +
 23 files changed, 97 insertions(+), 93 deletions(-)

diff --git a/src/libcore/cmath.rs b/src/libcore/cmath.rs
index b0aeb78afaa8..9a9a7cb31121 100644
--- a/src/libcore/cmath.rs
+++ b/src/libcore/cmath.rs
@@ -40,15 +40,15 @@ pub extern mod c_double {
     #[link_name="fmax"] pure fn fmax(a: c_double, b: c_double) -> c_double;
     #[link_name="fmin"] pure fn fmin(a: c_double, b: c_double) -> c_double;
     pure fn nextafter(x: c_double, y: c_double) -> c_double;
-    pure fn frexp(n: c_double, value: &mut c_int) -> c_double;
+    pure fn frexp(n: c_double, &value: c_int) -> c_double;
     pure fn hypot(x: c_double, y: c_double) -> c_double;
     pure fn ldexp(x: c_double, n: c_int) -> c_double;
     #[cfg(unix)]
     #[link_name="lgamma_r"] pure fn lgamma(n: c_double,
-                                           sign: &mut c_int) -> c_double;
+                                           &sign: c_int) -> c_double;
     #[cfg(windows)]
     #[link_name="__lgamma_r"] pure fn lgamma(n: c_double,
-                                             sign: &mut c_int) -> c_double;
+                                             &sign: c_int) -> c_double;
     // renamed: log is a reserved keyword; ln seems more natural, too
     #[link_name="log"] pure fn ln(n: c_double) -> c_double;
     // renamed: "logb" /often/ is confused for log2 by beginners
@@ -58,7 +58,7 @@ pub extern mod c_double {
     pure fn log10(n: c_double) -> c_double;
     pure fn log2(n: c_double) -> c_double;
     #[link_name="ilogb"] pure fn ilog_radix(n: c_double) -> c_int;
-    pure fn modf(n: c_double, iptr: &mut c_double) -> c_double;
+    pure fn modf(n: c_double, &iptr: c_double) -> c_double;
     pure fn pow(n: c_double, e: c_double) -> c_double;
 // FIXME (#1379): enable when rounding modes become available
 //    pure fn rint(n: c_double) -> c_double;
@@ -110,7 +110,7 @@ pub extern mod c_float {
     #[link_name="fdimf"] pure fn abs_sub(a: c_float, b: c_float) -> c_float;
     #[link_name="floorf"] pure fn floor(n: c_float) -> c_float;
     #[link_name="frexpf"] pure fn frexp(n: c_float,
-                                        value: &mut c_int) -> c_float;
+                                        &value: c_int) -> c_float;
     #[link_name="fmaf"] pure fn mul_add(a: c_float,
                                         b: c_float, c: c_float) -> c_float;
     #[link_name="fmaxf"] pure fn fmax(a: c_float, b: c_float) -> c_float;
@@ -122,11 +122,11 @@ pub extern mod c_float {
 
     #[cfg(unix)]
     #[link_name="lgammaf_r"] pure fn lgamma(n: c_float,
-                                            sign: &mut c_int) -> c_float;
+                                            &sign: c_int) -> c_float;
 
     #[cfg(windows)]
     #[link_name="__lgammaf_r"] pure fn lgamma(n: c_float,
-                                              sign: &mut c_int) -> c_float;
+                                              &sign: c_int) -> c_float;
 
     #[link_name="logf"] pure fn ln(n: c_float) -> c_float;
     #[link_name="logbf"] pure fn log_radix(n: c_float) -> c_float;
@@ -135,7 +135,7 @@ pub extern mod c_float {
     #[link_name="log10f"] pure fn log10(n: c_float) -> c_float;
     #[link_name="ilogbf"] pure fn ilog_radix(n: c_float) -> c_int;
     #[link_name="modff"] pure fn modf(n: c_float,
-                                      iptr: &mut c_float) -> c_float;
+                                      &iptr: c_float) -> c_float;
     #[link_name="powf"] pure fn pow(n: c_float, e: c_float) -> c_float;
 // FIXME (#1379): enable when rounding modes become available
 //    #[link_name="rintf"] pure fn rint(n: c_float) -> c_float;
diff --git a/src/libstd/time.rs b/src/libstd/time.rs
index 8fa1e0cf3f0a..627a3b8eeae0 100644
--- a/src/libstd/time.rs
+++ b/src/libstd/time.rs
@@ -7,18 +7,9 @@ use result::{Result, Ok, Err};
 
 #[abi = "cdecl"]
 extern mod rustrt {
-    #[legacy_exports]
-    #[cfg(stage0)]
+    #[legacy_exports];
     fn get_time(&sec: i64, &nsec: i32);
-    #[cfg(stage1)]
-    #[cfg(stage2)]
-    fn get_time(sec: &mut i64, nsec: &mut i32);
-
-    #[cfg(stage0)]
     fn precise_time_ns(&ns: u64);
-    #[cfg(stage1)]
-    #[cfg(stage2)]
-    fn precise_time_ns(ns: &mut u64);
 
     fn rust_tzset();
     // FIXME: The i64 values can be passed by-val when #2064 is fixed.
@@ -42,41 +33,22 @@ impl Timespec : Eq {
  * Returns the current time as a `timespec` containing the seconds and
  * nanoseconds since 1970-01-01T00:00:00Z.
  */
-#[cfg(stage0)]
 pub fn get_time() -> Timespec {
     let mut sec = 0i64;
     let mut nsec = 0i32;
     rustrt::get_time(sec, nsec);
     return {sec: sec, nsec: nsec};
 }
-#[cfg(stage1)]
-#[cfg(stage2)]
-pub fn get_time() -> Timespec {
-    let mut sec = 0i64;
-    let mut nsec = 0i32;
-    rustrt::get_time(&mut sec, &mut nsec);
-    return {sec: sec, nsec: nsec};
-}
-
 
 /**
  * Returns the current value of a high-resolution performance counter
  * in nanoseconds since an unspecified epoch.
  */
-#[cfg(stage0)]
 pub fn precise_time_ns() -> u64 {
     let mut ns = 0u64;
     rustrt::precise_time_ns(ns);
     ns
 }
-#[cfg(stage1)]
-#[cfg(stage2)]
-pub fn precise_time_ns() -> u64 {
-    let mut ns = 0u64;
-    rustrt::precise_time_ns(&mut ns);
-    ns
-}
-
 
 /**
  * Returns the current value of a high-resolution performance counter
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index a50189cf5989..e17b52fb27d1 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -574,7 +574,7 @@ impl inferable : cmp::Eq {
 
 // "resolved" mode: the real modes.
 #[auto_serialize]
-enum rmode { by_ref, by_val, by_move, by_copy }
+enum rmode { by_ref, by_val, by_mutbl_ref, by_move, by_copy }
 
 impl rmode : to_bytes::IterBytes {
     pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) {
diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs
index 4f265e1919c2..cb8416501b37 100644
--- a/src/libsyntax/parse/comments.rs
+++ b/src/libsyntax/parse/comments.rs
@@ -127,14 +127,14 @@ fn consume_non_eol_whitespace(rdr: string_reader) {
     }
 }
 
-fn push_blank_line_comment(rdr: string_reader, comments: &mut ~[cmnt]) {
+fn push_blank_line_comment(rdr: string_reader, &comments: ~[cmnt]) {
     debug!(">>> blank-line comment");
     let v: ~[~str] = ~[];
     comments.push({style: blank_line, lines: v, pos: rdr.chpos});
 }
 
 fn consume_whitespace_counting_blank_lines(rdr: string_reader,
-                                           comments: &mut ~[cmnt]) {
+                                           &comments: ~[cmnt]) {
     while is_whitespace(rdr.curr) && !is_eof(rdr) {
         if rdr.col == 0u && rdr.curr == '\n' {
             push_blank_line_comment(rdr, comments);
@@ -145,7 +145,7 @@ fn consume_whitespace_counting_blank_lines(rdr: string_reader,
 
 
 fn read_shebang_comment(rdr: string_reader, code_to_the_left: bool,
-                                            comments: &mut ~[cmnt]) {
+                                                        &comments: ~[cmnt]) {
     debug!(">>> shebang comment");
     let p = rdr.chpos;
     debug!("<<< shebang comment");
@@ -157,7 +157,7 @@ fn read_shebang_comment(rdr: string_reader, code_to_the_left: bool,
 }
 
 fn read_line_comments(rdr: string_reader, code_to_the_left: bool,
-                                          comments: &mut ~[cmnt]) {
+                                                        &comments: ~[cmnt]) {
     debug!(">>> line comments");
     let p = rdr.chpos;
     let mut lines: ~[~str] = ~[];
@@ -188,8 +188,8 @@ fn all_whitespace(s: ~str, begin: uint, end: uint) -> bool {
     return true;
 }
 
-fn trim_whitespace_prefix_and_push_line(lines: &mut ~[~str],
-                                        s: ~str, col: uint) {
+fn trim_whitespace_prefix_and_push_line(&lines: ~[~str],
+                                        s: ~str, col: uint) unsafe {
     let mut s1;
     let len = str::len(s);
     if all_whitespace(s, 0u, uint::min(len, col)) {
@@ -202,7 +202,7 @@ fn trim_whitespace_prefix_and_push_line(lines: &mut ~[~str],
 }
 
 fn read_block_comment(rdr: string_reader, code_to_the_left: bool,
-                                          comments: &mut ~[cmnt]) {
+                                                        &comments: ~[cmnt]) {
     debug!(">>> block comment");
     let p = rdr.chpos;
     let mut lines: ~[~str] = ~[];
@@ -228,7 +228,7 @@ fn read_block_comment(rdr: string_reader, code_to_the_left: bool,
         debug!("=== block comment level %d", level);
         if is_eof(rdr) {(rdr as reader).fatal(~"unterminated block comment");}
         if rdr.curr == '\n' {
-            trim_whitespace_prefix_and_push_line(&mut lines, curr_line, col);
+            trim_whitespace_prefix_and_push_line(lines, curr_line, col);
             curr_line = ~"";
             bump(rdr);
         } else {
@@ -248,8 +248,8 @@ fn read_block_comment(rdr: string_reader, code_to_the_left: bool,
             }
         }
     }
-    if str::len(curr_line) != 0 {
-        trim_whitespace_prefix_and_push_line(&mut lines, curr_line, col);
+    if str::len(curr_line) != 0u {
+        trim_whitespace_prefix_and_push_line(lines, curr_line, col);
     }
     let mut style = if code_to_the_left { trailing } else { isolated };
     consume_non_eol_whitespace(rdr);
@@ -267,7 +267,7 @@ fn peeking_at_comment(rdr: string_reader) -> bool {
 }
 
 fn consume_comment(rdr: string_reader, code_to_the_left: bool,
-                   comments: &mut ~[cmnt]) {
+                   &comments: ~[cmnt]) {
     debug!(">>> consume comment");
     if rdr.curr == '/' && nextch(rdr) == '/' {
         read_line_comments(rdr, code_to_the_left, comments);
@@ -299,11 +299,11 @@ fn gather_comments_and_literals(span_diagnostic: diagnostic::span_handler,
             consume_non_eol_whitespace(rdr);
             if rdr.curr == '\n' {
                 code_to_the_left = false;
-                consume_whitespace_counting_blank_lines(rdr, &mut comments);
+                consume_whitespace_counting_blank_lines(rdr, comments);
             }
             while peeking_at_comment(rdr) {
-                consume_comment(rdr, code_to_the_left, &mut comments);
-                consume_whitespace_counting_blank_lines(rdr, &mut comments);
+                consume_comment(rdr, code_to_the_left, comments);
+                consume_whitespace_counting_blank_lines(rdr, comments);
             }
             break;
         }
diff --git a/src/libsyntax/parse/eval.rs b/src/libsyntax/parse/eval.rs
index c91060284910..14dc490346eb 100644
--- a/src/libsyntax/parse/eval.rs
+++ b/src/libsyntax/parse/eval.rs
@@ -10,8 +10,8 @@ type ctx =
 fn eval_crate_directives(cx: ctx,
                          cdirs: ~[@ast::crate_directive],
                          prefix: &Path,
-                         view_items: &mut~[@ast::view_item],
-                         items: &mut~[@ast::item]) {
+                         &view_items: ~[@ast::view_item],
+                         &items: ~[@ast::item]) {
     for cdirs.each |sub_cdir| {
         eval_crate_directive(cx, *sub_cdir, prefix, view_items, items);
     }
@@ -24,7 +24,7 @@ fn eval_crate_directives_to_mod(cx: ctx, cdirs: ~[@ast::crate_directive],
         = parse_companion_mod(cx, prefix, suffix);
     let mut view_items: ~[@ast::view_item] = ~[];
     let mut items: ~[@ast::item] = ~[];
-    eval_crate_directives(cx, cdirs, prefix, &mut view_items, &mut items);
+    eval_crate_directives(cx, cdirs, prefix, view_items, items);
     return ({view_items: vec::append(view_items, cview_items),
           items: vec::append(items, citems)},
          cattrs);
@@ -82,8 +82,8 @@ fn cdir_path_opt(default: ~str, attrs: ~[ast::attribute]) -> ~str {
 }
 
 fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: &Path,
-                        view_items: &mut ~[@ast::view_item],
-                        items: &mut ~[@ast::item]) {
+                        &view_items: ~[@ast::view_item],
+                        &items: ~[@ast::item]) {
     match cdir.node {
       ast::cdir_src_mod(vis, id, attrs) => {
         let file_path = Path(cdir_path_opt(
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 79f7d72d2a56..1a87d7fed695 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -26,7 +26,7 @@ use ast::{_mod, add, alt_check, alt_exhaustive, arg, arm, attribute,
              bind_by_ref, bind_by_implicit_ref, bind_by_value, bind_by_move,
              bitand, bitor, bitxor, blk, blk_check_mode, bound_const,
              bound_copy, bound_send, bound_trait, bound_owned, box, by_copy,
-             by_move, by_ref, by_val, capture_clause,
+             by_move, by_mutbl_ref, by_ref, by_val, capture_clause,
              capture_item, cdir_dir_mod, cdir_src_mod, cdir_view_item,
              class_immutable, class_mutable,
              crate, crate_cfg, crate_directive, decl, decl_item, decl_local,
@@ -571,7 +571,7 @@ impl parser {
     fn parse_arg_mode() -> mode {
         if self.eat(token::BINOP(token::AND)) {
             self.warn(~"Obsolete syntax has no effect");
-            expl(by_val)
+            expl(by_mutbl_ref)
         } else if self.eat(token::BINOP(token::MINUS)) {
             expl(by_move)
         } else if self.eat(token::ANDAND) {
@@ -1276,8 +1276,7 @@ impl parser {
 
         return match self.token {
           token::LPAREN | token::LBRACE | token::LBRACKET => {
-              // tjc: ??????
-            let ket = token::flip_delimiter(copy self.token);
+            let ket = token::flip_delimiter(self.token);
             tt_delim(vec::append(
                 ~[parse_tt_tok(self, true)],
                 vec::append(
@@ -1298,8 +1297,7 @@ impl parser {
         return match self.token {
           token::LBRACE | token::LPAREN | token::LBRACKET => {
             self.parse_matcher_subseq(name_idx, copy self.token,
-                                      // tjc: not sure why we need a copy
-                                      token::flip_delimiter(copy self.token))
+                                      token::flip_delimiter(self.token))
           }
           _ => self.fatal(~"expected open delimiter")
         }
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 99b789cf63fc..a328ff1bdf64 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -230,7 +230,7 @@ pure fn can_begin_expr(t: token) -> bool {
 }
 
 /// what's the opposite delimiter?
-fn flip_delimiter(t: token::token) -> token::token {
+fn flip_delimiter(&t: token::token) -> token::token {
     match t {
       token::LPAREN => token::RPAREN,
       token::LBRACE => token::RBRACE,
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index bff356e5cb72..d08b20eed843 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1688,6 +1688,7 @@ fn print_fn_block_args(s: ps, decl: ast::fn_decl,
 
 fn mode_to_str(m: ast::mode) -> ~str {
     match m {
+      ast::expl(ast::by_mutbl_ref) => ~"&",
       ast::expl(ast::by_move) => ~"-",
       ast::expl(ast::by_ref) => ~"&&",
       ast::expl(ast::by_val) => ~"++",
diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs
index 47d91c10818c..87ef3b4749c3 100644
--- a/src/rustc/metadata/encoder.rs
+++ b/src/rustc/metadata/encoder.rs
@@ -116,7 +116,7 @@ fn encode_mutability(ebml_w: ebml::Writer, mt: class_mutability) {
 type entry = {val: T, pos: uint};
 
 fn add_to_index(ecx: @encode_ctxt, ebml_w: ebml::Writer, path: &[ident],
-                index: &mut ~[entry<~str>], name: ident) {
+                &index: ~[entry<~str>], name: ident) {
     let mut full_path = ~[];
     full_path.push_all(path);
     full_path.push(name);
diff --git a/src/rustc/metadata/tydecode.rs b/src/rustc/metadata/tydecode.rs
index 1375ff2d0be0..f3fa0e3f3507 100644
--- a/src/rustc/metadata/tydecode.rs
+++ b/src/rustc/metadata/tydecode.rs
@@ -394,6 +394,7 @@ fn parse_arg(st: @pstate, conv: conv_did) -> ty::arg {
 
 fn parse_mode(st: @pstate) -> ast::mode {
     let m = ast::expl(match next(st) {
+        '&' => ast::by_mutbl_ref,
         '-' => ast::by_move,
         '+' => ast::by_copy,
         '=' => ast::by_ref,
diff --git a/src/rustc/metadata/tyencode.rs b/src/rustc/metadata/tyencode.rs
index 83f92b44fe8f..88d83ca23f4c 100644
--- a/src/rustc/metadata/tyencode.rs
+++ b/src/rustc/metadata/tyencode.rs
@@ -332,6 +332,7 @@ fn enc_arg(w: io::Writer, cx: @ctxt, arg: ty::arg) {
 
 fn enc_mode(w: io::Writer, cx: @ctxt, m: mode) {
     match ty::resolved_mode(cx.tcx, m) {
+      by_mutbl_ref => w.write_char('&'),
       by_move => w.write_char('-'),
       by_copy => w.write_char('+'),
       by_ref => w.write_char('='),
diff --git a/src/rustc/middle/borrowck.rs b/src/rustc/middle/borrowck.rs
index e2f7ba20642a..414890cbd7c6 100644
--- a/src/rustc/middle/borrowck.rs
+++ b/src/rustc/middle/borrowck.rs
@@ -396,10 +396,10 @@ type req_maps = {
     pure_map: HashMap
 };
 
-fn save_and_restore(save_and_restore_t: &mut T, f: fn() -> U) -> U {
-    let old_save_and_restore_t = *save_and_restore_t;
+fn save_and_restore(&save_and_restore_t: T, f: fn() -> U) -> U {
+    let old_save_and_restore_t = save_and_restore_t;
     let u <- f();
-    *save_and_restore_t = old_save_and_restore_t;
+    save_and_restore_t = old_save_and_restore_t;
     move u
 }
 
diff --git a/src/rustc/middle/borrowck/check_loans.rs b/src/rustc/middle/borrowck/check_loans.rs
index 51beff021fa7..0c79c0fcd7f3 100644
--- a/src/rustc/middle/borrowck/check_loans.rs
+++ b/src/rustc/middle/borrowck/check_loans.rs
@@ -529,7 +529,8 @@ impl check_loan_ctxt {
                 ast::by_move => {
                     self.check_move_out(*arg);
                 }
-                ast::by_ref | ast::by_copy | ast::by_val => {
+                ast::by_mutbl_ref | ast::by_ref |
+                ast::by_copy | ast::by_val => {
                 }
             }
         }
@@ -541,9 +542,9 @@ fn check_loans_in_fn(fk: visit::fn_kind, decl: ast::fn_decl, body: ast::blk,
                      visitor: visit::vt) {
 
     debug!("purity on entry=%?", copy self.declared_purity);
-    do save_and_restore(&mut(self.in_ctor)) {
-        do save_and_restore(&mut(self.declared_purity)) {
-            do save_and_restore(&mut(self.fn_args)) {
+    do save_and_restore(self.in_ctor) {
+        do save_and_restore(self.declared_purity) {
+            do save_and_restore(self.fn_args) {
                 let is_stack_closure = self.is_stack_closure(id);
                 let fty = ty::node_id_to_type(self.tcx(), id);
                 self.declared_purity = ty::determine_inherited_purity(
@@ -666,7 +667,7 @@ fn check_loans_in_expr(expr: @ast::expr,
 fn check_loans_in_block(blk: ast::blk,
                         &&self: check_loan_ctxt,
                         vt: visit::vt) {
-    do save_and_restore(&mut(self.declared_purity)) {
+    do save_and_restore(self.declared_purity) {
         self.check_for_conflicting_loans(blk.node.id);
 
         match blk.node.rules {
diff --git a/src/rustc/middle/borrowck/gather_loans.rs b/src/rustc/middle/borrowck/gather_loans.rs
index 5dfde8c9af64..327db51518be 100644
--- a/src/rustc/middle/borrowck/gather_loans.rs
+++ b/src/rustc/middle/borrowck/gather_loans.rs
@@ -115,6 +115,10 @@ fn req_loans_in_expr(ex: @ast::expr,
         let scope_r = ty::re_scope(ex.id);
         for vec::each2(args, arg_tys) |arg, arg_ty| {
             match ty::resolved_mode(self.tcx(), arg_ty.mode) {
+              ast::by_mutbl_ref => {
+                let arg_cmt = self.bccx.cat_expr(*arg);
+                self.guarantee_valid(arg_cmt, m_mutbl, scope_r);
+              }
               ast::by_ref => {
                 let arg_cmt = self.bccx.cat_expr(*arg);
                 self.guarantee_valid(arg_cmt, m_imm,  scope_r);
diff --git a/src/rustc/middle/kind.rs b/src/rustc/middle/kind.rs
index 1da145cabc9f..9aff382775c8 100644
--- a/src/rustc/middle/kind.rs
+++ b/src/rustc/middle/kind.rs
@@ -319,13 +319,13 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt) {
         for exprs.each |expr| { maybe_copy(cx, *expr, None); }
       }
       expr_call(f, args, _) => {
-        let mut i = 0;
+        let mut i = 0u;
         for ty::ty_fn_args(ty::expr_ty(cx.tcx, f)).each |arg_t| {
             match ty::arg_mode(cx.tcx, *arg_t) {
               by_copy => maybe_copy(cx, args[i], None),
-              by_ref | by_val | by_move => ()
+              by_ref | by_val | by_mutbl_ref | by_move => ()
             }
-            i += 1;
+            i += 1u;
         }
       }
       expr_field(lhs, _, _) => {
@@ -335,7 +335,7 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt) {
             Some(ref mme) => {
                 match ty::arg_mode(cx.tcx, mme.self_arg) {
                     by_copy => maybe_copy(cx, lhs, None),
-                    by_ref | by_val | by_move => ()
+                    by_ref | by_val | by_mutbl_ref | by_move => ()
                 }
             }
             _ => ()
@@ -465,10 +465,18 @@ fn check_imm_free_var(cx: ctx, def: def, sp: span) {
             cx.tcx.sess.span_err(sp, msg);
         }
       }
+      def_arg(_, mode) => {
+        match ty::resolved_mode(cx.tcx, mode) {
+          by_ref | by_val | by_move | by_copy => { /* ok */ }
+          by_mutbl_ref => {
+            cx.tcx.sess.span_err(sp, msg);
+          }
+        }
+      }
       def_upvar(_, def1, _, _) => {
         check_imm_free_var(cx, *def1, sp);
       }
-      def_arg(*) | def_binding(*) | def_self(*) => { /*ok*/ }
+      def_binding(*) | def_self(*) => { /*ok*/ }
       _ => {
         cx.tcx.sess.span_bug(
             sp,
diff --git a/src/rustc/middle/liveness.rs b/src/rustc/middle/liveness.rs
index bdf808e8568f..69b325b03a4a 100644
--- a/src/rustc/middle/liveness.rs
+++ b/src/rustc/middle/liveness.rs
@@ -398,8 +398,8 @@ impl IrMaps {
 
             (*v).push(id);
           }
-          Arg(_, _, by_ref) | Arg(_, _, by_val) | Self | Field(_) |
-          ImplicitRet |
+          Arg(_, _, by_ref) | Arg(_, _, by_mutbl_ref) |
+          Arg(_, _, by_val) | Self | Field(_) | ImplicitRet |
           Local(LocalInfo {kind: FromMatch(bind_by_implicit_ref), _}) => {
             debug!("--but it is not owned");
           }
@@ -831,9 +831,9 @@ impl Liveness {
         let mut changed = false;
         do self.indices2(ln, succ_ln) |idx, succ_idx| {
             changed |= copy_if_invalid(copy self.users[succ_idx].reader,
-                                       &mut self.users[idx].reader);
+                                       self.users[idx].reader);
             changed |= copy_if_invalid(copy self.users[succ_idx].writer,
-                                       &mut self.users[idx].writer);
+                                       self.users[idx].writer);
             if self.users[succ_idx].used && !self.users[idx].used {
                 self.users[idx].used = true;
                 changed = true;
@@ -844,10 +844,10 @@ impl Liveness {
                ln.to_str(), self.ln_str(succ_ln), first_merge, changed);
         return changed;
 
-        fn copy_if_invalid(src: LiveNode, dst: &mut LiveNode) -> bool {
+        fn copy_if_invalid(src: LiveNode, &dst: LiveNode) -> bool {
             if src.is_valid() {
                 if !dst.is_valid() {
-                    *dst = src;
+                    dst = src;
                     return true;
                 }
             }
@@ -919,7 +919,7 @@ impl Liveness {
         // inputs passed by & mode should be considered live on exit:
         for decl.inputs.each |arg| {
             match ty::resolved_mode(self.tcx, arg.mode) {
-              by_ref | by_val => {
+              by_mutbl_ref | by_ref | by_val => {
                 // These are "non-owned" modes, so register a read at
                 // the end.  This will prevent us from moving out of
                 // such variables but also prevent us from registering
@@ -1573,7 +1573,7 @@ fn check_expr(expr: @expr, &&self: @Liveness, vt: vt<@Liveness>) {
         let targs = ty::ty_fn_args(ty::expr_ty(self.tcx, f));
         for vec::each2(args, targs) |arg_expr, arg_ty| {
             match ty::resolved_mode(self.tcx, arg_ty.mode) {
-                by_val | by_copy | by_ref => {}
+                by_val | by_copy | by_ref | by_mutbl_ref => {}
                 by_move => {
                     self.check_move_from_expr(*arg_expr, vt);
                 }
@@ -1866,6 +1866,19 @@ impl @Liveness {
         for decl.inputs.each |arg| {
             let var = self.variable(arg.id, arg.ty.span);
             match ty::resolved_mode(self.tcx, arg.mode) {
+              by_mutbl_ref => {
+                // for mutable reference arguments, something like
+                //    x = 1;
+                // is not worth warning about, as it has visible
+                // side effects outside the fn.
+                match self.assigned_on_entry(entry_ln, var) {
+                  Some(_) => { /*ok*/ }
+                  None => {
+                    // but if it is not written, it ought to be used
+                    self.warn_about_unused(sp, entry_ln, var);
+                  }
+                }
+              }
               by_val | by_ref | by_move | by_copy => {
                 self.warn_about_unused(sp, entry_ln, var);
               }
diff --git a/src/rustc/middle/mem_categorization.rs b/src/rustc/middle/mem_categorization.rs
index dc5874ea2cfa..fe465db1312c 100644
--- a/src/rustc/middle/mem_categorization.rs
+++ b/src/rustc/middle/mem_categorization.rs
@@ -523,6 +523,9 @@ impl &mem_categorization_ctxt {
             // m: mutability of the argument
             // lp: loan path, must be none for aliasable things
             let {m,lp} = match ty::resolved_mode(self.tcx, mode) {
+              ast::by_mutbl_ref => {
+                {m: m_mutbl, lp: None}
+              }
               ast::by_move | ast::by_copy => {
                 {m: m_imm, lp: Some(@lp_arg(vid))}
               }
diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs
index 368a523306e0..ce596586ddc4 100644
--- a/src/rustc/middle/trans/base.rs
+++ b/src/rustc/middle/trans/base.rs
@@ -1503,7 +1503,7 @@ fn copy_args_to_allocas(fcx: fn_ctxt,
         // the event it's not truly needed.
         let llarg;
         match ty::resolved_mode(tcx, arg_ty.mode) {
-            ast::by_ref => {
+            ast::by_ref | ast::by_mutbl_ref => {
                 llarg = raw_llarg;
             }
             ast::by_move | ast::by_copy => {
diff --git a/src/rustc/middle/trans/callee.rs b/src/rustc/middle/trans/callee.rs
index c851c5bc7250..e7b4dd171e31 100644
--- a/src/rustc/middle/trans/callee.rs
+++ b/src/rustc/middle/trans/callee.rs
@@ -592,7 +592,7 @@ fn trans_arg_expr(bcx: block,
             DoAutorefArg => { val = arg_datum.to_ref_llval(bcx); }
             DontAutorefArg => {
                 match arg_mode {
-                    ast::by_ref => {
+                    ast::by_ref | ast::by_mutbl_ref => {
                         val = arg_datum.to_ref_llval(bcx);
                     }
 
diff --git a/src/rustc/middle/trans/reflect.rs b/src/rustc/middle/trans/reflect.rs
index ef1cc15f5c0e..cdd11ee85c57 100644
--- a/src/rustc/middle/trans/reflect.rs
+++ b/src/rustc/middle/trans/reflect.rs
@@ -208,6 +208,7 @@ impl reflector {
                   ast::expl(e) => match e {
                     ast::by_ref => 1u,
                     ast::by_val => 2u,
+                    ast::by_mutbl_ref => 3u,
                     ast::by_move => 4u,
                     ast::by_copy => 5u
                   }
diff --git a/src/rustc/middle/trans/shape.rs b/src/rustc/middle/trans/shape.rs
index e7dfac42becc..cf58b5b51c4c 100644
--- a/src/rustc/middle/trans/shape.rs
+++ b/src/rustc/middle/trans/shape.rs
@@ -49,12 +49,12 @@ fn mk_ctxt(llmod: ModuleRef) -> ctxt {
     return {mut next_tag_id: 0u16, pad: 0u16, pad2: 0u32};
 }
 
-fn add_u16(dest: &mut ~[u8], val: u16) {
-    *dest += ~[(val & 0xffu16) as u8, (val >> 8u16) as u8];
+fn add_u16(&dest: ~[u8], val: u16) {
+    dest += ~[(val & 0xffu16) as u8, (val >> 8u16) as u8];
 }
 
-fn add_substr(dest: &mut ~[u8], src: ~[u8]) {
+fn add_substr(&dest: ~[u8], src: ~[u8]) {
     add_u16(dest, vec::len(src) as u16);
-    *dest += src;
+    dest += src;
 }
 
diff --git a/src/rustc/middle/trans/type_use.rs b/src/rustc/middle/trans/type_use.rs
index 9140ea94e9ca..6bd3c22f626a 100644
--- a/src/rustc/middle/trans/type_use.rs
+++ b/src/rustc/middle/trans/type_use.rs
@@ -53,7 +53,7 @@ fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint)
                     by_val | by_move | by_copy => {
                         type_needs(cx, use_repr, arg.ty);
                     }
-                    by_ref => {}
+                    by_ref | by_mutbl_ref => {}
                 }
             }
         }
diff --git a/src/rustc/middle/trans/uniq.rs b/src/rustc/middle/trans/uniq.rs
index 50ea363ace2a..6ab91c4a1d79 100644
--- a/src/rustc/middle/trans/uniq.rs
+++ b/src/rustc/middle/trans/uniq.rs
@@ -3,6 +3,7 @@ use lib::llvm::ValueRef;
 use common::*;
 use build::*;
 use base::*;
+use shape::llsize_of;
 use datum::immediate_rvalue;
 
 export make_free_glue, autoderef, duplicate;

From 04497ea7b9b9598faa7456e7de1304e9118d2bb0 Mon Sep 17 00:00:00 2001
From: Patrick Walton 
Date: Fri, 5 Oct 2012 16:55:42 -0700
Subject: [PATCH 59/80] rustc: Implement simple uses of &trait

---
 src/rustc/metadata/encoder.rs                 | 11 +++
 src/rustc/metadata/tyencode.rs                |  1 +
 src/rustc/middle/astencode.rs                 | 11 ++-
 src/rustc/middle/privacy.rs                   |  2 +-
 src/rustc/middle/trans/common.rs              |  9 +-
 src/rustc/middle/trans/glue.rs                |  5 +-
 src/rustc/middle/trans/meth.rs                | 38 +++++---
 src/rustc/middle/trans/reflect.rs             |  4 +-
 src/rustc/middle/trans/type_of.rs             |  2 +-
 src/rustc/middle/trans/type_use.rs            |  2 +-
 src/rustc/middle/ty.rs                        | 29 ++++--
 src/rustc/middle/typeck.rs                    |  2 +-
 src/rustc/middle/typeck/astconv.rs            | 17 ++--
 src/rustc/middle/typeck/check/method.rs       | 16 ++--
 src/rustc/middle/typeck/check/regionck.rs     |  6 +-
 src/rustc/middle/typeck/check/vtable.rs       | 94 ++++++++++++++-----
 .../run-pass/trait-region-pointer-simple.rs   | 21 +++++
 17 files changed, 201 insertions(+), 69 deletions(-)
 create mode 100644 src/test/run-pass/trait-region-pointer-simple.rs

diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs
index 87ef3b4749c3..597640ef4109 100644
--- a/src/rustc/metadata/encoder.rs
+++ b/src/rustc/metadata/encoder.rs
@@ -34,6 +34,7 @@ export metadata_encoding_version;
 export def_to_str;
 export encode_ctxt;
 export write_type;
+export write_vstore;
 export encode_def_id;
 
 type abbrev_map = map::HashMap;
@@ -180,6 +181,16 @@ fn write_type(ecx: @encode_ctxt, ebml_w: ebml::Writer, typ: ty::t) {
     tyencode::enc_ty(ebml_w.writer, ty_str_ctxt, typ);
 }
 
+fn write_vstore(ecx: @encode_ctxt, ebml_w: ebml::Writer, vstore: ty::vstore) {
+    let ty_str_ctxt =
+        @{diag: ecx.diag,
+          ds: def_to_str,
+          tcx: ecx.tcx,
+          reachable: |a| reachable(ecx, a),
+          abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
+    tyencode::enc_vstore(ebml_w.writer, ty_str_ctxt, vstore);
+}
+
 fn encode_type(ecx: @encode_ctxt, ebml_w: ebml::Writer, typ: ty::t) {
     ebml_w.start_tag(tag_items_data_item_type);
     write_type(ecx, ebml_w, typ);
diff --git a/src/rustc/metadata/tyencode.rs b/src/rustc/metadata/tyencode.rs
index 88d83ca23f4c..611ffb598ae5 100644
--- a/src/rustc/metadata/tyencode.rs
+++ b/src/rustc/metadata/tyencode.rs
@@ -16,6 +16,7 @@ export enc_ty;
 export enc_bounds;
 export enc_mode;
 export enc_arg;
+export enc_vstore;
 
 type ctxt = {
     diag: span_handler,
diff --git a/src/rustc/middle/astencode.rs b/src/rustc/middle/astencode.rs
index 29368ae95b80..f2ee3df66106 100644
--- a/src/rustc/middle/astencode.rs
+++ b/src/rustc/middle/astencode.rs
@@ -490,8 +490,8 @@ impl method_origin: tr {
           typeck::method_param(mp) => {
             typeck::method_param({trait_id:mp.trait_id.tr(xcx),.. mp})
           }
-          typeck::method_trait(did, m) => {
-            typeck::method_trait(did.tr(xcx), m)
+          typeck::method_trait(did, m, vstore) => {
+            typeck::method_trait(did.tr(xcx), m, vstore)
           }
         }
     }
@@ -631,6 +631,7 @@ impl @e::encode_ctxt: get_ty_str_ctxt {
 trait ebml_writer_helpers {
     fn emit_arg(ecx: @e::encode_ctxt, arg: ty::arg);
     fn emit_ty(ecx: @e::encode_ctxt, ty: ty::t);
+    fn emit_vstore(ecx: @e::encode_ctxt, vstore: ty::vstore);
     fn emit_tys(ecx: @e::encode_ctxt, tys: ~[ty::t]);
     fn emit_bounds(ecx: @e::encode_ctxt, bs: ty::param_bounds);
     fn emit_tpbt(ecx: @e::encode_ctxt, tpbt: ty::ty_param_bounds_and_ty);
@@ -643,6 +644,12 @@ impl ebml::Writer: ebml_writer_helpers {
         }
     }
 
+    fn emit_vstore(ecx: @e::encode_ctxt, vstore: ty::vstore) {
+        do self.emit_opaque {
+            e::write_vstore(ecx, self, vstore)
+        }
+    }
+
     fn emit_arg(ecx: @e::encode_ctxt, arg: ty::arg) {
         do self.emit_opaque {
             tyencode::enc_arg(self.writer, ecx.ty_str_ctxt(), arg);
diff --git a/src/rustc/middle/privacy.rs b/src/rustc/middle/privacy.rs
index 4d291ceb590d..f15ace40d309 100644
--- a/src/rustc/middle/privacy.rs
+++ b/src/rustc/middle/privacy.rs
@@ -81,7 +81,7 @@ fn check_crate(tcx: ty::ctxt, method_map: &method_map, crate: @ast::crate) {
                 }
             }
             method_param({trait_id: trait_id, method_num: method_num, _}) |
-            method_trait(trait_id, method_num) => {
+            method_trait(trait_id, method_num, _) => {
                 if trait_id.crate == local_crate {
                     match tcx.items.find(trait_id.node) {
                         Some(node_item(item, _)) => {
diff --git a/src/rustc/middle/trans/common.rs b/src/rustc/middle/trans/common.rs
index 6768f3e71a0d..68e957bfe709 100644
--- a/src/rustc/middle/trans/common.rs
+++ b/src/rustc/middle/trans/common.rs
@@ -963,8 +963,13 @@ fn T_captured_tydescs(cx: @crate_ctxt, n: uint) -> TypeRef {
     return T_struct(vec::from_elem::(n, T_ptr(cx.tydesc_type)));
 }
 
-fn T_opaque_trait(cx: @crate_ctxt) -> TypeRef {
-    T_struct(~[T_ptr(cx.tydesc_type), T_opaque_box_ptr(cx)])
+fn T_opaque_trait(cx: @crate_ctxt, vstore: ty::vstore) -> TypeRef {
+    match vstore {
+        ty::vstore_box =>
+            T_struct(~[T_ptr(cx.tydesc_type), T_opaque_box_ptr(cx)]),
+        _ =>
+            T_struct(~[T_ptr(cx.tydesc_type), T_ptr(T_i8())])
+    }
 }
 
 fn T_opaque_port_ptr() -> TypeRef { return T_ptr(T_i8()); }
diff --git a/src/rustc/middle/trans/glue.rs b/src/rustc/middle/trans/glue.rs
index a8a750cd4be4..d60a5a0bd7df 100644
--- a/src/rustc/middle/trans/glue.rs
+++ b/src/rustc/middle/trans/glue.rs
@@ -477,10 +477,13 @@ fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) {
       ty::ty_fn(_) => {
         closure::make_fn_glue(bcx, v0, t, drop_ty)
       }
-      ty::ty_trait(_, _, _) => {
+      ty::ty_trait(_, _, ty::vstore_box) => {
         let llbox = Load(bcx, GEPi(bcx, v0, [0u, 1u]));
         decr_refcnt_maybe_free(bcx, llbox, ty::mk_opaque_box(ccx.tcx))
       }
+      ty::ty_trait(_, _, ty::vstore_uniq) => {
+        ccx.tcx.sess.unimpl(~"drop of unique trait");
+      }
       ty::ty_opaque_closure_ptr(ck) => {
         closure::make_opaque_cbox_drop_glue(bcx, ck, v0)
       }
diff --git a/src/rustc/middle/trans/meth.rs b/src/rustc/middle/trans/meth.rs
index a94519306a48..6710a64054db 100644
--- a/src/rustc/middle/trans/meth.rs
+++ b/src/rustc/middle/trans/meth.rs
@@ -142,8 +142,8 @@ fn trans_method_callee(bcx: block, callee_id: ast::node_id,
                 None => fail ~"trans_method_callee: missing param_substs"
             }
         }
-        typeck::method_trait(_, off) => {
-            trans_trait_callee(bcx, callee_id, off, self)
+        typeck::method_trait(_, off, vstore) => {
+            trans_trait_callee(bcx, callee_id, off, self, vstore)
         }
     }
 }
@@ -288,8 +288,8 @@ fn trans_monomorphized_callee(bcx: block,
               })
           }
       }
-      typeck::vtable_trait(*) => {
-          trans_trait_callee(bcx, callee_id, n_method, base)
+      typeck::vtable_trait(_, _) => {
+          trans_trait_callee(bcx, callee_id, n_method, base, ty::vstore_box)
       }
       typeck::vtable_param(*) => {
           fail ~"vtable_param left in monomorphized function's vtable substs";
@@ -390,7 +390,8 @@ fn combine_impl_and_methods_origins(bcx: block,
 fn trans_trait_callee(bcx: block,
                       callee_id: ast::node_id,
                       n_method: uint,
-                      self_expr: @ast::expr)
+                      self_expr: @ast::expr,
+                      vstore: ty::vstore)
     -> Callee
 {
     //!
@@ -398,8 +399,8 @@ fn trans_trait_callee(bcx: block,
     // Create a method callee where the method is coming from a trait
     // instance (e.g., @Trait type).  In this case, we must pull the
     // fn pointer out of the vtable that is packaged up with the
-    // @Trait instance.  @Traits are represented as a pair, so we first
-    // evaluate the self expression (expected a by-ref result) and then
+    // @/~/&Trait instance.  @/~/&Traits are represented as a pair, so we
+    // first evaluate the self expression (expected a by-ref result) and then
     // extract the self data and vtable out of the pair.
 
     let _icx = bcx.insn_ctxt("impl::trans_trait_callee");
@@ -407,13 +408,14 @@ fn trans_trait_callee(bcx: block,
     let self_datum = unpack_datum!(bcx, expr::trans_to_datum(bcx, self_expr));
     let llpair = self_datum.to_ref_llval(bcx);
     let callee_ty = node_id_type(bcx, callee_id);
-    trans_trait_callee_from_llval(bcx, callee_ty, n_method, llpair)
+    trans_trait_callee_from_llval(bcx, callee_ty, n_method, llpair, vstore)
 }
 
 fn trans_trait_callee_from_llval(bcx: block,
                                  callee_ty: ty::t,
                                  n_method: uint,
-                                 llpair: ValueRef)
+                                 llpair: ValueRef,
+                                 vstore: ty::vstore)
     -> Callee
 {
     //!
@@ -431,9 +433,21 @@ fn trans_trait_callee_from_llval(bcx: block,
                                   GEPi(bcx, llpair, [0u, 0u]),
                                   T_ptr(T_ptr(T_vtable()))));
 
-    // Load the box from the @Trait pair and GEP over the box header:
+    // Load the box from the @Trait pair and GEP over the box header if
+    // necessary:
+    let llself;
     let llbox = Load(bcx, GEPi(bcx, llpair, [0u, 1u]));
-    let llself = GEPi(bcx, llbox, [0u, abi::box_field_body]);
+    match vstore {
+        ty::vstore_box | ty::vstore_uniq => {
+            llself = GEPi(bcx, llbox, [0u, abi::box_field_body]);
+        }
+        ty::vstore_slice(_) => {
+            llself = llbox;
+        }
+        ty::vstore_fixed(*) => {
+            bcx.tcx().sess.bug(~"vstore_fixed trait");
+        }
+    }
 
     // Load the function from the vtable and cast it to the expected type.
     let llcallee_ty = type_of::type_of_fn_from_ty(ccx, callee_ty);
@@ -503,7 +517,7 @@ fn make_impl_vtable(ccx: @crate_ctxt, impl_id: ast::def_id, substs: ~[ty::t],
     // XXX: This should support multiple traits.
     let trt_id = driver::session::expect(
         tcx.sess,
-        ty::ty_to_def_id(ty::impl_traits(tcx, impl_id)[0]),
+        ty::ty_to_def_id(ty::impl_traits(tcx, impl_id, ty::vstore_box)[0]),
         || ~"make_impl_vtable: non-trait-type implemented");
 
     let has_tps = (*ty::lookup_item_type(ccx.tcx, impl_id).bounds).len() > 0u;
diff --git a/src/rustc/middle/trans/reflect.rs b/src/rustc/middle/trans/reflect.rs
index cdd11ee85c57..3996f0ff5ee2 100644
--- a/src/rustc/middle/trans/reflect.rs
+++ b/src/rustc/middle/trans/reflect.rs
@@ -70,10 +70,12 @@ impl reflector {
         }
         let bool_ty = ty::mk_bool(tcx);
         let scratch = scratch_datum(bcx, bool_ty, false);
+        // XXX: Should not be vstore_box!
         let bcx = callee::trans_call_inner(
             self.bcx, None, mth_ty, bool_ty,
             |bcx| meth::trans_trait_callee_from_llval(bcx, mth_ty,
-                                                      mth_idx, v),
+                                                      mth_idx, v,
+                                                      ty::vstore_box),
             ArgVals(args), SaveIn(scratch.val), DontAutorefArg);
         let result = scratch.to_value_llval(bcx);
         let next_bcx = sub_block(bcx, ~"next");
diff --git a/src/rustc/middle/trans/type_of.rs b/src/rustc/middle/trans/type_of.rs
index b45da3b27004..7b5a912ed7f2 100644
--- a/src/rustc/middle/trans/type_of.rs
+++ b/src/rustc/middle/trans/type_of.rs
@@ -159,7 +159,7 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
         T_struct(~[T_struct(tys)])
       }
       ty::ty_fn(_) => T_fn_pair(cx, type_of_fn_from_ty(cx, t)),
-      ty::ty_trait(_, _, _) => T_opaque_trait(cx),
+      ty::ty_trait(_, _, vstore) => T_opaque_trait(cx, vstore),
       ty::ty_type => T_ptr(cx.tydesc_type),
       ty::ty_tup(elts) => {
         let mut tys = ~[];
diff --git a/src/rustc/middle/trans/type_use.rs b/src/rustc/middle/trans/type_use.rs
index 6bd3c22f626a..8bd5bd7afc78 100644
--- a/src/rustc/middle/trans/type_use.rs
+++ b/src/rustc/middle/trans/type_use.rs
@@ -247,7 +247,7 @@ fn mark_for_expr(cx: ctx, e: @expr) {
               typeck::method_param({param_num: param, _}) => {
                 cx.uses[param] |= use_tydesc;
               }
-              typeck::method_trait(_, _) => (),
+              typeck::method_trait(*) => (),
             }
         }
       }
diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs
index 109db9ace099..78949ec5f794 100644
--- a/src/rustc/middle/ty.rs
+++ b/src/rustc/middle/ty.rs
@@ -90,6 +90,7 @@ export ty_estr, mk_estr, type_is_str;
 export ty_evec, mk_evec, type_is_vec;
 export ty_unboxed_vec, mk_unboxed_vec, mk_mut_unboxed_vec;
 export vstore, vstore_fixed, vstore_uniq, vstore_box, vstore_slice;
+export serialize_vstore, deserialize_vstore;
 export ty_nil, mk_nil, type_is_nil;
 export ty_trait, mk_trait;
 export ty_param, mk_param, ty_params_to_tys;
@@ -217,6 +218,7 @@ type method = {ident: ast::ident,
 
 type mt = {ty: t, mutbl: ast::mutability};
 
+#[auto_serialize]
 enum vstore {
     vstore_fixed(uint),
     vstore_uniq,
@@ -1624,7 +1626,10 @@ fn type_needs_drop(cx: ctxt, ty: t) -> bool {
       ty_evec(_, vstore_uniq) |
       ty_evec(_, vstore_box) => true,
 
-      ty_trait(*) => true,
+      ty_trait(_, _, vstore_box) |
+      ty_trait(_, _, vstore_uniq) => true,
+      ty_trait(_, _, vstore_fixed(_)) |
+      ty_trait(_, _, vstore_slice(_)) => false,
 
       ty_param(*) | ty_infer(*) => true,
 
@@ -2821,7 +2826,7 @@ fn method_call_bounds(tcx: ctxt, method_map: typeck::method_map,
           }
           typeck::method_param({trait_id:trt_id,
                                 method_num:n_mth, _}) |
-          typeck::method_trait(trt_id, n_mth) => {
+          typeck::method_trait(trt_id, n_mth, _) => {
             // ...trait methods bounds, in contrast, include only the
             // method bounds, so we must preprend the tps from the
             // trait itself.  This ought to be harmonized.
@@ -3362,7 +3367,15 @@ fn trait_methods(cx: ctxt, id: ast::def_id) -> @~[method] {
 /*
   Could this return a list of (def_id, substs) pairs?
  */
-fn impl_traits(cx: ctxt, id: ast::def_id) -> ~[t] {
+fn impl_traits(cx: ctxt, id: ast::def_id, vstore: vstore) -> ~[t] {
+    fn vstoreify(cx: ctxt, ty: t, vstore: vstore) -> t {
+        match ty::get(ty).sty {
+            ty::ty_trait(_, _, trait_vstore) if vstore == trait_vstore => ty,
+            ty::ty_trait(did, substs, _) => mk_trait(cx, did, substs, vstore),
+            _ => cx.sess.bug(~"impl_traits: not a trait")
+        }
+    }
+
     if id.crate == ast::local_crate {
         debug!("(impl_traits) searching for trait impl %?", id);
         match cx.items.find(id.node) {
@@ -3372,19 +3385,23 @@ fn impl_traits(cx: ctxt, id: ast::def_id) -> ~[t] {
                     _)) => {
 
                do option::map_default(&opt_trait, ~[]) |trait_ref| {
-                       ~[node_id_to_type(cx, trait_ref.ref_id)]
+                       ~[vstoreify(cx,
+                                   node_id_to_type(cx, trait_ref.ref_id),
+                                   vstore)]
                    }
            }
            Some(ast_map::node_item(@{node: ast::item_class(sd,_),
                            _},_)) => {
                do vec::map(sd.traits) |trait_ref| {
-                    node_id_to_type(cx, trait_ref.ref_id)
+                    vstoreify(cx, node_id_to_type(cx, trait_ref.ref_id),
+                              vstore)
                 }
            }
            _ => ~[]
         }
     } else {
-        csearch::get_impl_traits(cx, id)
+        vec::map(csearch::get_impl_traits(cx, id),
+                 |x| vstoreify(cx, *x, vstore))
     }
 }
 
diff --git a/src/rustc/middle/typeck.rs b/src/rustc/middle/typeck.rs
index 3a9471139f96..6c461126853f 100644
--- a/src/rustc/middle/typeck.rs
+++ b/src/rustc/middle/typeck.rs
@@ -86,7 +86,7 @@ enum method_origin {
     method_param(method_param),
 
     // method invoked on a trait instance
-    method_trait(ast::def_id, uint),
+    method_trait(ast::def_id, uint, ty::vstore),
 }
 
 // details for a method invoked with a receiver whose type is a type parameter
diff --git a/src/rustc/middle/typeck/astconv.rs b/src/rustc/middle/typeck/astconv.rs
index 45a7c22e2f90..14797fcdd6bb 100644
--- a/src/rustc/middle/typeck/astconv.rs
+++ b/src/rustc/middle/typeck/astconv.rs
@@ -189,16 +189,19 @@ fn ast_ty_to_ty(
                                                        type_def_id, path);
                 match ty::get(result.ty).sty {
                     ty::ty_trait(trait_def_id, substs, _) => {
-                        if vst != ty::vstore_box {
-                            tcx.sess.span_unimpl(path.span,
-                                                 ~"`~trait` and `&trait` are \
-                                                   unimplemented; use \
-                                                   `@trait` instead for now");
+                        match vst {
+                            ty::vstore_box | ty::vstore_slice(*) => {}
+                            _ => {
+                                tcx.sess.span_unimpl(path.span,
+                                                     ~"`~trait` is \
+                                                       unimplemented; use \
+                                                       `@trait` instead for \
+                                                       now");
+                            }
                         }
                         return ty::mk_trait(tcx, trait_def_id, substs, vst);
                     }
-                    _ =>
-                        {}
+                    _ => {}
                 }
               }
               _ => ()
diff --git a/src/rustc/middle/typeck/check/method.rs b/src/rustc/middle/typeck/check/method.rs
index d08d3e9b8478..d55f9facc626 100644
--- a/src/rustc/middle/typeck/check/method.rs
+++ b/src/rustc/middle/typeck/check/method.rs
@@ -221,9 +221,9 @@ impl LookupContext {
                 ty_param(p) => {
                     self.push_inherent_candidates_from_param(p);
                 }
-                ty_trait(did, ref substs, _) => {
+                ty_trait(did, ref substs, vstore) => {
                     self.push_inherent_candidates_from_trait(
-                        self_ty, did, substs);
+                        self_ty, did, substs, vstore);
                     self.push_inherent_impl_candidates_for_type(did);
                 }
                 ty_self => {
@@ -233,7 +233,8 @@ impl LookupContext {
                         ~"unexpected `none` for self_impl_def_id");
                     let substs = {self_r: None, self_ty: None, tps: ~[]};
                     self.push_inherent_candidates_from_trait(
-                        self_ty, self_did, &substs);
+                        self_ty, self_did, &substs,
+                        ty::vstore_slice(ty::re_static));   // XXX: Wrong!
                 }
                 ty_enum(did, _) | ty_class(did, _) => {
                     self.push_inherent_impl_candidates_for_type(did);
@@ -347,7 +348,8 @@ impl LookupContext {
     fn push_inherent_candidates_from_trait(&self,
                                            self_ty: ty::t,
                                            did: def_id,
-                                           substs: &ty::substs)
+                                           substs: &ty::substs,
+                                           vstore: ty::vstore)
     {
         debug!("push_inherent_candidates_from_trait(did=%s, substs=%s)",
                self.did_to_str(did),
@@ -391,7 +393,7 @@ impl LookupContext {
             rcvr_substs: move rcvr_substs,
             num_method_tps: method.tps.len(),
             self_mode: get_mode_from_self_type(method.self_ty),
-            origin: method_trait(did, index)
+            origin: method_trait(did, index, vstore)
         });
     }
 
@@ -770,7 +772,7 @@ impl LookupContext {
             method_param(ref mp) => {
                 type_of_trait_method(self.tcx(), mp.trait_id, mp.method_num)
             }
-            method_trait(did, idx) => {
+            method_trait(did, idx, _) => {
                 type_of_trait_method(self.tcx(), did, idx)
             }
         };
@@ -791,7 +793,7 @@ impl LookupContext {
             method_param(mp) => {
                 self.report_param_candidate(idx, mp.trait_id)
             }
-            method_trait(trait_did, _) => {
+            method_trait(trait_did, _, _) => {
                 self.report_param_candidate(idx, trait_did)
             }
         }
diff --git a/src/rustc/middle/typeck/check/regionck.rs b/src/rustc/middle/typeck/check/regionck.rs
index d8ea330ee11f..0b258da5672d 100644
--- a/src/rustc/middle/typeck/check/regionck.rs
+++ b/src/rustc/middle/typeck/check/regionck.rs
@@ -221,11 +221,7 @@ fn visit_expr(expr: @ast::expr, &&rcx: @rcx, v: rvt) {
                 result::Err(_) => { return; /*typeck will fail anyhow*/ }
                 result::Ok(target_ty) => {
                     match ty::get(target_ty).sty {
-                        ty::ty_trait(_, substs, _) => {
-                            let trait_region = match substs.self_r {
-                                Some(r) => {r}
-                                None => {ty::re_static}
-                            };
+                        ty::ty_trait(_, _, vstore_slice(trait_region)) => {
                             let source_ty = rcx.fcx.expr_ty(source);
                             constrain_regions_in_type(rcx, trait_region,
                                                       expr.span, source_ty);
diff --git a/src/rustc/middle/typeck/check/vtable.rs b/src/rustc/middle/typeck/check/vtable.rs
index e8926468b3a8..00fb134f2be5 100644
--- a/src/rustc/middle/typeck/check/vtable.rs
+++ b/src/rustc/middle/typeck/check/vtable.rs
@@ -156,8 +156,8 @@ fn lookup_vtable_invariant(fcx: @fn_ctxt,
     let _i = indenter();
 
     let tcx = fcx.ccx.tcx;
-    let (trait_id, trait_substs) = match ty::get(trait_ty).sty {
-        ty::ty_trait(did, substs, _) => (did, substs),
+    let (trait_id, trait_substs, trait_vstore) = match ty::get(trait_ty).sty {
+        ty::ty_trait(did, substs, vstore) => (did, substs, vstore),
         _ => tcx.sess.impossible_case(expr.span,
                                       "lookup_vtable_invariant: \
                                        don't know how to handle a non-trait")
@@ -270,7 +270,8 @@ fn lookup_vtable_invariant(fcx: @fn_ctxt,
                         // it's the same trait as trait_ty, we need to
                         // unify it with trait_ty in order to get all
                         // the ty vars sorted out.
-                        for vec::each(ty::impl_traits(tcx, im.did)) |of_ty| {
+                        for vec::each(ty::impl_traits(tcx, im.did,
+                                                      trait_vstore)) |of_ty| {
                             match ty::get(*of_ty).sty {
                                 ty::ty_trait(id, _, _) => {
                                     // Not the trait we're looking for
@@ -378,7 +379,8 @@ fn lookup_vtable_invariant(fcx: @fn_ctxt,
                             // lists of types to unify pairwise.
 
                             connect_trait_tps(fcx, expr, substs_f.tps,
-                                              trait_tps, im.did);
+                                              trait_tps, im.did,
+                                              trait_vstore);
                             let subres = lookup_vtables(
                                 fcx, expr, im_bs, &substs_f,
                                 false, is_early);
@@ -436,11 +438,12 @@ fn fixup_ty(fcx: @fn_ctxt,
 }
 
 fn connect_trait_tps(fcx: @fn_ctxt, expr: @ast::expr, impl_tys: ~[ty::t],
-                     trait_tys: ~[ty::t], impl_did: ast::def_id) {
+                     trait_tys: ~[ty::t], impl_did: ast::def_id,
+                     vstore: ty::vstore) {
     let tcx = fcx.ccx.tcx;
 
     // XXX: This should work for multiple traits.
-    let ity = ty::impl_traits(tcx, impl_did)[0];
+    let ity = ty::impl_traits(tcx, impl_did, vstore)[0];
     let trait_ty = ty::subst_tps(tcx, impl_tys, ity);
     debug!("(connect trait tps) trait type is %?, impl did is %?",
            ty::get(trait_ty).sty, impl_did);
@@ -508,7 +511,7 @@ fn early_resolve_expr(ex: @ast::expr, &&fcx: @fn_ctxt, is_early: bool) {
       ast::expr_cast(src, _) => {
         let target_ty = fcx.expr_ty(ex);
         match ty::get(target_ty).sty {
-          ty::ty_trait(*) => {
+          ty::ty_trait(_, _, vstore) => {
             // Look up vtables for the type we're casting to, passing in the
             // source and target type.
             //
@@ -520,26 +523,73 @@ fn early_resolve_expr(ex: @ast::expr, &&fcx: @fn_ctxt, is_early: bool) {
             match vtable_opt {
                 None => {
                     // Try the new-style boxed trait; "@int as @Trait".
+                    // Or the new-style region trait; "&int as &Trait".
                     let mut err = false;
                     let ty = structurally_resolved_type(fcx, ex.span, ty);
                     match ty::get(ty).sty {
-                        ty::ty_box(boxed_ty) => {
-                            let vtable_opt =
-                                lookup_vtable_invariant(fcx, ex, boxed_ty.ty,
-                                                        target_ty, true,
-                                                        is_early);
-                            match vtable_opt {
-                                Some(vtable) => {
-                                    /*
-                                    Map this expression to that vtable (that
-                                    is: "ex has vtable ")
-                                    */
-                                    if !is_early {
-                                        cx.vtable_map.insert(ex.id,
-                                                             @~[vtable]);
+                        ty::ty_box(mt) | ty::ty_rptr(_, mt) => {
+                            // Ensure that the trait vstore and the pointer
+                            // type match.
+                            match (ty::get(ty).sty, vstore) {
+                                (ty::ty_box(_), ty::vstore_box) |
+                                (ty::ty_rptr(*), ty::vstore_slice(*)) => {
+                                    let vtable_opt =
+                                        lookup_vtable_invariant(fcx,
+                                                                ex,
+                                                                mt.ty,
+                                                                target_ty,
+                                                                true,
+                                                                is_early);
+                                    match vtable_opt {
+                                        Some(vtable) => {
+                                            // Map this expression to that
+                                            // vtable (that is: "ex has vtable
+                                            // ")
+                                            if !is_early {
+                                                cx.vtable_map.insert(
+                                                    ex.id, @~[vtable]);
+                                            }
+                                        }
+                                        None => err = true
+                                    }
+
+                                    // Now, if this is &trait, we need to link
+                                    // the regions.
+                                    match (ty::get(ty).sty, vstore) {
+                                        (ty::ty_rptr(ra, _),
+                                         ty::vstore_slice(rb)) => {
+                                            infer::mk_subr(fcx.infcx(),
+                                                           false,
+                                                           ex.span,
+                                                           rb,
+                                                           ra);
+                                        }
+                                        _ => {}
                                     }
                                 }
-                                None => err = true
+                                (ty::ty_box(_), _) => {
+                                    fcx.ccx.tcx.sess.span_err(ex.span,
+                                                              ~"must cast \
+                                                                a boxed \
+                                                                pointer to \
+                                                                a boxed
+                                                                trait");
+                                    err = true;
+                                }
+                                (ty::ty_rptr(*), _) => {
+                                    fcx.ccx.tcx.sess.span_err(ex.span,
+                                                              ~"must cast \
+                                                                a borrowed \
+                                                                pointer to \
+                                                                a borrowed \
+                                                                trait");
+                                }
+                                _ => {
+                                    fcx.ccx.tcx.sess.impossible_case(
+                                        ex.span,
+                                        ~"impossible combination of type and \
+                                          trait vstore");
+                                }
                             }
                         }
                         _ => err = true
diff --git a/src/test/run-pass/trait-region-pointer-simple.rs b/src/test/run-pass/trait-region-pointer-simple.rs
new file mode 100644
index 000000000000..dfcbfc3993f1
--- /dev/null
+++ b/src/test/run-pass/trait-region-pointer-simple.rs
@@ -0,0 +1,21 @@
+trait Foo {
+    fn f() -> int;
+}
+
+struct A {
+    x: int
+}
+
+impl A : Foo {
+    fn f() -> int {
+        io::println(~"Today's number is " + self.x.to_str());
+        return self.x;
+    }
+}
+
+fn main() {
+    let a = A { x: 3 };
+    let b = (&a) as &Foo;
+    assert b.f() == 3;
+}
+

From 45345bda6ab439599838bbf3df0c524d86c8da2a Mon Sep 17 00:00:00 2001
From: Tim Chevalier 
Date: Fri, 5 Oct 2012 16:17:10 -0700
Subject: [PATCH 60/80] Remove uses of mutable ref mode.

It's still in the compiler right now, but warned about
---
 src/libcore/cmath.rs                     | 16 ++++++-------
 src/libstd/time.rs                       | 30 +++++++++++++++++++++++-
 src/libsyntax/parse/comments.rs          | 28 +++++++++++-----------
 src/libsyntax/parse/eval.rs              | 10 ++++----
 src/libsyntax/parse/parser.rs            |  6 +++--
 src/libsyntax/parse/token.rs             |  2 +-
 src/rustc/metadata/encoder.rs            |  2 +-
 src/rustc/middle/borrowck.rs             |  6 ++---
 src/rustc/middle/borrowck/check_loans.rs |  8 +++----
 src/rustc/middle/liveness.rs             |  8 +++----
 src/rustc/middle/trans/uniq.rs           |  1 -
 11 files changed, 73 insertions(+), 44 deletions(-)

diff --git a/src/libcore/cmath.rs b/src/libcore/cmath.rs
index 9a9a7cb31121..b0aeb78afaa8 100644
--- a/src/libcore/cmath.rs
+++ b/src/libcore/cmath.rs
@@ -40,15 +40,15 @@ pub extern mod c_double {
     #[link_name="fmax"] pure fn fmax(a: c_double, b: c_double) -> c_double;
     #[link_name="fmin"] pure fn fmin(a: c_double, b: c_double) -> c_double;
     pure fn nextafter(x: c_double, y: c_double) -> c_double;
-    pure fn frexp(n: c_double, &value: c_int) -> c_double;
+    pure fn frexp(n: c_double, value: &mut c_int) -> c_double;
     pure fn hypot(x: c_double, y: c_double) -> c_double;
     pure fn ldexp(x: c_double, n: c_int) -> c_double;
     #[cfg(unix)]
     #[link_name="lgamma_r"] pure fn lgamma(n: c_double,
-                                           &sign: c_int) -> c_double;
+                                           sign: &mut c_int) -> c_double;
     #[cfg(windows)]
     #[link_name="__lgamma_r"] pure fn lgamma(n: c_double,
-                                             &sign: c_int) -> c_double;
+                                             sign: &mut c_int) -> c_double;
     // renamed: log is a reserved keyword; ln seems more natural, too
     #[link_name="log"] pure fn ln(n: c_double) -> c_double;
     // renamed: "logb" /often/ is confused for log2 by beginners
@@ -58,7 +58,7 @@ pub extern mod c_double {
     pure fn log10(n: c_double) -> c_double;
     pure fn log2(n: c_double) -> c_double;
     #[link_name="ilogb"] pure fn ilog_radix(n: c_double) -> c_int;
-    pure fn modf(n: c_double, &iptr: c_double) -> c_double;
+    pure fn modf(n: c_double, iptr: &mut c_double) -> c_double;
     pure fn pow(n: c_double, e: c_double) -> c_double;
 // FIXME (#1379): enable when rounding modes become available
 //    pure fn rint(n: c_double) -> c_double;
@@ -110,7 +110,7 @@ pub extern mod c_float {
     #[link_name="fdimf"] pure fn abs_sub(a: c_float, b: c_float) -> c_float;
     #[link_name="floorf"] pure fn floor(n: c_float) -> c_float;
     #[link_name="frexpf"] pure fn frexp(n: c_float,
-                                        &value: c_int) -> c_float;
+                                        value: &mut c_int) -> c_float;
     #[link_name="fmaf"] pure fn mul_add(a: c_float,
                                         b: c_float, c: c_float) -> c_float;
     #[link_name="fmaxf"] pure fn fmax(a: c_float, b: c_float) -> c_float;
@@ -122,11 +122,11 @@ pub extern mod c_float {
 
     #[cfg(unix)]
     #[link_name="lgammaf_r"] pure fn lgamma(n: c_float,
-                                            &sign: c_int) -> c_float;
+                                            sign: &mut c_int) -> c_float;
 
     #[cfg(windows)]
     #[link_name="__lgammaf_r"] pure fn lgamma(n: c_float,
-                                              &sign: c_int) -> c_float;
+                                              sign: &mut c_int) -> c_float;
 
     #[link_name="logf"] pure fn ln(n: c_float) -> c_float;
     #[link_name="logbf"] pure fn log_radix(n: c_float) -> c_float;
@@ -135,7 +135,7 @@ pub extern mod c_float {
     #[link_name="log10f"] pure fn log10(n: c_float) -> c_float;
     #[link_name="ilogbf"] pure fn ilog_radix(n: c_float) -> c_int;
     #[link_name="modff"] pure fn modf(n: c_float,
-                                      &iptr: c_float) -> c_float;
+                                      iptr: &mut c_float) -> c_float;
     #[link_name="powf"] pure fn pow(n: c_float, e: c_float) -> c_float;
 // FIXME (#1379): enable when rounding modes become available
 //    #[link_name="rintf"] pure fn rint(n: c_float) -> c_float;
diff --git a/src/libstd/time.rs b/src/libstd/time.rs
index 627a3b8eeae0..8fa1e0cf3f0a 100644
--- a/src/libstd/time.rs
+++ b/src/libstd/time.rs
@@ -7,9 +7,18 @@ use result::{Result, Ok, Err};
 
 #[abi = "cdecl"]
 extern mod rustrt {
-    #[legacy_exports];
+    #[legacy_exports]
+    #[cfg(stage0)]
     fn get_time(&sec: i64, &nsec: i32);
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    fn get_time(sec: &mut i64, nsec: &mut i32);
+
+    #[cfg(stage0)]
     fn precise_time_ns(&ns: u64);
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    fn precise_time_ns(ns: &mut u64);
 
     fn rust_tzset();
     // FIXME: The i64 values can be passed by-val when #2064 is fixed.
@@ -33,22 +42,41 @@ impl Timespec : Eq {
  * Returns the current time as a `timespec` containing the seconds and
  * nanoseconds since 1970-01-01T00:00:00Z.
  */
+#[cfg(stage0)]
 pub fn get_time() -> Timespec {
     let mut sec = 0i64;
     let mut nsec = 0i32;
     rustrt::get_time(sec, nsec);
     return {sec: sec, nsec: nsec};
 }
+#[cfg(stage1)]
+#[cfg(stage2)]
+pub fn get_time() -> Timespec {
+    let mut sec = 0i64;
+    let mut nsec = 0i32;
+    rustrt::get_time(&mut sec, &mut nsec);
+    return {sec: sec, nsec: nsec};
+}
+
 
 /**
  * Returns the current value of a high-resolution performance counter
  * in nanoseconds since an unspecified epoch.
  */
+#[cfg(stage0)]
 pub fn precise_time_ns() -> u64 {
     let mut ns = 0u64;
     rustrt::precise_time_ns(ns);
     ns
 }
+#[cfg(stage1)]
+#[cfg(stage2)]
+pub fn precise_time_ns() -> u64 {
+    let mut ns = 0u64;
+    rustrt::precise_time_ns(&mut ns);
+    ns
+}
+
 
 /**
  * Returns the current value of a high-resolution performance counter
diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs
index cb8416501b37..4f265e1919c2 100644
--- a/src/libsyntax/parse/comments.rs
+++ b/src/libsyntax/parse/comments.rs
@@ -127,14 +127,14 @@ fn consume_non_eol_whitespace(rdr: string_reader) {
     }
 }
 
-fn push_blank_line_comment(rdr: string_reader, &comments: ~[cmnt]) {
+fn push_blank_line_comment(rdr: string_reader, comments: &mut ~[cmnt]) {
     debug!(">>> blank-line comment");
     let v: ~[~str] = ~[];
     comments.push({style: blank_line, lines: v, pos: rdr.chpos});
 }
 
 fn consume_whitespace_counting_blank_lines(rdr: string_reader,
-                                           &comments: ~[cmnt]) {
+                                           comments: &mut ~[cmnt]) {
     while is_whitespace(rdr.curr) && !is_eof(rdr) {
         if rdr.col == 0u && rdr.curr == '\n' {
             push_blank_line_comment(rdr, comments);
@@ -145,7 +145,7 @@ fn consume_whitespace_counting_blank_lines(rdr: string_reader,
 
 
 fn read_shebang_comment(rdr: string_reader, code_to_the_left: bool,
-                                                        &comments: ~[cmnt]) {
+                                            comments: &mut ~[cmnt]) {
     debug!(">>> shebang comment");
     let p = rdr.chpos;
     debug!("<<< shebang comment");
@@ -157,7 +157,7 @@ fn read_shebang_comment(rdr: string_reader, code_to_the_left: bool,
 }
 
 fn read_line_comments(rdr: string_reader, code_to_the_left: bool,
-                                                        &comments: ~[cmnt]) {
+                                          comments: &mut ~[cmnt]) {
     debug!(">>> line comments");
     let p = rdr.chpos;
     let mut lines: ~[~str] = ~[];
@@ -188,8 +188,8 @@ fn all_whitespace(s: ~str, begin: uint, end: uint) -> bool {
     return true;
 }
 
-fn trim_whitespace_prefix_and_push_line(&lines: ~[~str],
-                                        s: ~str, col: uint) unsafe {
+fn trim_whitespace_prefix_and_push_line(lines: &mut ~[~str],
+                                        s: ~str, col: uint) {
     let mut s1;
     let len = str::len(s);
     if all_whitespace(s, 0u, uint::min(len, col)) {
@@ -202,7 +202,7 @@ fn trim_whitespace_prefix_and_push_line(&lines: ~[~str],
 }
 
 fn read_block_comment(rdr: string_reader, code_to_the_left: bool,
-                                                        &comments: ~[cmnt]) {
+                                          comments: &mut ~[cmnt]) {
     debug!(">>> block comment");
     let p = rdr.chpos;
     let mut lines: ~[~str] = ~[];
@@ -228,7 +228,7 @@ fn read_block_comment(rdr: string_reader, code_to_the_left: bool,
         debug!("=== block comment level %d", level);
         if is_eof(rdr) {(rdr as reader).fatal(~"unterminated block comment");}
         if rdr.curr == '\n' {
-            trim_whitespace_prefix_and_push_line(lines, curr_line, col);
+            trim_whitespace_prefix_and_push_line(&mut lines, curr_line, col);
             curr_line = ~"";
             bump(rdr);
         } else {
@@ -248,8 +248,8 @@ fn read_block_comment(rdr: string_reader, code_to_the_left: bool,
             }
         }
     }
-    if str::len(curr_line) != 0u {
-        trim_whitespace_prefix_and_push_line(lines, curr_line, col);
+    if str::len(curr_line) != 0 {
+        trim_whitespace_prefix_and_push_line(&mut lines, curr_line, col);
     }
     let mut style = if code_to_the_left { trailing } else { isolated };
     consume_non_eol_whitespace(rdr);
@@ -267,7 +267,7 @@ fn peeking_at_comment(rdr: string_reader) -> bool {
 }
 
 fn consume_comment(rdr: string_reader, code_to_the_left: bool,
-                   &comments: ~[cmnt]) {
+                   comments: &mut ~[cmnt]) {
     debug!(">>> consume comment");
     if rdr.curr == '/' && nextch(rdr) == '/' {
         read_line_comments(rdr, code_to_the_left, comments);
@@ -299,11 +299,11 @@ fn gather_comments_and_literals(span_diagnostic: diagnostic::span_handler,
             consume_non_eol_whitespace(rdr);
             if rdr.curr == '\n' {
                 code_to_the_left = false;
-                consume_whitespace_counting_blank_lines(rdr, comments);
+                consume_whitespace_counting_blank_lines(rdr, &mut comments);
             }
             while peeking_at_comment(rdr) {
-                consume_comment(rdr, code_to_the_left, comments);
-                consume_whitespace_counting_blank_lines(rdr, comments);
+                consume_comment(rdr, code_to_the_left, &mut comments);
+                consume_whitespace_counting_blank_lines(rdr, &mut comments);
             }
             break;
         }
diff --git a/src/libsyntax/parse/eval.rs b/src/libsyntax/parse/eval.rs
index 14dc490346eb..c91060284910 100644
--- a/src/libsyntax/parse/eval.rs
+++ b/src/libsyntax/parse/eval.rs
@@ -10,8 +10,8 @@ type ctx =
 fn eval_crate_directives(cx: ctx,
                          cdirs: ~[@ast::crate_directive],
                          prefix: &Path,
-                         &view_items: ~[@ast::view_item],
-                         &items: ~[@ast::item]) {
+                         view_items: &mut~[@ast::view_item],
+                         items: &mut~[@ast::item]) {
     for cdirs.each |sub_cdir| {
         eval_crate_directive(cx, *sub_cdir, prefix, view_items, items);
     }
@@ -24,7 +24,7 @@ fn eval_crate_directives_to_mod(cx: ctx, cdirs: ~[@ast::crate_directive],
         = parse_companion_mod(cx, prefix, suffix);
     let mut view_items: ~[@ast::view_item] = ~[];
     let mut items: ~[@ast::item] = ~[];
-    eval_crate_directives(cx, cdirs, prefix, view_items, items);
+    eval_crate_directives(cx, cdirs, prefix, &mut view_items, &mut items);
     return ({view_items: vec::append(view_items, cview_items),
           items: vec::append(items, citems)},
          cattrs);
@@ -82,8 +82,8 @@ fn cdir_path_opt(default: ~str, attrs: ~[ast::attribute]) -> ~str {
 }
 
 fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: &Path,
-                        &view_items: ~[@ast::view_item],
-                        &items: ~[@ast::item]) {
+                        view_items: &mut ~[@ast::view_item],
+                        items: &mut ~[@ast::item]) {
     match cdir.node {
       ast::cdir_src_mod(vis, id, attrs) => {
         let file_path = Path(cdir_path_opt(
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 1a87d7fed695..bc0beec5b36e 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -1276,7 +1276,8 @@ impl parser {
 
         return match self.token {
           token::LPAREN | token::LBRACE | token::LBRACKET => {
-            let ket = token::flip_delimiter(self.token);
+              // tjc: ??????
+            let ket = token::flip_delimiter(copy self.token);
             tt_delim(vec::append(
                 ~[parse_tt_tok(self, true)],
                 vec::append(
@@ -1297,7 +1298,8 @@ impl parser {
         return match self.token {
           token::LBRACE | token::LPAREN | token::LBRACKET => {
             self.parse_matcher_subseq(name_idx, copy self.token,
-                                      token::flip_delimiter(self.token))
+                                      // tjc: not sure why we need a copy
+                                      token::flip_delimiter(copy self.token))
           }
           _ => self.fatal(~"expected open delimiter")
         }
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index a328ff1bdf64..99b789cf63fc 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -230,7 +230,7 @@ pure fn can_begin_expr(t: token) -> bool {
 }
 
 /// what's the opposite delimiter?
-fn flip_delimiter(&t: token::token) -> token::token {
+fn flip_delimiter(t: token::token) -> token::token {
     match t {
       token::LPAREN => token::RPAREN,
       token::LBRACE => token::RBRACE,
diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs
index 597640ef4109..fe432edeec69 100644
--- a/src/rustc/metadata/encoder.rs
+++ b/src/rustc/metadata/encoder.rs
@@ -117,7 +117,7 @@ fn encode_mutability(ebml_w: ebml::Writer, mt: class_mutability) {
 type entry = {val: T, pos: uint};
 
 fn add_to_index(ecx: @encode_ctxt, ebml_w: ebml::Writer, path: &[ident],
-                &index: ~[entry<~str>], name: ident) {
+                index: &mut ~[entry<~str>], name: ident) {
     let mut full_path = ~[];
     full_path.push_all(path);
     full_path.push(name);
diff --git a/src/rustc/middle/borrowck.rs b/src/rustc/middle/borrowck.rs
index 414890cbd7c6..e2f7ba20642a 100644
--- a/src/rustc/middle/borrowck.rs
+++ b/src/rustc/middle/borrowck.rs
@@ -396,10 +396,10 @@ type req_maps = {
     pure_map: HashMap
 };
 
-fn save_and_restore(&save_and_restore_t: T, f: fn() -> U) -> U {
-    let old_save_and_restore_t = save_and_restore_t;
+fn save_and_restore(save_and_restore_t: &mut T, f: fn() -> U) -> U {
+    let old_save_and_restore_t = *save_and_restore_t;
     let u <- f();
-    save_and_restore_t = old_save_and_restore_t;
+    *save_and_restore_t = old_save_and_restore_t;
     move u
 }
 
diff --git a/src/rustc/middle/borrowck/check_loans.rs b/src/rustc/middle/borrowck/check_loans.rs
index 0c79c0fcd7f3..5ff2a8933a91 100644
--- a/src/rustc/middle/borrowck/check_loans.rs
+++ b/src/rustc/middle/borrowck/check_loans.rs
@@ -542,9 +542,9 @@ fn check_loans_in_fn(fk: visit::fn_kind, decl: ast::fn_decl, body: ast::blk,
                      visitor: visit::vt) {
 
     debug!("purity on entry=%?", copy self.declared_purity);
-    do save_and_restore(self.in_ctor) {
-        do save_and_restore(self.declared_purity) {
-            do save_and_restore(self.fn_args) {
+    do save_and_restore(&mut(self.in_ctor)) {
+        do save_and_restore(&mut(self.declared_purity)) {
+            do save_and_restore(&mut(self.fn_args)) {
                 let is_stack_closure = self.is_stack_closure(id);
                 let fty = ty::node_id_to_type(self.tcx(), id);
                 self.declared_purity = ty::determine_inherited_purity(
@@ -667,7 +667,7 @@ fn check_loans_in_expr(expr: @ast::expr,
 fn check_loans_in_block(blk: ast::blk,
                         &&self: check_loan_ctxt,
                         vt: visit::vt) {
-    do save_and_restore(self.declared_purity) {
+    do save_and_restore(&mut(self.declared_purity)) {
         self.check_for_conflicting_loans(blk.node.id);
 
         match blk.node.rules {
diff --git a/src/rustc/middle/liveness.rs b/src/rustc/middle/liveness.rs
index 69b325b03a4a..6b39a21a7ba5 100644
--- a/src/rustc/middle/liveness.rs
+++ b/src/rustc/middle/liveness.rs
@@ -831,9 +831,9 @@ impl Liveness {
         let mut changed = false;
         do self.indices2(ln, succ_ln) |idx, succ_idx| {
             changed |= copy_if_invalid(copy self.users[succ_idx].reader,
-                                       self.users[idx].reader);
+                                       &mut self.users[idx].reader);
             changed |= copy_if_invalid(copy self.users[succ_idx].writer,
-                                       self.users[idx].writer);
+                                       &mut self.users[idx].writer);
             if self.users[succ_idx].used && !self.users[idx].used {
                 self.users[idx].used = true;
                 changed = true;
@@ -844,10 +844,10 @@ impl Liveness {
                ln.to_str(), self.ln_str(succ_ln), first_merge, changed);
         return changed;
 
-        fn copy_if_invalid(src: LiveNode, &dst: LiveNode) -> bool {
+        fn copy_if_invalid(src: LiveNode, dst: &mut LiveNode) -> bool {
             if src.is_valid() {
                 if !dst.is_valid() {
-                    dst = src;
+                    *dst = src;
                     return true;
                 }
             }
diff --git a/src/rustc/middle/trans/uniq.rs b/src/rustc/middle/trans/uniq.rs
index 6ab91c4a1d79..50ea363ace2a 100644
--- a/src/rustc/middle/trans/uniq.rs
+++ b/src/rustc/middle/trans/uniq.rs
@@ -3,7 +3,6 @@ use lib::llvm::ValueRef;
 use common::*;
 use build::*;
 use base::*;
-use shape::llsize_of;
 use datum::immediate_rvalue;
 
 export make_free_glue, autoderef, duplicate;

From 937f8f4067836de1a56dbe75fb8b1ae3179a73e9 Mon Sep 17 00:00:00 2001
From: Patrick Walton 
Date: Fri, 5 Oct 2012 17:17:50 -0700
Subject: [PATCH 61/80] test: XFAIL trait-inheritance-simple because of
 suspected 32-bit brokenness

---
 src/test/run-pass/trait-inheritance-simple.rs | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/test/run-pass/trait-inheritance-simple.rs b/src/test/run-pass/trait-inheritance-simple.rs
index fcd4cf1de6b3..37dd11aadc48 100644
--- a/src/test/run-pass/trait-inheritance-simple.rs
+++ b/src/test/run-pass/trait-inheritance-simple.rs
@@ -1,3 +1,8 @@
+// xfail-fast
+// xfail-test
+
+// Broken on 32 bit, I guess?
+
 trait Foo {
     fn f();
 }

From d8287f0e41be93fa0c902cac71637cbcb1632a50 Mon Sep 17 00:00:00 2001
From: Patrick Walton 
Date: Fri, 5 Oct 2012 17:31:46 -0700
Subject: [PATCH 62/80] rustc: Translate default methods on traits for each
 impl in which they're used instead of once.

This is a step on the way to default methods.
---
 src/rustc/middle/trans/base.rs | 32 +++++++++++++++++++++++++++-----
 1 file changed, 27 insertions(+), 5 deletions(-)

diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs
index ce596586ddc4..ce4ec72a582c 100644
--- a/src/rustc/middle/trans/base.rs
+++ b/src/rustc/middle/trans/base.rs
@@ -21,7 +21,7 @@ use session::session;
 use syntax::attr;
 use back::{link, abi, upcall};
 use syntax::{ast, ast_util, codemap, ast_map};
-use ast_util::{local_def, path_to_ident};
+use ast_util::{def_id_of_def, local_def, path_to_ident};
 use syntax::visit;
 use syntax::codemap::span;
 use syntax::print::pprust::{expr_to_str, stmt_to_str, path_to_str};
@@ -1847,8 +1847,33 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
             }
         }
       }
-      ast::item_impl(tps, _, _, ms) => {
+      ast::item_impl(tps, trait_refs, _, ms) => {
         meth::trans_impl(ccx, *path, item.ident, ms, tps);
+
+        // Translate any methods that have provided implementations.
+        for trait_refs.each |trait_ref_ptr| {
+            let trait_def = ccx.tcx.def_map.get(trait_ref_ptr.ref_id);
+
+            // XXX: Cross-crate default methods.
+            match ccx.tcx.items.get(def_id_of_def(trait_def).node) {
+                ast_map::node_item(trait_item, _) => {
+                    match trait_item.node {
+                        ast::item_trait(tps, _, trait_methods) => {
+                            trans_trait(ccx, tps, trait_methods, path,
+                                        item.ident);
+                        }
+                        _ => {
+                            ccx.tcx.sess.impossible_case(item.span,
+                                                         ~"trait item not a \
+                                                           trait");
+                        }
+                    }
+                }
+                _ => {
+                    ccx.tcx.sess.impossible_case(item.span, ~"no trait item");
+                }
+            }
+        }
       }
       ast::item_mod(m) => {
         trans_mod(ccx, m);
@@ -1873,9 +1898,6 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
       ast::item_class(struct_def, tps) => {
         trans_struct_def(ccx, struct_def, tps, path, item.ident, item.id);
       }
-      ast::item_trait(tps, _, trait_methods) => {
-        trans_trait(ccx, tps, trait_methods, path, item.ident);
-      }
       _ => {/* fall through */ }
     }
 }

From 38aab8e40034ae21b7c801ae8532ec1f5ae5022d Mon Sep 17 00:00:00 2001
From: Patrick Walton 
Date: Fri, 5 Oct 2012 17:49:13 -0700
Subject: [PATCH 63/80] rustc: Thread a self type through trans_impl; fix
 cross-crate trait issue

---
 src/rustc/middle/trans/base.rs         | 19 +++++++++++++------
 src/rustc/middle/trans/meth.rs         | 15 ++++++++++++---
 src/rustc/middle/trans/monomorphize.rs |  3 ++-
 3 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs
index ce4ec72a582c..24774add4dc3 100644
--- a/src/rustc/middle/trans/base.rs
+++ b/src/rustc/middle/trans/base.rs
@@ -1848,19 +1848,25 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
         }
       }
       ast::item_impl(tps, trait_refs, _, ms) => {
-        meth::trans_impl(ccx, *path, item.ident, ms, tps);
+        meth::trans_impl(ccx, *path, item.ident, ms, tps, None);
 
         // Translate any methods that have provided implementations.
         for trait_refs.each |trait_ref_ptr| {
             let trait_def = ccx.tcx.def_map.get(trait_ref_ptr.ref_id);
 
             // XXX: Cross-crate default methods.
-            match ccx.tcx.items.get(def_id_of_def(trait_def).node) {
+            let trait_id = def_id_of_def(trait_def);
+            if trait_id.crate != ast::local_crate {
+                loop;
+            }
+
+            match ccx.tcx.items.get(trait_id.node) {
                 ast_map::node_item(trait_item, _) => {
                     match trait_item.node {
                         ast::item_trait(tps, _, trait_methods) => {
+                            // XXX: ty_self is wrong here. Get the real type.
                             trans_trait(ccx, tps, trait_methods, path,
-                                        item.ident);
+                                        item.ident, ty::mk_self(ccx.tcx));
                         }
                         _ => {
                             ccx.tcx.sess.impossible_case(item.span,
@@ -1922,15 +1928,16 @@ fn trans_struct_def(ccx: @crate_ctxt, struct_def: @ast::struct_def,
     // If there are ty params, the ctor will get monomorphized
 
     // Translate methods
-    meth::trans_impl(ccx, *path, ident, struct_def.methods, tps);
+    meth::trans_impl(ccx, *path, ident, struct_def.methods, tps, None);
 }
 
 fn trans_trait(ccx: @crate_ctxt, tps: ~[ast::ty_param],
                trait_methods: ~[ast::trait_method],
-               path: @ast_map::path, ident: ast::ident) {
+               path: @ast_map::path, ident: ast::ident,
+               self_ty: ty::t) {
     // Translate any methods that have provided implementations
     let (_, provided_methods) = ast_util::split_trait_methods(trait_methods);
-    meth::trans_impl(ccx, *path, ident, provided_methods, tps);
+    meth::trans_impl(ccx, *path, ident, provided_methods, tps, Some(self_ty));
 }
 
 // Translate a module. Doing this amounts to translating the items in the
diff --git a/src/rustc/middle/trans/meth.rs b/src/rustc/middle/trans/meth.rs
index 6710a64054db..65605f0e4668 100644
--- a/src/rustc/middle/trans/meth.rs
+++ b/src/rustc/middle/trans/meth.rs
@@ -27,7 +27,8 @@ be generated once they are invoked with specific type parameters,
 see `trans::base::lval_static_fn()` or `trans::base::monomorphic_fn()`.
 */
 fn trans_impl(ccx: @crate_ctxt, path: path, name: ast::ident,
-              methods: ~[@ast::method], tps: ~[ast::ty_param]) {
+              methods: ~[@ast::method], tps: ~[ast::ty_param],
+              self_ty: Option) {
     let _icx = ccx.insn_ctxt("impl::trans_impl");
     if tps.len() > 0u { return; }
     let sub_path = vec::append_one(path, path_name(name));
@@ -35,7 +36,7 @@ fn trans_impl(ccx: @crate_ctxt, path: path, name: ast::ident,
         if method.tps.len() == 0u {
             let llfn = get_item_val(ccx, method.id);
             let path = vec::append_one(sub_path, path_name(method.ident));
-            trans_method(ccx, path, *method, None, llfn);
+            trans_method(ccx, path, *method, None, self_ty, llfn);
         }
     }
 }
@@ -49,12 +50,16 @@ Translates a (possibly monomorphized) method body.
 - `method`: the AST node for the method
 - `param_substs`: if this is a generic method, the current values for
   type parameters and so forth, else none
+- `base_self_ty`: optionally, the explicit self type for this method. This
+  will be none if this is not a default method and must always be present
+  if this is a default method.
 - `llfn`: the LLVM ValueRef for the method
 */
 fn trans_method(ccx: @crate_ctxt,
                 path: path,
                 method: &ast::method,
                 param_substs: Option,
+                base_self_ty: Option,
                 llfn: ValueRef) {
 
     // figure out how self is being passed
@@ -65,7 +70,11 @@ fn trans_method(ccx: @crate_ctxt,
       _ => {
         // determine the (monomorphized) type that `self` maps to for
         // this method
-        let self_ty = ty::node_id_to_type(ccx.tcx, method.self_id);
+        let self_ty;
+        match base_self_ty {
+            None => self_ty = ty::node_id_to_type(ccx.tcx, method.self_id),
+            Some(provided_self_ty) => self_ty = provided_self_ty
+        }
         let self_ty = match param_substs {
           None => self_ty,
           Some({tys: ref tys, _}) => ty::subst_tps(ccx.tcx, *tys, self_ty)
diff --git a/src/rustc/middle/trans/monomorphize.rs b/src/rustc/middle/trans/monomorphize.rs
index cd8cffa297a6..17eaf591c9f3 100644
--- a/src/rustc/middle/trans/monomorphize.rs
+++ b/src/rustc/middle/trans/monomorphize.rs
@@ -156,9 +156,10 @@ fn monomorphic_fn(ccx: @crate_ctxt,
         d
       }
       ast_map::node_method(mth, _, _) => {
+        // XXX: What should the self type be here?
         let d = mk_lldecl();
         set_inline_hint_if_appr(mth.attrs, d);
-        meth::trans_method(ccx, pt, mth, psubsts, d);
+        meth::trans_method(ccx, pt, mth, psubsts, None, d);
         d
       }
       ast_map::node_ctor(_, tps, ctor, parent_id, _) => {

From 3077a2bfaf0bde121072ff71649df6c39f9b66f4 Mon Sep 17 00:00:00 2001
From: Brian Anderson 
Date: Fri, 5 Oct 2012 18:39:09 -0700
Subject: [PATCH 64/80] docs: Add a section on pointer dereferencing

---
 doc/tutorial.md | 67 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/doc/tutorial.md b/doc/tutorial.md
index 952fcd30f4c3..88643d38d4ad 100644
--- a/doc/tutorial.md
+++ b/doc/tutorial.md
@@ -1284,6 +1284,73 @@ For a more in-depth explanation of borrowed pointers, read the
 
 [borrowtut]: tutorial-borrowed-ptr.html
 
+## Dereferencing pointers
+
+Rust uses the unary star operator (`*`) to access the contents of a
+box or pointer, similarly to C.
+
+~~~
+let managed = @10;
+let owned = ~20;
+let borrowed = &30;
+
+let sum = *managed + *owned + *borrowed;
+~~~
+
+Dereferenced mutable pointers may appear on the left hand side of
+assignments, in which case the value they point to is modified.
+
+~~~
+let managed = @mut 10;
+let owned = ~mut 20;
+
+let mut value = 30;
+let borrowed = &mut value;
+
+*managed = *owned + 10;
+*owned = *borrowed + 100;
+*borrowed = *managed + 1000;
+~~~
+
+Pointers have high operator precedence, but lower precedence than the
+dot operator used for field and method access. This can lead to some
+awkward code filled with parenthesis.
+
+~~~
+# struct Point { x: float, y: float }
+# enum Shape { Rectangle(Point, Point) }
+# impl Shape { fn area() -> int { 0 } }
+let start = @Point { x: 10f, y: 20f };
+let end = ~Point { x: (*start).x + 100f, y: (*start).y + 100f };
+let rect = &Rectangle(*start, *end);
+let area = (*rect).area();
+~~~
+
+To combat this ugliness the dot operator performs _automatic pointer
+dereferencing_ on the receiver (the value on the left hand side of the
+dot), so in most cases dereferencing the receiver is not necessary.
+
+~~~
+# struct Point { x: float, y: float }
+# enum Shape { Rectangle(Point, Point) }
+# impl Shape { fn area() -> int { 0 } }
+let start = @Point { x: 10f, y: 20f };
+let end = ~Point { x: start.x + 100f, y: start.y + 100f };
+let rect = &Rectangle(*start, *end);
+let area = rect.area();
+~~~
+
+Auto-dereferencing is performed through any number of pointers. If you
+felt inclined you could write something silly like
+
+~~~
+# struct Point { x: float, y: float }
+let point = &@~Point { x: 10f, y: 20f };
+io::println(fmt!("%f", point.x));
+~~~
+
+The indexing operator (`[]`) is also auto-dereferencing.
+
 # Vectors and strings
 
 Vectors are a contiguous section of memory containing zero or more

From 02c33f8d316cca760b380e5d9fc4762629a9f968 Mon Sep 17 00:00:00 2001
From: Brian Anderson 
Date: Fri, 5 Oct 2012 18:42:48 -0700
Subject: [PATCH 65/80] doc: Strings are vectors of u8, not [u8]

---
 doc/tutorial.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/tutorial.md b/doc/tutorial.md
index 88643d38d4ad..d5a2f66b1c0a 100644
--- a/doc/tutorial.md
+++ b/doc/tutorial.md
@@ -1448,7 +1448,7 @@ mutable_crayons[0] = Apricot;
 This is a simple example of Rust's _dual-mode data structures_, also
 referred to as _freezing and thawing_.
 
-Strings are implemented with vectors of `[u8]`, though they have a distinct
+Strings are implemented with vectors of `u8`, though they have a distinct
 type. They support most of the same allocation options as
 vectors, though the string literal without a storage sigil, e.g.
 `"foo"` is treated differently than a comparable vector (`[foo]`).

From b80b0688d5ccc276e1dd3b6dfeeaea5e6f2782de Mon Sep 17 00:00:00 2001
From: Patrick Walton 
Date: Fri, 5 Oct 2012 18:51:36 -0700
Subject: [PATCH 66/80] rustc: Add a new method_self method call origin. Part
 of default methods.

---
 src/rustc/middle/astencode.rs           |  3 ++
 src/rustc/middle/privacy.rs             |  7 +++--
 src/rustc/middle/trans/base.rs          | 15 ++++++++--
 src/rustc/middle/trans/meth.rs          |  3 ++
 src/rustc/middle/trans/type_use.rs      |  2 +-
 src/rustc/middle/ty.rs                  |  3 +-
 src/rustc/middle/typeck.rs              |  5 +++-
 src/rustc/middle/typeck/check/method.rs | 38 +++++++++++++++++++++----
 8 files changed, 61 insertions(+), 15 deletions(-)

diff --git a/src/rustc/middle/astencode.rs b/src/rustc/middle/astencode.rs
index f2ee3df66106..a364c1d75d43 100644
--- a/src/rustc/middle/astencode.rs
+++ b/src/rustc/middle/astencode.rs
@@ -493,6 +493,9 @@ impl method_origin: tr {
           typeck::method_trait(did, m, vstore) => {
             typeck::method_trait(did.tr(xcx), m, vstore)
           }
+          typeck::method_self(did, m) => {
+            typeck::method_self(did.tr(xcx), m)
+          }
         }
     }
 }
diff --git a/src/rustc/middle/privacy.rs b/src/rustc/middle/privacy.rs
index f15ace40d309..98260a0d0819 100644
--- a/src/rustc/middle/privacy.rs
+++ b/src/rustc/middle/privacy.rs
@@ -8,8 +8,8 @@ use syntax::ast::{item_trait, local_crate, node_id, pat_struct, private};
 use syntax::ast::{provided, required};
 use syntax::ast_map::{node_item, node_method};
 use ty::ty_class;
-use typeck::{method_map, method_origin, method_param, method_static};
-use typeck::{method_trait};
+use typeck::{method_map, method_origin, method_param, method_self};
+use typeck::{method_static, method_trait};
 
 use core::util::ignore;
 use dvec::DVec;
@@ -81,7 +81,8 @@ fn check_crate(tcx: ty::ctxt, method_map: &method_map, crate: @ast::crate) {
                 }
             }
             method_param({trait_id: trait_id, method_num: method_num, _}) |
-            method_trait(trait_id, method_num, _) => {
+            method_trait(trait_id, method_num, _) |
+            method_self(trait_id, method_num) => {
                 if trait_id.crate == local_crate {
                     match tcx.items.find(trait_id.node) {
                         Some(node_item(item, _)) => {
diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs
index 24774add4dc3..afa008fdbb77 100644
--- a/src/rustc/middle/trans/base.rs
+++ b/src/rustc/middle/trans/base.rs
@@ -1847,7 +1847,7 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
             }
         }
       }
-      ast::item_impl(tps, trait_refs, _, ms) => {
+      ast::item_impl(tps, trait_refs, self_ast_ty, ms) => {
         meth::trans_impl(ccx, *path, item.ident, ms, tps, None);
 
         // Translate any methods that have provided implementations.
@@ -1860,13 +1860,22 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
                 loop;
             }
 
+            // Get the self type.
+            let self_ty;
+            match ccx.tcx.ast_ty_to_ty_cache.get(self_ast_ty) {
+                ty::atttce_resolved(self_type) => self_ty = self_type,
+                ty::atttce_unresolved => {
+                    ccx.tcx.sess.impossible_case(item.span,
+                                                 ~"didn't cache self ast ty");
+                }
+            }
+
             match ccx.tcx.items.get(trait_id.node) {
                 ast_map::node_item(trait_item, _) => {
                     match trait_item.node {
                         ast::item_trait(tps, _, trait_methods) => {
-                            // XXX: ty_self is wrong here. Get the real type.
                             trans_trait(ccx, tps, trait_methods, path,
-                                        item.ident, ty::mk_self(ccx.tcx));
+                                        item.ident, self_ty);
                         }
                         _ => {
                             ccx.tcx.sess.impossible_case(item.span,
diff --git a/src/rustc/middle/trans/meth.rs b/src/rustc/middle/trans/meth.rs
index 65605f0e4668..b4a64abeed7e 100644
--- a/src/rustc/middle/trans/meth.rs
+++ b/src/rustc/middle/trans/meth.rs
@@ -154,6 +154,9 @@ fn trans_method_callee(bcx: block, callee_id: ast::node_id,
         typeck::method_trait(_, off, vstore) => {
             trans_trait_callee(bcx, callee_id, off, self, vstore)
         }
+        typeck::method_self(_, off) => {
+            bcx.tcx().sess.span_bug(self.span, ~"self method call");
+        }
     }
 }
 
diff --git a/src/rustc/middle/trans/type_use.rs b/src/rustc/middle/trans/type_use.rs
index 8bd5bd7afc78..8eabf26e2178 100644
--- a/src/rustc/middle/trans/type_use.rs
+++ b/src/rustc/middle/trans/type_use.rs
@@ -247,7 +247,7 @@ fn mark_for_expr(cx: ctx, e: @expr) {
               typeck::method_param({param_num: param, _}) => {
                 cx.uses[param] |= use_tydesc;
               }
-              typeck::method_trait(*) => (),
+              typeck::method_trait(*) | typeck::method_self(*) => (),
             }
         }
       }
diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs
index 78949ec5f794..f2f7b32b6706 100644
--- a/src/rustc/middle/ty.rs
+++ b/src/rustc/middle/ty.rs
@@ -2826,7 +2826,8 @@ fn method_call_bounds(tcx: ctxt, method_map: typeck::method_map,
           }
           typeck::method_param({trait_id:trt_id,
                                 method_num:n_mth, _}) |
-          typeck::method_trait(trt_id, n_mth, _) => {
+          typeck::method_trait(trt_id, n_mth, _) |
+          typeck::method_self(trt_id, n_mth) => {
             // ...trait methods bounds, in contrast, include only the
             // method bounds, so we must preprend the tps from the
             // trait itself.  This ought to be harmonized.
diff --git a/src/rustc/middle/typeck.rs b/src/rustc/middle/typeck.rs
index 6c461126853f..514fc2cfbb32 100644
--- a/src/rustc/middle/typeck.rs
+++ b/src/rustc/middle/typeck.rs
@@ -73,7 +73,7 @@ export deserialize_method_map_entry;
 export vtable_map;
 export vtable_res;
 export vtable_origin;
-export method_static, method_param, method_trait;
+export method_static, method_param, method_trait, method_self;
 export vtable_static, vtable_param, vtable_trait;
 export provided_methods_map;
 
@@ -87,6 +87,9 @@ enum method_origin {
 
     // method invoked on a trait instance
     method_trait(ast::def_id, uint, ty::vstore),
+
+    // method invoked on "self" inside a default method
+    method_self(ast::def_id, uint),
 }
 
 // details for a method invoked with a receiver whose type is a type parameter
diff --git a/src/rustc/middle/typeck/check/method.rs b/src/rustc/middle/typeck/check/method.rs
index d55f9facc626..f3b2c8f1b7ed 100644
--- a/src/rustc/middle/typeck/check/method.rs
+++ b/src/rustc/middle/typeck/check/method.rs
@@ -232,9 +232,8 @@ impl LookupContext {
                     let self_did = self.fcx.self_impl_def_id.expect(
                         ~"unexpected `none` for self_impl_def_id");
                     let substs = {self_r: None, self_ty: None, tps: ~[]};
-                    self.push_inherent_candidates_from_trait(
-                        self_ty, self_did, &substs,
-                        ty::vstore_slice(ty::re_static));   // XXX: Wrong!
+                    self.push_inherent_candidates_from_self(
+                        self_ty, self_did, &substs);
                 }
                 ty_enum(did, _) | ty_class(did, _) => {
                     self.push_inherent_impl_candidates_for_type(did);
@@ -397,6 +396,33 @@ impl LookupContext {
         });
     }
 
+    fn push_inherent_candidates_from_self(&self,
+                                          self_ty: ty::t,
+                                          did: def_id,
+                                          substs: &ty::substs) {
+        let tcx = self.tcx();
+        let methods = ty::trait_methods(tcx, did);  // XXX: Inherited methods.
+        let index;
+        match vec::position(*methods, |m| m.ident == self.m_name) {
+            Some(i) => index = i,
+            None => return
+        }
+        let method = &methods[index];
+
+        let rcvr_substs = { self_ty: Some(self_ty), ..*substs };
+        let (rcvr_ty, rcvr_substs) =
+            self.create_rcvr_ty_and_substs_for_method(
+                method.self_ty, self_ty, move rcvr_substs);
+
+        self.inherent_candidates.push(Candidate {
+            rcvr_ty: rcvr_ty,
+            rcvr_substs: move rcvr_substs,
+            num_method_tps: method.tps.len(),
+            self_mode: get_mode_from_self_type(method.self_ty),
+            origin: method_self(did, index)
+        });
+    }
+
     fn push_inherent_impl_candidates_for_type(did: def_id)
     {
         let opt_impl_infos =
@@ -737,7 +763,7 @@ impl LookupContext {
          * vtable and hence cannot be monomorphized. */
 
         match candidate.origin {
-            method_static(*) | method_param(*) => {
+            method_static(*) | method_param(*) | method_self(*) => {
                 return; // not a call to a trait instance
             }
             method_trait(*) => {}
@@ -772,7 +798,7 @@ impl LookupContext {
             method_param(ref mp) => {
                 type_of_trait_method(self.tcx(), mp.trait_id, mp.method_num)
             }
-            method_trait(did, idx, _) => {
+            method_trait(did, idx, _) | method_self(did, idx) => {
                 type_of_trait_method(self.tcx(), did, idx)
             }
         };
@@ -793,7 +819,7 @@ impl LookupContext {
             method_param(mp) => {
                 self.report_param_candidate(idx, mp.trait_id)
             }
-            method_trait(trait_did, _, _) => {
+            method_trait(trait_did, _, _) | method_self(trait_did, _) => {
                 self.report_param_candidate(idx, trait_did)
             }
         }

From 46371e107634ba9e8947cc1c45cecd8b24328e88 Mon Sep 17 00:00:00 2001
From: Graydon Hoare 
Date: Fri, 5 Oct 2012 10:18:10 -0700
Subject: [PATCH 67/80] Remove port/chan-specific lifecycle terminology.

---
 doc/rust.md | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/doc/rust.md b/doc/rust.md
index 62b3b4409abd..301219dd832e 100644
--- a/doc/rust.md
+++ b/doc/rust.md
@@ -2896,12 +2896,11 @@ A task begins its lifecycle -- once it has been spawned -- in the *running*
 state. In this state it executes the statements of its entry function, and any
 functions called by the entry function.
 
-A task may transition from the *running* state to the *blocked* state any time
-it makes a blocking receive call on a port, or attempts a rate-limited
-blocking send on a channel. When the communication expression can be completed
--- when a message arrives at a sender, or a queue drains sufficiently to
-complete a rate-limited send -- then the blocked task will unblock and
-transition back to *running*.
+A task may transition from the *running* state to the *blocked*
+state any time it makes a blocking communication call. When the
+call can be completed -- when a message arrives at a sender, or a
+buffer opens to receive a message -- then the blocked task will
+unblock and transition back to *running*.
 
 A task may transition to the *failing* state at any time, due being
 killed by some external event or internally, from the evaluation of a

From 6c2c6947256db3841ceb3253ebace259a72dd917 Mon Sep 17 00:00:00 2001
From: Graydon Hoare 
Date: Fri, 5 Oct 2012 10:36:21 -0700
Subject: [PATCH 68/80] Rewrite the communication-between-tasks section
 completely.

---
 doc/rust.md | 59 ++++++++++++-----------------------------------------
 1 file changed, 13 insertions(+), 46 deletions(-)

diff --git a/doc/rust.md b/doc/rust.md
index 301219dd832e..8e0a03865533 100644
--- a/doc/rust.md
+++ b/doc/rust.md
@@ -2832,54 +2832,21 @@ exploiting.]
 
 ### Communication between tasks
 
-With the exception of *unsafe* blocks, Rust tasks are isolated from
-interfering with one another's memory directly. Instead of manipulating shared
-storage, Rust tasks communicate with one another using a typed, asynchronous,
-simplex message-passing system.
+Rust tasks are isolated and generally unable to interfere with one another's memory directly,
+except through [`unsafe` code](#unsafe-code).
+All contact between tasks is mediated by safe forms of ownership transfer,
+and data races on memory are prohibited by the type system.
 
-A _port_ is a communication endpoint that can *receive* messages. Ports
-receive messages from channels.
+Inter-task communication and co-ordination facilities are provided in the standard library.
+These include:
+  - synchronous and asynchronous communication channels with various communication topologies
+  - read-only and read-write shared variables with various safe mutual exclusion patterns
+  - simple locks and semaphores
 
-A _channel_ is a communication endpoint that can *send* messages. Channels
-send messages to ports.
-
-Each port is implicitly boxed and mutable; as such a port has a unique
-per-task identity and cannot be replicated or transmitted. If a port value is
-copied, both copies refer to the *same* port. New ports can be
-constructed dynamically and stored in data structures.
-
-Each channel is bound to a port when the channel is constructed, so the
-destination port for a channel must exist before the channel itself. A channel
-cannot be rebound to a different port from the one it was constructed with.
-
-Channels are weak: a channel does not keep the port it is bound to
-alive. Ports are owned by their allocating task and cannot be sent over
-channels; if a task dies its ports die with it, and all channels bound to
-those ports no longer function. Messages sent to a channel connected to a dead
-port will be dropped.
-
-Channels are immutable types with meaning known to the runtime; channels can
-be sent over channels.
-
-Many channels can be bound to the same port, but each channel is bound to a
-single port. In other words, channels and ports exist in an N:1 relationship,
-N channels to 1 port. ^[It may help to remember nautical terminology
-when differentiating channels from ports.  Many different waterways --
-channels -- may lead to the same port.]
-
-Each port and channel can carry only one type of message. The message type is
-encoded as a parameter of the channel or port type. The message type of a
-channel is equal to the message type of the port it is bound to. The types of
-messages must satisfy the `send` built-in trait.
-
-Messages are generally sent asynchronously, with optional
-rate-limiting on the transmit side.  Each port contains a message
-queue and sending a message over a channel merely means inserting it
-into the associated port's queue; message receipt is the
-responsibility of the receiving task.
-
-Messages are sent on channels and received on ports using standard library
-functions.
+When such facilities carry values, the values are restricted to the [`Send` type-kind](#type-kinds).
+Restricting communication interfaces to this kind ensures that no borrowed or managed pointers move between tasks.
+Thus access to an entire data structure can be mediated through its owning "root" value;
+no further locking or copying is required to avoid data races within the substructure of such a value.
 
 
 ### Task lifecycle

From cb4c747e9f6b51f8e44caab27ca376b59df3a56d Mon Sep 17 00:00:00 2001
From: Graydon Hoare 
Date: Fri, 5 Oct 2012 14:19:50 -0700
Subject: [PATCH 69/80] Add section on lvals, rvals and temps.

---
 doc/rust.md | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/doc/rust.md b/doc/rust.md
index 8e0a03865533..e514990ab8ec 100644
--- a/doc/rust.md
+++ b/doc/rust.md
@@ -1468,6 +1468,25 @@ structure of expressions. Blocks themselves are expressions, so the nesting
 sequence of block, statement, expression, and block can repeatedly nest to an
 arbitrary depth.
 
+#### Lvalues, rvalues and temporaries
+
+Expressions are divided into two main categories: _lvalues_ and _rvalues_.
+Likewise within each expression, sub-expressions may occur in _lvalue context_ or _rvalue context_.
+The evaluation of an expression depends both on its own category and the context it occurs within.
+
+Path, field and index expressions are lvalues.
+All other expressions are rvalues.
+
+The left operand of an assignment expression and the operand of the borrow operator are lvalue contexts.
+All other expression contexts are rvalue contexts.
+
+When an lvalue is evaluated in an _lvalue context_, it denotes a memory location;
+when evaluated in an _rvalue context_, it denotes the value held _in_ that memory location.
+
+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.
+
+
 ### Literal expressions
 
 A _literal expression_ consists of one of the [literal](#literals)

From 5947141aef34bd87db4997fe74c23b90314f7a22 Mon Sep 17 00:00:00 2001
From: Graydon Hoare 
Date: Fri, 5 Oct 2012 15:46:22 -0700
Subject: [PATCH 70/80] Add section on unsafe functions, reword explanation on
 unsafe-overriding-purity.

---
 doc/rust.md | 50 ++++++++++++++++++++++++++++++--------------------
 1 file changed, 30 insertions(+), 20 deletions(-)

diff --git a/doc/rust.md b/doc/rust.md
index e514990ab8ec..877c02c8ae1b 100644
--- a/doc/rust.md
+++ b/doc/rust.md
@@ -960,24 +960,12 @@ pure fn pure_length(ls: List) -> uint { ... }
 pure fn nonempty_list(ls: List) -> bool { pure_length(ls) > 0u }
 ~~~~
 
-*TODO:* should actually define referential transparency.
-
-The effect checking rules previously enumerated are a restricted set
-of typechecking rules meant to approximate the universe of observably
-referentially transparent Rust procedures conservatively. Sometimes,
-these rules are *too* restrictive. Rust allows programmers to violate
-these rules by writing pure functions that the compiler cannot prove
-to be referentially transparent, using "unsafe blocks". When writing
-code that uses unsafe blocks, programmers should always be aware that
-they have an obligation to show that the code *behaves* referentially
-transparently at all times, even if the compiler cannot *prove*
-automatically that the code is referentially transparent. In the
-presence of unsafe blocks, the compiler provides no static guarantee
-that the code will behave as expected at runtime. Rather, the
-programmer has an independent obligation to verify the semantics of
-the pure functions they write.
-
-*TODO:* last two sentences are vague.
+These purity-checking rules approximate the concept of referential transparency:
+that a call-expression could be rewritten with the literal-expression of its return value, without changing the meaning of the program.
+Since they are an approximation, sometimes these rules are *too* restrictive.
+Rust allows programmers to violate these rules using [`unsafe` blocks](#unsafe-blocks).
+As with any `unsafe` block, those that violate static purity carry transfer the burden of safety-proof from the compiler to the programmer.
+Programmers should exercise caution when breaking such rules.
 
 An example of a pure function that uses an unsafe block:
 
@@ -1045,6 +1033,28 @@ Similarly, [trait](#traits) bounds can be specified for type
 parameters to allow methods with that trait to be called on values
 of that type.
 
+#### Unsafe functions
+
+Unsafe functions are those containing unsafe operations that are not contained in an [`unsafe` block](#unsafe-blocks).
+
+Unsafe operations are those that potentially violate the memory-safety guarantees of Rust's static semantics.
+Specifically, the following operations are considered unsafe:
+
+  - Dereferencing a [raw pointer](#pointer-types)
+  - Casting a [raw pointer](#pointer-types) to a safe pointer type
+  - Breaking the [purity-checking rules](#pure-functions)
+  - Calling an unsafe function
+
+##### Unsafe blocks
+
+A block of code can also be prefixed with the `unsafe` keyword,
+to permit a sequence of unsafe operations in an otherwise-safe function.
+This facility exists because the static semantics of a Rust are a necessary approximation of the dynamic semantics.
+When a programmer has sufficient conviction that a sequence of unsafe operations is actually safe,
+they can encapsulate that sequence (taken as a whole) within an `unsafe` block.
+The compiler will consider uses of such code "safe", to the surrounding context.
+
+
 #### Extern functions
 
 Extern functions are part of Rust's foreign function interface, providing
@@ -1059,7 +1069,7 @@ extern fn new_vec() -> ~[int] { ~[] }
 ~~~
 
 Extern functions may not be called from Rust code, but their value
-may be taken as an unsafe `u8` pointer.
+may be taken as a raw `u8` pointer.
 
 ~~~
 # extern fn new_vec() -> ~[int] { ~[] }
@@ -2852,7 +2862,7 @@ exploiting.]
 ### Communication between tasks
 
 Rust tasks are isolated and generally unable to interfere with one another's memory directly,
-except through [`unsafe` code](#unsafe-code).
+except through [`unsafe` code](#unsafe-functions).
 All contact between tasks is mediated by safe forms of ownership transfer,
 and data races on memory are prohibited by the type system.
 

From e513bc98754c1dfa33e8d71b7352a0409905e5f3 Mon Sep 17 00:00:00 2001
From: Graydon Hoare 
Date: Fri, 5 Oct 2012 15:46:49 -0700
Subject: [PATCH 71/80] Minor reformatting.

---
 doc/rust.md | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/doc/rust.md b/doc/rust.md
index 877c02c8ae1b..588fceba6191 100644
--- a/doc/rust.md
+++ b/doc/rust.md
@@ -773,8 +773,8 @@ A view item manages the namespace of a module; it does not define new items
 but simply changes the visibility of other items. There are several kinds of
 view item:
 
- * [extern mod declarations](#extern-mod-declarations)
- * [use declarations](#use-declarations)
+ * [`extern mod` declarations](#extern-mod-declarations)
+ * [`use` declarations](#use-declarations)
 
 ##### Extern mod declarations
 
@@ -784,7 +784,7 @@ link_attrs : link_attr [ ',' link_attrs ] + ;
 link_attr : ident '=' literal ;
 ~~~~~~~~
 
-An _extern mod declaration_ specifies a dependency on an external crate.
+An _`extern mod` declaration_ specifies a dependency on an external crate.
 The external crate is then bound into the declaring scope as the `ident` provided in the `extern_mod_decl`.
 
 The external crate is resolved to a specific `soname` at compile time, and a
@@ -1737,9 +1737,9 @@ A type cast expression is denoted with the binary operator `as`.
 Executing an `as` expression casts the value on the left-hand side to the type
 on the right-hand side.
 
-A numeric value can be cast to any numeric type.  An unsafe pointer value can
-be cast to or from any integral type or unsafe pointer type.  Any other cast
-is unsupported and will fail to compile.
+A numeric value can be cast to any numeric type.
+A raw pointer value can be cast to or from any integral type or raw pointer type.
+Any other cast is unsupported and will fail to compile.
 
 An example of an `as` expression:
 

From df98cb8e884e7546b83ee229975759deb948e05a Mon Sep 17 00:00:00 2001
From: Graydon Hoare 
Date: Fri, 5 Oct 2012 15:48:14 -0700
Subject: [PATCH 72/80] Replace box types section with pointer types section.

---
 doc/rust.md | 60 ++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 43 insertions(+), 17 deletions(-)

diff --git a/doc/rust.md b/doc/rust.md
index 588fceba6191..31b734b9f6d6 100644
--- a/doc/rust.md
+++ b/doc/rust.md
@@ -2510,27 +2510,53 @@ tuple of arguments.
 Enumerated types cannot be denoted *structurally* as types, but must be
 denoted by named reference to an [*enumeration* item](#enumerations).
 
-### Box types
+### Pointer types
 
-Box types are represented as pointers. There are three flavours of
-pointers:
+All pointers in Rust are explicit first-class values.
+They can be copied, stored into data structures, and returned from functions.
+There are four varieties of pointer in Rust:
 
-Shared boxes (`@`)
-  : These are reference-counted boxes. Their type is written
-    `@content`, for example `@int` means a shared box containing an
-    integer. Copying a value of such a type means copying the pointer
-    and increasing the reference count.
+Managed pointers (`@`)
+  : These point to managed heap allocations (or "boxes") in the task-local, managed heap.
+    Managed pointers are written `@content`,
+    for example `@int` means a managed pointer to a managed box containing an integer.
+    Copying a managed pointer is a "shallow" operation:
+    it involves only copying the pointer itself
+    (as well as any reference-count or GC-barriers required by the managed heap).
+    Dropping a managed pointer does not necessarily release the box it points to;
+    the lifecycles of managed boxes are subject to an unspecified garbage collection algorithm.
 
-Unique boxes (`~`)
-  : Unique boxes have only a single owner, and are freed when their
-    owner releases them. They are written `~content`. Copying a
-    unique box involves copying the contents into a new box.
+Owning pointers (`~`)
+  : These point to owned heap allocations (or "boxes") in the shared, inter-task heap.
+    Each owned box has a single owning pointer; pointer and pointee retain a 1:1 relationship at all times.
+    Owning pointers are written `~content`,
+    for example `~int` means an owning pointer to an owned box containing an integer.
+    Copying an owned box is a "deep" operation:
+    it involves allocating a new owned box and copying the contents of the old box into the new box.
+    Releasing an owning pointer immediately releases its corresponding owned box.
 
-Unsafe pointers (`*`)
-  : Unsafe pointers are pointers without safety guarantees or
-    language-enforced semantics. Their type is written `*content`.
-    They can be copied and dropped freely. Dereferencing an unsafe
-    pointer is part of the unsafe sub-dialect of Rust.
+Borrowed pointers (`&`)
+  : These point to memory _owned by some other value_.
+    Borrowed pointers arise by (automatic) conversion from owning pointers, managed pointers,
+    or by applying the borrowing operator `&` to some other value,
+    including [lvalues, rvalues or temporaries](#lvalues-rvalues-and-temporaries).
+    Borrowed pointers are written `&content`, or in some cases `&f/content` for some lifetime-variable `f`,
+    for example `&int` means a borrowed pointer to an integer.
+    Copying a borrowed pointer is a "shallow" operation:
+    it involves only copying the pointer itself.
+    Releasing a borrowed pointer typically has no effect on the value it points to,
+    with the exception of temporary values,
+    which are released when the last borrowed pointer to them is released.
+
+Raw pointers (`*`)
+  : Raw pointers are pointers without safety or liveness guarantees.
+    Raw pointers are written `*content`,
+    for example `*int` means a raw pointer to an integer.
+    Copying or dropping a raw pointer is has no effect on the lifecycle of any other value.
+    Dereferencing a raw pointer or converting it to any other pointer type is an [`unsafe` operation](#unsafe-functions).
+    Raw pointers are generally discouraged in Rust code;
+    they exist to support interoperability with foreign code,
+    and writing performance-critical or low-level functions.
 
 ### Function types
 

From 2f50607d8840d2ea7de6a7367ab9854d6951e889 Mon Sep 17 00:00:00 2001
From: Graydon Hoare 
Date: Fri, 5 Oct 2012 15:48:28 -0700
Subject: [PATCH 73/80] Reword memory-ownership section.

---
 doc/rust.md | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/doc/rust.md b/doc/rust.md
index 31b734b9f6d6..b9eb633743fc 100644
--- a/doc/rust.md
+++ b/doc/rust.md
@@ -2733,20 +2733,17 @@ the box values pointing to it. Since box values may themselves be passed in
 and out of frames, or stored in the heap, heap allocations may outlive the
 frame they are allocated within.
 
-
 ### Memory ownership
 
 A task owns all memory it can *safely* reach through local variables,
-shared or unique boxes, and/or references. Sharing memory between tasks can
-only be accomplished using *unsafe* constructs, such as raw pointer
-operations or calling C code.
+as well as managed, owning and borrowed pointers.
 
-When a task sends a value that has the `send` trait over a channel, it
-loses ownership of the value sent and can no longer refer to it. This is
-statically guaranteed by the combined use of "move semantics" and the
-compiler-checked _meaning_ of the `send` trait: it is only instantiated
-for (transitively) unique kinds of data constructor and pointers, never shared
-pointers.
+When a task sends a value that has the `Send` trait to another task,
+it loses ownership of the value sent and can no longer refer to it.
+This is statically guaranteed by the combined use of "move semantics",
+and the compiler-checked _meaning_ of the `Send` trait:
+it is only instantiated for (transitively) sendable kinds of data constructor and pointers,
+never including managed or borrowed pointers.
 
 When a stack frame is exited, its local allocations are all released, and its
 references to boxes (both shared and owned) are dropped.

From 0dd4b42a00e01189a28ec12d20a8b144b4e02a14 Mon Sep 17 00:00:00 2001
From: Graydon Hoare 
Date: Fri, 5 Oct 2012 15:56:45 -0700
Subject: [PATCH 74/80] Fix nits in logging section.

---
 doc/rust.md | 27 +++++++++++----------------
 1 file changed, 11 insertions(+), 16 deletions(-)

diff --git a/doc/rust.md b/doc/rust.md
index b9eb633743fc..31c52300312c 100644
--- a/doc/rust.md
+++ b/doc/rust.md
@@ -2306,30 +2306,25 @@ logging level:
 // Full version, logging a value.
 log(core::error, ~"file not found: " + filename);
 
-// Log-level abbreviated, since core::* is imported by default.
+// Log-level abbreviated, since core::* is used by default.
 log(error, ~"file not found: " + filename);
 
-// Formatting the message using a format-string and #fmt
+// Formatting the message using a format-string and fmt!
 log(error, fmt!("file not found: %s", filename));
 
-// Using the #error macro, that expands to the previous call.
+// Using the error! macro, that expands to the previous call.
 error!("file not found: %s", filename);
 ~~~~
 
-A `log` expression is *not evaluated* when logging at the specified
-logging-level, module or task is disabled at runtime. This makes inactive
-`log` expressions very cheap; they should be used extensively in Rust
-code, as diagnostic aids, as they add little overhead beyond a single
-integer-compare and branch at runtime.
+A `log` expression is *not evaluated* when logging at the specified logging-level, module or task is disabled at runtime.
+This makes inactive `log` expressions very cheap;
+they should be used extensively in Rust code, as diagnostic aids,
+as they add little overhead beyond a single integer-compare and branch at runtime.
 
-Logging is presently implemented as a language built-in feature, as it makes
-use of compiler-provided logic for allocating the associated per-module
-logging-control structures visible to the runtime, and lazily evaluating
-arguments. In the future, as more of the supporting compiler-provided logic is
-moved into libraries, logging is likely to move to a component of the core
-library. It is best to use the macro forms of logging (*#error*,
-*#debug*, etc.) to minimize disruption to code using the logging facility
-when it is changed.
+Logging is presently implemented as a language built-in feature,
+as it makes use of compiler-provided, per-module data tables and flags.
+In the future, logging will move into a library, and will no longer be a core expression type.
+It is therefore recommended to use the macro forms of logging (`error!`, `debug!`, etc.) to minimize disruption in code that uses logging.
 
 
 ### Assert expressions

From 28c45601b299c309d7c9f5b3f53318b9dfc62b34 Mon Sep 17 00:00:00 2001
From: Tim Chevalier 
Date: Fri, 5 Oct 2012 19:23:44 -0700
Subject: [PATCH 75/80] De-mode mysterious unused functions in
 middle::trans::shape (see comment)

---
 src/rustc/middle/trans/shape.rs | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/src/rustc/middle/trans/shape.rs b/src/rustc/middle/trans/shape.rs
index cf58b5b51c4c..127af4388073 100644
--- a/src/rustc/middle/trans/shape.rs
+++ b/src/rustc/middle/trans/shape.rs
@@ -49,12 +49,16 @@ fn mk_ctxt(llmod: ModuleRef) -> ctxt {
     return {mut next_tag_id: 0u16, pad: 0u16, pad2: 0u32};
 }
 
-fn add_u16(&dest: ~[u8], val: u16) {
-    dest += ~[(val & 0xffu16) as u8, (val >> 8u16) as u8];
+/*
+Although these two functions are never called, they are here
+for a VERY GOOD REASON. See #3670
+*/
+fn add_u16(dest: &mut ~[u8], val: u16) {
+    *dest += ~[(val & 0xffu16) as u8, (val >> 8u16) as u8];
 }
 
-fn add_substr(&dest: ~[u8], src: ~[u8]) {
+fn add_substr(dest: &mut ~[u8], src: ~[u8]) {
     add_u16(dest, vec::len(src) as u16);
-    dest += src;
+    *dest += src;
 }
 

From 95d9c8699c252f3dfe1836e93a47718d14983165 Mon Sep 17 00:00:00 2001
From: Brian Anderson 
Date: Fri, 5 Oct 2012 19:10:41 -0700
Subject: [PATCH 76/80] docs: Simplify a tutorial example

---
 doc/tutorial.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/tutorial.md b/doc/tutorial.md
index d5a2f66b1c0a..9688989abc9d 100644
--- a/doc/tutorial.md
+++ b/doc/tutorial.md
@@ -1558,7 +1558,7 @@ access local variables in the enclosing scope.
 
 ~~~~
 let mut max = 0;
-(~[1, 2, 3]).map(|x| if *x > max { max = *x });
+[1, 2, 3].map(|x| if *x > max { max = *x });
 ~~~~
 
 Stack closures are very efficient because their environment is

From e90425999e59983f5140a070c250968c265e2456 Mon Sep 17 00:00:00 2001
From: Brian Anderson 
Date: Fri, 5 Oct 2012 19:51:36 -0700
Subject: [PATCH 77/80] docs: Remove some 'extern mod std's from tutorial

---
 doc/tutorial.md | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/doc/tutorial.md b/doc/tutorial.md
index 9688989abc9d..bf262105f6e4 100644
--- a/doc/tutorial.md
+++ b/doc/tutorial.md
@@ -162,12 +162,7 @@ and functions defined in it. If it has a `main` function, it can be
 compiled to an executable. Rust does not allow code that's not a
 declaration to appear at the top level of the file—all statements must
 live inside a function.  Rust programs can also be compiled as
-libraries, and included in other programs. The `extern mod std`
-directive that appears at the top of many examples imports the
-[standard library][std], described in more detail [later
-on](#modules-and-crates).
-
-[std]: http://doc.rust-lang.org/doc/std
+libraries, and included in other programs.
 
 ## Editing Rust code
 
@@ -1586,8 +1581,7 @@ This code creates a closure that adds a given string to its argument,
 returns it from a function, and then calls it:
 
 ~~~~
-extern mod std;
-
+# extern mod std;
 fn mk_appender(suffix: ~str) -> fn@(~str) -> ~str {
     return fn@(s: ~str) -> ~str { s + suffix };
 }

From 688a920045627a3afa8ef46ee9d62b253ccfa243 Mon Sep 17 00:00:00 2001
From: Tim Chevalier 
Date: Fri, 5 Oct 2012 21:02:56 -0700
Subject: [PATCH 78/80] Register snapshots

---
 src/snapshots.txt | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/snapshots.txt b/src/snapshots.txt
index 0ce74d2d5633..e1469d99d2b7 100644
--- a/src/snapshots.txt
+++ b/src/snapshots.txt
@@ -1,3 +1,11 @@
+S 2012-10-05 937f8f4
+  macos-i386 8b5ddc78b3004e539c6fbe224e492e4a6a1bc867
+  macos-x86_64 03793e0136512c644edfb5f13cc5bb7d67fb24e5
+  freebsd-x86_64 f7f4b402f06b9344fe327a9aa0282aa4ac18fcb0
+  linux-i386 789223cb3db37f6f81f48dff5fa202311fae6c2b
+  linux-x86_64 b5f1ada95528ac5b24d2b3dd3c817b8bcfc3302e
+  winnt-i386 e984437412dc4450931e0bb7ed140652bd66443c
+
 S 2012-10-03 5585514
   macos-i386 c910d42405e66b444b7870ea66b93e1135776df3
   macos-x86_64 e0dfa93e8d0d25b91c9684d4f6e92dec521e2d74

From 05999290e23ad5f57bdfbfd56bde694a627c342e Mon Sep 17 00:00:00 2001
From: Tim Chevalier 
Date: Fri, 5 Oct 2012 17:19:50 -0700
Subject: [PATCH 79/80] Finally removing all uses of by-mut-ref

The code for the mode itself is still there.
---
 src/libcore/at_vec.rs         |  18 ------
 src/libcore/vec.rs            |  46 --------------
 src/libstd/arena.rs           | 115 ----------------------------------
 src/libstd/time.rs            |  33 ++--------
 src/libsyntax/parse/parser.rs |   3 +-
 5 files changed, 6 insertions(+), 209 deletions(-)

diff --git a/src/libcore/at_vec.rs b/src/libcore/at_vec.rs
index 8c023a7cb4c0..ce3dec89e418 100644
--- a/src/libcore/at_vec.rs
+++ b/src/libcore/at_vec.rs
@@ -21,10 +21,6 @@ extern mod rustrt {
 #[abi = "rust-intrinsic"]
 extern mod rusti {
     #[legacy_exports];
-    #[cfg(stage0)]
-    fn move_val_init(&dst: T, -src: T);
-    #[cfg(stage1)]
-    #[cfg(stage2)]
     fn move_val_init(dst: &mut T, -src: T);
 }
 
@@ -181,20 +177,6 @@ pub mod raw {
         }
     }
 
-    // This doesn't bother to make sure we have space.
-    #[cfg(stage0)]
-    #[inline(always)] // really pretty please
-    pub unsafe fn push_fast(v: &mut @[const T], initval: T) {
-        let repr: **VecRepr = ::cast::reinterpret_cast(&v);
-        let fill = (**repr).unboxed.fill;
-        (**repr).unboxed.fill += sys::size_of::();
-        let p = addr_of(&((**repr).unboxed.data));
-        let p = ptr::offset(p, fill) as *mut T;
-        rusti::move_val_init(*p, move initval);
-    }
-    // This doesn't bother to make sure we have space.
-    #[cfg(stage1)]
-    #[cfg(stage2)]
     #[inline(always)] // really pretty please
     pub unsafe fn push_fast(v: &mut @[const T], initval: T) {
         let repr: **VecRepr = ::cast::reinterpret_cast(&v);
diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs
index ce1193aa730e..3a2b73f5b5b4 100644
--- a/src/libcore/vec.rs
+++ b/src/libcore/vec.rs
@@ -18,10 +18,6 @@ extern mod rustrt {
 
 #[abi = "rust-intrinsic"]
 extern mod rusti {
-    #[cfg(stage0)]
-    fn move_val_init(&dst: T, -src: T);
-    #[cfg(stage1)]
-    #[cfg(stage2)]
     fn move_val_init(dst: &mut T, -src: T);
 }
 
@@ -103,23 +99,6 @@ pub pure fn len(v: &[const T]) -> uint {
  * Creates an immutable vector of size `n_elts` and initializes the elements
  * to the value returned by the function `op`.
  */
-#[cfg(stage0)]
-pub pure fn from_fn(n_elts: uint, op: iter::InitOp) -> ~[T] {
-    unsafe {
-        let mut v = with_capacity(n_elts);
-        do as_mut_buf(v) |p, _len| {
-            let mut i: uint = 0u;
-            while i < n_elts {
-                rusti::move_val_init(*ptr::mut_offset(p, i), op(i));
-                i += 1u;
-            }
-        }
-        raw::set_len(&mut v, n_elts);
-        return move v;
-    }
-}
-#[cfg(stage1)]
-#[cfg(stage2)]
 pub pure fn from_fn(n_elts: uint, op: iter::InitOp) -> ~[T] {
     unsafe {
         let mut v = with_capacity(n_elts);
@@ -503,19 +482,6 @@ pub fn push(v: &mut ~[T], initval: T) {
     }
 }
 
-#[cfg(stage0)]
-// This doesn't bother to make sure we have space.
-#[inline(always)] // really pretty please
-unsafe fn push_fast(v: &mut ~[T], initval: T) {
-    let repr: **raw::VecRepr = ::cast::transmute(v);
-    let fill = (**repr).unboxed.fill;
-    (**repr).unboxed.fill += sys::size_of::();
-    let p = addr_of(&((**repr).unboxed.data));
-    let p = ptr::offset(p, fill) as *mut T;
-    rusti::move_val_init(*p, move initval);
-}
-#[cfg(stage1)]
-#[cfg(stage2)]
 // This doesn't bother to make sure we have space.
 #[inline(always)] // really pretty please
 unsafe fn push_fast(v: &mut ~[T], initval: T) {
@@ -1793,18 +1759,6 @@ pub mod raw {
         as_const_buf(v, |p, _len| *ptr::const_offset(p, i))
     }
 
-    #[cfg(stage0)]
-    #[inline(always)]
-    pub unsafe fn init_elem(v: &[mut T], i: uint, val: T) {
-        let mut box = Some(move val);
-        do as_mut_buf(v) |p, _len| {
-            let mut box2 = None;
-            box2 <-> box;
-            rusti::move_val_init(*ptr::mut_offset(p, i),
-                                 option::unwrap(move box2));
-        }
-    }
-    #[cfg(stage1)]
     /**
      * Unchecked vector index assignment.  Does not drop the
      * old value and hence is only suitable when the vector
diff --git a/src/libstd/arena.rs b/src/libstd/arena.rs
index 69478b3e731f..6a2ac88f7143 100644
--- a/src/libstd/arena.rs
+++ b/src/libstd/arena.rs
@@ -31,10 +31,6 @@ use libc::size_t;
 
 #[abi = "rust-intrinsic"]
 extern mod rusti {
-    #[cfg(stage0)]
-    fn move_val_init(&dst: T, -src: T);
-    #[cfg(stage1)]
-    #[cfg(stage2)]
     fn move_val_init(dst: &mut T, -src: T);
     fn needs_drop() -> bool;
 }
@@ -132,117 +128,6 @@ unsafe fn un_bitpack_tydesc_ptr(p: uint) -> (*TypeDesc, bool) {
     (reinterpret_cast(&(p & !1)), p & 1 == 1)
 }
 
-// tjc: Can get rid of the duplication post-snapshot
-#[cfg(stage0)]
-// The duplication between the POD and non-POD functions is annoying.
-impl &Arena {
-    // Functions for the POD part of the arena
-    fn alloc_pod_grow(n_bytes: uint, align: uint) -> *u8 {
-        // Allocate a new chunk.
-        let chunk_size = at_vec::capacity(self.pod_head.data);
-        let new_min_chunk_size = uint::max(n_bytes, chunk_size);
-        self.chunks = @Cons(copy self.pod_head, self.chunks);
-        self.pod_head =
-            chunk(uint::next_power_of_two(new_min_chunk_size + 1u), true);
-
-        return self.alloc_pod_inner(n_bytes, align);
-    }
-
-    #[inline(always)]
-    fn alloc_pod_inner(n_bytes: uint, align: uint) -> *u8 {
-        let head = &mut self.pod_head;
-
-        let start = round_up_to(head.fill, align);
-        let end = start + n_bytes;
-        if end > at_vec::capacity(head.data) {
-            return self.alloc_pod_grow(n_bytes, align);
-        }
-        head.fill = end;
-
-        //debug!("idx = %u, size = %u, align = %u, fill = %u",
-        //       start, n_bytes, align, head.fill);
-
-        unsafe {
-            ptr::offset(vec::raw::to_ptr(head.data), start)
-        }
-    }
-
-    #[inline(always)]
-    fn alloc_pod(op: fn() -> T) -> &self/T {
-        unsafe {
-            let tydesc = sys::get_type_desc::();
-            let ptr = self.alloc_pod_inner((*tydesc).size, (*tydesc).align);
-            let ptr: *mut T = reinterpret_cast(&ptr);
-            rusti::move_val_init(*ptr, op());
-            return reinterpret_cast(&ptr);
-        }
-    }
-
-    // Functions for the non-POD part of the arena
-    fn alloc_nonpod_grow(n_bytes: uint, align: uint) -> (*u8, *u8) {
-        // Allocate a new chunk.
-        let chunk_size = at_vec::capacity(self.head.data);
-        let new_min_chunk_size = uint::max(n_bytes, chunk_size);
-        self.chunks = @Cons(copy self.head, self.chunks);
-        self.head =
-            chunk(uint::next_power_of_two(new_min_chunk_size + 1u), false);
-
-        return self.alloc_nonpod_inner(n_bytes, align);
-    }
-
-    #[inline(always)]
-    fn alloc_nonpod_inner(n_bytes: uint, align: uint) -> (*u8, *u8) {
-        let head = &mut self.head;
-
-        let tydesc_start = head.fill;
-        let after_tydesc = head.fill + sys::size_of::<*TypeDesc>();
-        let start = round_up_to(after_tydesc, align);
-        let end = start + n_bytes;
-        if end > at_vec::capacity(head.data) {
-            return self.alloc_nonpod_grow(n_bytes, align);
-        }
-        head.fill = round_up_to(end, sys::pref_align_of::<*TypeDesc>());
-
-        //debug!("idx = %u, size = %u, align = %u, fill = %u",
-        //       start, n_bytes, align, head.fill);
-
-        unsafe {
-            let buf = vec::raw::to_ptr(head.data);
-            return (ptr::offset(buf, tydesc_start), ptr::offset(buf, start));
-        }
-    }
-
-    #[inline(always)]
-    fn alloc_nonpod(op: fn() -> T) -> &self/T {
-        unsafe {
-            let tydesc = sys::get_type_desc::();
-            let (ty_ptr, ptr) =
-                self.alloc_nonpod_inner((*tydesc).size, (*tydesc).align);
-            let ty_ptr: *mut uint = reinterpret_cast(&ty_ptr);
-            let ptr: *mut T = reinterpret_cast(&ptr);
-            // Write in our tydesc along with a bit indicating that it
-            // has *not* been initialized yet.
-            *ty_ptr = reinterpret_cast(&tydesc);
-            // Actually initialize it
-            rusti::move_val_init(*ptr, op());
-            // Now that we are done, update the tydesc to indicate that
-            // the object is there.
-            *ty_ptr = bitpack_tydesc_ptr(tydesc, true);
-
-            return reinterpret_cast(&ptr);
-        }
-    }
-
-    // The external interface
-    #[inline(always)]
-    fn alloc(op: fn() -> T) -> &self/T {
-        if !rusti::needs_drop::() {
-            self.alloc_pod(op)
-        } else { self.alloc_nonpod(op) }
-    }
-}
-#[cfg(stage1)]
-#[cfg(stage2)]
 impl &Arena {
     // Functions for the POD part of the arena
     fn alloc_pod_grow(n_bytes: uint, align: uint) -> *u8 {
diff --git a/src/libstd/time.rs b/src/libstd/time.rs
index 8fa1e0cf3f0a..65872a013aba 100644
--- a/src/libstd/time.rs
+++ b/src/libstd/time.rs
@@ -8,24 +8,16 @@ use result::{Result, Ok, Err};
 #[abi = "cdecl"]
 extern mod rustrt {
     #[legacy_exports]
-    #[cfg(stage0)]
-    fn get_time(&sec: i64, &nsec: i32);
-    #[cfg(stage1)]
-    #[cfg(stage2)]
     fn get_time(sec: &mut i64, nsec: &mut i32);
 
-    #[cfg(stage0)]
-    fn precise_time_ns(&ns: u64);
-    #[cfg(stage1)]
-    #[cfg(stage2)]
     fn precise_time_ns(ns: &mut u64);
 
     fn rust_tzset();
     // FIXME: The i64 values can be passed by-val when #2064 is fixed.
     fn rust_gmtime(&&sec: i64, &&nsec: i32, &&result: Tm);
     fn rust_localtime(&&sec: i64, &&nsec: i32, &&result: Tm);
-    fn rust_timegm(&&tm: Tm, &sec: i64);
-    fn rust_mktime(&&tm: Tm, &sec: i64);
+    fn rust_timegm(&&tm: Tm, sec: &mut i64);
+    fn rust_mktime(&&tm: Tm, sec: &mut i64);
 }
 
 /// A record specifying a time value in seconds and nanoseconds.
@@ -42,15 +34,6 @@ impl Timespec : Eq {
  * Returns the current time as a `timespec` containing the seconds and
  * nanoseconds since 1970-01-01T00:00:00Z.
  */
-#[cfg(stage0)]
-pub fn get_time() -> Timespec {
-    let mut sec = 0i64;
-    let mut nsec = 0i32;
-    rustrt::get_time(sec, nsec);
-    return {sec: sec, nsec: nsec};
-}
-#[cfg(stage1)]
-#[cfg(stage2)]
 pub fn get_time() -> Timespec {
     let mut sec = 0i64;
     let mut nsec = 0i32;
@@ -63,14 +46,6 @@ pub fn get_time() -> Timespec {
  * Returns the current value of a high-resolution performance counter
  * in nanoseconds since an unspecified epoch.
  */
-#[cfg(stage0)]
-pub fn precise_time_ns() -> u64 {
-    let mut ns = 0u64;
-    rustrt::precise_time_ns(ns);
-    ns
-}
-#[cfg(stage1)]
-#[cfg(stage2)]
 pub fn precise_time_ns() -> u64 {
     let mut ns = 0u64;
     rustrt::precise_time_ns(&mut ns);
@@ -790,9 +765,9 @@ impl Tm {
     fn to_timespec() -> Timespec {
         let mut sec = 0i64;
         if self.tm_gmtoff == 0_i32 {
-            rustrt::rust_timegm(self, sec);
+            rustrt::rust_timegm(self, &mut sec);
         } else {
-            rustrt::rust_mktime(self, sec);
+            rustrt::rust_mktime(self, &mut sec);
         }
         { sec: sec, nsec: self.tm_nsec }
     }
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index bc0beec5b36e..6bee9190a832 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -570,7 +570,8 @@ impl parser {
 
     fn parse_arg_mode() -> mode {
         if self.eat(token::BINOP(token::AND)) {
-            self.warn(~"Obsolete syntax has no effect");
+            self.span_fatal(copy self.last_span,
+                            ~"Obsolete syntax has no effect");
             expl(by_mutbl_ref)
         } else if self.eat(token::BINOP(token::MINUS)) {
             expl(by_move)

From f96a2a2ca16a44f869336f7e28fc261551c1184c Mon Sep 17 00:00:00 2001
From: Tim Chevalier 
Date: Fri, 5 Oct 2012 22:07:53 -0700
Subject: [PATCH 80/80] Remove by-mutable-ref mode from the compiler

and test cases. Closes #3513
---
 doc/rust.md                                   | 10 +++-----
 src/libsyntax/ast.rs                          |  2 +-
 src/libsyntax/parse/obsolete.rs               |  7 +++++-
 src/libsyntax/parse/parser.rs                 | 11 ++++----
 src/libsyntax/print/pprust.rs                 |  1 -
 src/rustc/metadata/tydecode.rs                |  1 -
 src/rustc/metadata/tyencode.rs                |  1 -
 src/rustc/middle/borrowck/check_loans.rs      |  2 +-
 src/rustc/middle/borrowck/gather_loans.rs     |  4 ---
 src/rustc/middle/kind.rs                      | 13 +++-------
 src/rustc/middle/liveness.rs                  | 25 +++----------------
 src/rustc/middle/mem_categorization.rs        |  3 ---
 src/rustc/middle/trans/base.rs                |  2 +-
 src/rustc/middle/trans/callee.rs              |  2 +-
 src/rustc/middle/trans/meth.rs                |  2 +-
 src/rustc/middle/trans/reflect.rs             |  1 -
 src/rustc/middle/trans/type_use.rs            |  2 +-
 .../bench/task-perf-word-count-generic.rs     | 16 ++++++------
 .../compile-fail/deprecated-mode-fn-arg.rs    |  6 ++---
 .../compile-fail/unnamed_argument_mode.rs     |  5 +---
 src/test/run-pass/argument-passing.rs         |  8 +++---
 src/test/run-pass/fn-bare-assign.rs           |  8 +++---
 src/test/run-pass/lazy-and-or.rs              |  4 +--
 src/test/run-pass/mutable-alias-vec.rs        |  8 +++---
 src/test/run-pass/unique-fn-arg-mut.rs        |  6 ++---
 src/test/run-pass/writealias.rs               |  4 +--
 26 files changed, 59 insertions(+), 95 deletions(-)

diff --git a/doc/rust.md b/doc/rust.md
index 31c52300312c..66552c29017f 100644
--- a/doc/rust.md
+++ b/doc/rust.md
@@ -2784,14 +2784,12 @@ aside a copy of that value to refer to. If this is not semantically safe (for
 example, if the referred-to value contains mutable fields), it will reject the
 program. If the compiler deems copying the value expensive, it will warn.
 
-A function can be declared to take an argument by mutable reference. This
-allows the function to write to the slot that the reference refers to.
-
-An example function that accepts an value by mutable reference:
+A function with an argument of type `&mut T`, for some type `T`, can write to
+the slot that its argument refers to. An example of such a function is:
 
 ~~~~~~~~
-fn incr(&i: int) {
-    i = i + 1;
+fn incr(i: &mut int) {
+    *i = *i + 1;
 }
 ~~~~~~~~
 
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index e17b52fb27d1..a50189cf5989 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -574,7 +574,7 @@ impl inferable : cmp::Eq {
 
 // "resolved" mode: the real modes.
 #[auto_serialize]
-enum rmode { by_ref, by_val, by_mutbl_ref, by_move, by_copy }
+enum rmode { by_ref, by_val, by_move, by_copy }
 
 impl rmode : to_bytes::IterBytes {
     pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) {
diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs
index 782535f5c2b2..828d498ca3c2 100644
--- a/src/libsyntax/parse/obsolete.rs
+++ b/src/libsyntax/parse/obsolete.rs
@@ -22,7 +22,8 @@ pub enum ObsoleteSyntax {
     ObsoleteClassMethod,
     ObsoleteClassTraits,
     ObsoletePrivSection,
-    ObsoleteModeInFnType
+    ObsoleteModeInFnType,
+    ObsoleteByMutRefMode
 }
 
 impl ObsoleteSyntax : cmp::Eq {
@@ -94,6 +95,10 @@ impl parser : ObsoleteReporter {
                 "to use a (deprecated) mode in a fn type, you should \
                  give the argument an explicit name (like `&&v: int`)"
             ),
+            ObsoleteByMutRefMode => (
+                "by-mutable-reference mode",
+                "Declare an argument of type &mut T instead"
+            ),
         };
 
         self.report(sp, kind, kind_str, desc);
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 6bee9190a832..22c25186c918 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -20,13 +20,13 @@ use obsolete::{
     ObsoleteLowerCaseKindBounds, ObsoleteLet,
     ObsoleteFieldTerminator, ObsoleteStructCtor,
     ObsoleteWith, ObsoleteClassMethod, ObsoleteClassTraits,
-    ObsoleteModeInFnType
+    ObsoleteModeInFnType, ObsoleteByMutRefMode
 };
 use ast::{_mod, add, alt_check, alt_exhaustive, arg, arm, attribute,
              bind_by_ref, bind_by_implicit_ref, bind_by_value, bind_by_move,
              bitand, bitor, bitxor, blk, blk_check_mode, bound_const,
              bound_copy, bound_send, bound_trait, bound_owned, box, by_copy,
-             by_move, by_mutbl_ref, by_ref, by_val, capture_clause,
+             by_move, by_ref, by_val, capture_clause,
              capture_item, cdir_dir_mod, cdir_src_mod, cdir_view_item,
              class_immutable, class_mutable,
              crate, crate_cfg, crate_directive, decl, decl_item, decl_local,
@@ -570,9 +570,10 @@ impl parser {
 
     fn parse_arg_mode() -> mode {
         if self.eat(token::BINOP(token::AND)) {
-            self.span_fatal(copy self.last_span,
-                            ~"Obsolete syntax has no effect");
-            expl(by_mutbl_ref)
+            self.obsolete(copy self.span,
+                          ObsoleteByMutRefMode);
+            // Bogus mode, but doesn't matter since it's an error
+            expl(by_ref)
         } else if self.eat(token::BINOP(token::MINUS)) {
             expl(by_move)
         } else if self.eat(token::ANDAND) {
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index d08b20eed843..bff356e5cb72 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1688,7 +1688,6 @@ fn print_fn_block_args(s: ps, decl: ast::fn_decl,
 
 fn mode_to_str(m: ast::mode) -> ~str {
     match m {
-      ast::expl(ast::by_mutbl_ref) => ~"&",
       ast::expl(ast::by_move) => ~"-",
       ast::expl(ast::by_ref) => ~"&&",
       ast::expl(ast::by_val) => ~"++",
diff --git a/src/rustc/metadata/tydecode.rs b/src/rustc/metadata/tydecode.rs
index f3fa0e3f3507..1375ff2d0be0 100644
--- a/src/rustc/metadata/tydecode.rs
+++ b/src/rustc/metadata/tydecode.rs
@@ -394,7 +394,6 @@ fn parse_arg(st: @pstate, conv: conv_did) -> ty::arg {
 
 fn parse_mode(st: @pstate) -> ast::mode {
     let m = ast::expl(match next(st) {
-        '&' => ast::by_mutbl_ref,
         '-' => ast::by_move,
         '+' => ast::by_copy,
         '=' => ast::by_ref,
diff --git a/src/rustc/metadata/tyencode.rs b/src/rustc/metadata/tyencode.rs
index 611ffb598ae5..69689b16e154 100644
--- a/src/rustc/metadata/tyencode.rs
+++ b/src/rustc/metadata/tyencode.rs
@@ -333,7 +333,6 @@ fn enc_arg(w: io::Writer, cx: @ctxt, arg: ty::arg) {
 
 fn enc_mode(w: io::Writer, cx: @ctxt, m: mode) {
     match ty::resolved_mode(cx.tcx, m) {
-      by_mutbl_ref => w.write_char('&'),
       by_move => w.write_char('-'),
       by_copy => w.write_char('+'),
       by_ref => w.write_char('='),
diff --git a/src/rustc/middle/borrowck/check_loans.rs b/src/rustc/middle/borrowck/check_loans.rs
index 5ff2a8933a91..cc8d89a8ace7 100644
--- a/src/rustc/middle/borrowck/check_loans.rs
+++ b/src/rustc/middle/borrowck/check_loans.rs
@@ -529,7 +529,7 @@ impl check_loan_ctxt {
                 ast::by_move => {
                     self.check_move_out(*arg);
                 }
-                ast::by_mutbl_ref | ast::by_ref |
+                ast::by_ref |
                 ast::by_copy | ast::by_val => {
                 }
             }
diff --git a/src/rustc/middle/borrowck/gather_loans.rs b/src/rustc/middle/borrowck/gather_loans.rs
index 327db51518be..5dfde8c9af64 100644
--- a/src/rustc/middle/borrowck/gather_loans.rs
+++ b/src/rustc/middle/borrowck/gather_loans.rs
@@ -115,10 +115,6 @@ fn req_loans_in_expr(ex: @ast::expr,
         let scope_r = ty::re_scope(ex.id);
         for vec::each2(args, arg_tys) |arg, arg_ty| {
             match ty::resolved_mode(self.tcx(), arg_ty.mode) {
-              ast::by_mutbl_ref => {
-                let arg_cmt = self.bccx.cat_expr(*arg);
-                self.guarantee_valid(arg_cmt, m_mutbl, scope_r);
-              }
               ast::by_ref => {
                 let arg_cmt = self.bccx.cat_expr(*arg);
                 self.guarantee_valid(arg_cmt, m_imm,  scope_r);
diff --git a/src/rustc/middle/kind.rs b/src/rustc/middle/kind.rs
index 9aff382775c8..e2b85441a8fd 100644
--- a/src/rustc/middle/kind.rs
+++ b/src/rustc/middle/kind.rs
@@ -323,7 +323,7 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt) {
         for ty::ty_fn_args(ty::expr_ty(cx.tcx, f)).each |arg_t| {
             match ty::arg_mode(cx.tcx, *arg_t) {
               by_copy => maybe_copy(cx, args[i], None),
-              by_ref | by_val | by_mutbl_ref | by_move => ()
+              by_ref | by_val | by_move => ()
             }
             i += 1u;
         }
@@ -335,7 +335,7 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt) {
             Some(ref mme) => {
                 match ty::arg_mode(cx.tcx, mme.self_arg) {
                     by_copy => maybe_copy(cx, lhs, None),
-                    by_ref | by_val | by_mutbl_ref | by_move => ()
+                    by_ref | by_val | by_move => ()
                 }
             }
             _ => ()
@@ -465,14 +465,7 @@ fn check_imm_free_var(cx: ctx, def: def, sp: span) {
             cx.tcx.sess.span_err(sp, msg);
         }
       }
-      def_arg(_, mode) => {
-        match ty::resolved_mode(cx.tcx, mode) {
-          by_ref | by_val | by_move | by_copy => { /* ok */ }
-          by_mutbl_ref => {
-            cx.tcx.sess.span_err(sp, msg);
-          }
-        }
-      }
+      def_arg(*) => { /* ok */ }
       def_upvar(_, def1, _, _) => {
         check_imm_free_var(cx, *def1, sp);
       }
diff --git a/src/rustc/middle/liveness.rs b/src/rustc/middle/liveness.rs
index 6b39a21a7ba5..12d63cdacbf6 100644
--- a/src/rustc/middle/liveness.rs
+++ b/src/rustc/middle/liveness.rs
@@ -398,7 +398,7 @@ impl IrMaps {
 
             (*v).push(id);
           }
-          Arg(_, _, by_ref) | Arg(_, _, by_mutbl_ref) |
+          Arg(_, _, by_ref) |
           Arg(_, _, by_val) | Self | Field(_) | ImplicitRet |
           Local(LocalInfo {kind: FromMatch(bind_by_implicit_ref), _}) => {
             debug!("--but it is not owned");
@@ -919,7 +919,7 @@ impl Liveness {
         // inputs passed by & mode should be considered live on exit:
         for decl.inputs.each |arg| {
             match ty::resolved_mode(self.tcx, arg.mode) {
-              by_mutbl_ref | by_ref | by_val => {
+              by_ref | by_val => {
                 // These are "non-owned" modes, so register a read at
                 // the end.  This will prevent us from moving out of
                 // such variables but also prevent us from registering
@@ -1573,7 +1573,7 @@ fn check_expr(expr: @expr, &&self: @Liveness, vt: vt<@Liveness>) {
         let targs = ty::ty_fn_args(ty::expr_ty(self.tcx, f));
         for vec::each2(args, targs) |arg_expr, arg_ty| {
             match ty::resolved_mode(self.tcx, arg_ty.mode) {
-                by_val | by_copy | by_ref | by_mutbl_ref => {}
+                by_val | by_copy | by_ref => {}
                 by_move => {
                     self.check_move_from_expr(*arg_expr, vt);
                 }
@@ -1865,24 +1865,7 @@ impl @Liveness {
     fn warn_about_unused_args(sp: span, decl: fn_decl, entry_ln: LiveNode) {
         for decl.inputs.each |arg| {
             let var = self.variable(arg.id, arg.ty.span);
-            match ty::resolved_mode(self.tcx, arg.mode) {
-              by_mutbl_ref => {
-                // for mutable reference arguments, something like
-                //    x = 1;
-                // is not worth warning about, as it has visible
-                // side effects outside the fn.
-                match self.assigned_on_entry(entry_ln, var) {
-                  Some(_) => { /*ok*/ }
-                  None => {
-                    // but if it is not written, it ought to be used
-                    self.warn_about_unused(sp, entry_ln, var);
-                  }
-                }
-              }
-              by_val | by_ref | by_move | by_copy => {
-                self.warn_about_unused(sp, entry_ln, var);
-              }
-            }
+            self.warn_about_unused(sp, entry_ln, var);
         }
     }
 
diff --git a/src/rustc/middle/mem_categorization.rs b/src/rustc/middle/mem_categorization.rs
index fe465db1312c..dc5874ea2cfa 100644
--- a/src/rustc/middle/mem_categorization.rs
+++ b/src/rustc/middle/mem_categorization.rs
@@ -523,9 +523,6 @@ impl &mem_categorization_ctxt {
             // m: mutability of the argument
             // lp: loan path, must be none for aliasable things
             let {m,lp} = match ty::resolved_mode(self.tcx, mode) {
-              ast::by_mutbl_ref => {
-                {m: m_mutbl, lp: None}
-              }
               ast::by_move | ast::by_copy => {
                 {m: m_imm, lp: Some(@lp_arg(vid))}
               }
diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs
index afa008fdbb77..95711f8da36a 100644
--- a/src/rustc/middle/trans/base.rs
+++ b/src/rustc/middle/trans/base.rs
@@ -1503,7 +1503,7 @@ fn copy_args_to_allocas(fcx: fn_ctxt,
         // the event it's not truly needed.
         let llarg;
         match ty::resolved_mode(tcx, arg_ty.mode) {
-            ast::by_ref | ast::by_mutbl_ref => {
+            ast::by_ref => {
                 llarg = raw_llarg;
             }
             ast::by_move | ast::by_copy => {
diff --git a/src/rustc/middle/trans/callee.rs b/src/rustc/middle/trans/callee.rs
index e7b4dd171e31..c851c5bc7250 100644
--- a/src/rustc/middle/trans/callee.rs
+++ b/src/rustc/middle/trans/callee.rs
@@ -592,7 +592,7 @@ fn trans_arg_expr(bcx: block,
             DoAutorefArg => { val = arg_datum.to_ref_llval(bcx); }
             DontAutorefArg => {
                 match arg_mode {
-                    ast::by_ref | ast::by_mutbl_ref => {
+                    ast::by_ref => {
                         val = arg_datum.to_ref_llval(bcx);
                     }
 
diff --git a/src/rustc/middle/trans/meth.rs b/src/rustc/middle/trans/meth.rs
index b4a64abeed7e..d8a2fda4d14b 100644
--- a/src/rustc/middle/trans/meth.rs
+++ b/src/rustc/middle/trans/meth.rs
@@ -154,7 +154,7 @@ fn trans_method_callee(bcx: block, callee_id: ast::node_id,
         typeck::method_trait(_, off, vstore) => {
             trans_trait_callee(bcx, callee_id, off, self, vstore)
         }
-        typeck::method_self(_, off) => {
+        typeck::method_self(*) => {
             bcx.tcx().sess.span_bug(self.span, ~"self method call");
         }
     }
diff --git a/src/rustc/middle/trans/reflect.rs b/src/rustc/middle/trans/reflect.rs
index 3996f0ff5ee2..c105caecaebb 100644
--- a/src/rustc/middle/trans/reflect.rs
+++ b/src/rustc/middle/trans/reflect.rs
@@ -210,7 +210,6 @@ impl reflector {
                   ast::expl(e) => match e {
                     ast::by_ref => 1u,
                     ast::by_val => 2u,
-                    ast::by_mutbl_ref => 3u,
                     ast::by_move => 4u,
                     ast::by_copy => 5u
                   }
diff --git a/src/rustc/middle/trans/type_use.rs b/src/rustc/middle/trans/type_use.rs
index 8eabf26e2178..ee247eb5db79 100644
--- a/src/rustc/middle/trans/type_use.rs
+++ b/src/rustc/middle/trans/type_use.rs
@@ -53,7 +53,7 @@ fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint)
                     by_val | by_move | by_copy => {
                         type_needs(cx, use_repr, arg.ty);
                     }
-                    by_ref | by_mutbl_ref => {}
+                    by_ref => {}
                 }
             }
         }
diff --git a/src/test/bench/task-perf-word-count-generic.rs b/src/test/bench/task-perf-word-count-generic.rs
index 97b031c6024a..30add8c730c7 100644
--- a/src/test/bench/task-perf-word-count-generic.rs
+++ b/src/test/bench/task-perf-word-count-generic.rs
@@ -144,7 +144,7 @@ mod map_reduce {
     fn start_mappers(
         map: &mapper,
-        &ctrls: ~[ctrl_proto::server::open],
+        ctrls: &mut ~[ctrl_proto::server::open],
         inputs: &~[K1])
         -> ~[joinable_task]
     {
@@ -213,9 +213,9 @@ mod map_reduce {
         let mut is_done = false;
 
         fn get(p: Port>,
-                             &ref_count: int, &is_done: bool)
+                             ref_count: &mut int, is_done: &mut bool)
            -> Option {
-            while !is_done || ref_count > 0 {
+            while !*is_done || *ref_count > 0 {
                 match recv(p) {
                   emit_val(v) => {
                     // error!("received %d", v);
@@ -223,16 +223,16 @@ mod map_reduce {
                   }
                   done => {
                     // error!("all done");
-                    is_done = true;
+                    *is_done = true;
                   }
-                  addref => { ref_count += 1; }
-                  release => { ref_count -= 1; }
+                  addref => { *ref_count += 1; }
+                  release => { *ref_count -= 1; }
                 }
             }
             return None;
         }
 
-        (*reduce)(&key, || get(p, ref_count, is_done) );
+        (*reduce)(&key, || get(p, &mut ref_count, &mut is_done) );
     }
 
     fn map_reduce(
@@ -246,7 +246,7 @@ mod map_reduce {
         // to do the rest.
 
         let reducers = map::HashMap();
-        let mut tasks = start_mappers(&map, ctrl, &inputs);
+        let mut tasks = start_mappers(&map, &mut ctrl, &inputs);
         let mut num_mappers = vec::len(inputs) as int;
 
         while num_mappers > 0 {
diff --git a/src/test/compile-fail/deprecated-mode-fn-arg.rs b/src/test/compile-fail/deprecated-mode-fn-arg.rs
index 2c20e604f502..bb466e2c00b8 100644
--- a/src/test/compile-fail/deprecated-mode-fn-arg.rs
+++ b/src/test/compile-fail/deprecated-mode-fn-arg.rs
@@ -1,11 +1,9 @@
 #[forbid(deprecated_mode)];
 
-fn foo(_f: fn(&i: int)) { //~ ERROR explicit mode
-    //~^ WARNING Obsolete syntax has no effect
+fn foo(_f: fn(&i: int)) { //~ ERROR by-mutable-reference mode
 }
 
-type Bar = fn(&i: int); //~ ERROR explicit mode
-    //~^ WARNING Obsolete syntax has no effect
+type Bar = fn(&i: int); //~ ERROR by-mutable-reference mode
 
 fn main() {
 }
\ No newline at end of file
diff --git a/src/test/compile-fail/unnamed_argument_mode.rs b/src/test/compile-fail/unnamed_argument_mode.rs
index 36e6edc96f99..77d40aae6a27 100644
--- a/src/test/compile-fail/unnamed_argument_mode.rs
+++ b/src/test/compile-fail/unnamed_argument_mode.rs
@@ -1,11 +1,8 @@
-//error-pattern: mismatched types
+//error-pattern: by-mutable-reference mode
 
 fn bad(&a: int) {
 }
 
-// unnamed argument &int is now parsed x: &int
-// it's not parsed &x: int anymore
-
 fn called(f: fn(&int)) {
 }
 
diff --git a/src/test/run-pass/argument-passing.rs b/src/test/run-pass/argument-passing.rs
index 2a8398634551..e8aaf88374f9 100644
--- a/src/test/run-pass/argument-passing.rs
+++ b/src/test/run-pass/argument-passing.rs
@@ -1,10 +1,10 @@
 // xfail-fast
 #[legacy_modes];
 
-fn f1(a: {mut x: int}, &b: int, -c: int) -> int {
-    let r = a.x + b + c;
+fn f1(a: {mut x: int}, b: &mut int, -c: int) -> int {
+    let r = a.x + *b + c;
     a.x = 0;
-    b = 10;
+    *b = 10;
     return r;
 }
 
@@ -12,7 +12,7 @@ fn f2(a: int, f: fn(int)) -> int { f(1); return a; }
 
 fn main() {
     let mut a = {mut x: 1}, b = 2, c = 3;
-    assert (f1(a, b, c) == 6);
+    assert (f1(a, &mut b, c) == 6);
     assert (a.x == 0);
     assert (b == 10);
     assert (f2(a.x, |x| a.x = 50 ) == 0);
diff --git a/src/test/run-pass/fn-bare-assign.rs b/src/test/run-pass/fn-bare-assign.rs
index ae6b1a1079ff..71996552d0cc 100644
--- a/src/test/run-pass/fn-bare-assign.rs
+++ b/src/test/run-pass/fn-bare-assign.rs
@@ -1,15 +1,15 @@
-fn f(i: int, &called: bool) {
+fn f(i: int, called: &mut bool) {
     assert i == 10;
-    called = true;
+    *called = true;
 }
 
-fn g(f: extern fn(int, &v: bool), &called: bool) {
+fn g(f: extern fn(int, v: &mut bool), called: &mut bool) {
     f(10, called);
 }
 
 fn main() {
     let mut called = false;
     let h = f;
-    g(h, called);
+    g(h, &mut called);
     assert called == true;
 }
\ No newline at end of file
diff --git a/src/test/run-pass/lazy-and-or.rs b/src/test/run-pass/lazy-and-or.rs
index 7ad71854dc42..3e84c9f6f726 100644
--- a/src/test/run-pass/lazy-and-or.rs
+++ b/src/test/run-pass/lazy-and-or.rs
@@ -1,12 +1,12 @@
 
 
-fn incr(&x: int) -> bool { x += 1; assert (false); return false; }
+fn incr(x: &mut int) -> bool { *x += 1; assert (false); return false; }
 
 fn main() {
     let x = 1 == 2 || 3 == 3;
     assert (x);
     let mut y: int = 10;
-    log(debug, x || incr(y));
+    log(debug, x || incr(&mut y));
     assert (y == 10);
     if true && x { assert (true); } else { assert (false); }
 }
diff --git a/src/test/run-pass/mutable-alias-vec.rs b/src/test/run-pass/mutable-alias-vec.rs
index e54197ccc6b5..d5b1eef993e1 100644
--- a/src/test/run-pass/mutable-alias-vec.rs
+++ b/src/test/run-pass/mutable-alias-vec.rs
@@ -3,13 +3,13 @@
 // -*- rust -*-
 extern mod std;
 
-fn grow(&v: ~[int]) { v += ~[1]; }
+fn grow(v: &mut ~[int]) { *v += ~[1]; }
 
 fn main() {
     let mut v: ~[int] = ~[];
-    grow(v);
-    grow(v);
-    grow(v);
+    grow(&mut v);
+    grow(&mut v);
+    grow(&mut v);
     let len = vec::len::(v);
     log(debug, len);
     assert (len == 3 as uint);
diff --git a/src/test/run-pass/unique-fn-arg-mut.rs b/src/test/run-pass/unique-fn-arg-mut.rs
index 8d9386d70fff..36d1d689f5fb 100644
--- a/src/test/run-pass/unique-fn-arg-mut.rs
+++ b/src/test/run-pass/unique-fn-arg-mut.rs
@@ -1,9 +1,9 @@
-fn f(&i: ~int) {
-    i = ~200;
+fn f(i: &mut ~int) {
+    *i = ~200;
 }
 
 fn main() {
     let mut i = ~100;
-    f(i);
+    f(&mut i);
     assert *i == 200;
 }
\ No newline at end of file
diff --git a/src/test/run-pass/writealias.rs b/src/test/run-pass/writealias.rs
index 9dba2e2adfdc..eb3fa602f12a 100644
--- a/src/test/run-pass/writealias.rs
+++ b/src/test/run-pass/writealias.rs
@@ -4,10 +4,10 @@
 // -*- rust -*-
 type point = {x: int, y: int, mut z: int};
 
-fn f(&p: point) { p.z = 13; }
+fn f(p: &mut point) { p.z = 13; }
 
 fn main() {
     let mut x: point = {x: 10, y: 11, mut z: 12};
-    f(x);
+    f(&mut x);
     assert (x.z == 13);
 }