about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEric Reed <ereed@mozilla.com>2013-06-25 11:45:44 -0700
committerEric Reed <ereed@mozilla.com>2013-06-25 11:45:44 -0700
commit4870dce3ebfd0e988a2e45360c724ebe912c3ad5 (patch)
treec676e677bf36924cbf177b0723b4ffe0fc435d40
parent794923c99511398bc90400e380dd11770ec8e614 (diff)
parente65d0cbabebc73f2c9733a7ed158576c9702e71e (diff)
Merge remote-tracking branch 'upstream/io' into io
Conflicts:
	src/rt/rustrt.def.in
-rw-r--r--Makefile.in8
-rw-r--r--RELEASES.txt70
-rw-r--r--doc/rust.css21
-rw-r--r--doc/rust.md2
-rw-r--r--doc/tutorial-tasks.md2
-rw-r--r--doc/tutorial.md17
-rw-r--r--mk/clean.mk6
-rw-r--r--mk/dist.mk1
-rw-r--r--mk/pp.mk1
-rw-r--r--mk/rt.mk4
-rw-r--r--mk/tools.mk39
-rw-r--r--src/README.txt4
-rw-r--r--src/compiletest/procsrv.rs2
-rw-r--r--src/compiletest/runtest.rs1
-rw-r--r--src/driver/driver.rs3
-rw-r--r--src/etc/snapshot.py8
-rw-r--r--src/libextra/arc.rs38
-rw-r--r--src/libextra/arena.rs16
-rw-r--r--src/libextra/base64.rs2
-rw-r--r--src/libextra/bitv.rs82
-rw-r--r--src/libextra/c_vec.rs2
-rw-r--r--src/libextra/deque.rs36
-rw-r--r--src/libextra/dlist.rs21
-rw-r--r--src/libextra/flatpipes.rs9
-rw-r--r--src/libextra/future.rs2
-rw-r--r--src/libextra/list.rs4
-rw-r--r--src/libextra/net_tcp.rs269
-rw-r--r--src/libextra/num/complex.rs8
-rw-r--r--src/libextra/num/rational.rs10
-rw-r--r--src/libextra/priority_queue.rs4
-rw-r--r--src/libextra/rc.rs2
-rw-r--r--src/libextra/rope.rs1
-rw-r--r--src/libextra/semver.rs20
-rw-r--r--src/libextra/sha1.rs5
-rw-r--r--src/libextra/smallintmap.rs17
-rw-r--r--src/libextra/sort.rs25
-rw-r--r--src/libextra/stats.rs1
-rw-r--r--src/libextra/std.rc20
-rw-r--r--src/libextra/sync.rs2
-rw-r--r--src/libextra/tempfile.rs1
-rw-r--r--src/libextra/terminfo/parm.rs17
-rw-r--r--src/libextra/terminfo/parser/compiled.rs1
-rw-r--r--src/libextra/test.rs22
-rw-r--r--src/libextra/time.rs2
-rw-r--r--src/libextra/treemap.rs51
-rw-r--r--src/libextra/workcache.rs2
-rw-r--r--src/libfuzzer/ast_match.rs42
-rw-r--r--src/libfuzzer/cycles.rs108
-rw-r--r--src/libfuzzer/fuzzer.rc713
-rw-r--r--src/libfuzzer/ivec_fuzz.rs121
-rw-r--r--src/libfuzzer/rand_util.rs106
-rw-r--r--src/librustc/back/passes.rs17
-rw-r--r--src/librustc/back/rpath.rs35
-rw-r--r--src/librustc/driver/driver.rs105
-rw-r--r--src/librustc/lib/llvm.rs212
-rw-r--r--src/librustc/metadata/encoder.rs2
-rw-r--r--src/librustc/metadata/loader.rs44
-rw-r--r--src/librustc/middle/astencode.rs1
-rw-r--r--src/librustc/middle/borrowck/check_loans.rs4
-rw-r--r--src/librustc/middle/borrowck/gather_loans/gather_moves.rs6
-rw-r--r--src/librustc/middle/borrowck/mod.rs6
-rw-r--r--src/librustc/middle/borrowck/move_data.rs16
-rw-r--r--src/librustc/middle/dataflow.rs93
-rw-r--r--src/librustc/middle/liveness.rs6
-rw-r--r--src/librustc/middle/resolve.rs2
-rw-r--r--src/librustc/middle/trans/adt.rs7
-rw-r--r--src/librustc/middle/trans/base.rs37
-rw-r--r--src/librustc/middle/trans/build.rs12
-rw-r--r--src/librustc/middle/trans/closure.rs2
-rw-r--r--src/librustc/middle/trans/common.rs22
-rw-r--r--src/librustc/middle/trans/context.rs6
-rw-r--r--src/librustc/middle/trans/debuginfo.rs1181
-rw-r--r--src/librustc/middle/trans/glue.rs31
-rw-r--r--src/librustc/middle/ty.rs46
-rw-r--r--src/librustc/middle/typeck/check/mod.rs2
-rw-r--r--src/librustc/middle/typeck/check/vtable.rs11
-rw-r--r--src/librustc/middle/typeck/coherence.rs8
-rw-r--r--src/librustc/middle/typeck/infer/lattice.rs65
-rw-r--r--src/librustc/middle/typeck/infer/mod.rs4
-rw-r--r--src/librustc/middle/typeck/infer/unify.rs42
-rw-r--r--src/librustc/rustc.rc8
-rw-r--r--src/librustdoc/astsrv.rs2
-rw-r--r--src/librustdoc/attr_parser.rs4
-rw-r--r--src/librustdoc/desc_to_brief_pass.rs17
-rw-r--r--src/librustdoc/extract.rs2
-rw-r--r--src/librustdoc/markdown_pass.rs7
-rw-r--r--src/librustdoc/page_pass.rs1
-rw-r--r--src/librustdoc/prune_hidden_pass.rs2
-rw-r--r--src/librustdoc/prune_private_pass.rs1
-rw-r--r--src/librustdoc/sectionalize_pass.rs27
-rw-r--r--src/librustdoc/text_pass.rs2
-rw-r--r--src/librustdoc/unindent_pass.rs31
-rw-r--r--src/librusti/rusti.rc8
-rw-r--r--src/librustpkg/tests.rs2
-rw-r--r--src/libstd/at_vec.rs86
-rw-r--r--src/libstd/bool.rs18
-rw-r--r--src/libstd/borrow.rs16
-rw-r--r--src/libstd/cast.rs52
-rw-r--r--src/libstd/char.rs34
-rw-r--r--src/libstd/cleanup.rs116
-rw-r--r--src/libstd/clone.rs18
-rw-r--r--src/libstd/cmp.rs20
-rw-r--r--src/libstd/comm.rs53
-rw-r--r--src/libstd/container.rs4
-rw-r--r--src/libstd/core.rc35
-rw-r--r--src/libstd/either.rs32
-rw-r--r--src/libstd/hash.rs27
-rw-r--r--src/libstd/hashmap.rs22
-rw-r--r--src/libstd/io.rs8
-rw-r--r--src/libstd/iter.rs10
-rw-r--r--src/libstd/iterator.rs100
-rw-r--r--src/libstd/libc.rs8
-rw-r--r--src/libstd/logging.rs24
-rw-r--r--src/libstd/managed.rs28
-rw-r--r--src/libstd/nil.rs16
-rw-r--r--src/libstd/num/f32.rs258
-rw-r--r--src/libstd/num/f64.rs264
-rw-r--r--src/libstd/num/float.rs258
-rw-r--r--src/libstd/num/i16.rs6
-rw-r--r--src/libstd/num/i32.rs6
-rw-r--r--src/libstd/num/i64.rs6
-rw-r--r--src/libstd/num/i8.rs6
-rw-r--r--src/libstd/num/int.rs12
-rw-r--r--src/libstd/num/int_macros.rs136
-rw-r--r--src/libstd/num/num.rs55
-rw-r--r--src/libstd/num/strconv.rs64
-rw-r--r--src/libstd/num/uint.rs4
-rw-r--r--src/libstd/num/uint_macros.rs130
-rw-r--r--src/libstd/old_iter.rs91
-rw-r--r--src/libstd/option.rs53
-rw-r--r--src/libstd/os.rs36
-rw-r--r--src/libstd/owned.rs12
-rw-r--r--src/libstd/path.rs15
-rw-r--r--src/libstd/pipes.rs12
-rw-r--r--src/libstd/prelude.rs6
-rw-r--r--src/libstd/ptr.rs135
-rw-r--r--src/libstd/rand.rs12
-rw-r--r--src/libstd/rand/distributions.rs10
-rw-r--r--src/libstd/reflect.rs10
-rw-r--r--src/libstd/repr.rs15
-rw-r--r--src/libstd/result.rs62
-rw-r--r--src/libstd/rt/args.rs125
-rw-r--r--src/libstd/rt/borrowck.rs283
-rw-r--r--src/libstd/rt/comm.rs12
-rw-r--r--src/libstd/rt/context.rs2
-rw-r--r--src/libstd/rt/io/extensions.rs3
-rw-r--r--src/libstd/rt/local_heap.rs59
-rw-r--r--src/libstd/rt/logging.rs20
-rw-r--r--src/libstd/rt/mod.rs113
-rw-r--r--src/libstd/rt/sched.rs4
-rw-r--r--src/libstd/rt/task.rs58
-rw-r--r--src/libstd/rt/test.rs2
-rw-r--r--src/libstd/rt/util.rs12
-rw-r--r--src/libstd/rt/uv/timer.rs8
-rw-r--r--src/libstd/run.rs31
-rw-r--r--src/libstd/str.rs682
-rw-r--r--src/libstd/str/ascii.rs152
-rw-r--r--src/libstd/sys.rs40
-rw-r--r--src/libstd/task/spawn.rs44
-rw-r--r--src/libstd/to_bytes.rs82
-rw-r--r--src/libstd/to_str.rs20
-rw-r--r--src/libstd/trie.rs56
-rw-r--r--src/libstd/tuple.rs55
-rw-r--r--src/libstd/unstable/atomics.rs60
-rw-r--r--src/libstd/unstable/dynamic_lib.rs50
-rw-r--r--src/libstd/unstable/extfmt.rs2
-rw-r--r--src/libstd/unstable/global.rs2
-rw-r--r--src/libstd/unstable/intrinsics.rs13
-rw-r--r--src/libstd/unstable/lang.rs284
-rw-r--r--src/libstd/unstable/mod.rs5
-rw-r--r--src/libstd/unstable/sync.rs10
-rw-r--r--src/libstd/util.rs10
-rw-r--r--src/libstd/vec.rs264
-rw-r--r--src/libsyntax/ast.rs2
-rw-r--r--src/libsyntax/ast_util.rs54
-rw-r--r--src/libsyntax/attr.rs2
-rw-r--r--src/libsyntax/diagnostic.rs2
-rw-r--r--src/libsyntax/ext/deriving/generic.rs10
-rw-r--r--src/libsyntax/ext/deriving/mod.rs2
-rw-r--r--src/libsyntax/ext/deriving/zero.rs96
-rw-r--r--src/libsyntax/ext/quote.rs2
-rw-r--r--src/libsyntax/fold.rs2
-rw-r--r--src/libsyntax/opt_vec.rs33
-rw-r--r--src/libsyntax/parse/comments.rs98
-rw-r--r--src/libsyntax/parse/obsolete.rs2
-rw-r--r--src/libsyntax/parse/token.rs143
-rw-r--r--src/libsyntax/print/pprust.rs12
-rw-r--r--src/libsyntax/syntax.rc9
-rw-r--r--src/libsyntax/util/interner.rs6
-rw-r--r--src/libsyntax/visit.rs212
-rw-r--r--src/rt/arch/i386/morestack.S2
-rw-r--r--src/rt/rust_builtin.cpp65
-rw-r--r--src/rt/rust_gc_metadata.cpp5
-rw-r--r--src/rt/rust_log.cpp12
-rw-r--r--src/rt/rust_task.cpp8
-rw-r--r--src/rt/rust_type.h8
-rw-r--r--src/rt/rust_util.h10
-rw-r--r--src/rt/rustrt.def.in8
-rw-r--r--src/rustllvm/PassWrapper.cpp5
-rw-r--r--src/rustllvm/RustWrapper.cpp225
-rw-r--r--src/rustllvm/rustllvm.def.in20
-rw-r--r--src/rustllvm/rustllvm.h2
-rw-r--r--src/snapshots.txt8
-rw-r--r--src/test/auxiliary/cci_capture_clause.rs2
-rw-r--r--src/test/auxiliary/cci_nested_lib.rs2
-rw-r--r--src/test/bench/msgsend-pipes-shared.rs6
-rw-r--r--src/test/bench/msgsend-pipes.rs6
-rw-r--r--src/test/bench/msgsend-ring-pipes.rs6
-rw-r--r--src/test/bench/shootout-fasta-redux.rs3
-rw-r--r--src/test/bench/shootout-k-nucleotide-pipes.rs8
-rw-r--r--src/test/bench/task-perf-one-million.rs2
-rw-r--r--src/test/compile-fail/infinite-instantiation.rs2
-rw-r--r--src/test/compile-fail/kindck-owned.rs5
-rw-r--r--src/test/debug-info/basic-types.rs9
-rw-r--r--src/test/debug-info/box.rs7
-rw-r--r--src/test/debug-info/struct.rs9
-rw-r--r--src/test/debug-info/tuple.rs9
-rw-r--r--src/test/debug-info/vec.rs7
-rw-r--r--src/test/run-pass/alignment-gep-tup-like-1.rs2
-rw-r--r--src/test/run-pass/alignment-gep-tup-like-2.rs2
-rw-r--r--src/test/run-pass/auto-encode.rs61
-rw-r--r--src/test/run-pass/borrowck-move-from-unsafe-ptr-ok.rs21
-rw-r--r--src/test/run-pass/borrowed-ptr-pattern.rs2
-rw-r--r--src/test/run-pass/box-unbox.rs2
-rw-r--r--src/test/run-pass/close-over-big-then-small-data.rs2
-rw-r--r--src/test/run-pass/deriving-zero.rs40
-rw-r--r--src/test/run-pass/expr-block-generic-box2.rs2
-rw-r--r--src/test/run-pass/expr-block-generic-unique2.rs2
-rw-r--r--src/test/run-pass/expr-block-generic.rs2
-rw-r--r--src/test/run-pass/expr-if-generic-box2.rs2
-rw-r--r--src/test/run-pass/expr-if-generic.rs2
-rw-r--r--src/test/run-pass/expr-match-generic-box2.rs2
-rw-r--r--src/test/run-pass/expr-match-generic.rs2
-rw-r--r--src/test/run-pass/extern-pub.rs6
-rw-r--r--src/test/run-pass/generic-derived-type.rs3
-rw-r--r--src/test/run-pass/issue-2718.rs8
-rw-r--r--src/test/run-pass/ivec-add.rs4
-rw-r--r--src/test/run-pass/kindck-owned-trait-contains-1.rs2
-rw-r--r--src/test/run-pass/morestack6.rs3
-rw-r--r--src/test/run-pass/pipe-bank-proto.rs10
-rw-r--r--src/test/run-pass/reflect-visit-data.rs4
-rw-r--r--src/test/run-pass/resource-generic.rs2
-rwxr-xr-xsrc/test/run-pass/sized-borrowed-pointerbin12750 -> 0 bytes
-rwxr-xr-xsrc/test/run-pass/sized-owned-pointerbin12746 -> 0 bytes
-rw-r--r--src/test/run-pass/static-method-test.rs2
-rw-r--r--src/test/run-pass/unfoldr-cross-crate.rs34
246 files changed, 5078 insertions, 5368 deletions
diff --git a/Makefile.in b/Makefile.in
index ca82f296022..baae56c4f40 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -111,7 +111,7 @@ ifdef SAVE_TEMPS
   CFG_RUSTC_FLAGS += --save-temps
 endif
 ifdef ASM_COMMENTS
-  CFG_RUSTC_FLAGS += -z asm-comments
+  CFG_RUSTC_FLAGS += -Z asm-comments
 endif
 ifdef TIME_PASSES
   CFG_RUSTC_FLAGS += -Z time-passes
@@ -208,7 +208,6 @@ CFG_STDLIB_$(1) :=$(call CFG_LIB_NAME_$(1),std)
 CFG_EXTRALIB_$(1) :=$(call CFG_LIB_NAME_$(1),extra)
 CFG_LIBRUSTC_$(1) :=$(call CFG_LIB_NAME_$(1),rustc)
 CFG_LIBSYNTAX_$(1) :=$(call CFG_LIB_NAME_$(1),syntax)
-CFG_LIBFUZZER_$(1) :=$(call CFG_LIB_NAME_$(1),fuzzer)
 CFG_LIBRUSTPKG_$(1) :=$(call CFG_LIB_NAME_$(1),rustpkg)
 CFG_LIBRUSTDOC_$(1) :=$(call CFG_LIB_NAME_$(1),rustdoc)
 CFG_LIBRUSTI_$(1) :=$(call CFG_LIB_NAME_$(1),rusti)
@@ -218,7 +217,6 @@ EXTRALIB_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),extra)
 STDLIB_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),std)
 LIBRUSTC_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),rustc)
 LIBSYNTAX_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),syntax)
-LIBFUZZER_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),fuzzer)
 LIBRUSTPKG_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),rustpkg)
 LIBRUSTDOC_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),rustdoc)
 LIBRUSTI_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),rusti)
@@ -227,7 +225,6 @@ EXTRALIB_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),extra)
 STDLIB_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),std)
 LIBRUSTC_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),rustc)
 LIBSYNTAX_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),syntax)
-LIBFUZZER_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),fuzzer)
 LIBRUSTPKG_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),rustpkg)
 LIBRUSTDOC_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),rustdoc)
 LIBRUSTI_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),rusti)
@@ -402,12 +399,10 @@ SREQ$(1)_T_$(2)_H_$(3) = \
 # Prerequisites for a working stageN compiler and libraries, for a specific target
 CSREQ$(1)_T_$(2)_H_$(3) = \
 	$$(TSREQ$(1)_T_$(2)_H_$(3)) \
-	$$(HBIN$(1)_H_$(3))/fuzzer$$(X_$(3)) \
 	$$(HBIN$(1)_H_$(3))/rustpkg$$(X_$(3)) \
 	$$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3)) \
 	$$(HBIN$(1)_H_$(3))/rusti$$(X_$(3)) \
 	$$(HBIN$(1)_H_$(3))/rust$$(X_$(3)) \
-	$$(HLIB$(1)_H_$(3))/$(CFG_LIBFUZZER_$(3)) \
 	$$(HLIB$(1)_H_$(3))/$(CFG_LIBRUSTPKG_$(3)) \
 	$$(HLIB$(1)_H_$(3))/$(CFG_LIBRUSTDOC_$(3)) \
 	$$(HLIB$(1)_H_$(3))/$(CFG_LIBRUSTI_$(3)) \
@@ -416,7 +411,6 @@ CSREQ$(1)_T_$(2)_H_$(3) = \
 	$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_EXTRALIB_$(2))  \
 	$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBSYNTAX_$(2))  \
 	$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTC_$(2)) \
-	$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBFUZZER_$(2)) \
 	$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTPKG_$(2)) \
 	$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTDOC_$(2)) \
 	$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTI_$(2)) \
diff --git a/RELEASES.txt b/RELEASES.txt
index 5bf160d6248..d099b1336df 100644
--- a/RELEASES.txt
+++ b/RELEASES.txt
@@ -4,36 +4,90 @@ Version 0.7 (July 2013)
    * ??? changes, numerous bugfixes
 
    * Syntax changes
-      * `#[deriving(Encodable)]`, `#[deriving(Decodable)]`
+      * `use mod` is no longer valid.
+      * `fail!` and `assert!` accept `~str`, `&'static str` or `fmt!`-style
+        argument list.
+      * `Encodable`, `Decodable`, `TotalOrd`, `TotalEq`, `DeepClone` can all
+        be automatically derived with `#[deriving(...)]`.
+      * The `Durable` trait is replaced with the `'static` bounds.
+      * At long last, 'argument modes' no longer exist.
+      * The `bytes!` macro returns a vector of bytes for string, u8, char,
+        and unsuffixed integer literals.
 
    * Semantic changes
+      * The borrow checker has been rewritten with flow-sensitivity, fixing
+        many bugs and inconveniences.
       * The `self` parameter no longer implicitly means `&'self self`,
         and can be explicitly marked with a lifetime.
       * Structs with the `#[packed]` attribute have byte alignment and
         no padding between fields.
+      * The `for` loop protocol now requires `for`-iterators to return `bool`
+        so they compose better.
+      * `Option<~T>` is now represented as a nullable pointer.
+      * `@mut` does dynamic borrow checks correctly.
+      * Macros TODO
+      * The `main` function is only detected at the topmost level of the crate.
+        The `#[main]` attribute is still valid anywhere.
+      * Struct fields may no longer be mutable. Use inherited mutability.
+      * The `#[non_owned]` attribute makes a type that would otherwise be
+        `Owned`, not. TODO this may change to non_send before 0.7
+      * The `#[mutable]` attribute makes a type that would otherwise be
+        `Const`, note. TODO this may change to non_freeze before 0.7
+      * Unbounded recursion will abort the process after reaching the limit
+        specified by the `RUST_MAX_STACK` environment variable.
+      * The `vecs_implicitly_copyable` lint mode has been removed. Vectors
+        are never implicitly copyable.
 
    * Libraries
-
-      **Note: in 0.7 `core` was renamed `std` and `std` to `extra.
-        These notes use the new crate names.**
-
       * The `core` crate was renamed to `std`.
       * The `std` crate was renamed to `extra`.
       * `std::mut` removed.
+      * std: The prelude no longer reexports any modules, only types and traits.
+      * std: Prelude additions: `print`, `println`, `FromStr`, `ApproxEq`, `Equiv`,
+        `Iterator`, `IteratorUtil`, many numeric traits, many tuple traits.
       * std: `iterator` module for external iterator objects.
+      * std: new numeric traits: `Fractional`, `Real`, `RealExt`, `Integer`, `Ratio`,
+        `Algebraic`, `Trigonometric`, `Exponential`, `Primitive`.
+      * std: Tuple traits and accessors defined for up to 12-tuples, e.g.
+        `(0, 1, 2).n2()` or `(0, 1, 2).n2_ref()`.
       * std: many types implement `Clone` - tuples, @, @mut. TODO
       * std: `path` type renamed to `Path`.
       * std: Many standalone functions removed in favor of methods in
-        `vec`, `str`, TODO. In the future methods will also work as functions.
+        `vec`, `str`. In the future methods will also work as functions.
+      * std: `reinterpret_cast` removed. Used `transmute`.
+      * std: ascii string handling in `std::ascii`.
+      * std: `Rand` is implemented for ~/@.
+      * std: `run` module for spawning processes overhauled.
+      * std: Various atomic types added to `unstable::atomic`.
+      * std: `LinearMap` and `LinearSet` renamed to `HashMap` and `HashSet`.
+      * std: Added `os::mkdir_recursive`.
+      * std: Added `os::glob` function performs filesystems globs.
+      * std: `FuzzyEq` renamed to `ApproxEq`.
+      * std: `Map` now defines `pop` and `swap` methods.
+      * extra: `flate` module moved from `std` to `extra`.
       * extra: `FileInput` implements `std::io::Reader`.
       * extra: `Complex` number type and `complex` module.
       * extra: `Rational` number type and `rational` module.
       * extra: `BigInt`, `BigUint` implement numeric and comparison traits.
+      * extra: `term` uses terminfo now, is more correct.
 
-   * Other
+   * Tooling
       * `unused_unsafe` lint mode for detecting unnecessary `unsafe` blocks.
-      * More and improved library documentation.
+      * `unused_mut` lint mode for identifying unused `mut` qualifiers.
       * The `rusti` command has been rewritten and a number of bugs addressed.
+      * rustc outputs in color on more terminals.
+      * rustc accepts a `--link-args` flag to pass arguments to the linker.
+      * rustc accepts a `-Z print-link-args` flag for debugging linkage.
+      * Compiling with `-g` will make the binary record information about
+        dynamic borrowcheck failures for debugging.
+      * rustdoc has a nicer stylesheet.
+      * Various improvements to rustdoc.
+
+   * Other
+      * More and improved library documentation.
+      * Various improvements on ARM and Android.
+      * Various improvements to MIPS backend.
+      * jemalloc is the Rust allocator.
 
 Version 0.6 (April 2013)
 ------------------------
diff --git a/doc/rust.css b/doc/rust.css
index 35581a8d4ed..ed9ea446aa8 100644
--- a/doc/rust.css
+++ b/doc/rust.css
@@ -12,41 +12,38 @@ body {
 }
 
 h1 {
-    font-size: 20pt;
-    margin-top: 2em;
+    font-size: 24pt;
+    margin-top: 1.6em;
     padding-left: 0.4em;
     line-height: 1.6em;
     background-color:#FFF2CE;
     border-radius: 0.2em;
-    border: 1px solid rgba(0, 0, 0, 0.15);
 }
 
 h2 {
-    font-size: 15pt;
-    margin-top: 2em;
-    padding-left: 0.4em;
+    font-size: 16pt;
+    margin-top: 1.6em;
+    padding: 0.2em 0.5em;
     background-color:#FFF2CE;
     border-radius: 0.4em;
-    border: 1px solid rgba(0, 0, 0, 0.15);
 }
 
 h2 code {
     color: #097334;
-    font-size: 15pt;
+    font-size: 16pt;
 }
 
 h3 {
-    font-size: 13pt;
+    font-size: 14pt;
     color: black;
     background-color:#D9E7FF;
     border-radius: 0.4em;
-    border: 1px solid rgba(0, 0, 0, 0.15);
-    padding: 0 0.4em 0 0.4em;
+    padding: 0.2em 0.5em;
 }
 
 h3 code {
     color: #541800;
-    font-size: 13pt;
+    font-size: 14pt;
     font-style: italic;
 }
 
diff --git a/doc/rust.md b/doc/rust.md
index 3c0828def15..9edbc44d6c2 100644
--- a/doc/rust.md
+++ b/doc/rust.md
@@ -2826,7 +2826,7 @@ Within the body of an item that has type parameter declarations, the names of it
 ~~~~~~~
 fn map<A: Copy, B: Copy>(f: &fn(A) -> B, xs: &[A]) -> ~[B] {
    if xs.len() == 0 { return ~[]; }
-   let first: B = f(xs[0]);
+   let first: B = f(copy xs[0]);
    let rest: ~[B] = map(f, xs.slice(1, xs.len()));
    return ~[first] + rest;
 }
diff --git a/doc/tutorial-tasks.md b/doc/tutorial-tasks.md
index b00cd665271..2e3ce40c9f7 100644
--- a/doc/tutorial-tasks.md
+++ b/doc/tutorial-tasks.md
@@ -359,7 +359,7 @@ fn pnorm(nums: &~[float], p: uint) -> float {
 
 fn main() {
     let numbers = vec::from_fn(1000000, |_| rand::random::<float>());
-    println(fmt!("Inf-norm = %?",  numbers.max()));
+    println(fmt!("Inf-norm = %?",  *numbers.iter().max().unwrap()));
 
     let numbers_arc = ARC(numbers);
 
diff --git a/doc/tutorial.md b/doc/tutorial.md
index a4580361166..f69f569faee 100644
--- a/doc/tutorial.md
+++ b/doc/tutorial.md
@@ -1941,12 +1941,14 @@ fn head_bad<T>(v: &[T]) -> T {
 ~~~~
 
 However, we can tell the compiler that the `head` function is only for
-copyable types: that is, those that have the `Copy` trait.
+copyable types: that is, those that have the `Copy` trait. In that
+case, we can explicitly create a second copy of the value we are
+returning using the `copy` keyword:
 
 ~~~~
 // This does
 fn head<T: Copy>(v: &[T]) -> T {
-    v[0]
+    copy v[0]
 }
 ~~~~
 
@@ -2039,17 +2041,12 @@ themselves contain type parameters. A trait for generalized sequence
 types might look like the following:
 
 ~~~~
-# use std::vec;
 trait Seq<T> {
-    fn len(&self) -> uint;
-    fn iter(&self, b: &fn(v: &T));
+    fn length(&self) -> uint;
 }
 
 impl<T> Seq<T> for ~[T] {
-    fn len(&self) -> uint { self.len() }
-    fn iter(&self, b: &fn(v: &T)) {
-        for vec::each(*self) |elt| { b(elt); }
-    }
+    fn length(&self) -> uint { self.len() }
 }
 ~~~~
 
@@ -2142,7 +2139,7 @@ as in this version of `print_all` that copies elements.
 fn print_all<T: Printable + Copy>(printable_things: ~[T]) {
     let mut i = 0;
     while i < printable_things.len() {
-        let copy_of_thing = printable_things[i];
+        let copy_of_thing = copy printable_things[i];
         copy_of_thing.print();
         i += 1;
     }
diff --git a/mk/clean.mk b/mk/clean.mk
index 9a074b29d8b..23efbb3ee15 100644
--- a/mk/clean.mk
+++ b/mk/clean.mk
@@ -63,13 +63,11 @@ define CLEAN_HOST_STAGE_N
 
 clean$(1)_H_$(2):
 	$(Q)rm -f $$(HBIN$(1)_H_$(2))/rustc$(X_$(2))
-	$(Q)rm -f $$(HBIN$(1)_H_$(2))/fuzzer$(X_$(2))
 	$(Q)rm -f $$(HBIN$(1)_H_$(2))/rustpkg$(X_$(2))
 	$(Q)rm -f $$(HBIN$(1)_H_$(2))/serializer$(X_$(2))
 	$(Q)rm -f $$(HBIN$(1)_H_$(2))/rustdoc$(X_$(2))
 	$(Q)rm -f $$(HBIN$(1)_H_$(2))/rusti$(X_$(2))
 	$(Q)rm -f $$(HBIN$(1)_H_$(2))/rust$(X_$(2))
-	$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBFUZZER_$(2))
 	$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUSTPKG_$(2))
 	$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUSTDOC_$(2))
 	$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_RUNTIME_$(2))
@@ -83,7 +81,6 @@ clean$(1)_H_$(2):
 	$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(EXTRALIB_GLOB_$(2))
 	$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTC_GLOB_$(2))
 	$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBSYNTAX_GLOB_$(2))
-	$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBFUZZER_GLOB_$(2))
 	$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTPKG_GLOB_$(2))
 	$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTDOC_GLOB_$(2))
 	$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTI_GLOB_$(2))
@@ -101,13 +98,11 @@ define CLEAN_TARGET_STAGE_N
 
 clean$(1)_T_$(2)_H_$(3):
 	$(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/rustc$(X_$(2))
-	$(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/fuzzer$(X_$(2))
 	$(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/rustpkg$(X_$(2))
 	$(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/serializer$(X_$(2))
 	$(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/rustdoc$(X_$(2))
 	$(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/rusti$(X_$(2))
 	$(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/rust$(X_$(2))
-	$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBFUZZER_$(2))
 	$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTPKG_$(2))
 	$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTDOC_$(2))
 	$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_RUNTIME_$(2))
@@ -121,7 +116,6 @@ clean$(1)_T_$(2)_H_$(3):
 	$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(EXTRALIB_GLOB_$(2))
 	$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTC_GLOB_$(2))
 	$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBSYNTAX_GLOB_$(2))
-	$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBFUZZER_GLOB_$(2))
 	$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTPKG_GLOB_$(2))
 	$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTDOC_GLOB_$(2))
 	$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTI_GLOB_$(2))
diff --git a/mk/dist.mk b/mk/dist.mk
index 96f35031de9..912b692a247 100644
--- a/mk/dist.mk
+++ b/mk/dist.mk
@@ -32,7 +32,6 @@ PKG_FILES := \
       librustc                                 \
       compiletest                              \
       etc                                      \
-      libfuzzer                                \
       libextra                                 \
       libstd                                   \
       libsyntax                                \
diff --git a/mk/pp.mk b/mk/pp.mk
index 0a24d9e8797..f86bbb7f281 100644
--- a/mk/pp.mk
+++ b/mk/pp.mk
@@ -17,7 +17,6 @@ else
               $(wildcard $(addprefix $(S)src/rustc/,*.rs */*.rs */*/*.rs)) \
               $(wildcard $(S)src/test/*/*.rs    \
                          $(S)src/test/*/*/*.rs) \
-              $(wildcard $(S)src/fuzzer/*.rs)   \
               $(wildcard $(S)src/rustpkg/*.rs) \
               $(wildcard $(S)src/rusti/*.rs) \
               $(wildcard $(S)src/rust/*.rs)
diff --git a/mk/rt.mk b/mk/rt.mk
index 1c498aacddd..da950dffab5 100644
--- a/mk/rt.mk
+++ b/mk/rt.mk
@@ -158,10 +158,10 @@ rt/$(1)/stage$(2)/arch/$$(HOST_$(1))/libmorestack.a: $$(MORESTACK_OBJ_$(1)_$(2))
 	$$(Q)$(AR_$(1)) rcs $$@ $$<
 
 rt/$(1)/stage$(2)/$(CFG_RUNTIME_$(1)): $$(RUNTIME_OBJS_$(1)_$(2)) $$(MKFILE_DEPS) \
-                        $$(RUNTIME_DEF_$(1)_$(2)) $$(LIBUV_LIB_$(1)_$(2)) $$(JEMALLOC_LIB_$(1)_$(2))
+                        $$(RUNTIME_DEF_$(1)_$(2)) $$(LIBUV_LIB_$(1)_$(2))
 	@$$(call E, link: $$@)
 	$$(Q)$$(call CFG_LINK_CXX_$(1),$$@, $$(RUNTIME_OBJS_$(1)_$(2)) \
-	  $$(JEMALLOC_LIB_$(1)_$(2)) $$(CFG_GCCISH_POST_LIB_FLAGS_$(1)) $$(LIBUV_LIB_$(1)_$(2)) \
+	  $$(CFG_GCCISH_POST_LIB_FLAGS_$(1)) $$(LIBUV_LIB_$(1)_$(2)) \
 	  $$(CFG_LIBUV_LINK_FLAGS_$(1)),$$(RUNTIME_DEF_$(1)_$(2)),$$(CFG_RUNTIME_$(1)))
 
 # FIXME: For some reason libuv's makefiles can't figure out the
diff --git a/mk/tools.mk b/mk/tools.mk
index 018da2a6401..8319d8d4e48 100644
--- a/mk/tools.mk
+++ b/mk/tools.mk
@@ -11,9 +11,6 @@
 # Rules for non-core tools built with the compiler, both for target
 # and host architectures
 
-FUZZER_LIB := $(S)src/libfuzzer/fuzzer.rc
-FUZZER_INPUTS := $(wildcard $(addprefix $(S)src/libfuzzer/, *.rs))
-
 # The test runner that runs the cfail/rfail/rpass and bxench tests
 COMPILETEST_CRATE := $(S)src/compiletest/compiletest.rc
 COMPILETEST_INPUTS := $(wildcard $(S)src/compiletest/*rs)
@@ -38,21 +35,6 @@ RUST_INPUTS := $(wildcard $(S)src/librust/*.rs)
 # have tools that need to built for other targets.
 define TOOLS_STAGE_N_TARGET
 
-$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBFUZZER_$(4)):          \
-		$$(FUZZER_LIB) $$(FUZZER_INPUTS)			\
-		$$(TSREQ$(1)_T_$(4)_H_$(3))					\
-		$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_STDLIB_$(4))	\
-		$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_EXTRALIB_$(4))	\
-		$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTC_$(4))
-	@$$(call E, compile_and_link: $$@)
-	$$(STAGE$(1)_T_$(4)_H_$(3)) -o $$@ $$< && touch $$@
-
-$$(TBIN$(1)_T_$(4)_H_$(3))/fuzzer$$(X_$(4)):				\
-		$$(DRIVER_CRATE)								\
-		$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBFUZZER_$(4))
-	@$$(call E, compile_and_link: $$@)
-	$$(STAGE$(1)_T_$(4)_H_$(3)) --cfg fuzzer -o $$@ $$<
-
 $$(TBIN$(1)_T_$(4)_H_$(3))/compiletest$$(X_$(4)):			\
 		$$(COMPILETEST_CRATE) $$(COMPILETEST_INPUTS)	\
 		$$(TSREQ$(1)_T_$(4)_H_$(3))						\
@@ -128,27 +110,6 @@ endef
 
 define TOOLS_STAGE_N_HOST
 
-
-# Promote the stageN target to stageN+1 host
-# FIXME: Shouldn't need to depend on host/librustc.so once
-# rpath is working
-$$(HLIB$(2)_H_$(4))/$(CFG_LIBFUZZER_$(4)):					\
-		$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBFUZZER_$(4))	\
-		$$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTC_$(4))			\
-		$$(HSREQ$(2)_H_$(4))
-	@$$(call E, cp: $$@)
-	$$(Q)cp $$< $$@
-	$$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBFUZZER_GLOB_$(4)) \
-		$$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBFUZZER_DSYM_GLOB_$(4))) \
-	        $$(HLIB$(2)_H_$(4))
-
-$$(HBIN$(2)_H_$(4))/fuzzer$$(X_$(4)):				\
-		$$(TBIN$(1)_T_$(4)_H_$(3))/fuzzer$$(X_$(4))	\
-		$$(HLIB$(2)_H_$(4))/$(CFG_LIBFUZZER_$(4))	\
-		$$(HSREQ$(2)_H_$(4))
-	@$$(call E, cp: $$@)
-	$$(Q)cp $$< $$@
-
 $$(HBIN$(2)_H_$(4))/compiletest$$(X_$(4)):				\
 		$$(TBIN$(1)_T_$(4)_H_$(3))/compiletest$$(X_$(4))	\
 		$$(HSREQ$(2)_H_$(4))
diff --git a/src/README.txt b/src/README.txt
index 1b06c4259fc..f229068731f 100644
--- a/src/README.txt
+++ b/src/README.txt
@@ -4,8 +4,8 @@ Source layout:
 
 librustc/          The self-hosted compiler
 
-libcore/           The core library (imported and linked by default)
-libstd/            The standard library (slightly more peripheral code)
+libstd/            The standard library (imported and linked by default)
+libextra/          The "extras" library (slightly more peripheral code)
 libsyntax/         The Rust parser and pretty-printer
 
 rt/                The runtime system
diff --git a/src/compiletest/procsrv.rs b/src/compiletest/procsrv.rs
index b5404e38ec9..93fe258d167 100644
--- a/src/compiletest/procsrv.rs
+++ b/src/compiletest/procsrv.rs
@@ -23,7 +23,7 @@ fn target_env(lib_path: &str, prog: &str) -> ~[(~str,~str)] {
     assert!(prog.ends_with(".exe"));
     let aux_path = prog.slice(0u, prog.len() - 4u).to_owned() + ".libaux";
 
-    env = do vec::map(env) |pair| {
+    env = do env.map() |pair| {
         let (k,v) = copy *pair;
         if k == ~"PATH" { (~"PATH", v + ";" + lib_path + ";" + aux_path) }
         else { (k,v) }
diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs
index 891935dcadd..e0ceb79a37d 100644
--- a/src/compiletest/runtest.rs
+++ b/src/compiletest/runtest.rs
@@ -24,7 +24,6 @@ use util::logv;
 
 use core::io;
 use core::os;
-use core::str;
 use core::uint;
 use core::vec;
 
diff --git a/src/driver/driver.rs b/src/driver/driver.rs
index 97e01d1bcdc..ccedd3adbaa 100644
--- a/src/driver/driver.rs
+++ b/src/driver/driver.rs
@@ -16,9 +16,6 @@ extern mod core(name = "std", vers = "0.7-pre");
 #[cfg(rustpkg)]
 extern mod this(name = "rustpkg");
 
-#[cfg(fuzzer)]
-extern mod this(name = "fuzzer");
-
 #[cfg(rustdoc)]
 extern mod this(name = "rustdoc");
 
diff --git a/src/etc/snapshot.py b/src/etc/snapshot.py
index 123987d4b1e..608dbdcca5d 100644
--- a/src/etc/snapshot.py
+++ b/src/etc/snapshot.py
@@ -26,29 +26,29 @@ download_unpack_base = os.path.join(download_dir_base, "unpack")
 
 snapshot_files = {
     "linux": ["bin/rustc",
-              "lib/libcore-*.so",
               "lib/libstd-*.so",
+              "lib/libextra-*.so",
               "lib/librustc-*.so",
               "lib/libsyntax-*.so",
               "lib/librustrt.so",
               "lib/librustllvm.so"],
     "macos": ["bin/rustc",
-              "lib/libcore-*.dylib",
               "lib/libstd-*.dylib",
+              "lib/libextra-*.dylib",
               "lib/librustc-*.dylib",
               "lib/libsyntax-*.dylib",
               "lib/librustrt.dylib",
               "lib/librustllvm.dylib"],
     "winnt": ["bin/rustc.exe",
-              "bin/core-*.dll",
               "bin/std-*.dll",
+              "bin/extra-*.dll",
               "bin/rustc-*.dll",
               "bin/syntax-*.dll",
               "bin/rustrt.dll",
               "bin/rustllvm.dll"],
     "freebsd": ["bin/rustc",
-                "lib/libcore-*.so",
                 "lib/libstd-*.so",
+                "lib/libextra-*.so",
                 "lib/librustc-*.so",
                 "lib/libsyntax-*.so",
                 "lib/librustrt.so",
diff --git a/src/libextra/arc.rs b/src/libextra/arc.rs
index b1bec1f95db..661224b0a80 100644
--- a/src/libextra/arc.rs
+++ b/src/libextra/arc.rs
@@ -58,7 +58,7 @@ pub struct Condvar<'self> {
 
 impl<'self> Condvar<'self> {
     /// Atomically exit the associated ARC and block until a signal is sent.
-    #[inline(always)]
+    #[inline]
     pub fn wait(&self) { self.wait_on(0) }
 
     /**
@@ -67,7 +67,7 @@ impl<'self> Condvar<'self> {
      *
      * wait() is equivalent to wait_on(0).
      */
-    #[inline(always)]
+    #[inline]
     pub fn wait_on(&self, condvar_id: uint) {
         assert!(!*self.failed);
         self.cond.wait_on(condvar_id);
@@ -76,28 +76,28 @@ impl<'self> Condvar<'self> {
     }
 
     /// Wake up a blocked task. Returns false if there was no blocked task.
-    #[inline(always)]
+    #[inline]
     pub fn signal(&self) -> bool { self.signal_on(0) }
 
     /**
      * Wake up a blocked task on a specified condvar (as
      * sync::cond.signal_on). Returns false if there was no blocked task.
      */
-    #[inline(always)]
+    #[inline]
     pub fn signal_on(&self, condvar_id: uint) -> bool {
         assert!(!*self.failed);
         self.cond.signal_on(condvar_id)
     }
 
     /// Wake up all blocked tasks. Returns the number of tasks woken.
-    #[inline(always)]
+    #[inline]
     pub fn broadcast(&self) -> uint { self.broadcast_on(0) }
 
     /**
      * Wake up all blocked tasks on a specified condvar (as
      * sync::cond.broadcast_on). Returns the number of tasks woken.
      */
-    #[inline(always)]
+    #[inline]
     pub fn broadcast_on(&self, condvar_id: uint) -> uint {
         assert!(!*self.failed);
         self.cond.broadcast_on(condvar_id)
@@ -198,22 +198,20 @@ impl<T:Owned> MutexARC<T> {
      * any tasks that subsequently try to access it (including those already
      * blocked on the mutex) will also fail immediately.
      */
-    #[inline(always)]
+    #[inline]
     pub unsafe fn access<U>(&self, blk: &fn(x: &mut T) -> U) -> U {
-        unsafe {
-            let state = self.x.get();
-            // Borrowck would complain about this if the function were
-            // not already unsafe. See borrow_rwlock, far below.
-            do (&(*state).lock).lock {
-                check_poison(true, (*state).failed);
-                let _z = PoisonOnFail(&mut (*state).failed);
-                blk(&mut (*state).data)
-            }
+        let state = self.x.get();
+        // Borrowck would complain about this if the function were
+        // not already unsafe. See borrow_rwlock, far below.
+        do (&(*state).lock).lock {
+            check_poison(true, (*state).failed);
+            let _z = PoisonOnFail(&mut (*state).failed);
+            blk(&mut (*state).data)
         }
     }
 
     /// As access(), but with a condvar, as sync::mutex.lock_cond().
-    #[inline(always)]
+    #[inline]
     pub unsafe fn access_cond<'x, 'c, U>(&self,
                                          blk: &fn(x: &'x mut T,
                                                   c: &'c Condvar) -> U)
@@ -231,7 +229,7 @@ impl<T:Owned> MutexARC<T> {
 }
 
 // Common code for {mutex.access,rwlock.write}{,_cond}.
-#[inline(always)]
+#[inline]
 #[doc(hidden)]
 fn check_poison(is_mutex: bool, failed: bool) {
     if failed {
@@ -322,7 +320,7 @@ impl<T:Const + Owned> RWARC<T> {
      * that other tasks won't block forever. As MutexARC.access, it will also
      * poison the ARC, so subsequent readers and writers will both also fail.
      */
-    #[inline(always)]
+    #[inline]
     pub fn write<U>(&self, blk: &fn(x: &mut T) -> U) -> U {
         unsafe {
             let state = self.x.get();
@@ -335,7 +333,7 @@ impl<T:Const + Owned> RWARC<T> {
     }
 
     /// As write(), but with a condvar, as sync::rwlock.write_cond().
-    #[inline(always)]
+    #[inline]
     pub fn write_cond<'x, 'c, U>(&self,
                                  blk: &fn(x: &'x mut T, c: &'c Condvar) -> U)
                                  -> U {
diff --git a/src/libextra/arena.rs b/src/libextra/arena.rs
index 2926d5958f1..db4cf564bab 100644
--- a/src/libextra/arena.rs
+++ b/src/libextra/arena.rs
@@ -119,7 +119,7 @@ pub fn Arena() -> Arena {
     arena_with_size(32u)
 }
 
-#[inline(always)]
+#[inline]
 fn round_up_to(base: uint, align: uint) -> uint {
     (base + (align - 1)) & !(align - 1)
 }
@@ -156,12 +156,12 @@ unsafe fn destroy_chunk(chunk: &Chunk) {
 // initialized in the arena in the low bit of the tydesc pointer. This
 // is necessary in order to properly do cleanup if a failure occurs
 // during an initializer.
-#[inline(always)]
+#[inline]
 unsafe fn bitpack_tydesc_ptr(p: *TypeDesc, is_done: bool) -> uint {
     let p_bits: uint = transmute(p);
     p_bits | (is_done as uint)
 }
-#[inline(always)]
+#[inline]
 unsafe fn un_bitpack_tydesc_ptr(p: uint) -> (*TypeDesc, bool) {
     (transmute(p & !1), p & 1 == 1)
 }
@@ -179,7 +179,7 @@ impl Arena {
         return self.alloc_pod_inner(n_bytes, align);
     }
 
-    #[inline(always)]
+    #[inline]
     fn alloc_pod_inner(&mut self, n_bytes: uint, align: uint) -> *u8 {
         unsafe {
             // XXX: Borrow check
@@ -199,7 +199,7 @@ impl Arena {
         }
     }
 
-    #[inline(always)]
+    #[inline]
     fn alloc_pod<'a, T>(&'a mut self, op: &fn() -> T) -> &'a T {
         unsafe {
             let tydesc = sys::get_type_desc::<T>();
@@ -223,7 +223,7 @@ impl Arena {
         return self.alloc_nonpod_inner(n_bytes, align);
     }
 
-    #[inline(always)]
+    #[inline]
     fn alloc_nonpod_inner(&mut self, n_bytes: uint, align: uint)
                           -> (*u8, *u8) {
         unsafe {
@@ -246,7 +246,7 @@ impl Arena {
         }
     }
 
-    #[inline(always)]
+    #[inline]
     fn alloc_nonpod<'a, T>(&'a mut self, op: &fn() -> T) -> &'a T {
         unsafe {
             let tydesc = sys::get_type_desc::<T>();
@@ -268,7 +268,7 @@ impl Arena {
     }
 
     // The external interface
-    #[inline(always)]
+    #[inline]
     pub fn alloc<'a, T>(&'a mut self, op: &fn() -> T) -> &'a T {
         unsafe {
             // XXX: Borrow check
diff --git a/src/libextra/base64.rs b/src/libextra/base64.rs
index f4754b3e4cb..5bf4dd517a5 100644
--- a/src/libextra/base64.rs
+++ b/src/libextra/base64.rs
@@ -229,8 +229,6 @@ impl<'self> FromBase64 for &'self str {
 
 #[cfg(test)]
 mod tests {
-    use core::str;
-
     #[test]
     fn test_to_base64() {
         assert_eq!("".to_base64(), ~"");
diff --git a/src/libextra/bitv.rs b/src/libextra/bitv.rs
index e3a15f76c78..647fa81c718 100644
--- a/src/libextra/bitv.rs
+++ b/src/libextra/bitv.rs
@@ -23,7 +23,7 @@ struct SmallBitv {
 }
 
 /// a mask that has a 1 for each defined bit in a small_bitv, assuming n bits
-#[inline(always)]
+#[inline]
 fn small_mask(nbits: uint) -> uint {
     (1 << nbits) - 1
 }
@@ -33,7 +33,7 @@ impl SmallBitv {
         SmallBitv {bits: bits}
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn bits_op(&mut self,
                    right_bits: uint,
                    nbits: uint,
@@ -46,32 +46,32 @@ impl SmallBitv {
         mask & old_b != mask & new_b
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn union(&mut self, s: &SmallBitv, nbits: uint) -> bool {
         self.bits_op(s.bits, nbits, |u1, u2| u1 | u2)
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn intersect(&mut self, s: &SmallBitv, nbits: uint) -> bool {
         self.bits_op(s.bits, nbits, |u1, u2| u1 & u2)
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn become(&mut self, s: &SmallBitv, nbits: uint) -> bool {
         self.bits_op(s.bits, nbits, |_u1, u2| u2)
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn difference(&mut self, s: &SmallBitv, nbits: uint) -> bool {
         self.bits_op(s.bits, nbits, |u1, u2| u1 & !u2)
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn get(&self, i: uint) -> bool {
         (self.bits & (1 << i)) != 0
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn set(&mut self, i: uint, x: bool) {
         if x {
             self.bits |= 1<<i;
@@ -81,29 +81,29 @@ impl SmallBitv {
         }
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn equals(&self, b: &SmallBitv, nbits: uint) -> bool {
         let mask = small_mask(nbits);
         mask & self.bits == mask & b.bits
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn clear(&mut self) { self.bits = 0; }
 
-    #[inline(always)]
+    #[inline]
     pub fn set_all(&mut self) { self.bits = !0; }
 
-    #[inline(always)]
+    #[inline]
     pub fn is_true(&self, nbits: uint) -> bool {
         small_mask(nbits) & !self.bits == 0
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn is_false(&self, nbits: uint) -> bool {
         small_mask(nbits) & self.bits == 0
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn invert(&mut self) { self.bits = !self.bits; }
 }
 
@@ -115,7 +115,7 @@ struct BigBitv {
  * a mask that has a 1 for each defined bit in the nth element of a big_bitv,
  * assuming n bits.
  */
-#[inline(always)]
+#[inline]
 fn big_mask(nbits: uint, elem: uint) -> uint {
     let rmd = nbits % uint::bits;
     let nelems = nbits/uint::bits + if rmd == 0 {0} else {1};
@@ -132,7 +132,7 @@ impl BigBitv {
         BigBitv {storage: storage}
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn process(&mut self,
                    b: &BigBitv,
                    nbits: uint,
@@ -154,35 +154,35 @@ impl BigBitv {
         changed
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn each_storage(&mut self, op: &fn(v: &mut uint) -> bool) -> bool {
         uint::range(0, self.storage.len(), |i| op(&mut self.storage[i]))
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn invert(&mut self) { for self.each_storage |w| { *w = !*w } }
 
-    #[inline(always)]
+    #[inline]
     pub fn union(&mut self, b: &BigBitv, nbits: uint) -> bool {
         self.process(b, nbits, |w1, w2| w1 | w2)
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn intersect(&mut self, b: &BigBitv, nbits: uint) -> bool {
         self.process(b, nbits, |w1, w2| w1 & w2)
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn become(&mut self, b: &BigBitv, nbits: uint) -> bool {
         self.process(b, nbits, |_, w| w)
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn difference(&mut self, b: &BigBitv, nbits: uint) -> bool {
         self.process(b, nbits, |w1, w2| w1 & !w2)
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn get(&self, i: uint) -> bool {
         let w = i / uint::bits;
         let b = i % uint::bits;
@@ -190,7 +190,7 @@ impl BigBitv {
         x == 1
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn set(&mut self, i: uint, x: bool) {
         let w = i / uint::bits;
         let b = i % uint::bits;
@@ -199,7 +199,7 @@ impl BigBitv {
                           else { self.storage[w] & !flag };
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn equals(&self, b: &BigBitv, nbits: uint) -> bool {
         let len = b.storage.len();
         for uint::iterate(0, len) |i| {
@@ -229,7 +229,7 @@ fn die() -> ! {
 }
 
 impl Bitv {
-    #[inline(always)]
+    #[inline]
     fn do_op(&mut self, op: Op, other: &Bitv) -> bool {
         if self.nbits != other.nbits {
             die();
@@ -279,7 +279,7 @@ impl Bitv {
      * Sets `self` to the union of `self` and `v1`. Both bitvectors must be
      * the same length. Returns 'true' if `self` changed.
     */
-    #[inline(always)]
+    #[inline]
     pub fn union(&mut self, v1: &Bitv) -> bool { self.do_op(Union, v1) }
 
     /**
@@ -288,7 +288,7 @@ impl Bitv {
      * Sets `self` to the intersection of `self` and `v1`. Both bitvectors
      * must be the same length. Returns 'true' if `self` changed.
     */
-    #[inline(always)]
+    #[inline]
     pub fn intersect(&mut self, v1: &Bitv) -> bool {
         self.do_op(Intersect, v1)
     }
@@ -299,11 +299,11 @@ impl Bitv {
      * Both bitvectors must be the same length. Returns `true` if `self` was
      * changed
      */
-    #[inline(always)]
+    #[inline]
     pub fn assign(&mut self, v: &Bitv) -> bool { self.do_op(Assign, v) }
 
     /// Retrieve the value at index `i`
-    #[inline(always)]
+    #[inline]
     pub fn get(&self, i: uint) -> bool {
         assert!((i < self.nbits));
         match self.rep {
@@ -317,7 +317,7 @@ impl Bitv {
      *
      * `i` must be less than the length of the bitvector.
      */
-    #[inline(always)]
+    #[inline]
     pub fn set(&mut self, i: uint, x: bool) {
       assert!((i < self.nbits));
       match self.rep {
@@ -332,7 +332,7 @@ impl Bitv {
      * Both bitvectors must be the same length. Returns `true` if both
      * bitvectors contain identical elements.
      */
-    #[inline(always)]
+    #[inline]
     pub fn equal(&self, v1: &Bitv) -> bool {
       if self.nbits != v1.nbits { return false; }
       match self.rep {
@@ -348,7 +348,7 @@ impl Bitv {
     }
 
     /// Set all bits to 0
-    #[inline(always)]
+    #[inline]
     pub fn clear(&mut self) {
         match self.rep {
           Small(ref mut b) => b.clear(),
@@ -357,7 +357,7 @@ impl Bitv {
     }
 
     /// Set all bits to 1
-    #[inline(always)]
+    #[inline]
     pub fn set_all(&mut self) {
       match self.rep {
         Small(ref mut b) => b.set_all(),
@@ -365,7 +365,7 @@ impl Bitv {
     }
 
     /// Invert all bits
-    #[inline(always)]
+    #[inline]
     pub fn invert(&mut self) {
       match self.rep {
         Small(ref mut b) => b.invert(),
@@ -381,13 +381,13 @@ impl Bitv {
      *
      * Returns `true` if `v0` was changed.
      */
-    #[inline(always)]
+    #[inline]
     pub fn difference(&mut self, v: &Bitv) -> bool {
         self.do_op(Difference, v)
     }
 
     /// Returns true if all bits are 1
-    #[inline(always)]
+    #[inline]
     pub fn is_true(&self) -> bool {
       match self.rep {
         Small(ref b) => b.is_true(self.nbits),
@@ -398,7 +398,7 @@ impl Bitv {
       }
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn each(&self, f: &fn(bool) -> bool) -> bool {
         let mut i = 0;
         while i < self.nbits {
@@ -508,7 +508,7 @@ impl Bitv {
 
 impl Clone for Bitv {
     /// Makes a copy of a bitvector
-    #[inline(always)]
+    #[inline]
     fn clone(&self) -> Bitv {
         match self.rep {
           Small(ref b) => {
@@ -562,7 +562,7 @@ impl ops::Index<uint,bool> for Bitv {
     }
 }
 
-#[inline(always)]
+#[inline]
 fn iterate_bits(base: uint, bits: uint, f: &fn(uint) -> bool) -> bool {
     if bits == 0 {
         return true;
@@ -623,7 +623,7 @@ impl BitvSet {
         return Bitv{ nbits:cap, rep: Big(~bitv) };
     }
 
-    #[inline(always)]
+    #[inline]
     fn other_op(&mut self, other: &BitvSet, f: &fn(uint, uint) -> uint) {
         fn nbits(mut w: uint) -> uint {
             let mut bits = 0;
diff --git a/src/libextra/c_vec.rs b/src/libextra/c_vec.rs
index 7cc7b659ed9..fd48e7d5958 100644
--- a/src/libextra/c_vec.rs
+++ b/src/libextra/c_vec.rs
@@ -122,7 +122,7 @@ pub unsafe fn c_vec_with_dtor<T>(base: *mut T, len: uint, dtor: @fn())
  */
 pub fn get<T:Copy>(t: CVec<T>, ofs: uint) -> T {
     assert!(ofs < len(t));
-    return unsafe { *ptr::mut_offset(t.base, ofs) };
+    return unsafe { copy *ptr::mut_offset(t.base, ofs) };
 }
 
 /**
diff --git a/src/libextra/deque.rs b/src/libextra/deque.rs
index 89e23a3a77f..c8bb984736a 100644
--- a/src/libextra/deque.rs
+++ b/src/libextra/deque.rs
@@ -264,31 +264,31 @@ mod tests {
     fn test_parameterized<T:Copy + Eq>(a: T, b: T, c: T, d: T) {
         let mut deq = Deque::new();
         assert_eq!(deq.len(), 0);
-        deq.add_front(a);
-        deq.add_front(b);
-        deq.add_back(c);
+        deq.add_front(copy a);
+        deq.add_front(copy b);
+        deq.add_back(copy c);
         assert_eq!(deq.len(), 3);
-        deq.add_back(d);
+        deq.add_back(copy d);
         assert_eq!(deq.len(), 4);
-        assert_eq!(*deq.peek_front(), b);
-        assert_eq!(*deq.peek_back(), d);
-        assert_eq!(deq.pop_front(), b);
-        assert_eq!(deq.pop_back(), d);
-        assert_eq!(deq.pop_back(), c);
-        assert_eq!(deq.pop_back(), a);
+        assert_eq!(copy *deq.peek_front(), copy b);
+        assert_eq!(copy *deq.peek_back(), copy d);
+        assert_eq!(deq.pop_front(), copy b);
+        assert_eq!(deq.pop_back(), copy d);
+        assert_eq!(deq.pop_back(), copy c);
+        assert_eq!(deq.pop_back(), copy a);
         assert_eq!(deq.len(), 0);
-        deq.add_back(c);
+        deq.add_back(copy c);
         assert_eq!(deq.len(), 1);
-        deq.add_front(b);
+        deq.add_front(copy b);
         assert_eq!(deq.len(), 2);
-        deq.add_back(d);
+        deq.add_back(copy d);
         assert_eq!(deq.len(), 3);
-        deq.add_front(a);
+        deq.add_front(copy a);
         assert_eq!(deq.len(), 4);
-        assert_eq!(*deq.get(0), a);
-        assert_eq!(*deq.get(1), b);
-        assert_eq!(*deq.get(2), c);
-        assert_eq!(*deq.get(3), d);
+        assert_eq!(copy *deq.get(0), copy a);
+        assert_eq!(copy *deq.get(1), copy b);
+        assert_eq!(copy *deq.get(2), copy c);
+        assert_eq!(copy *deq.get(3), copy d);
     }
 
     #[deriving(Eq)]
diff --git a/src/libextra/dlist.rs b/src/libextra/dlist.rs
index c3e2beb122f..953803c6843 100644
--- a/src/libextra/dlist.rs
+++ b/src/libextra/dlist.rs
@@ -111,7 +111,8 @@ pub fn from_elem<T>(data: T) -> @mut DList<T> {
 /// Creates a new dlist from a vector of elements, maintaining the same order
 pub fn from_vec<T:Copy>(vec: &[T]) -> @mut DList<T> {
     do vec.iter().fold(DList()) |list,data| {
-        list.push(*data); // Iterating left-to-right -- add newly to the tail.
+        // Iterating left-to-right -- add newly to the tail.
+        list.push(copy *data);
         list
     }
 }
@@ -159,7 +160,7 @@ impl<T> DList<T> {
     }
     // Link two nodes together. If either of them are 'none', also sets
     // the head and/or tail pointers appropriately.
-    #[inline(always)]
+    #[inline]
     fn link(&mut self, before: DListLink<T>, after: DListLink<T>) {
         match before {
             Some(neighbour) => neighbour.next = after,
@@ -460,35 +461,35 @@ impl<T> DList<T> {
 impl<T:Copy> DList<T> {
     /// Remove data from the head of the list. O(1).
     pub fn pop(@mut self) -> Option<T> {
-        self.pop_n().map(|nobe| nobe.data)
+        self.pop_n().map(|nobe| copy nobe.data)
     }
 
     /// Remove data from the tail of the list. O(1).
     pub fn pop_tail(@mut self) -> Option<T> {
-        self.pop_tail_n().map(|nobe| nobe.data)
+        self.pop_tail_n().map(|nobe| copy nobe.data)
     }
 
     /// Get data at the list's head. O(1).
     pub fn peek(@mut self) -> Option<T> {
-        self.peek_n().map(|nobe| nobe.data)
+        self.peek_n().map(|nobe| copy nobe.data)
     }
 
     /// Get data at the list's tail. O(1).
     pub fn peek_tail(@mut self) -> Option<T> {
-        self.peek_tail_n().map (|nobe| nobe.data)
+        self.peek_tail_n().map (|nobe| copy nobe.data)
     }
 
     /// Get data at the list's head, failing if empty. O(1).
-    pub fn head(@mut self) -> T { self.head_n().data }
+    pub fn head(@mut self) -> T { copy self.head_n().data }
 
     /// Get data at the list's tail, failing if empty. O(1).
-    pub fn tail(@mut self) -> T { self.tail_n().data }
+    pub fn tail(@mut self) -> T { copy self.tail_n().data }
 
     /// Get the elements of the list as a vector. O(n).
     pub fn to_vec(@mut self) -> ~[T] {
         let mut v = vec::with_capacity(self.size);
         for old_iter::eachi(&self) |index,data| {
-            v[index] = *data;
+            v[index] = copy *data;
         }
         v
     }
@@ -531,7 +532,7 @@ impl<T> BaseIter<T> for @mut DList<T> {
         return true;
     }
 
-    #[inline(always)]
+    #[inline]
     fn size_hint(&self) -> Option<uint> { Some(self.len()) }
 }
 
diff --git a/src/libextra/flatpipes.rs b/src/libextra/flatpipes.rs
index c0f619c1b85..9a8ee395936 100644
--- a/src/libextra/flatpipes.rs
+++ b/src/libextra/flatpipes.rs
@@ -516,7 +516,6 @@ pub mod bytepipes {
     use core::comm::{Port, Chan};
     use core::comm;
     use core::io::{Writer, Reader, ReaderUtil};
-    use core::vec;
 
     pub struct ReaderBytePort<R> {
         reader: R
@@ -583,12 +582,12 @@ pub mod bytepipes {
 
     impl BytePort for PipeBytePort {
         fn try_recv(&self, count: uint) -> Option<~[u8]> {
-            if vec::uniq_len(&const *self.buf) >= count {
+            if self.buf.len() >= count {
                 let mut bytes = ::core::util::replace(&mut *self.buf, ~[]);
                 *self.buf = bytes.slice(count, bytes.len()).to_owned();
                 bytes.truncate(count);
                 return Some(bytes);
-            } else if vec::uniq_len(&const *self.buf) > 0 {
+            } else if !self.buf.is_empty() {
                 let mut bytes = ::core::util::replace(&mut *self.buf, ~[]);
                 assert!(count > bytes.len());
                 match self.try_recv(count - bytes.len()) {
@@ -598,7 +597,7 @@ pub mod bytepipes {
                     }
                     None => return None
                 }
-            } else if vec::uniq_len(&const *self.buf) == 0 {
+            } else /* empty */ {
                 match self.port.try_recv() {
                     Some(buf) => {
                         assert!(!buf.is_empty());
@@ -607,8 +606,6 @@ pub mod bytepipes {
                     }
                     None => return None
                 }
-            } else {
-                ::core::util::unreachable()
             }
         }
     }
diff --git a/src/libextra/future.rs b/src/libextra/future.rs
index 40cfeebd5dc..4652e1d6477 100644
--- a/src/libextra/future.rs
+++ b/src/libextra/future.rs
@@ -57,7 +57,7 @@ priv enum FutureState<A> {
 impl<A:Copy> Future<A> {
     pub fn get(&mut self) -> A {
         //! Get the value of the future.
-        *(self.get_ref())
+        copy *(self.get_ref())
     }
 }
 
diff --git a/src/libextra/list.rs b/src/libextra/list.rs
index 68d9bb4e1ae..34c35e0d7fd 100644
--- a/src/libextra/list.rs
+++ b/src/libextra/list.rs
@@ -27,7 +27,7 @@ pub enum MutList<T> {
 
 /// Create a list from a vector
 pub fn from_vec<T:Copy>(v: &[T]) -> @List<T> {
-    v.rev_iter().fold(@Nil::<T>, |t, h| @Cons(*h, t))
+    v.rev_iter().fold(@Nil::<T>, |t, h| @Cons(copy *h, t))
 }
 
 /**
@@ -61,7 +61,7 @@ pub fn find<T:Copy>(ls: @List<T>, f: &fn(&T) -> bool) -> Option<T> {
     loop {
         ls = match *ls {
           Cons(ref hd, tl) => {
-            if f(hd) { return Some(*hd); }
+            if f(hd) { return Some(copy *hd); }
             tl
           }
           Nil => return None
diff --git a/src/libextra/net_tcp.rs b/src/libextra/net_tcp.rs
index d95807f2b91..51d744955b8 100644
--- a/src/libextra/net_tcp.rs
+++ b/src/libextra/net_tcp.rs
@@ -181,90 +181,88 @@ pub fn connect(input_ip: ip::IpAddr, port: uint,
         debug!("stream_handle_ptr outside interact %?",
                         stream_handle_ptr);
         do iotask::interact(iotask) |loop_ptr| {
-            unsafe {
-                debug!("in interact cb for tcp client connect..");
-                debug!("stream_handle_ptr in interact %?",
-                                stream_handle_ptr);
-                match uv::ll::tcp_init( loop_ptr, stream_handle_ptr) {
-                    0i32 => {
-                        debug!("tcp_init successful");
-                        debug!("dealing w/ ipv4 connection..");
-                        let connect_req_ptr: *uv::ll::uv_connect_t =
-                            &(*socket_data_ptr).connect_req;
-                        let addr_str = ip::format_addr(&input_ip);
-                        let connect_result = match input_ip {
-                            ip::Ipv4(ref addr) => {
-                                // have to "recreate" the
-                                // sockaddr_in/6 since the ip_addr
-                                // discards the port info.. should
-                                // probably add an additional rust
-                                // type that actually is closer to
-                                // what the libuv API expects (ip str
-                                // + port num)
-                                debug!("addr: %?", addr);
-                                let in_addr = uv::ll::ip4_addr(addr_str,
-                                                               port as int);
-                                uv::ll::tcp_connect(
-                                    connect_req_ptr,
-                                    stream_handle_ptr,
-                                    &in_addr,
-                                    tcp_connect_on_connect_cb)
-                            }
-                            ip::Ipv6(ref addr) => {
-                                debug!("addr: %?", addr);
-                                let in_addr = uv::ll::ip6_addr(addr_str,
-                                                               port as int);
-                                uv::ll::tcp_connect6(
-                                    connect_req_ptr,
-                                    stream_handle_ptr,
-                                    &in_addr,
-                                    tcp_connect_on_connect_cb)
-                            }
-                        };
-                        match connect_result {
-                            0i32 => {
-                                debug!("tcp_connect successful: \
-                                        stream %x,
-                                        socket data %x",
-                                       stream_handle_ptr as uint,
-                                       socket_data_ptr as uint);
-                                // reusable data that we'll have for the
-                                // duration..
-                                uv::ll::set_data_for_uv_handle(
-                                    stream_handle_ptr,
-                                    socket_data_ptr as
-                                    *libc::c_void);
-                                // just so the connect_cb can send the
-                                // outcome..
-                                uv::ll::set_data_for_req(connect_req_ptr,
-                                                         conn_data_ptr);
-                                debug!("leaving tcp_connect interact cb...");
-                                // let tcp_connect_on_connect_cb send on
-                                // the result_ch, now..
-                            }
-                            _ => {
-                                // immediate connect
-                                // failure.. probably a garbage ip or
-                                // somesuch
-                                let err_data =
-                                    uv::ll::get_last_err_data(loop_ptr);
-                                let result_ch = (*conn_data_ptr)
-                                    .result_ch.clone();
-                                result_ch.send(ConnFailure(err_data));
-                                uv::ll::set_data_for_uv_handle(
-                                    stream_handle_ptr,
-                                    conn_data_ptr);
-                                uv::ll::close(stream_handle_ptr,
-                                              stream_error_close_cb);
-                            }
+            debug!("in interact cb for tcp client connect..");
+            debug!("stream_handle_ptr in interact %?",
+                            stream_handle_ptr);
+            match uv::ll::tcp_init( loop_ptr, stream_handle_ptr) {
+                0i32 => {
+                    debug!("tcp_init successful");
+                    debug!("dealing w/ ipv4 connection..");
+                    let connect_req_ptr: *uv::ll::uv_connect_t =
+                        &(*socket_data_ptr).connect_req;
+                    let addr_str = ip::format_addr(&input_ip);
+                    let connect_result = match input_ip {
+                        ip::Ipv4(ref addr) => {
+                            // have to "recreate" the
+                            // sockaddr_in/6 since the ip_addr
+                            // discards the port info.. should
+                            // probably add an additional rust
+                            // type that actually is closer to
+                            // what the libuv API expects (ip str
+                            // + port num)
+                            debug!("addr: %?", addr);
+                            let in_addr = uv::ll::ip4_addr(addr_str,
+                                                           port as int);
+                            uv::ll::tcp_connect(
+                                connect_req_ptr,
+                                stream_handle_ptr,
+                                &in_addr,
+                                tcp_connect_on_connect_cb)
+                        }
+                        ip::Ipv6(ref addr) => {
+                            debug!("addr: %?", addr);
+                            let in_addr = uv::ll::ip6_addr(addr_str,
+                                                           port as int);
+                            uv::ll::tcp_connect6(
+                                connect_req_ptr,
+                                stream_handle_ptr,
+                                &in_addr,
+                                tcp_connect_on_connect_cb)
+                        }
+                    };
+                    match connect_result {
+                        0i32 => {
+                            debug!("tcp_connect successful: \
+                                    stream %x,
+                                    socket data %x",
+                                   stream_handle_ptr as uint,
+                                   socket_data_ptr as uint);
+                            // reusable data that we'll have for the
+                            // duration..
+                            uv::ll::set_data_for_uv_handle(
+                                stream_handle_ptr,
+                                socket_data_ptr as
+                                *libc::c_void);
+                            // just so the connect_cb can send the
+                            // outcome..
+                            uv::ll::set_data_for_req(connect_req_ptr,
+                                                     conn_data_ptr);
+                            debug!("leaving tcp_connect interact cb...");
+                            // let tcp_connect_on_connect_cb send on
+                            // the result_ch, now..
+                        }
+                        _ => {
+                            // immediate connect
+                            // failure.. probably a garbage ip or
+                            // somesuch
+                            let err_data =
+                                uv::ll::get_last_err_data(loop_ptr);
+                            let result_ch = (*conn_data_ptr)
+                                .result_ch.clone();
+                            result_ch.send(ConnFailure(err_data));
+                            uv::ll::set_data_for_uv_handle(
+                                stream_handle_ptr,
+                                conn_data_ptr);
+                            uv::ll::close(stream_handle_ptr,
+                                          stream_error_close_cb);
                         }
                     }
-                    _ => {
-                        // failure to create a tcp handle
-                        let err_data = uv::ll::get_last_err_data(loop_ptr);
-                        let result_ch = (*conn_data_ptr).result_ch.clone();
-                        result_ch.send(ConnFailure(err_data));
-                    }
+                }
+                _ => {
+                    // failure to create a tcp handle
+                    let err_data = uv::ll::get_last_err_data(loop_ptr);
+                    let result_ch = (*conn_data_ptr).result_ch.clone();
+                    result_ch.send(ConnFailure(err_data));
                 }
             }
         }
@@ -879,8 +877,7 @@ impl io::Reader for TcpSocketBuf {
 
           // If possible, copy up to `len` bytes from the internal
           // `data.buf` into `buf`
-          let nbuffered = vec::uniq_len(&const self.data.buf) -
-                self.data.buf_off;
+          let nbuffered = self.data.buf.len() - self.data.buf_off;
           let needed = len - count;
             if nbuffered > 0 {
                 unsafe {
@@ -934,7 +931,7 @@ impl io::Reader for TcpSocketBuf {
     }
     fn read_byte(&self) -> int {
         loop {
-          if vec::uniq_len(&const self.data.buf) > self.data.buf_off {
+          if self.data.buf.len() > self.data.buf_off {
             let c = self.data.buf[self.data.buf_off];
             self.data.buf_off += 1;
             return c as int
@@ -1016,14 +1013,12 @@ fn tear_down_socket_data(socket_data: @TcpSocketData) {
         let close_data_ptr: *TcpSocketCloseData = &close_data;
         let stream_handle_ptr = (*socket_data).stream_handle_ptr;
         do iotask::interact(&(*socket_data).iotask) |loop_ptr| {
-            unsafe {
-                debug!(
-                    "interact dtor for tcp_socket stream %? loop %?",
-                         stream_handle_ptr, loop_ptr);
-                uv::ll::set_data_for_uv_handle(stream_handle_ptr,
-                                               close_data_ptr);
-                uv::ll::close(stream_handle_ptr, tcp_socket_dtor_close_cb);
-            }
+            debug!(
+                "interact dtor for tcp_socket stream %? loop %?",
+                     stream_handle_ptr, loop_ptr);
+            uv::ll::set_data_for_uv_handle(stream_handle_ptr,
+                                           close_data_ptr);
+            uv::ll::close(stream_handle_ptr, tcp_socket_dtor_close_cb);
         };
         closed_po.recv();
         //the line below will most likely crash
@@ -1083,19 +1078,17 @@ fn read_stop_common_impl(socket_data: *TcpSocketData) ->
         let stream_handle_ptr = (*socket_data).stream_handle_ptr;
         let (stop_po, stop_ch) = stream::<Option<TcpErrData>>();
         do iotask::interact(&(*socket_data).iotask) |loop_ptr| {
-            unsafe {
-                debug!("in interact cb for tcp::read_stop");
-                match uv::ll::read_stop(stream_handle_ptr
-                                        as *uv::ll::uv_stream_t) {
-                    0i32 => {
-                        debug!("successfully called uv_read_stop");
-                        stop_ch.send(None);
-                    }
-                    _ => {
-                        debug!("failure in calling uv_read_stop");
-                        let err_data = uv::ll::get_last_err_data(loop_ptr);
-                        stop_ch.send(Some(err_data.to_tcp_err()));
-                    }
+            debug!("in interact cb for tcp::read_stop");
+            match uv::ll::read_stop(stream_handle_ptr
+                                    as *uv::ll::uv_stream_t) {
+                0i32 => {
+                    debug!("successfully called uv_read_stop");
+                    stop_ch.send(None);
+                }
+                _ => {
+                    debug!("failure in calling uv_read_stop");
+                    let err_data = uv::ll::get_last_err_data(loop_ptr);
+                    stop_ch.send(Some(err_data.to_tcp_err()));
                 }
             }
         }
@@ -1115,22 +1108,20 @@ fn read_start_common_impl(socket_data: *TcpSocketData)
         let (start_po, start_ch) = stream::<Option<uv::ll::uv_err_data>>();
         debug!("in tcp::read_start before interact loop");
         do iotask::interact(&(*socket_data).iotask) |loop_ptr| {
-            unsafe {
-                debug!("in tcp::read_start interact cb %?",
-                                loop_ptr);
-                match uv::ll::read_start(stream_handle_ptr
-                                         as *uv::ll::uv_stream_t,
-                                         on_alloc_cb,
-                                         on_tcp_read_cb) {
-                    0i32 => {
-                        debug!("success doing uv_read_start");
-                        start_ch.send(None);
-                    }
-                    _ => {
-                        debug!("error attempting uv_read_start");
-                        let err_data = uv::ll::get_last_err_data(loop_ptr);
-                        start_ch.send(Some(err_data));
-                    }
+            debug!("in tcp::read_start interact cb %?",
+                            loop_ptr);
+            match uv::ll::read_start(stream_handle_ptr
+                                     as *uv::ll::uv_stream_t,
+                                     on_alloc_cb,
+                                     on_tcp_read_cb) {
+                0i32 => {
+                    debug!("success doing uv_read_start");
+                    start_ch.send(None);
+                }
+                _ => {
+                    debug!("error attempting uv_read_start");
+                    let err_data = uv::ll::get_last_err_data(loop_ptr);
+                    start_ch.send(Some(err_data));
                 }
             }
         }
@@ -1167,24 +1158,22 @@ fn write_common_impl(socket_data_ptr: *TcpSocketData,
         };
         let write_data_ptr: *WriteReqData = &write_data;
         do iotask::interact(&(*socket_data_ptr).iotask) |loop_ptr| {
-            unsafe {
-                debug!("in interact cb for tcp::write %?",
-                                loop_ptr);
-                match uv::ll::write(write_req_ptr,
-                                    stream_handle_ptr,
-                                    write_buf_vec_ptr,
-                                    tcp_write_complete_cb) {
-                    0i32 => {
-                        debug!("uv_write() invoked successfully");
-                        uv::ll::set_data_for_req(write_req_ptr,
-                                                 write_data_ptr);
-                    }
-                    _ => {
-                        debug!("error invoking uv_write()");
-                        let err_data = uv::ll::get_last_err_data(loop_ptr);
-                        let result_ch = (*write_data_ptr).result_ch.clone();
-                        result_ch.send(TcpWriteError(err_data.to_tcp_err()));
-                    }
+            debug!("in interact cb for tcp::write %?",
+                            loop_ptr);
+            match uv::ll::write(write_req_ptr,
+                                stream_handle_ptr,
+                                write_buf_vec_ptr,
+                                tcp_write_complete_cb) {
+                0i32 => {
+                    debug!("uv_write() invoked successfully");
+                    uv::ll::set_data_for_req(write_req_ptr,
+                                             write_data_ptr);
+                }
+                _ => {
+                    debug!("error invoking uv_write()");
+                    let err_data = uv::ll::get_last_err_data(loop_ptr);
+                    let result_ch = (*write_data_ptr).result_ch.clone();
+                    result_ch.send(TcpWriteError(err_data.to_tcp_err()));
                 }
             }
         }
diff --git a/src/libextra/num/complex.rs b/src/libextra/num/complex.rs
index 1bb364f3a1c..c626260043e 100644
--- a/src/libextra/num/complex.rs
+++ b/src/libextra/num/complex.rs
@@ -80,19 +80,17 @@ impl<T: Clone + Num> Cmplx<T> {
     }
 }
 
-#[cfg(not(stage0))] // Fixed by #4228
 impl<T: Clone + Algebraic + Num> Cmplx<T> {
     /// Calculate |self|
-    #[inline(always)]
+    #[inline]
     pub fn norm(&self) -> T {
         self.re.hypot(&self.im)
     }
 }
 
-#[cfg(not(stage0))] // Fixed by #4228
 impl<T: Clone + Trigonometric + Algebraic + Num> Cmplx<T> {
     /// Calculate the principal Arg of self.
-    #[inline(always)]
+    #[inline]
     pub fn arg(&self) -> T {
         self.im.atan2(&self.re)
     }
@@ -222,6 +220,8 @@ mod test {
     }
 
     #[test]
+    #[ignore(cfg(target_arch = "x86"))]
+    // FIXME #7158: (maybe?) currently failing on x86.
     fn test_norm() {
         fn test(c: Complex, ns: float) {
             assert_eq!(c.norm_sqr(), ns);
diff --git a/src/libextra/num/rational.rs b/src/libextra/num/rational.rs
index ebb88a13481..b2b966928e9 100644
--- a/src/libextra/num/rational.rs
+++ b/src/libextra/num/rational.rs
@@ -36,19 +36,19 @@ pub type BigRational = Ratio<BigInt>;
 impl<T: Clone + Integer + Ord>
     Ratio<T> {
     /// Create a ratio representing the integer `t`.
-    #[inline(always)]
+    #[inline]
     pub fn from_integer(t: T) -> Ratio<T> {
         Ratio::new_raw(t, One::one())
     }
 
     /// Create a ratio without checking for `denom == 0` or reducing.
-    #[inline(always)]
+    #[inline]
     pub fn new_raw(numer: T, denom: T) -> Ratio<T> {
         Ratio { numer: numer, denom: denom }
     }
 
     /// Create a new Ratio. Fails if `denom == 0`.
-    #[inline(always)]
+    #[inline]
     pub fn new(numer: T, denom: T) -> Ratio<T> {
         if denom == Zero::zero() {
             fail!("denominator == 0");
@@ -206,7 +206,7 @@ impl<T: Clone + Integer + Ord>
         }
     }
 
-    #[inline(always)]
+    #[inline]
     fn round(&self) -> Ratio<T> {
         if *self < Zero::zero() {
             Ratio::from_integer((self.numer - self.denom + One::one()) / self.denom)
@@ -215,7 +215,7 @@ impl<T: Clone + Integer + Ord>
         }
     }
 
-    #[inline(always)]
+    #[inline]
     fn trunc(&self) -> Ratio<T> {
         Ratio::from_integer(self.numer / self.denom)
     }
diff --git a/src/libextra/priority_queue.rs b/src/libextra/priority_queue.rs
index 601b7685f3c..efbf23f11b1 100644
--- a/src/libextra/priority_queue.rs
+++ b/src/libextra/priority_queue.rs
@@ -35,10 +35,10 @@ impl<T:Ord> BaseIter<T> for PriorityQueue<T> {
 
 impl<T:Ord> Container for PriorityQueue<T> {
     /// Returns the length of the queue
-    fn len(&const self) -> uint { vec::uniq_len(&const self.data) }
+    fn len(&self) -> uint { self.data.len() }
 
     /// Returns true if a queue contains no elements
-    fn is_empty(&const self) -> bool { self.len() == 0 }
+    fn is_empty(&self) -> bool { self.len() == 0 }
 }
 
 impl<T:Ord> Mutable for PriorityQueue<T> {
diff --git a/src/libextra/rc.rs b/src/libextra/rc.rs
index 96ad629ea83..b90b0983dc2 100644
--- a/src/libextra/rc.rs
+++ b/src/libextra/rc.rs
@@ -60,7 +60,7 @@ pub fn rc_from_const<T: Const>(value: T) -> Rc<T> {
 }
 
 impl<T> Rc<T> {
-    #[inline(always)]
+    #[inline]
     pub fn borrow<'r>(&'r self) -> &'r T {
         unsafe { cast::copy_lifetime(self, &(*self.ptr).value) }
     }
diff --git a/src/libextra/rope.rs b/src/libextra/rope.rs
index 12539cd4759..fed73256c00 100644
--- a/src/libextra/rope.rs
+++ b/src/libextra/rope.rs
@@ -1271,7 +1271,6 @@ mod tests {
 
     use rope::*;
 
-    use core::str;
     use core::uint;
     use core::vec;
 
diff --git a/src/libextra/semver.rs b/src/libextra/semver.rs
index 462461439e6..cb372dd920d 100644
--- a/src/libextra/semver.rs
+++ b/src/libextra/semver.rs
@@ -29,7 +29,7 @@ pub enum Identifier {
 }
 
 impl cmp::Ord for Identifier {
-    #[inline(always)]
+    #[inline]
     fn lt(&self, other: &Identifier) -> bool {
         match (self, other) {
             (&Numeric(a), &Numeric(b)) => a < b,
@@ -38,22 +38,22 @@ impl cmp::Ord for Identifier {
             (&AlphaNumeric(_), _) => false
         }
     }
-    #[inline(always)]
+    #[inline]
     fn le(&self, other: &Identifier) -> bool {
         ! (other < self)
     }
-    #[inline(always)]
+    #[inline]
     fn gt(&self, other: &Identifier) -> bool {
         other < self
     }
-    #[inline(always)]
+    #[inline]
     fn ge(&self, other: &Identifier) -> bool {
         ! (self < other)
     }
 }
 
 impl ToStr for Identifier {
-    #[inline(always)]
+    #[inline]
     fn to_str(&self) -> ~str {
         match self {
             &Numeric(n) => n.to_str(),
@@ -73,7 +73,7 @@ pub struct Version {
 }
 
 impl ToStr for Version {
-    #[inline(always)]
+    #[inline]
     fn to_str(&self) -> ~str {
         let s = fmt!("%u.%u.%u", self.major, self.minor, self.patch);
         let s = if self.pre.is_empty() {
@@ -90,7 +90,7 @@ impl ToStr for Version {
 }
 
 impl cmp::Ord for Version {
-    #[inline(always)]
+    #[inline]
     fn lt(&self, other: &Version) -> bool {
 
         self.major < other.major ||
@@ -123,15 +123,15 @@ impl cmp::Ord for Version {
              self.build < other.build)
     }
 
-    #[inline(always)]
+    #[inline]
     fn le(&self, other: &Version) -> bool {
         ! (other < self)
     }
-    #[inline(always)]
+    #[inline]
     fn gt(&self, other: &Version) -> bool {
         other < self
     }
-    #[inline(always)]
+    #[inline]
     fn ge(&self, other: &Version) -> bool {
         ! (self < other)
     }
diff --git a/src/libextra/sha1.rs b/src/libextra/sha1.rs
index 908e497b959..7c4b3f4ce39 100644
--- a/src/libextra/sha1.rs
+++ b/src/libextra/sha1.rs
@@ -24,7 +24,6 @@
 
 use core::prelude::*;
 
-use core::str;
 use core::uint;
 use core::vec;
 
@@ -93,7 +92,7 @@ pub fn sha1() -> @Sha1 {
     }
     fn process_msg_block(st: &mut Sha1State) {
         assert_eq!(st.h.len(), digest_buf_len);
-        assert_eq!(vec::uniq_len(st.work_buf), work_buf_len);
+        assert_eq!(st.work_buf.len(), work_buf_len);
         let mut t: int; // Loop counter
         let w = st.work_buf;
 
@@ -279,8 +278,6 @@ pub fn sha1() -> @Sha1 {
 mod tests {
     use sha1;
 
-    use core::vec;
-
     #[test]
     fn test() {
         struct Test {
diff --git a/src/libextra/smallintmap.rs b/src/libextra/smallintmap.rs
index 7f566bc16e7..aee087d3764 100644
--- a/src/libextra/smallintmap.rs
+++ b/src/libextra/smallintmap.rs
@@ -32,9 +32,9 @@ pub struct SmallIntMap<T> {
 
 impl<V> Container for SmallIntMap<V> {
     /// Return the number of elements in the map
-    fn len(&const self) -> uint {
+    fn len(&self) -> uint {
         let mut sz = 0;
-        for uint::range(0, vec::uniq_len(&const self.v)) |i| {
+        for uint::range(0, self.v.len()) |i| {
             match self.v[i] {
                 Some(_) => sz += 1,
                 None => {}
@@ -44,7 +44,7 @@ impl<V> Container for SmallIntMap<V> {
     }
 
     /// Return true if the map contains no elements
-    fn is_empty(&const self) -> bool { self.len() == 0 }
+    fn is_empty(&self) -> bool { self.len() == 0 }
 }
 
 impl<V> Mutable for SmallIntMap<V> {
@@ -179,7 +179,7 @@ impl<V:Copy> SmallIntMap<V> {
                            ff: &fn(uint, V, V) -> V) -> bool {
         let new_val = match self.find(&key) {
             None => val,
-            Some(orig) => ff(key, *orig, val)
+            Some(orig) => ff(key, copy *orig, val)
         };
         self.insert(key, new_val)
     }
@@ -199,12 +199,12 @@ pub struct SmallIntSet {
 
 impl Container for SmallIntSet {
     /// Return the number of elements in the map
-    fn len(&const self) -> uint {
+    fn len(&self) -> uint {
         self.map.len()
     }
 
     /// Return true if the map contains no elements
-    fn is_empty(&const self) -> bool { self.len() == 0 }
+    fn is_empty(&self) -> bool { self.len() == 0 }
 }
 
 impl Mutable for SmallIntSet {
@@ -294,11 +294,6 @@ mod tests {
 
     use super::SmallIntMap;
 
-    use core::local_data;
-    use core::rand;
-    use core::uint;
-    use core::vec;
-
     #[test]
     fn test_find_mut() {
         let mut m = SmallIntMap::new();
diff --git a/src/libextra/sort.rs b/src/libextra/sort.rs
index 0189e0db6d4..3e81216fc3a 100644
--- a/src/libextra/sort.rs
+++ b/src/libextra/sort.rs
@@ -37,7 +37,7 @@ pub fn merge_sort<T:Copy>(v: &[T], le: Le<T>) -> ~[T] {
 
         let v_len = end - begin;
         if v_len == 0 { return ~[]; }
-        if v_len == 1 { return ~[v[begin]]; }
+        if v_len == 1 { return ~[copy v[begin]]; }
 
         let mid = v_len / 2 + begin;
         let a = (begin, mid);
@@ -53,9 +53,9 @@ pub fn merge_sort<T:Copy>(v: &[T], le: Le<T>) -> ~[T] {
         let mut b_ix = 0;
         while a_ix < a_len && b_ix < b_len {
             if le(&a[a_ix], &b[b_ix]) {
-                rs.push(a[a_ix]);
+                rs.push(copy a[a_ix]);
                 a_ix += 1;
-            } else { rs.push(b[b_ix]); b_ix += 1; }
+            } else { rs.push(copy b[b_ix]); b_ix += 1; }
         }
         rs.push_all(vec::slice(a, a_ix, a_len));
         rs.push_all(vec::slice(b, b_ix, b_len));
@@ -106,7 +106,7 @@ pub fn quick_sort<T>(arr: &mut [T], compare_func: Le<T>) {
 
 fn qsort3<T:Copy + Ord + Eq>(arr: &mut [T], left: int, right: int) {
     if right <= left { return; }
-    let v: T = arr[right];
+    let v: T = copy arr[right];
     let mut i: int = left - 1;
     let mut j: int = right;
     let mut p: int = i;
@@ -233,7 +233,7 @@ fn binarysort<T:Copy + Ord>(array: &mut [T], start: uint) {
     if start == 0 { start += 1; }
 
     while start < size {
-        let pivot = array[start];
+        let pivot = copy array[start];
         let mut left = 0;
         let mut right = start;
         assert!(left <= right);
@@ -470,7 +470,7 @@ impl<T:Copy + Ord> MergeState<T> {
 
         let mut tmp = ~[];
         for uint::range(base1, base1+len1) |i| {
-            tmp.push(array[i]);
+            tmp.push(copy array[i]);
         }
 
         let mut c1 = 0;
@@ -580,7 +580,7 @@ impl<T:Copy + Ord> MergeState<T> {
 
         let mut tmp = ~[];
         for uint::range(base2, base2+len2) |i| {
-            tmp.push(array[i]);
+            tmp.push(copy array[i]);
         }
 
         let mut c1 = base1 + len1 - 1;
@@ -725,18 +725,18 @@ impl<T:Copy + Ord> MergeState<T> {
     }
 }
 
-#[inline(always)]
+#[inline]
 fn copy_vec<T:Copy>(dest: &mut [T],
                     s1: uint,
                     from: &[T]) {
     assert!(s1+from.len() <= dest.len());
 
     for from.eachi |i, v| {
-        dest[s1+i] = *v;
+        dest[s1+i] = copy *v;
     }
 }
 
-#[inline(always)]
+#[inline]
 fn shift_vec<T:Copy>(dest: &mut [T],
                      s1: uint,
                      s2: uint,
@@ -751,7 +751,6 @@ fn shift_vec<T:Copy>(dest: &mut [T],
 mod test_qsort3 {
     use sort::*;
 
-    use core::vec;
 
     fn check_sort(v1: &mut [int], v2: &mut [int]) {
         let len = v1.len();
@@ -861,8 +860,6 @@ mod tests {
 
     use sort::*;
 
-    use core::vec;
-
     fn check_sort(v1: &[int], v2: &[int]) {
         let len = v1.len();
         pub fn le(a: &int, b: &int) -> bool { *a <= *b }
@@ -1048,7 +1045,7 @@ mod big_tests {
     fn multiplyVec<T:Copy>(arr: &[T], num: uint) -> ~[T] {
         let size = arr.len();
         let res = do vec::from_fn(num) |i| {
-            arr[i % size]
+            copy arr[i % size]
         };
         res
     }
diff --git a/src/libextra/stats.rs b/src/libextra/stats.rs
index 4af47fa806f..3a1de5de01d 100644
--- a/src/libextra/stats.rs
+++ b/src/libextra/stats.rs
@@ -12,7 +12,6 @@
 
 use core::prelude::*;
 
-use core::vec;
 use core::f64;
 use core::cmp;
 use core::num;
diff --git a/src/libextra/std.rc b/src/libextra/std.rc
index 83c0bb516b4..d4c85ef5136 100644
--- a/src/libextra/std.rc
+++ b/src/libextra/std.rc
@@ -10,34 +10,32 @@
 
 /*!
 
-The Rust standard library.
+Rust extras.
 
-The Rust standand library provides a number of useful features that are
-not required in or otherwise suitable for the core library.
+The `extra` crate is a set of useful modules for a variety of
+purposes, including collections, numerics, I/O, serialization,
+and concurrency.
+
+Rust extras are part of the standard Rust distribution.
 
 */
 
 #[link(name = "extra",
        vers = "0.7-pre",
        uuid = "122bed0b-c19b-4b82-b0b7-7ae8aead7297",
-       url = "https://github.com/mozilla/rust/tree/master/src/libstd")];
+       url = "https://github.com/mozilla/rust/tree/master/src/libextra")];
 
-#[comment = "The Rust standard library"];
+#[comment = "Rust extras"];
 #[license = "MIT/ASL2"];
 #[crate_type = "lib"];
 
 #[deny(non_camel_case_types)];
 #[deny(missing_doc)];
 
-// NOTE: remove these two attributes after the next snapshot
-#[no_core]; // for stage0
-#[allow(unrecognized_lint)]; // otherwise stage0 is seriously ugly
-
 #[no_std];
 
 extern mod core(name = "std", vers = "0.7-pre");
 
-use core::{str, unstable};
 use core::str::{StrSlice, OwnedStr};
 
 pub use core::os;
@@ -127,7 +125,7 @@ pub mod test;
 pub mod serialize;
 
 // A curious inner-module that's not exported that contains the binding
-// 'extra' so that macro-expanded references to std::serialize and such
+// 'extra' so that macro-expanded references to extra::serialize and such
 // can be resolved within libextra.
 #[doc(hidden)]
 pub mod std {
diff --git a/src/libextra/sync.rs b/src/libextra/sync.rs
index 5930bf50ff7..f5d0b6946d3 100644
--- a/src/libextra/sync.rs
+++ b/src/libextra/sync.rs
@@ -363,7 +363,7 @@ impl<'self> Condvar<'self> {
 
 // Checks whether a condvar ID was out of bounds, and fails if so, or does
 // something else next on success.
-#[inline(always)]
+#[inline]
 #[doc(hidden)]
 fn check_cvar_bounds<U>(out_of_bounds: Option<uint>, id: uint, act: &str,
                         blk: &fn() -> U) -> U {
diff --git a/src/libextra/tempfile.rs b/src/libextra/tempfile.rs
index c239e65e2d9..39dcee5eff3 100644
--- a/src/libextra/tempfile.rs
+++ b/src/libextra/tempfile.rs
@@ -36,7 +36,6 @@ mod tests {
     use tempfile::mkdtemp;
 
     use core::os;
-    use core::str;
 
     #[test]
     fn test_mkdtemp() {
diff --git a/src/libextra/terminfo/parm.rs b/src/libextra/terminfo/parm.rs
index c395b57219c..11f0fc23be5 100644
--- a/src/libextra/terminfo/parm.rs
+++ b/src/libextra/terminfo/parm.rs
@@ -224,9 +224,9 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
                         }
                     } else { return Err(~"stack is empty") },
                     'i' => match (copy mparams[0], copy mparams[1]) {
-                        (Number(ref mut x), Number(ref mut y)) => {
-                            *x += 1;
-                            *y += 1;
+                        (Number(x), Number(y)) => {
+                            mparams[0] = Number(x+1);
+                            mparams[1] = Number(y+1);
                         },
                         (_, _) => return Err(~"first two params not numbers with %i")
                     },
@@ -352,6 +352,7 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
 #[cfg(test)]
 mod test {
     use super::*;
+    use core::result::Ok;
 
     #[test]
     fn test_basic_setabf() {
@@ -367,6 +368,16 @@ mod test {
     }
 
     #[test]
+    fn test_op_i() {
+        let mut vars = Variables::new();
+        assert_eq!(expand(bytes!("%p1%d%p2%d%p3%d%i%p1%d%p2%d%p3%d"),
+                          [Number(1),Number(2),Number(3)], &mut vars),
+                   Ok(bytes!("123233").to_owned()));
+        assert_eq!(expand(bytes!("%p1%d%p2%d%i%p1%d%p2%d"), [], &mut vars),
+                   Ok(bytes!("0011").to_owned()));
+    }
+
+    #[test]
     fn test_param_stack_failure_conditions() {
         let mut varstruct = Variables::new();
         let vars = &mut varstruct;
diff --git a/src/libextra/terminfo/parser/compiled.rs b/src/libextra/terminfo/parser/compiled.rs
index 81b6083db01..66649c62fca 100644
--- a/src/libextra/terminfo/parser/compiled.rs
+++ b/src/libextra/terminfo/parser/compiled.rs
@@ -313,7 +313,6 @@ pub fn parse(file: @Reader, longnames: bool) -> Result<~TermInfo, ~str> {
 #[cfg(test)]
 mod test {
     use super::*;
-    use p = core::path::Path;
 
     #[test]
     fn test_veclens() {
diff --git a/src/libextra/test.rs b/src/libextra/test.rs
index 406dfb086ea..64c6a822a86 100644
--- a/src/libextra/test.rs
+++ b/src/libextra/test.rs
@@ -26,20 +26,11 @@ use core::either;
 use core::io;
 use core::option;
 use core::result;
-use core::str;
 use core::task;
 use core::to_str::ToStr;
 use core::uint;
 use core::vec;
 
-pub mod rustrt {
-    use core::libc::size_t;
-
-    #[abi = "cdecl"]
-    pub extern {
-        pub unsafe fn rust_sched_threads() -> size_t;
-    }
-}
 
 // The name of a test. By convention this follows the rules for rust
 // paths; i.e. it should be a series of identifiers separated by double
@@ -365,7 +356,7 @@ pub fn run_tests_console(opts: &TestOpts,
 fn print_failures(st: &ConsoleTestState) {
     st.out.write_line("\nfailures:");
     let mut failures = ~[];
-    for uint::range(0, vec::uniq_len(&const st.failures)) |i| {
+    for uint::range(0, st.failures.len()) |i| {
         let name = copy st.failures[i].name;
         failures.push(name.to_str());
     }
@@ -489,11 +480,10 @@ static sched_overcommit : uint = 1;
 static sched_overcommit : uint = 4u;
 
 fn get_concurrency() -> uint {
-    unsafe {
-        let threads = rustrt::rust_sched_threads() as uint;
-        if threads == 1 { 1 }
-        else { threads * sched_overcommit }
-    }
+    use core::rt;
+    let threads = rt::util::default_sched_threads();
+    if threads == 1 { 1 }
+    else { threads * sched_overcommit }
 }
 
 #[allow(non_implicitly_copyable_typarams)]
@@ -542,7 +532,7 @@ pub fn filter_tests(
 
     // Sort the tests alphabetically
     fn lteq(t1: &TestDescAndFn, t2: &TestDescAndFn) -> bool {
-        str::le(t1.desc.name.to_str(), t2.desc.name.to_str())
+        t1.desc.name.to_str() < t2.desc.name.to_str()
     }
     sort::quick_sort(filtered, lteq);
 
diff --git a/src/libextra/time.rs b/src/libextra/time.rs
index 50592d5f730..005238a564e 100644
--- a/src/libextra/time.rs
+++ b/src/libextra/time.rs
@@ -275,7 +275,7 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
         let mut i = 0u;
         let len = strs.len();
         while i < len {
-            match strs[i] { // can't use let due to stage0 bugs
+            match strs[i] { // can't use let due to let-pattern bugs
                 (ref needle, value) => {
                     if match_str(ss, pos, *needle) {
                         return Some((value, pos + needle.len()));
diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs
index f98758f64af..f857581c17d 100644
--- a/src/libextra/treemap.rs
+++ b/src/libextra/treemap.rs
@@ -75,13 +75,13 @@ fn lt<K: Ord + TotalOrd, V>(a: &TreeMap<K, V>,
 }
 
 impl<K: Ord + TotalOrd, V> Ord for TreeMap<K, V> {
-    #[inline(always)]
+    #[inline]
     fn lt(&self, other: &TreeMap<K, V>) -> bool { lt(self, other) }
-    #[inline(always)]
+    #[inline]
     fn le(&self, other: &TreeMap<K, V>) -> bool { !lt(other, self) }
-    #[inline(always)]
+    #[inline]
     fn ge(&self, other: &TreeMap<K, V>) -> bool { !lt(self, other) }
-    #[inline(always)]
+    #[inline]
     fn gt(&self, other: &TreeMap<K, V>) -> bool { lt(other, self) }
 }
 
@@ -145,7 +145,7 @@ impl<K: TotalOrd, V> Map<K, V> for TreeMap<K, V> {
     }
 
     /// Return a mutable reference to the value corresponding to the key
-    #[inline(always)]
+    #[inline]
     fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V> {
         find_mut(&mut self.root, key)
     }
@@ -236,7 +236,7 @@ impl<'self, K, V> Iterator<(&'self K, &'self V)> for TreeMapIterator<'self, K, V
 
 impl<'self, T> Iterator<&'self T> for TreeSetIterator<'self, T> {
     /// Advance the iterator to the next node (in order). If there are no more nodes, return `None`.
-    #[inline(always)]
+    #[inline]
     fn next(&mut self) -> Option<&'self T> {
         do self.iter.next().map |&(value, _)| { value }
     }
@@ -251,69 +251,69 @@ pub struct TreeSet<T> {
 
 impl<T: TotalOrd> BaseIter<T> for TreeSet<T> {
     /// Visit all values in order
-    #[inline(always)]
+    #[inline]
     fn each(&self, f: &fn(&T) -> bool) -> bool { self.map.each_key(f) }
-    #[inline(always)]
+    #[inline]
     fn size_hint(&self) -> Option<uint> { Some(self.len()) }
 }
 
 impl<T: TotalOrd> ReverseIter<T> for TreeSet<T> {
     /// Visit all values in reverse order
-    #[inline(always)]
+    #[inline]
     fn each_reverse(&self, f: &fn(&T) -> bool) -> bool {
         self.map.each_key_reverse(f)
     }
 }
 
 impl<T: Eq + TotalOrd> Eq for TreeSet<T> {
-    #[inline(always)]
+    #[inline]
     fn eq(&self, other: &TreeSet<T>) -> bool { self.map == other.map }
-    #[inline(always)]
+    #[inline]
     fn ne(&self, other: &TreeSet<T>) -> bool { self.map != other.map }
 }
 
 impl<T: Ord + TotalOrd> Ord for TreeSet<T> {
-    #[inline(always)]
+    #[inline]
     fn lt(&self, other: &TreeSet<T>) -> bool { self.map < other.map }
-    #[inline(always)]
+    #[inline]
     fn le(&self, other: &TreeSet<T>) -> bool { self.map <= other.map }
-    #[inline(always)]
+    #[inline]
     fn ge(&self, other: &TreeSet<T>) -> bool { self.map >= other.map }
-    #[inline(always)]
+    #[inline]
     fn gt(&self, other: &TreeSet<T>) -> bool { self.map > other.map }
 }
 
 impl<T: TotalOrd> Container for TreeSet<T> {
     /// Return the number of elements in the set
-    #[inline(always)]
+    #[inline]
     fn len(&const self) -> uint { self.map.len() }
 
     /// Return true if the set contains no elements
-    #[inline(always)]
+    #[inline]
     fn is_empty(&const self) -> bool { self.map.is_empty() }
 }
 
 impl<T: TotalOrd> Mutable for TreeSet<T> {
     /// Clear the set, removing all values.
-    #[inline(always)]
+    #[inline]
     fn clear(&mut self) { self.map.clear() }
 }
 
 impl<T: TotalOrd> Set<T> for TreeSet<T> {
     /// Return true if the set contains a value
-    #[inline(always)]
+    #[inline]
     fn contains(&self, value: &T) -> bool {
         self.map.contains_key(value)
     }
 
     /// Add a value to the set. Return true if the value was not already
     /// present in the set.
-    #[inline(always)]
+    #[inline]
     fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) }
 
     /// Remove a value from the set. Return true if the value was
     /// present in the set.
-    #[inline(always)]
+    #[inline]
     fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
 
     /// Return true if the set has no elements in common with `other`.
@@ -336,7 +336,7 @@ impl<T: TotalOrd> Set<T> for TreeSet<T> {
     }
 
     /// Return true if the set is a subset of another
-    #[inline(always)]
+    #[inline]
     fn is_subset(&self, other: &TreeSet<T>) -> bool {
         other.is_superset(self)
     }
@@ -490,12 +490,12 @@ impl<T: TotalOrd> Set<T> for TreeSet<T> {
 
 impl<T: TotalOrd> TreeSet<T> {
     /// Create an empty TreeSet
-    #[inline(always)]
+    #[inline]
     pub fn new() -> TreeSet<T> { TreeSet{map: TreeMap::new()} }
 
     /// Get a lazy iterator over the values in the set.
     /// Requires that it be frozen (immutable).
-    #[inline(always)]
+    #[inline]
     pub fn iter<'a>(&'a self) -> TreeSetIterator<'a, T> {
         TreeSetIterator{iter: self.map.iter()}
     }
@@ -518,7 +518,7 @@ struct TreeNode<K, V> {
 
 impl<K: TotalOrd, V> TreeNode<K, V> {
     /// Creates a new tree node.
-    #[inline(always)]
+    #[inline]
     pub fn new(key: K, value: V) -> TreeNode<K, V> {
         TreeNode{key: key, value: value, left: None, right: None, level: 1}
     }
@@ -710,7 +710,6 @@ mod test_treemap {
 
     use core::rand::RngUtil;
     use core::rand;
-    use core::str;
     use core::vec;
 
     #[test]
diff --git a/src/libextra/workcache.rs b/src/libextra/workcache.rs
index b2fd998b73f..12a26606f36 100644
--- a/src/libextra/workcache.rs
+++ b/src/libextra/workcache.rs
@@ -104,7 +104,7 @@ struct WorkKey {
 }
 
 impl to_bytes::IterBytes for WorkKey {
-    #[inline(always)]
+    #[inline]
     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool {
         self.kind.iter_bytes(lsb0, f) && self.name.iter_bytes(lsb0, f)
     }
diff --git a/src/libfuzzer/ast_match.rs b/src/libfuzzer/ast_match.rs
deleted file mode 100644
index 7d623919ff9..00000000000
--- a/src/libfuzzer/ast_match.rs
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::prelude::*;
-
-use vec;
-
-fn vec_equal<T>(v: ~[T],
-                u: ~[T],
-                element_equality_test: @fn(&&T, &&T) -> bool) ->
-   bool {
-    let Lv = v.len();
-    if Lv != u.len() { return false; }
-    let i = 0u;
-    while i < Lv {
-        if !element_equality_test(v[i], u[i]) { return false; }
-        i += 1u;
-    }
-    return true;
-}
-
-fn builtin_equal<T>(&&a: T, &&b: T) -> bool { return a == b; }
-fn builtin_equal_int(&&a: int, &&b: int) -> bool { return a == b; }
-
-fn main() {
-    assert!((builtin_equal(5, 5)));
-    assert!((!builtin_equal(5, 4)));
-    assert!((!vec_equal(~[5, 5], ~[5], bind builtin_equal(_, _))));
-    assert!((!vec_equal(~[5, 5], ~[5], builtin_equal_int)));
-    assert!((!vec_equal(~[5, 5], ~[5, 4], builtin_equal_int)));
-    assert!((!vec_equal(~[5, 5], ~[4, 5], builtin_equal_int)));
-    assert!((vec_equal(~[5, 5], ~[5, 5], builtin_equal_int)));
-
-    error!("Pass");
-}
diff --git a/src/libfuzzer/cycles.rs b/src/libfuzzer/cycles.rs
deleted file mode 100644
index 2256325fa43..00000000000
--- a/src/libfuzzer/cycles.rs
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use core::prelude::*;
-
-use extra;
-use extra::rand;
-use uint::range;
-
-// random uint less than n
-fn under(r : rand::rng, n : uint) -> uint {
-    assert!(n != 0u); r.next() as uint % n
-}
-
-// random choice from a vec
-fn choice<T:copy>(r : rand::rng, v : ~[const T]) -> T {
-    assert!(v.len() != 0u); v[under(r, v.len())]
-}
-
-// k in n chance of being true
-fn likelihood(r : rand::rng, k : uint, n : uint) -> bool { under(r, n) < k }
-
-
-static iters : uint = 1000u;
-static vlen  : uint = 100u;
-
-enum maybe_pointy {
-    none,
-    p(@pointy)
-}
-
-type pointy = {
-    mut a : maybe_pointy,
-    mut b : ~maybe_pointy,
-    mut c : @maybe_pointy,
-
-    mut f : @fn()->(),
-    mut g : ~fn()->(),
-
-    mut m : ~[maybe_pointy],
-    mut n : ~[maybe_pointy],
-    mut o : {x : int, y : maybe_pointy}
-};
-// To add: objects; traits; anything type-parameterized?
-
-fn empty_pointy() -> @pointy {
-    return @{
-        mut a : none,
-        mut b : ~none,
-        mut c : @none,
-
-        mut f : || {},
-        mut g : || {},
-
-        mut m : ~[],
-        mut n : ~[],
-        mut o : {x : 0, y : none}
-    }
-}
-
-fn nopP(_x : @pointy) { }
-fn nop<T>(_x: T) { }
-
-fn test_cycles(r : rand::rng, k: uint, n: uint)
-{
-    let mut v : ~[@pointy] = ~[];
-
-    // Create a graph with no edges
-    range(0u, vlen) {|_i|
-        v.push(empty_pointy());
-    }
-
-    // Fill in the graph with random edges, with density k/n
-    range(0u, vlen) {|i|
-        if (likelihood(r, k, n)) { v[i].a = p(choice(r, v)); }
-        if (likelihood(r, k, n)) { v[i].b = ~p(choice(r, v)); }
-        if (likelihood(r, k, n)) { v[i].c = @p(choice(r, v)); }
-
-        if (likelihood(r, k, n)) { v[i].f = bind nopP(choice(r, v)); }
-        //if (false)               { v[i].g = bind (|_: @pointy| { })(
-        // choice(r, v)); }
-          // https://github.com/mozilla/rust/issues/1899
-
-        if (likelihood(r, k, n)) { v[i].m = [p(choice(r, v))]; }
-        if (likelihood(r, k, n)) { v[i].n.push(mut p(choice(r, v))); }
-        if (likelihood(r, k, n)) { v[i].o = {x: 0, y: p(choice(r, v))}; }
-    }
-
-    // Drop refs one at a time
-    range(0u, vlen) {|i|
-        v[i] = empty_pointy()
-    }
-}
-
-fn main()
-{
-    let r = rand::rng();
-    range(0u, iters) {|i|
-        test_cycles(r, i, iters);
-    }
-}
diff --git a/src/libfuzzer/fuzzer.rc b/src/libfuzzer/fuzzer.rc
deleted file mode 100644
index 4e2103fcd70..00000000000
--- a/src/libfuzzer/fuzzer.rc
+++ /dev/null
@@ -1,713 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-
-#[link(name = "fuzzer",
-       vers = "0.7-pre",
-       uuid = "d6418797-2736-4833-bd82-d3c684b7c1b0",
-       url = "https://github.com/mozilla/rust/tree/master/src/libfuzzer")];
-
-#[comment = "The Rust fuzzer library"];
-#[license = "MIT/ASL2"];
-#[crate_type = "lib"];
-
-#[allow(non_camel_case_types)];
-
-#[no_std];
-
-extern mod std(name = "std", vers = "0.7-pre");
-extern mod extra(name = "extra", vers = "0.7-pre");
-
-extern mod syntax(vers = "0.7-pre");
-
-use std::prelude::*;
-
-use std::int;
-use std::io;
-use std::option;
-use std::os;
-use std::result;
-use std::run;
-use std::str;
-use std::uint;
-
-use syntax::diagnostic;
-use syntax::parse::token::ident_interner;
-use syntax::parse::token;
-use syntax::parse;
-use syntax::print::pprust;
-use syntax::{ast, fold, visit, codemap};
-
-#[deriving(Eq)]
-pub enum test_mode { tm_converge, tm_run, }
-
-pub struct Context { mode: test_mode } // + rng
-
-pub fn write_file(filename: &Path, content: &str) {
-    result::get(&io::file_writer(filename, [io::Create, io::Truncate]))
-                    .write_str(content);
-}
-
-pub fn contains(haystack: &str, needle: &str) -> bool {
-    haystack.contains(needle)
-}
-
-pub fn find_rust_files(files: &mut ~[Path], path: &Path) {
-    if path.filetype() == Some(~".rs") && !contains(path.to_str(), "utf8") {
-        // ignoring "utf8" tests because something is broken
-        files.push(path.clone());
-    } else if os::path_is_dir(path)
-        && !contains(path.to_str(), "compile-fail")
-        && !contains(path.to_str(), "build") {
-        for os::list_dir_path(path).each |p| {
-            find_rust_files(&mut *files, *p);
-        }
-    }
-}
-
-
-pub fn common_exprs() -> ~[@ast::expr] {
-    fn dse(e: ast::expr_) -> @ast::expr {
-        @ast::expr {
-            id: 0,
-            node: e,
-            span: codemap::dummy_sp(),
-        }
-    }
-
-    fn dsl(l: ast::lit_) -> ast::lit {
-        codemap::spanned { node: l, span: codemap::dummy_sp() }
-    }
-
-    ~[dse(ast::expr_break(option::None)),
-     dse(ast::expr_again(option::None)),
-     dse(ast::expr_ret(option::None)),
-     dse(ast::expr_lit(@dsl(ast::lit_nil))),
-     dse(ast::expr_lit(@dsl(ast::lit_bool(false)))),
-     dse(ast::expr_lit(@dsl(ast::lit_bool(true)))),
-     dse(ast::expr_unary(-1, ast::box(ast::m_imm),
-                         dse(ast::expr_lit(@dsl(ast::lit_bool(true)))))),
-     dse(ast::expr_unary(-1, ast::uniq(ast::m_imm),
-                         dse(ast::expr_lit(@dsl(ast::lit_bool(true))))))
-    ]
-}
-
-pub fn safe_to_steal_expr(e: @ast::expr, tm: test_mode) -> bool {
-    safe_to_use_expr(e, tm)
-}
-
-pub fn safe_to_use_expr(e: @ast::expr, tm: test_mode) -> bool {
-    match tm {
-      tm_converge => {
-        match e.node {
-          // If the fuzzer moves a block-ending-in-semicolon into callee
-          // position, the pretty-printer can't preserve this even by
-          // parenthesizing!!  See email to marijn.
-          ast::expr_if(*) | ast::expr_block(*)
-          | ast::expr_match(*) | ast::expr_while(*)  => { false }
-
-          // https://github.com/mozilla/rust/issues/929
-          ast::expr_cast(*) | ast::expr_binary(*) | ast::expr_assign(*) |
-          ast::expr_assign_op(*) => { false }
-
-          ast::expr_ret(option::None) => { false }
-
-          // https://github.com/mozilla/rust/issues/953
-          //ast::expr_fail(option::Some(_)) => { false }
-
-          // https://github.com/mozilla/rust/issues/928
-          //ast::expr_cast(_, _) { false }
-
-          // https://github.com/mozilla/rust/issues/1458
-          ast::expr_call(*) => { false }
-
-          _ => { true }
-        }
-      }
-      tm_run => { true }
-    }
-}
-
-pub fn safe_to_steal_ty(t: @ast::Ty, tm: test_mode) -> bool {
-    // Restrictions happen to be the same.
-    safe_to_replace_ty(&t.node, tm)
-}
-
-// Not type-parameterized: https://github.com/mozilla/rust/issues/898 (FIXED)
-pub fn stash_expr_if(c: @fn(@ast::expr, test_mode)->bool,
-                     es: @mut ~[@ast::expr],
-                     e: @ast::expr,
-                     tm: test_mode) {
-    if c(e, tm) {
-        *es = *es + [e];
-    } else {
-        /* now my indices are wrong :( */
-    }
-}
-
-pub fn stash_ty_if(c: @fn(@ast::Ty, test_mode) -> bool,
-                   es: @mut ~[@ast::Ty],
-                   e: @ast::Ty,
-                   tm: test_mode) {
-    if c(e, tm) {
-        es.push(e);
-    } else {
-        /* now my indices are wrong :( */
-    }
-}
-
-pub struct StolenStuff {
-    exprs: ~[@ast::expr],
-    tys: ~[@ast::Ty]
-}
-
-pub fn steal(crate: @ast::crate, tm: test_mode) -> StolenStuff {
-    let exprs = @mut ~[];
-    let tys = @mut ~[];
-    let v = visit::mk_simple_visitor(@visit::SimpleVisitor {
-        visit_expr: |a| stash_expr_if(safe_to_steal_expr, exprs, a, tm),
-        visit_ty: |a| stash_ty_if(safe_to_steal_ty, tys, a, tm),
-        .. *visit::default_simple_visitor()
-    });
-    visit::visit_crate(crate, ((), v));
-    StolenStuff {
-        exprs: (*exprs).clone(),
-        tys: (*tys).clone(),
-    }
-}
-
-
-pub fn safe_to_replace_expr(e: &ast::expr_, _tm: test_mode) -> bool {
-    match *e {
-        // https://github.com/mozilla/rust/issues/652
-        ast::expr_if(*) => false,
-        ast::expr_block(_) => false,
-
-        // expr_call is also missing a constraint
-        ast::expr_fn_block(*) => false,
-
-        _ => true,
-    }
-}
-
-pub fn safe_to_replace_ty(t: &ast::ty_, _tm: test_mode) -> bool {
-    match *t {
-      ast::ty_infer => { false } // always implicit, always top level
-      ast::ty_bot => { false }   // in source, can only appear
-                              // as the out type of a function
-      ast::ty_mac(_) => { false }
-      _ => { true }
-    }
-}
-
-// Replace the |i|th expr (in fold order) of |crate| with |newexpr|.
-pub fn replace_expr_in_crate(crate: @ast::crate,
-                             i: uint,
-                             newexpr: @ast::expr,
-                             tm: test_mode)
-                             -> @ast::crate {
-    let j: @mut uint = @mut 0u;
-    fn fold_expr_rep(j_: @mut uint,
-                     i_: uint,
-                     newexpr_: &ast::expr_,
-                     original: &ast::expr_,
-                     fld: @fold::ast_fold,
-                     tm_: test_mode)
-                     -> ast::expr_ {
-        *j_ += 1;
-        if i_ + 1 == *j_ && safe_to_replace_expr(original, tm_) {
-            copy *newexpr_
-        } else {
-            fold::noop_fold_expr(original, fld)
-        }
-    }
-    let afp = @fold::AstFoldFns {
-        fold_expr: fold::wrap(|a,b| {
-            fold_expr_rep(j, i, &newexpr.node, a, b, tm)
-        }),
-        .. *fold::default_ast_fold()
-    };
-    let af = fold::make_fold(afp);
-    let crate2: @ast::crate = @af.fold_crate(crate);
-    crate2
-}
-
-
-// Replace the |i|th ty (in fold order) of |crate| with |newty|.
-pub fn replace_ty_in_crate(crate: @ast::crate,
-                           i: uint,
-                           newty: @ast::Ty,
-                           tm: test_mode)
-                           -> @ast::crate {
-    let j: @mut uint = @mut 0u;
-    fn fold_ty_rep(j_: @mut uint,
-                   i_: uint,
-                   newty_: &ast::ty_,
-                   original: &ast::ty_,
-                   fld: @fold::ast_fold,
-                   tm_: test_mode)
-                   -> ast::ty_ {
-        *j_ += 1;
-        if i_ + 1 == *j_ && safe_to_replace_ty(original, tm_) {
-            copy *newty_
-        } else {
-            fold::noop_fold_ty(original, fld)
-        }
-    }
-    let afp = @fold::AstFoldFns {
-        fold_ty: fold::wrap(|a,b| fold_ty_rep(j, i, &newty.node, a, b, tm)),
-        .. *fold::default_ast_fold()
-    };
-    let af = fold::make_fold(afp);
-    let crate2: @ast::crate = @af.fold_crate(crate);
-    crate2
-}
-
-pub fn under(n: uint, it: &fn(uint)) {
-    let mut i: uint = 0u;
-    while i < n { it(i); i += 1u; }
-}
-
-pub fn as_str(f: @fn(x: @io::Writer)) -> ~str {
-    io::with_str_writer(f)
-}
-
-pub fn check_variants_of_ast(crate: @ast::crate,
-                             codemap: @codemap::CodeMap,
-                             filename: &Path,
-                             cx: Context) {
-    let stolen = steal(crate, cx.mode);
-    let extra_exprs = do common_exprs().filtered |&a| {
-        safe_to_use_expr(a, cx.mode)
-    };
-    check_variants_T(crate,
-                     codemap,
-                     filename,
-                     ~"expr",
-                     extra_exprs + stolen.exprs,
-                     pprust::expr_to_str,
-                     replace_expr_in_crate,
-                     cx);
-    check_variants_T(crate,
-                     codemap,
-                     filename,
-                     ~"ty",
-                     stolen.tys,
-                     pprust::ty_to_str,
-                     replace_ty_in_crate,
-                     cx);
-}
-
-pub fn check_variants_T<T:Copy>(crate: @ast::crate,
-                                codemap: @codemap::CodeMap,
-                                filename: &Path,
-                                thing_label: ~str,
-                                things: &[T],
-                                stringifier: @fn(T, @ident_interner) -> ~str,
-                                replacer: @fn(@ast::crate,
-                                              uint,
-                                              T,
-                                              test_mode)
-                                              -> @ast::crate,
-                                cx: Context) {
-    error!("%s contains %u %s objects", filename.to_str(),
-           things.len(), thing_label);
-
-    // Assuming we're not generating any token_trees
-    let intr = syntax::parse::token::mk_fake_ident_interner();
-
-    let L = things.len();
-
-    if L < 100 {
-        do under(uint::min(L, 20)) |i| {
-            error!("Replacing... #%?", uint::to_str(i));
-            let fname = str::to_owned(filename.to_str());
-            do under(uint::min(L, 30)) |j| {
-                let fname = fname.to_str();
-                error!("With... %?", stringifier(things[j], intr));
-                let crate2 = replacer(crate, i, things[j], cx.mode);
-                // It would be best to test the *crate* for stability, but
-                // testing the string for stability is easier and ok for now.
-                let handler = diagnostic::mk_handler(None);
-                let str3 = do io::with_str_reader("") |rdr| {
-                    let fname = fname.to_str();
-                    let string = do as_str |a| {
-                        let span_handler =
-                            diagnostic::mk_span_handler(handler, codemap);
-                        pprust::print_crate(codemap,
-                                            intr,
-                                            span_handler,
-                                            crate2,
-                                            fname.to_managed(),
-                                            rdr,
-                                            a,
-                                            pprust::no_ann(),
-                                            false)
-                    };
-                    string.to_managed()
-                };
-                match cx.mode {
-                    tm_converge => check_roundtrip_convergence(str3, 1),
-                    tm_run => {
-                        let file_label = fmt!("rusttmp/%s_%s_%u_%u",
-                                              last_part(filename.to_str()),
-                                              thing_label,
-                                              i,
-                                              j);
-                        let safe_to_run = !(content_is_dangerous_to_run(str3)
-                                            || has_raw_pointers(crate2));
-                        check_whole_compiler(str3,
-                                             &Path(file_label),
-                                             safe_to_run);
-                    }
-                }
-            }
-        }
-    }
-}
-
-pub fn last_part(filename: ~str) -> ~str {
-    let ix = filename.rfind('/').get();
-    filename.slice(ix + 1u, filename.len() - 3u).to_owned()
-}
-
-pub enum happiness {
-    passed,
-    cleanly_rejected(~str),
-    known_bug(~str),
-    failed(~str),
-}
-
-// We'd find more bugs if we could take an AST here, but
-// - that would find many "false positives" or unimportant bugs
-// - that would be tricky, requiring use of tasks or serialization
-//   or randomness.
-// This seems to find plenty of bugs as it is :)
-pub fn check_whole_compiler(code: &str,
-                            suggested_filename_prefix: &Path,
-                            allow_running: bool) {
-    let filename = &suggested_filename_prefix.with_filetype("rs");
-    write_file(filename, code);
-
-    let compile_result = check_compiling(filename);
-
-    let run_result = match (compile_result, allow_running) {
-      (passed, true) => { check_running(suggested_filename_prefix) }
-      (h, _) => { h }
-    };
-
-    match run_result {
-      passed | cleanly_rejected(_) | known_bug(_) => {
-        removeIfExists(suggested_filename_prefix);
-        removeIfExists(&suggested_filename_prefix.with_filetype("rs"));
-        removeDirIfExists(&suggested_filename_prefix.with_filetype("dSYM"));
-      }
-      failed(s) => {
-        error!("check_whole_compiler failure: %?", s);
-        error!("Saved as: %?", filename.to_str());
-      }
-    }
-}
-
-pub fn removeIfExists(filename: &Path) {
-    // So sketchy!
-    assert!(!contains(filename.to_str(), " "));
-    run::process_status("bash", [~"-c", ~"rm " + filename.to_str()]);
-}
-
-pub fn removeDirIfExists(filename: &Path) {
-    // So sketchy!
-    assert!(!contains(filename.to_str(), " "));
-    run::process_status("bash", [~"-c", ~"rm -r " + filename.to_str()]);
-}
-
-pub fn check_running(exe_filename: &Path) -> happiness {
-    let p = run::process_output(
-        "/Users/jruderman/scripts/timed_run_rust_program.py",
-        [exe_filename.to_str()]);
-    let comb = str::from_bytes(p.output) + "\n" + str::from_bytes(p.error);
-    if comb.len() > 1u {
-        error!("comb comb comb: %?", comb);
-    }
-
-    if contains(comb, "Assertion failed:") {
-        failed(~"C++ assertion failure")
-    } else if contains(comb, "leaked memory in rust main loop") {
-        // might also use exit code 134
-        //failed("Leaked")
-        known_bug(~"https://github.com/mozilla/rust/issues/910")
-    } else if contains(comb, "src/rt/") {
-        failed(~"Mentioned src/rt/")
-    } else if contains(comb, "malloc") {
-        failed(~"Mentioned malloc")
-    } else {
-        match p.status {
-            0         => { passed }
-            100       => { cleanly_rejected(~"running: explicit fail") }
-            101 | 247 => { cleanly_rejected(~"running: timed out") }
-            245 | 246 | 138 | 252 => {
-              known_bug(~"https://github.com/mozilla/rust/issues/1466")
-            }
-            136 | 248 => {
-              known_bug(
-                  ~"SIGFPE - https://github.com/mozilla/rust/issues/944")
-            }
-            rc => {
-              failed(~"Rust program ran but exited with status " +
-                     int::to_str(rc))
-            }
-        }
-    }
-}
-
-pub fn check_compiling(filename: &Path) -> happiness {
-    let p = run::process_output(
-        "/Users/jruderman/code/rust/build/x86_64-apple-darwin/stage1/bin/rustc",
-        [filename.to_str()]);
-
-    let out = str::from_bytes(p.output);
-    let err = str::from_bytes(p.error);
-
-    //error!("Status: %d", p.status);
-    if p.status == 0 {
-        passed
-    } else if !err.is_empty() {
-        if err.contains("error:") {
-            cleanly_rejected(~"rejected with span_error")
-        } else {
-            error!("Stderr: %?", err);
-            failed(~"Unfamiliar error message")
-        }
-    } else if out.contains("Assertion") && out.contains("failed") {
-        error!("Stdout: %?", out);
-        failed(~"Looks like an llvm assertion failure")
-    } else if out.contains("internal compiler error unimplemented") {
-        known_bug(~"Something unimplemented")
-    } else if out.contains("internal compiler error") {
-        error!("Stdout: %?", out);
-        failed(~"internal compiler error")
-
-    } else {
-        error!("%?", p.status);
-        error!("!Stdout: %?", out);
-        failed(~"What happened?")
-    }
-}
-
-
-pub fn parse_and_print(code: @str) -> @str {
-    let filename = Path("tmp.rs");
-    let sess = parse::new_parse_sess(option::None);
-    write_file(&filename, code);
-    let crate = parse::parse_crate_from_source_str(filename.to_str().to_managed(),
-                                                   code,
-                                                   ~[],
-                                                   sess);
-    do io::with_str_reader(code) |rdr| {
-        let filename = filename.to_str();
-        do as_str |a| {
-            pprust::print_crate(sess.cm,
-                                // Assuming there are no token_trees
-                                token::mk_fake_ident_interner(),
-                                copy sess.span_diagnostic,
-                                crate,
-                                filename.to_managed(),
-                                rdr,
-                                a,
-                                pprust::no_ann(),
-                                false)
-        }.to_managed()
-    }
-}
-
-pub fn has_raw_pointers(c: @ast::crate) -> bool {
-    let has_rp = @mut false;
-    fn visit_ty(flag: @mut bool, t: @ast::Ty) {
-        match t.node {
-          ast::ty_ptr(_) => { *flag = true; }
-          _ => { }
-        }
-    }
-    let v =
-        visit::mk_simple_visitor(@visit::SimpleVisitor {
-            visit_ty: |a| visit_ty(has_rp, a),
-            .. *visit::default_simple_visitor()});
-    visit::visit_crate(c, ((), v));
-    return *has_rp;
-}
-
-pub fn content_is_dangerous_to_run(code: &str) -> bool {
-    let dangerous_patterns =
-        ~[~"xfail-test",
-         ~"import",  // espeically fs, run
-         ~"extern",
-         ~"unsafe",
-         ~"log"];    // python --> rust pipe deadlock?
-
-    for dangerous_patterns.each |p| { if contains(code, *p) { return true; } }
-    return false;
-}
-
-pub fn content_is_dangerous_to_compile(code: &str) -> bool {
-    let dangerous_patterns =
-        ~[~"xfail-test"];
-
-    for dangerous_patterns.each |p| { if contains(code, *p) { return true; } }
-    return false;
-}
-
-pub fn content_might_not_converge(code: &str) -> bool {
-    let confusing_patterns =
-        ~[~"xfail-test",
-         ~"xfail-pretty",
-         ~"self",       // crazy rules enforced by parser not typechecker?
-         ~"spawn",      // precedence issues?
-         ~"bind",       // precedence issues?
-         ~" be ",       // don't want to replace its child with a non-call:
-                       // "Non-call expression in tail call"
-         ~"\n\n\n\n\n"  // https://github.com/mozilla/rust/issues/850
-        ];
-
-    for confusing_patterns.each |p| { if contains(code, *p) { return true; } }
-    return false;
-}
-
-pub fn file_might_not_converge(filename: &Path) -> bool {
-    let confusing_files = ~[
-      ~"expr-alt.rs", // pretty-printing "(a = b) = c"
-                     // vs "a = b = c" and wrapping
-      ~"block-arg-in-ternary.rs", // wrapping
-      ~"move-3-unique.rs", // 0 becomes (0), but both seem reasonable. wtf?
-      ~"move-3.rs"  // 0 becomes (0), but both seem reasonable. wtf?
-    ];
-
-
-    for confusing_files.each |f| {
-        if contains(filename.to_str(), *f) {
-            return true;
-        }
-    }
-
-    return false;
-}
-
-pub fn check_roundtrip_convergence(code: @str, maxIters: uint) {
-    let mut i = 0u;
-    let mut newv = code;
-    let mut oldv = code;
-
-    while i < maxIters {
-        oldv = newv;
-        if content_might_not_converge(oldv) { return; }
-        newv = parse_and_print(oldv);
-        if oldv == newv { break; }
-        i += 1u;
-    }
-
-    if oldv == newv {
-        error!("Converged after %u iterations", i);
-    } else {
-        error!("Did not converge after %u iterations!", i);
-        write_file(&Path("round-trip-a.rs"), oldv);
-        write_file(&Path("round-trip-b.rs"), newv);
-        run::process_status("diff", [~"-w", ~"-u", ~"round-trip-a.rs", ~"round-trip-b.rs"]);
-        fail!("Mismatch");
-    }
-}
-
-pub fn check_convergence(files: &[Path]) {
-    error!("pp convergence tests: %u files", files.len());
-    for files.each |file| {
-        if !file_might_not_converge(file) {
-            let s = result::get(&io::read_whole_file_str(file)).to_managed();
-            if !content_might_not_converge(s) {
-                error!("pp converge: %s", file.to_str());
-                // Change from 7u to 2u once
-                // https://github.com/mozilla/rust/issues/850 is fixed
-                check_roundtrip_convergence(s, 7u);
-            }
-        }
-    }
-}
-
-pub fn check_variants(files: &[Path], cx: Context) {
-    for files.each |file| {
-        if cx.mode == tm_converge &&
-            file_might_not_converge(file) {
-            error!("Skipping convergence test based on\
-                    file_might_not_converge");
-            loop;
-        }
-
-        let s = result::get(&io::read_whole_file_str(file)).to_managed();
-        if s.contains_char('#') {
-            loop; // Macros are confusing
-        }
-        if cx.mode == tm_converge && content_might_not_converge(s) {
-            loop;
-        }
-        if cx.mode == tm_run && content_is_dangerous_to_compile(s) {
-            loop;
-        }
-
-        let file_str = file.to_str();
-
-        error!("check_variants: %?", file_str);
-        let sess = parse::new_parse_sess(None);
-        let crate = parse::parse_crate_from_source_str(file_str.to_managed(),
-                                                       s,
-                                                       ~[],
-                                                       sess);
-        io::with_str_reader(s, |rdr| {
-            let file_str = file_str.to_str();
-            error!("%s",
-                   as_str(|a| {
-                    pprust::print_crate(
-                        sess.cm,
-                        // Assuming no token_trees
-                        token::mk_fake_ident_interner(),
-                        copy sess.span_diagnostic,
-                        crate,
-                        file_str.to_managed(),
-                        rdr,
-                        a,
-                        pprust::no_ann(),
-                        false)
-                    }))
-        });
-        check_variants_of_ast(crate, sess.cm, file, cx);
-    }
-}
-
-pub fn main() {
-    let args = os::args();
-    if args.len() != 2u {
-        error!("usage: %s <testdir>", args[0]);
-        return;
-    }
-    let mut files = ~[];
-    let root = Path(args[1]);
-
-    find_rust_files(&mut files, &root);
-    error!("== check_convergence ==");
-    check_convergence(files);
-    error!("== check_variants: converge ==");
-    check_variants(files, Context { mode: tm_converge });
-    error!("== check_variants: run ==");
-    check_variants(files, Context { mode: tm_run });
-
-    error!("Fuzzer done");
-}
-
-// For bootstrapping purposes...
-pub mod core {
-    pub use std::cmp;
-    pub use std::sys;
-}
diff --git a/src/libfuzzer/ivec_fuzz.rs b/src/libfuzzer/ivec_fuzz.rs
deleted file mode 100644
index 8f019a14eed..00000000000
--- a/src/libfuzzer/ivec_fuzz.rs
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*
-
-Idea: provide functions for 'exhaustive' and 'random' modification of vecs.
-
-  two functions, "return all edits" and "return a random edit" = move-
-    leaning toward this model or two functions, "return the number of
-    possible edits" and "return edit #n"
-
-It would be nice if this could be data-driven, so the two functions
-could share information:
-  type vec_modifier = rec(fn (<T> v, uint i) -> ~[T] fun, uint lo, uint di);
-  const ~[vec_modifier] vec_modifiers = ~[rec(fun=vec_omit, 0u, 1u), ...]/~;
-But that gives me "error: internal compiler error unimplemented consts
-that's not a plain literal".
-https://github.com/graydon/rust/issues/570
-
-vec_edits is not an iter because iters might go away.
-
-*/
-
-use std::prelude::*;
-
-use vec::slice;
-use vec::len;
-
-fn vec_omit<T:copy>(v: ~[T], i: uint) -> ~[T] {
-    slice(v, 0u, i) + slice(v, i + 1u, len(v))
-}
-fn vec_dup<T:copy>(v: ~[T], i: uint) -> ~[T] {
-    slice(v, 0u, i) + [v[i]] + slice(v, i, len(v))
-}
-fn vec_swadj<T:copy>(v: ~[T], i: uint) -> ~[T] {
-    slice(v, 0u, i) + [v[i + 1u], v[i]] + slice(v, i + 2u, len(v))
-}
-fn vec_prefix<T:copy>(v: ~[T], i: uint) -> ~[T] { slice(v, 0u, i) }
-fn vec_suffix<T:copy>(v: ~[T], i: uint) -> ~[T] { slice(v, i, len(v)) }
-
-fn vec_poke<T:copy>(v: ~[T], i: uint, x: T) -> ~[T] {
-    slice(v, 0u, i) + ~[x] + slice(v, i + 1u, len(v))
-}
-fn vec_insert<T:copy>(v: ~[T], i: uint, x: T) -> ~[T] {
-    slice(v, 0u, i) + ~[x] + slice(v, i, len(v))
-}
-
-// Iterates over 0...length, skipping the specified number on each side.
-fn ix(skip_low: uint, skip_high: uint, length: uint, it: block(uint)) {
-    let i: uint = skip_low;
-    while i + skip_high <= length { it(i); i += 1u; }
-}
-
-// Returns a bunch of modified versions of v, some of which introduce
-// new elements (borrowed from xs).
-fn vec_edits<T:copy>(v: ~[T], xs: ~[T]) -> ~[~[T]] {
-    let edits: ~[~[T]] = ~[];
-    let Lv: uint = len(v);
-
-    if Lv != 1u {
-        // When Lv == 1u, this is redundant with omit.
-        edits.push(~[]);
-    }
-    if Lv >= 3u {
-        // When Lv == 2u, this is redundant with swap.
-        edits.push(vec::reversed(v));
-    }
-    ix(0u, 1u, Lv) {|i| edits += ~[vec_omit(v, i)]; }
-    ix(0u, 1u, Lv) {|i| edits += ~[vec_dup(v, i)]; }
-    ix(0u, 2u, Lv) {|i| edits += ~[vec_swadj(v, i)]; }
-    ix(1u, 2u, Lv) {|i| edits += ~[vec_prefix(v, i)]; }
-    ix(2u, 1u, Lv) {|i| edits += ~[vec_suffix(v, i)]; }
-
-    ix(0u, 1u, len(xs)) {|j|
-        ix(0u, 1u, Lv) {|i|
-            edits.push(vec_poke(v, i, xs[j]));
-        }
-        ix(0u, 0u, Lv) {|i|
-            edits.push(vec_insert(v, i, xs[j]));
-        }
-    }
-
-    edits
-}
-
-// Would be nice if this were built in:
-// https://github.com/graydon/rust/issues/424
-fn vec_to_str(v: ~[int]) -> str {
-    let i = 0u;
-    let s = "[";
-    while i < len(v) {
-        s += int::str(v[i]);
-        if i + 1u < len(v) { s += ", "; }
-        i += 1u;
-    }
-    return s + "]";
-}
-
-fn show_edits(a: ~[int], xs: ~[int]) {
-    log(error, "=== Edits of " + vec_to_str(a) + " ===");
-    let b = vec_edits(a, xs);
-    ix(0u, 1u, len(b)) {|i| log(error, vec_to_str(b[i])); }
-}
-
-fn demo_edits() {
-    let xs = ~[7, 8];
-    show_edits(~[], xs);
-    show_edits(~[1], xs);
-    show_edits(~[1, 2], xs);
-    show_edits(~[1, 2, 3], xs);
-    show_edits(~[1, 2, 3, 4], xs);
-}
-
-fn main() { demo_edits(); }
diff --git a/src/libfuzzer/rand_util.rs b/src/libfuzzer/rand_util.rs
deleted file mode 100644
index abc6b1cfc0a..00000000000
--- a/src/libfuzzer/rand_util.rs
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::prelude::*;
-use extra::rand;
-
-// random uint less than n
-fn under(r : rand::rng, n : uint) -> uint {
-    assert!(n != 0u); r.next() as uint % n
-}
-
-// random choice from a vec
-fn choice<T:copy>(r : rand::rng, v : ~[T]) -> T {
-    assert!(v.len() != 0u); v[under(r, v.len())]
-}
-
-// 1 in n chance of being true
-fn unlikely(r : rand::rng, n : uint) -> bool { under(r, n) == 0u }
-
-// shuffle a vec in place
-fn shuffle<T>(r : rand::rng, &v : ~[T]) {
-    let i = v.len();
-    while i >= 2u {
-        // Loop invariant: elements with index >= i have been locked in place.
-        i -= 1u;
-        vec::swap(v, i, under(r, i + 1u)); // Lock element i in place.
-    }
-}
-
-// create a shuffled copy of a vec
-fn shuffled<T:copy>(r : rand::rng, v : ~[T]) -> ~[T] {
-    let w = vec::to_mut(v);
-    shuffle(r, w);
-    vec::from_mut(w) // Shouldn't this happen automatically?
-}
-
-// sample from a population without replacement
-//fn sample<T>(r : rand::rng, pop : ~[T], k : uint) -> ~[T] { fail!() }
-
-// Two ways to make a weighted choice.
-// * weighted_choice is O(number of choices) time
-// * weighted_vec is O(total weight) space
-type weighted<T> = { weight: uint, item: T };
-fn weighted_choice<T:copy>(r : rand::rng, v : ~[weighted<T>]) -> T {
-    assert!(v.len() != 0u);
-    let total = 0u;
-    for {weight: weight, item: _} in v {
-        total += weight;
-    }
-    assert!(total >= 0u);
-    let chosen = under(r, total);
-    let so_far = 0u;
-    for {weight: weight, item: item} in v {
-        so_far += weight;
-        if so_far > chosen {
-            return item;
-        }
-    }
-    std::unreachable();
-}
-
-fn weighted_vec<T:copy>(v : ~[weighted<T>]) -> ~[T] {
-    let r = ~[];
-    for {weight: weight, item: item} in v {
-        let i = 0u;
-        while i < weight {
-            r.push(item);
-            i += 1u;
-        }
-    }
-    r
-}
-
-fn main()
-{
-    let r = rand::mk_rng();
-
-    log(error, under(r, 5u));
-    log(error, choice(r, ~[10, 20, 30]));
-    log(error, if unlikely(r, 5u) { "unlikely" } else { "likely" });
-
-    let mut a = ~[1, 2, 3];
-    shuffle(r, a);
-    log(error, a);
-
-    let i = 0u;
-    let v = ~[
-        {weight:1u, item:"low"},
-        {weight:8u, item:"middle"},
-        {weight:1u, item:"high"}
-    ];
-    let w = weighted_vec(v);
-
-    while i < 1000u {
-        log(error, "Immed: " + weighted_choice(r, v));
-        log(error, "Fast:  " + choice(r, w));
-        i += 1u;
-    }
-}
diff --git a/src/librustc/back/passes.rs b/src/librustc/back/passes.rs
index 315bb5d6317..987c76dccb4 100644
--- a/src/librustc/back/passes.rs
+++ b/src/librustc/back/passes.rs
@@ -221,7 +221,7 @@ pub static analysis_passes : &'static [(&'static str, &'static str)] = &'static
 /** Transformation Passes */
 pub static transform_passes : &'static [(&'static str, &'static str)] = &'static [
     ("adce",                            "Aggressive Dead Code Elimination"),
-    ("always-inline",                   "Inliner for #[inline(always)] functions"),
+    ("always-inline",                   "Inliner for #[inline] functions"),
     ("argpromotion",                    "Promote 'by reference' arguments to scalars"),
     ("bb-vectorize",                    "Basic-Block Vectorization"),
     ("block-placement",                 "Profile Guided Basic Block Placement"),
@@ -299,18 +299,27 @@ fn passes_exist() {
     let mut failed = ~[];
     unsafe { llvm::LLVMInitializePasses(); }
     for analysis_passes.each() |&(name,_)| {
-        if !create_pass(name).is_some() {
+        let pass = create_pass(name);
+        if !pass.is_some() {
             failed.push(name);
+        } else {
+            unsafe { llvm::LLVMDestroyPass(pass.get()) }
         }
     }
     for transform_passes.each() |&(name,_)| {
-        if !create_pass(name).is_some() {
+        let pass = create_pass(name);
+        if !pass.is_some() {
             failed.push(name);
+        } else {
+            unsafe { llvm::LLVMDestroyPass(pass.get()) }
         }
     }
     for utility_passes.each() |&(name,_)| {
-        if !create_pass(name).is_some() {
+        let pass = create_pass(name);
+        if !pass.is_some() {
             failed.push(name);
+        } else {
+            unsafe { llvm::LLVMDestroyPass(pass.get()) }
         }
     }
 
diff --git a/src/librustc/back/rpath.rs b/src/librustc/back/rpath.rs
index 85fc0575170..fd22a7e79c6 100644
--- a/src/librustc/back/rpath.rs
+++ b/src/librustc/back/rpath.rs
@@ -77,6 +77,10 @@ fn get_rpaths(os: session::os,
     // crates they depend on.
     let rel_rpaths = get_rpaths_relative_to_output(os, output, libs);
 
+    // Make backup absolute paths to the libraries. Binaries can
+    // be moved as long as the crates they link against don't move.
+    let abs_rpaths = get_absolute_rpaths(libs);
+
     // And a final backup rpath to the global library location.
     let fallback_rpaths = ~[get_install_prefix_rpath(target_triple)];
 
@@ -88,9 +92,11 @@ fn get_rpaths(os: session::os,
     }
 
     log_rpaths("relative", rel_rpaths);
+    log_rpaths("absolute", abs_rpaths);
     log_rpaths("fallback", fallback_rpaths);
 
     let mut rpaths = rel_rpaths;
+    rpaths.push_all(abs_rpaths);
     rpaths.push_all(fallback_rpaths);
 
     // Remove duplicates
@@ -160,19 +166,14 @@ pub fn get_relative_to(abs1: &Path, abs2: &Path) -> Path {
     }
 }
 
-#[cfg(stage0)]
-pub fn get_install_prefix_rpath(target_triple: &str) -> Path {
-    let install_prefix = env!("CFG_PREFIX");
-
-    if install_prefix.is_empty() {
-        fail!("rustc compiled without CFG_PREFIX environment variable");
-    }
+fn get_absolute_rpaths(libs: &[Path]) -> ~[Path] {
+    vec::map(libs, |a| get_absolute_rpath(a) )
+}
 
-    let tlib = filesearch::relative_target_lib_path(target_triple);
-    os::make_absolute(&Path(install_prefix).push_rel(&tlib))
+pub fn get_absolute_rpath(lib: &Path) -> Path {
+    os::make_absolute(lib).dir_path()
 }
 
-#[cfg(not(stage0))]
 pub fn get_install_prefix_rpath(target_triple: &str) -> Path {
     let install_prefix = env!("CFG_PREFIX");
 
@@ -198,15 +199,13 @@ pub fn minimize_rpaths(rpaths: &[Path]) -> ~[Path] {
 #[cfg(unix, test)]
 mod test {
     use core::prelude::*;
-
     use core::os;
-    use core::str;
 
     // FIXME(#2119): the outer attribute should be #[cfg(unix, test)], then
     // these redundant #[cfg(test)] blocks can be removed
     #[cfg(test)]
     #[cfg(test)]
-    use back::rpath::{get_install_prefix_rpath};
+    use back::rpath::{get_absolute_rpath, get_install_prefix_rpath};
     use back::rpath::{get_relative_to, get_rpath_relative_to_output};
     use back::rpath::{minimize_rpaths, rpaths_to_flags};
     use driver::session;
@@ -350,4 +349,14 @@ mod test {
                                                &Path("lib/libstd.so"));
         assert_eq!(res.to_str(), ~"@executable_path/../lib");
     }
+
+    #[test]
+    fn test_get_absolute_rpath() {
+        let res = get_absolute_rpath(&Path("lib/libstd.so"));
+        debug!("test_get_absolute_rpath: %s vs. %s",
+               res.to_str(),
+               os::make_absolute(&Path("lib")).to_str());
+
+        assert_eq!(res, os::make_absolute(&Path("lib")));
+    }
 }
diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs
index 73347f2b91d..43b3397094b 100644
--- a/src/librustc/driver/driver.rs
+++ b/src/librustc/driver/driver.rs
@@ -65,34 +65,24 @@ pub fn source_name(input: &input) -> @str {
 
 pub fn default_configuration(sess: Session, argv0: @str, input: &input) ->
    ast::crate_cfg {
-    let libc = match sess.targ_cfg.os {
-      session::os_win32 => @"msvcrt.dll",
-      session::os_macos => @"libc.dylib",
-      session::os_linux => @"libc.so.6",
-      session::os_android => @"libc.so",
-      session::os_freebsd => @"libc.so.7"
-      // _ { "libc.so" }
+    let (libc, tos) = match sess.targ_cfg.os {
+        session::os_win32 =>   (@"msvcrt.dll", @"win32"),
+        session::os_macos =>   (@"libc.dylib", @"macos"),
+        session::os_linux =>   (@"libc.so.6",  @"linux"),
+        session::os_android => (@"libc.so",    @"android"),
+        session::os_freebsd => (@"libc.so.7",  @"freebsd")
     };
-    let tos = match sess.targ_cfg.os {
-      session::os_win32 => @"win32",
-      session::os_macos => @"macos",
-      session::os_linux => @"linux",
-      session::os_android => @"android",
-      session::os_freebsd => @"freebsd"
-      // _ { "libc.so" }
-    };
-
-    let mk = attr::mk_name_value_item_str;
 
     // ARM is bi-endian, however using NDK seems to default
     // to little-endian unless a flag is provided.
     let (end,arch,wordsz) = match sess.targ_cfg.arch {
-        abi::X86 => (@"little",@"x86",@"32"),
-        abi::X86_64 => (@"little",@"x86_64",@"64"),
-        abi::Arm => (@"little",@"arm",@"32"),
-        abi::Mips => (@"big",@"mips",@"32")
+        abi::X86 =>    (@"little", @"x86",    @"32"),
+        abi::X86_64 => (@"little", @"x86_64", @"64"),
+        abi::Arm =>    (@"little", @"arm",    @"32"),
+        abi::Mips =>   (@"big",    @"mips",   @"32")
     };
 
+    let mk = attr::mk_name_value_item_str;
     return ~[ // Target bindings.
          attr::mk_word_item(os::FAMILY.to_managed()),
          mk(@"target_os", tos),
@@ -463,36 +453,38 @@ pub fn pretty_print_input(sess: Session, cfg: ast::crate_cfg, input: &input,
 }
 
 pub fn get_os(triple: &str) -> Option<session::os> {
-    if triple.contains("win32") ||
-               triple.contains("mingw32") {
-            Some(session::os_win32)
-        } else if triple.contains("darwin") {
-            Some(session::os_macos)
-        } else if triple.contains("android") {
-            Some(session::os_android)
-        } else if triple.contains("linux") {
-            Some(session::os_linux)
-        } else if triple.contains("freebsd") {
-            Some(session::os_freebsd)
-        } else { None }
+    for os_names.each |&(name, os)| {
+        if triple.contains(name) { return Some(os) }
+    }
+    None
 }
+static os_names : &'static [(&'static str, session::os)] = &'static [
+    ("mingw32", session::os_win32),
+    ("win32",   session::os_win32),
+    ("darwin",  session::os_macos),
+    ("android", session::os_android),
+    ("linux",   session::os_linux),
+    ("freebsd", session::os_freebsd)];
 
 pub fn get_arch(triple: &str) -> Option<abi::Architecture> {
-    if triple.contains("i386") ||
-        triple.contains("i486") ||
-               triple.contains("i586") ||
-               triple.contains("i686") ||
-               triple.contains("i786") {
-            Some(abi::X86)
-        } else if triple.contains("x86_64") {
-            Some(abi::X86_64)
-        } else if triple.contains("arm") ||
-                      triple.contains("xscale") {
-            Some(abi::Arm)
-        } else if triple.contains("mips") {
-            Some(abi::Mips)
-        } else { None }
+    for architecture_abis.each |&(arch, abi)| {
+        if triple.contains(arch) { return Some(abi) }
+    }
+    None
 }
+static architecture_abis : &'static [(&'static str, abi::Architecture)] = &'static [
+    ("i386",   abi::X86),
+    ("i486",   abi::X86),
+    ("i586",   abi::X86),
+    ("i686",   abi::X86),
+    ("i786",   abi::X86),
+
+    ("x86_64", abi::X86_64),
+
+    ("arm",    abi::Arm),
+    ("xscale", abi::Arm),
+
+    ("mips",   abi::Mips)];
 
 pub fn build_target_config(sopts: @session::options,
                            demitter: diagnostic::Emitter)
@@ -529,25 +521,6 @@ pub fn build_target_config(sopts: @session::options,
     return target_cfg;
 }
 
-#[cfg(stage0)]
-pub fn host_triple() -> ~str {
-    // Get the host triple out of the build environment. This ensures that our
-    // idea of the host triple is the same as for the set of libraries we've
-    // actually built.  We can't just take LLVM's host triple because they
-    // normalize all ix86 architectures to i386.
-    //
-    // Instead of grabbing the host triple (for the current host), we grab (at
-    // compile time) the target triple that this rustc is built with and
-    // calling that (at runtime) the host triple.
-    let ht = env!("CFG_COMPILER_TRIPLE");
-    return if ht != ~"" {
-            ht
-        } else {
-            fail!("rustc built without CFG_COMPILER_TRIPLE")
-        };
-}
-
-#[cfg(not(stage0))]
 pub fn host_triple() -> ~str {
     // Get the host triple out of the build environment. This ensures that our
     // idea of the host triple is the same as for the set of libraries we've
diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs
index 289bb4f63f5..5d5a5e736bc 100644
--- a/src/librustc/lib/llvm.rs
+++ b/src/librustc/lib/llvm.rs
@@ -224,13 +224,50 @@ pub type SectionIteratorRef = *SectionIterator_opaque;
 pub enum Pass_opaque {}
 pub type PassRef = *Pass_opaque;
 
+pub mod debuginfo {
+    use super::{ValueRef};
+
+    pub enum DIBuilder_opaque {}
+    pub type DIBuilderRef = *DIBuilder_opaque;
+
+    pub type DIDescriptor = ValueRef;
+    pub type DIScope = DIDescriptor;
+    pub type DILocation = DIDescriptor;
+    pub type DIFile = DIScope;
+    pub type DILexicalBlock = DIScope;
+    pub type DISubprogram = DIScope;
+    pub type DIType = DIDescriptor;
+    pub type DIBasicType = DIType;
+    pub type DIDerivedType = DIType;
+    pub type DICompositeType = DIDerivedType;
+    pub type DIVariable = DIDescriptor;
+    pub type DIArray = DIDescriptor;
+    pub type DISubrange = DIDescriptor;
+
+    pub enum DIDescriptorFlags {
+      FlagPrivate            = 1 << 0,
+      FlagProtected          = 1 << 1,
+      FlagFwdDecl            = 1 << 2,
+      FlagAppleBlock         = 1 << 3,
+      FlagBlockByrefStruct   = 1 << 4,
+      FlagVirtual            = 1 << 5,
+      FlagArtificial         = 1 << 6,
+      FlagExplicit           = 1 << 7,
+      FlagPrototyped         = 1 << 8,
+      FlagObjcClassComplete  = 1 << 9,
+      FlagObjectPointer      = 1 << 10,
+      FlagVector             = 1 << 11,
+      FlagStaticMember       = 1 << 12
+    }
+}
+
 pub mod llvm {
     use super::{AtomicBinOp, AtomicOrdering, BasicBlockRef, ExecutionEngineRef};
     use super::{Bool, BuilderRef, ContextRef, MemoryBufferRef, ModuleRef};
     use super::{ObjectFileRef, Opcode, PassManagerRef, PassManagerBuilderRef};
     use super::{SectionIteratorRef, TargetDataRef, TypeKind, TypeRef, UseRef};
-    use super::{ValueRef,PassRef};
-
+    use super::{ValueRef, PassRef};
+    use super::debuginfo::*;
     use core::libc::{c_char, c_int, c_longlong, c_ushort, c_uint, c_ulonglong};
 
     #[link_args = "-Lrustllvm -lrustllvm"]
@@ -929,6 +966,12 @@ pub mod llvm {
         #[fast_ffi]
         pub unsafe fn LLVMDeleteBasicBlock(BB: BasicBlockRef);
 
+        #[fast_ffi]
+        pub unsafe fn LLVMMoveBasicBlockAfter(BB: BasicBlockRef, MoveAfter: BasicBlockRef);
+
+        #[fast_ffi]
+        pub unsafe fn LLVMMoveBasicBlockBefore(BB: BasicBlockRef, MoveBefore: BasicBlockRef);
+
         /* Operations on instructions */
         #[fast_ffi]
         pub unsafe fn LLVMGetInstructionParent(Inst: ValueRef)
@@ -1641,6 +1684,9 @@ pub mod llvm {
         #[fast_ffi]
         pub unsafe fn LLVMCreatePass(PassName:*c_char) -> PassRef;
 
+        #[fast_ffi]
+        pub unsafe fn LLVMDestroyPass(P: PassRef);
+
         /** Adds a verification pass. */
         #[fast_ffi]
         pub unsafe fn LLVMAddVerifierPass(PM: PassManagerRef);
@@ -1885,6 +1931,164 @@ pub mod llvm {
                                     AlignStack: Bool, Dialect: c_uint)
                                  -> ValueRef;
 
+
+        #[fast_ffi]
+        pub unsafe fn LLVMDIBuilderCreate(M: ModuleRef) -> DIBuilderRef;
+
+        #[fast_ffi]
+        pub unsafe fn LLVMDIBuilderDispose(Builder: DIBuilderRef);
+
+        #[fast_ffi]
+        pub unsafe fn LLVMDIBuilderFinalize(Builder: DIBuilderRef);
+
+        #[fast_ffi]
+        pub unsafe fn LLVMDIBuilderCreateCompileUnit(
+            Builder: DIBuilderRef,
+            Lang: c_uint,
+            File: *c_char,
+            Dir: *c_char,
+            Producer: *c_char,
+            isOptimized: bool,
+            Flags: *c_char,
+            RuntimeVer: c_uint,
+            SplitName: *c_char);
+
+        #[fast_ffi]
+        pub unsafe fn LLVMDIBuilderCreateFile(
+            Builder: DIBuilderRef,
+            Filename: *c_char,
+            Directory: *c_char) -> DIFile;
+
+        #[fast_ffi]
+        pub unsafe fn LLVMDIBuilderCreateSubroutineType(
+            Builder: DIBuilderRef,
+            File: DIFile,
+            ParameterTypes: DIArray) -> DICompositeType;
+
+        #[fast_ffi]
+        pub unsafe fn LLVMDIBuilderCreateFunction(
+            Builder: DIBuilderRef,
+            Scope: DIDescriptor,
+            Name: *c_char,
+            LinkageName: *c_char,
+            File: DIFile,
+            LineNo: c_uint,
+            Ty: DIType,
+            isLocalToUnit: bool,
+            isDefinition: bool,
+            ScopeLine: c_uint,
+            Flags: c_uint,
+            isOptimized: bool,
+            Fn: ValueRef,
+            TParam: ValueRef,
+            Decl: ValueRef) -> DISubprogram;
+
+        #[fast_ffi]
+        pub unsafe fn LLVMDIBuilderCreateBasicType(
+            Builder: DIBuilderRef,
+            Name: *c_char,
+            SizeInBits: c_ulonglong,
+            AlignInBits: c_ulonglong,
+            Encoding: c_uint) -> DIBasicType;
+
+        #[fast_ffi]
+        pub unsafe fn LLVMDIBuilderCreatePointerType(
+            Builder: DIBuilderRef,
+            PointeeTy: DIType,
+            SizeInBits: c_ulonglong,
+            AlignInBits: c_ulonglong,
+            Name: *c_char) -> DIDerivedType;
+
+        #[fast_ffi]
+        pub unsafe fn LLVMDIBuilderCreateStructType(
+            Builder: DIBuilderRef,
+            Scope: DIDescriptor,
+            Name: *c_char,
+            File: DIFile,
+            LineNumber: c_uint,
+            SizeInBits: c_ulonglong,
+            AlignInBits: c_ulonglong,
+            Flags: c_uint,
+            DerivedFrom: DIType,
+            Elements: DIArray,
+            RunTimeLang: c_uint,
+            VTableHolder: ValueRef) -> DICompositeType;
+
+        #[fast_ffi]
+        pub unsafe fn LLVMDIBuilderCreateMemberType(
+            Builder: DIBuilderRef,
+            Scope: DIDescriptor,
+            Name: *c_char,
+            File: DIFile,
+            LineNo: c_uint,
+            SizeInBits: c_ulonglong,
+            AlignInBits: c_ulonglong,
+            OffsetInBits: c_ulonglong,
+            Flags: c_uint,
+            Ty: DIType) -> DIDerivedType;
+
+        #[fast_ffi]
+        pub unsafe fn LLVMDIBuilderCreateLexicalBlock(
+            Builder: DIBuilderRef,
+            Scope: DIDescriptor,
+            File: DIFile,
+            Line: c_uint,
+            Col: c_uint) -> DILexicalBlock;
+
+        #[fast_ffi]
+        pub unsafe fn LLVMDIBuilderCreateLocalVariable(
+            Builder: DIBuilderRef,
+            Tag: c_uint,
+            Scope: DIDescriptor,
+            Name: *c_char,
+            File: DIFile,
+            LineNo: c_uint,
+            Ty: DIType,
+            AlwaysPreserve: bool,
+            Flags: c_uint,
+            ArgNo: c_uint) -> DIVariable;
+
+        #[fast_ffi]
+        pub unsafe fn LLVMDIBuilderCreateArrayType(
+            Builder: DIBuilderRef,
+            Size: c_ulonglong,
+            AlignInBits: c_ulonglong,
+            Ty: DIType,
+            Subscripts: DIArray) -> DIType;
+
+        #[fast_ffi]
+        pub unsafe fn LLVMDIBuilderCreateVectorType(
+            Builder: DIBuilderRef,
+            Size: c_ulonglong,
+            AlignInBits: c_ulonglong,
+            Ty: DIType,
+            Subscripts: DIArray) -> DIType;
+
+        #[fast_ffi]
+        pub unsafe fn LLVMDIBuilderGetOrCreateSubrange(
+            Builder: DIBuilderRef,
+            Lo: c_longlong,
+            Count: c_longlong) -> DISubrange;
+
+        #[fast_ffi]
+        pub unsafe fn LLVMDIBuilderGetOrCreateArray(
+            Builder: DIBuilderRef,
+            Ptr: *DIDescriptor,
+            Count: c_uint) -> DIArray;
+
+        #[fast_ffi]
+        pub unsafe fn LLVMDIBuilderInsertDeclareAtEnd(
+            Builder: DIBuilderRef,
+            Val: ValueRef,
+            VarInfo: DIVariable,
+            InsertAtEnd: BasicBlockRef) -> ValueRef;
+
+        #[fast_ffi]
+        pub unsafe fn LLVMDIBuilderInsertDeclareBefore(
+            Builder: DIBuilderRef,
+            Val: ValueRef,
+            VarInfo: DIVariable,
+            InsertBefore: ValueRef) -> ValueRef;
     }
 }
 
@@ -1988,9 +2192,7 @@ pub fn type_to_str_inner(names: @TypeNames, outer0: &[TypeRef], ty: TypeRef)
             let out_ty: TypeRef = llvm::LLVMGetReturnType(ty);
             let n_args = llvm::LLVMCountParamTypes(ty) as uint;
             let args = vec::from_elem(n_args, 0 as TypeRef);
-            unsafe {
-                llvm::LLVMGetParamTypes(ty, vec::raw::to_ptr(args));
-            }
+            llvm::LLVMGetParamTypes(ty, vec::raw::to_ptr(args));
             // See [Note at-str]
             return fmt!("fn(%s) -> %s",
                         tys_str(names, outer, args),
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index 110f686e5a6..5d5d7582b5f 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -1184,7 +1184,7 @@ fn create_index<T:Copy + Hash + IterBytes>(index: ~[entry<T>]) ->
     for uint::range(0u, 256u) |_i| { buckets.push(@mut ~[]); };
     for index.each |elt| {
         let h = elt.val.hash() as uint;
-        buckets[h % 256].push(*elt);
+        buckets[h % 256].push(copy *elt);
     }
 
     let mut buckets_frozen = ~[];
diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs
index 5d9355053de..585704381b6 100644
--- a/src/librustc/metadata/loader.rs
+++ b/src/librustc/metadata/loader.rs
@@ -204,35 +204,33 @@ fn get_metadata_section(os: os,
         let si = mk_section_iter(of.llof);
         while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False {
             let name_buf = llvm::LLVMGetSectionName(si.llsi);
-            let name = unsafe { str::raw::from_c_str(name_buf) };
+            let name = str::raw::from_c_str(name_buf);
             debug!("get_metadata_section: name %s", name);
             if name == read_meta_section_name(os) {
                 let cbuf = llvm::LLVMGetSectionContents(si.llsi);
                 let csz = llvm::LLVMGetSectionSize(si.llsi) as uint;
                 let mut found = None;
-                unsafe {
-                    let cvbuf: *u8 = cast::transmute(cbuf);
-                    let vlen = encoder::metadata_encoding_version.len();
-                    debug!("checking %u bytes of metadata-version stamp",
-                           vlen);
-                    let minsz = uint::min(vlen, csz);
-                    let mut version_ok = false;
-                    do vec::raw::buf_as_slice(cvbuf, minsz) |buf0| {
-                        version_ok = (buf0 ==
-                                      encoder::metadata_encoding_version);
-                    }
-                    if !version_ok { return None; }
+                let cvbuf: *u8 = cast::transmute(cbuf);
+                let vlen = encoder::metadata_encoding_version.len();
+                debug!("checking %u bytes of metadata-version stamp",
+                       vlen);
+                let minsz = uint::min(vlen, csz);
+                let mut version_ok = false;
+                do vec::raw::buf_as_slice(cvbuf, minsz) |buf0| {
+                    version_ok = (buf0 ==
+                                  encoder::metadata_encoding_version);
+                }
+                if !version_ok { return None; }
 
-                    let cvbuf1 = ptr::offset(cvbuf, vlen);
-                    debug!("inflating %u bytes of compressed metadata",
-                           csz - vlen);
-                    do vec::raw::buf_as_slice(cvbuf1, csz-vlen) |bytes| {
-                        let inflated = flate::inflate_bytes(bytes);
-                        found = Some(@(inflated));
-                    }
-                    if found != None {
-                        return found;
-                    }
+                let cvbuf1 = ptr::offset(cvbuf, vlen);
+                debug!("inflating %u bytes of compressed metadata",
+                       csz - vlen);
+                do vec::raw::buf_as_slice(cvbuf1, csz-vlen) |bytes| {
+                    let inflated = flate::inflate_bytes(bytes);
+                    found = Some(@(inflated));
+                }
+                if found != None {
+                    return found;
                 }
             }
             llvm::LLVMMoveToNextSection(si.llsi);
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index e11367a7a7d..925b1f506d7 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -15,7 +15,6 @@ use cstore = metadata::cstore;
 use driver::session::Session;
 use e = metadata::encoder;
 use metadata::decoder;
-use metadata::encoder;
 use metadata::tydecode;
 use metadata::tydecode::{DefIdSource, NominalType, TypeWithId, TypeParameter};
 use metadata::tyencode;
diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs
index e384d35373e..be87beba778 100644
--- a/src/librustc/middle/borrowck/check_loans.rs
+++ b/src/librustc/middle/borrowck/check_loans.rs
@@ -82,7 +82,7 @@ impl<'self> CheckLoanCtxt<'self> {
         //! are issued for future scopes and thus they may have been
         //! *issued* but not yet be in effect.
 
-        for self.dfcx_loans.each_bit_on_entry(scope_id) |loan_index| {
+        for self.dfcx_loans.each_bit_on_entry_frozen(scope_id) |loan_index| {
             let loan = &self.all_loans[loan_index];
             if !op(loan) {
                 return false;
@@ -134,7 +134,7 @@ impl<'self> CheckLoanCtxt<'self> {
         //! we encounter `scope_id`.
 
         let mut result = ~[];
-        for self.dfcx_loans.each_gen_bit(scope_id) |loan_index| {
+        for self.dfcx_loans.each_gen_bit_frozen(scope_id) |loan_index| {
             result.push(loan_index);
         }
         return result;
diff --git a/src/librustc/middle/borrowck/gather_loans/gather_moves.rs b/src/librustc/middle/borrowck/gather_loans/gather_moves.rs
index ef911c9a808..5431a0a2998 100644
--- a/src/librustc/middle/borrowck/gather_loans/gather_moves.rs
+++ b/src/librustc/middle/borrowck/gather_loans/gather_moves.rs
@@ -105,7 +105,8 @@ fn check_is_legal_to_move_from(bccx: @BorrowckCtxt,
         mc::cat_implicit_self(*) |
         mc::cat_copied_upvar(*) |
         mc::cat_deref(_, _, mc::region_ptr(*)) |
-        mc::cat_deref(_, _, mc::gc_ptr(*)) => {
+        mc::cat_deref(_, _, mc::gc_ptr(*)) |
+        mc::cat_deref(_, _, mc::unsafe_ptr(*)) => {
             bccx.span_err(
                 cmt0.span,
                 fmt!("cannot move out of %s",
@@ -129,8 +130,7 @@ fn check_is_legal_to_move_from(bccx: @BorrowckCtxt,
         mc::cat_rvalue(*) |
         mc::cat_local(*) |
         mc::cat_arg(*) |
-        mc::cat_self(*) |
-        mc::cat_deref(_, _, mc::unsafe_ptr(*)) => {
+        mc::cat_self(*) => {
             true
         }
 
diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs
index 95e26e9e42f..d7186ad9333 100644
--- a/src/librustc/middle/borrowck/mod.rs
+++ b/src/librustc/middle/borrowck/mod.rs
@@ -775,17 +775,17 @@ impl BorrowckCtxt {
 }
 
 impl DataFlowOperator for LoanDataFlowOperator {
-    #[inline(always)]
+    #[inline]
     fn initial_value(&self) -> bool {
         false // no loans in scope by default
     }
 
-    #[inline(always)]
+    #[inline]
     fn join(&self, succ: uint, pred: uint) -> uint {
         succ | pred // loans from both preds are in scope
     }
 
-    #[inline(always)]
+    #[inline]
     fn walk_closures(&self) -> bool {
         true
     }
diff --git a/src/librustc/middle/borrowck/move_data.rs b/src/librustc/middle/borrowck/move_data.rs
index bd560fca985..3b1c451d0a6 100644
--- a/src/librustc/middle/borrowck/move_data.rs
+++ b/src/librustc/middle/borrowck/move_data.rs
@@ -504,7 +504,7 @@ impl FlowedMoveData {
 
         let opt_loan_path_index = self.move_data.existing_move_path(loan_path);
 
-        for self.dfcx_moves.each_bit_on_entry(id) |index| {
+        for self.dfcx_moves.each_bit_on_entry_frozen(id) |index| {
             let move = &self.move_data.moves[index];
             let moved_path = move.path;
             if base_indices.contains(&moved_path) {
@@ -560,7 +560,7 @@ impl FlowedMoveData {
             }
         };
 
-        for self.dfcx_assign.each_bit_on_entry(id) |index| {
+        for self.dfcx_assign.each_bit_on_entry_frozen(id) |index| {
             let assignment = &self.move_data.var_assignments[index];
             if assignment.path == loan_path_index && !f(assignment) {
                 return false;
@@ -571,34 +571,34 @@ impl FlowedMoveData {
 }
 
 impl DataFlowOperator for MoveDataFlowOperator {
-    #[inline(always)]
+    #[inline]
     fn initial_value(&self) -> bool {
         false // no loans in scope by default
     }
 
-    #[inline(always)]
+    #[inline]
     fn join(&self, succ: uint, pred: uint) -> uint {
         succ | pred // moves from both preds are in scope
     }
 
-    #[inline(always)]
+    #[inline]
     fn walk_closures(&self) -> bool {
         true
     }
 }
 
 impl DataFlowOperator for AssignDataFlowOperator {
-    #[inline(always)]
+    #[inline]
     fn initial_value(&self) -> bool {
         false // no assignments in scope by default
     }
 
-    #[inline(always)]
+    #[inline]
     fn join(&self, succ: uint, pred: uint) -> uint {
         succ | pred // moves from both preds are in scope
     }
 
-    #[inline(always)]
+    #[inline]
     fn walk_closures(&self) -> bool {
         true
     }
diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs
index 8037bacd3e7..b4942fba05d 100644
--- a/src/librustc/middle/dataflow.rs
+++ b/src/librustc/middle/dataflow.rs
@@ -22,6 +22,7 @@ use core::cast;
 use core::io;
 use core::uint;
 use core::vec;
+use core::hashmap::HashMap;
 use syntax::ast;
 use syntax::ast_util;
 use syntax::ast_util::id_range;
@@ -37,9 +38,6 @@ pub struct DataFlowContext<O> {
     /// the data flow operator
     priv oper: O,
 
-    /// range of ids that appear within the item in question
-    priv id_range: id_range,
-
     /// number of bits to propagate per id
     priv bits_per_id: uint,
 
@@ -47,6 +45,9 @@ pub struct DataFlowContext<O> {
     /// equal to bits_per_id/uint::bits rounded up.
     priv words_per_id: uint,
 
+    // mapping from node to bitset index.
+    priv nodeid_to_bitset: HashMap<ast::node_id,uint>,
+
     // Bit sets per id.  The following three fields (`gens`, `kills`,
     // and `on_entry`) all have the same structure. For each id in
     // `id_range`, there is a range of words equal to `words_per_id`.
@@ -108,19 +109,17 @@ impl<O:DataFlowOperator> DataFlowContext<O> {
         debug!("DataFlowContext::new(id_range=%?, bits_per_id=%?, words_per_id=%?)",
                id_range, bits_per_id, words_per_id);
 
-        let len = (id_range.max - id_range.min) as uint * words_per_id;
-        let gens = vec::from_elem(len, 0);
-        let kills = vec::from_elem(len, 0);
-        let elem = if oper.initial_value() {uint::max_value} else {0};
-        let on_entry = vec::from_elem(len, elem);
+        let gens = ~[];
+        let kills = ~[];
+        let on_entry = ~[];
 
         DataFlowContext {
             tcx: tcx,
             method_map: method_map,
             words_per_id: words_per_id,
+            nodeid_to_bitset: HashMap::new(),
             bits_per_id: bits_per_id,
             oper: oper,
-            id_range: id_range,
             gens: gens,
             kills: kills,
             on_entry: on_entry
@@ -149,7 +148,7 @@ impl<O:DataFlowOperator> DataFlowContext<O> {
         }
     }
 
-    fn apply_gen_kill(&self, id: ast::node_id, bits: &mut [uint]) {
+    fn apply_gen_kill(&mut self, id: ast::node_id, bits: &mut [uint]) {
         //! Applies the gen and kill sets for `id` to `bits`
 
         debug!("apply_gen_kill(id=%?, bits=%s) [before]",
@@ -164,7 +163,7 @@ impl<O:DataFlowOperator> DataFlowContext<O> {
                id, mut_bits_to_str(bits));
     }
 
-    fn apply_kill(&self, id: ast::node_id, bits: &mut [uint]) {
+    fn apply_kill(&mut self, id: ast::node_id, bits: &mut [uint]) {
         debug!("apply_kill(id=%?, bits=%s) [before]",
                id, mut_bits_to_str(bits));
         let (start, end) = self.compute_id_range(id);
@@ -174,18 +173,56 @@ impl<O:DataFlowOperator> DataFlowContext<O> {
                id, mut_bits_to_str(bits));
     }
 
-    fn compute_id_range(&self, absolute_id: ast::node_id) -> (uint, uint) {
-        assert!(absolute_id >= self.id_range.min);
-        assert!(absolute_id < self.id_range.max);
+    fn compute_id_range_frozen(&self, id: ast::node_id) -> (uint, uint) {
+        let n = *self.nodeid_to_bitset.get(&id);
+        let start = n * self.words_per_id;
+        let end = start + self.words_per_id;
+        (start, end)
+    }
 
-        let relative_id = absolute_id - self.id_range.min;
-        let start = (relative_id as uint) * self.words_per_id;
+    fn compute_id_range(&mut self, id: ast::node_id) -> (uint, uint) {
+        let mut expanded = false;
+        let len = self.nodeid_to_bitset.len();
+        let n = do self.nodeid_to_bitset.find_or_insert_with(id) |_| {
+            expanded = true;
+            len
+        };
+        if expanded {
+            let entry = if self.oper.initial_value() { uint::max_value } else {0};
+            for self.words_per_id.times {
+                self.gens.push(0);
+                self.kills.push(0);
+                self.on_entry.push(entry);
+            }
+        }
+        let start = *n * self.words_per_id;
         let end = start + self.words_per_id;
+
+        assert!(start < self.gens.len());
+        assert!(end <= self.gens.len());
+        assert!(self.gens.len() == self.kills.len());
+        assert!(self.gens.len() == self.on_entry.len());
+
         (start, end)
     }
 
 
-    pub fn each_bit_on_entry(&self,
+    pub fn each_bit_on_entry_frozen(&self,
+                                    id: ast::node_id,
+                                    f: &fn(uint) -> bool) -> bool {
+        //! Iterates through each bit that is set on entry to `id`.
+        //! Only useful after `propagate()` has been called.
+        if !self.nodeid_to_bitset.contains_key(&id) {
+            return true;
+        }
+        let (start, end) = self.compute_id_range_frozen(id);
+        let on_entry = vec::slice(self.on_entry, start, end);
+        debug!("each_bit_on_entry_frozen(id=%?, on_entry=%s)",
+               id, bits_to_str(on_entry));
+        self.each_bit(on_entry, f)
+    }
+
+    pub fn each_bit_on_entry(&mut self,
                              id: ast::node_id,
                              f: &fn(uint) -> bool) -> bool {
         //! Iterates through each bit that is set on entry to `id`.
@@ -198,7 +235,7 @@ impl<O:DataFlowOperator> DataFlowContext<O> {
         self.each_bit(on_entry, f)
     }
 
-    pub fn each_gen_bit(&self,
+    pub fn each_gen_bit(&mut self,
                         id: ast::node_id,
                         f: &fn(uint) -> bool) -> bool {
         //! Iterates through each bit in the gen set for `id`.
@@ -210,6 +247,20 @@ impl<O:DataFlowOperator> DataFlowContext<O> {
         self.each_bit(gens, f)
     }
 
+    pub fn each_gen_bit_frozen(&self,
+                               id: ast::node_id,
+                               f: &fn(uint) -> bool) -> bool {
+        //! Iterates through each bit in the gen set for `id`.
+        if !self.nodeid_to_bitset.contains_key(&id) {
+            return true;
+        }
+        let (start, end) = self.compute_id_range_frozen(id);
+        let gens = vec::slice(self.gens, start, end);
+        debug!("each_gen_bit(id=%?, gens=%s)",
+               id, bits_to_str(gens));
+        self.each_bit(gens, f)
+    }
+
     fn each_bit(&self,
                 words: &[uint],
                 f: &fn(uint) -> bool) -> bool {
@@ -285,8 +336,8 @@ impl<O:DataFlowOperator+Copy+'static> DataFlowContext<O> {
                 pprust::node_pat(ps, pat) => (ps, pat.id)
             };
 
-            if id >= self.id_range.min || id < self.id_range.max {
-                let (start, end) = self.compute_id_range(id);
+            if self.nodeid_to_bitset.contains_key(&id) {
+                let (start, end) = self.compute_id_range_frozen(id);
                 let on_entry = vec::slice(self.on_entry, start, end);
                 let entry_str = bits_to_str(on_entry);
 
@@ -965,7 +1016,7 @@ fn join_bits<O:DataFlowOperator>(oper: &O,
     bitwise(out_vec, in_vec, |a, b| oper.join(a, b))
 }
 
-#[inline(always)]
+#[inline]
 fn bitwise(out_vec: &mut [uint],
            in_vec: &[uint],
            op: &fn(uint, uint) -> uint) -> bool {
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index 1c335ee4084..08cba4d51cd 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -749,11 +749,7 @@ impl Liveness {
             None => {
                 // Vanilla 'break' or 'loop', so use the enclosing
                 // loop scope
-                let len = { // FIXME(#5074) stage0
-                    let loop_scope = &mut *self.loop_scope;
-                    loop_scope.len()
-                };
-                if len == 0 {
+                if self.loop_scope.len() == 0 {
                     self.tcx.sess.span_bug(sp, "break outside loop");
                 } else {
                     // FIXME(#5275): this shouldn't have to be a method...
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 2803608567d..3e656b3e594 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -4845,7 +4845,7 @@ impl Resolver {
         let mut smallest = 0;
         for maybes.eachi |i, &other| {
 
-            values[i] = str::levdistance(name, other);
+            values[i] = name.lev_distance(other);
 
             if values[i] <= values[smallest] {
                 smallest = i;
diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs
index ad07f41f8c3..0976407b0bd 100644
--- a/src/librustc/middle/trans/adt.rs
+++ b/src/librustc/middle/trans/adt.rs
@@ -47,7 +47,6 @@
 use core::container::Map;
 use core::libc::c_ulonglong;
 use core::option::{Option, Some, None};
-use core::str;
 use core::vec;
 
 use lib::llvm::{ValueRef, TypeRef, True, IntEQ, IntNE};
@@ -165,7 +164,7 @@ fn represent_type_uncached(cx: &mut CrateContext, t: ty::t) -> Repr {
             if cases.all(|c| c.tys.len() == 0) {
                 // All bodies empty -> intlike
                 let discrs = cases.map(|c| c.discr);
-                return CEnum(discrs.min(), discrs.max());
+                return CEnum(*discrs.iter().min().unwrap(), *discrs.iter().max().unwrap());
             }
 
             if cases.len() == 1 {
@@ -509,7 +508,7 @@ pub fn trans_const(ccx: &mut CrateContext, r: &Repr, discr: int,
         }
         General(ref cases) => {
             let case = &cases[discr as uint];
-            let max_sz = cases.map(|s| s.size).max();
+            let max_sz = cases.iter().transform(|x| x.size).max().unwrap();
             let discr_ty = C_int(ccx, discr);
             let contents = build_const_struct(ccx, case,
                                               ~[discr_ty] + vals);
@@ -577,7 +576,7 @@ fn padding(size: u64) -> ValueRef {
 }
 
 // XXX this utility routine should be somewhere more general
-#[inline(always)]
+#[inline]
 fn roundup(x: u64, a: u64) -> u64 { ((x + (a - 1)) / a) * a }
 
 /// Get the discriminant of a constant value.  (Not currently used.)
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index e2073d21fe3..d7d21707f40 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -71,7 +71,6 @@ use core::libc::c_uint;
 use core::str;
 use core::uint;
 use core::vec;
-use core::local_data;
 use extra::time;
 use syntax::ast::ident;
 use syntax::ast_map::{path, path_elt_to_str, path_name};
@@ -1318,26 +1317,38 @@ pub fn cleanup_and_leave(bcx: block,
 
         match cur.kind {
             block_scope(inf) if !inf.empty_cleanups() => {
-                let (sub_cx, inf_cleanups) = {
-                    let inf = &mut *inf; // FIXME(#5074) workaround stage0
+                let (sub_cx, dest, inf_cleanups) = {
+                    let inf = &mut *inf;
+                    let mut skip = 0;
+                    let mut dest = None;
                     {
-                        let r = vec::find((*inf).cleanup_paths, |cp| cp.target == leave);
+                        let r = vec::rfind((*inf).cleanup_paths, |cp| cp.target == leave);
                         for r.iter().advance |cp| {
-                            Br(bcx, cp.dest);
-                            return;
+                            if cp.size == inf.cleanups.len() {
+                                Br(bcx, cp.dest);
+                                return;
+                            }
+
+                            skip = cp.size;
+                            dest = Some(cp.dest);
                         }
                     }
                     let sub_cx = sub_block(bcx, "cleanup");
                     Br(bcx, sub_cx.llbb);
                     inf.cleanup_paths.push(cleanup_path {
                         target: leave,
+                        size: inf.cleanups.len(),
                         dest: sub_cx.llbb
                     });
-                    (sub_cx, copy inf.cleanups)
+                    (sub_cx, dest, inf.cleanups.tailn(skip).to_owned())
                 };
                 bcx = trans_block_cleanups_(sub_cx,
                                             inf_cleanups,
                                             is_lpad);
+                for dest.iter().advance |&dest| {
+                    Br(bcx, dest);
+                    return;
+                }
             }
             _ => ()
         }
@@ -1897,6 +1908,12 @@ pub fn trans_closure(ccx: @mut CrateContext,
     finish(bcx);
     cleanup_and_Br(bcx, bcx_top, fcx.llreturn);
 
+    // Put return block after all other blocks.
+    // This somewhat improves single-stepping experience in debugger.
+    unsafe {
+        llvm::LLVMMoveBasicBlockAfter(fcx.llreturn, bcx.llbb);
+    }
+
     // Insert the mandatory first few basic blocks before lltop.
     finish_fn(fcx, lltop);
 }
@@ -3033,7 +3050,7 @@ pub fn write_metadata(cx: &mut CrateContext, crate: &ast::crate) {
 
 // Writes the current ABI version into the crate.
 pub fn write_abi_version(ccx: &mut CrateContext) {
-    mk_global(ccx, ~"rust_abi_version", C_uint(ccx, abi::abi_version),
+    mk_global(ccx, "rust_abi_version", C_uint(ccx, abi::abi_version),
                      false);
 }
 
@@ -3091,6 +3108,9 @@ pub fn trans_crate(sess: session::Session,
     fill_crate_map(ccx, ccx.crate_map);
     glue::emit_tydescs(ccx);
     write_abi_version(ccx);
+    if ccx.sess.opts.debuginfo {
+        debuginfo::finalize(ccx);
+    }
 
     // Translate the metadata.
     write_metadata(ccx, crate);
@@ -3120,4 +3140,3 @@ pub fn trans_crate(sess: session::Session,
 
     return (llcx, llmod, link_meta);
 }
-
diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs
index 604cd3d2ba6..a55e89747f5 100644
--- a/src/librustc/middle/trans/build.rs
+++ b/src/librustc/middle/trans/build.rs
@@ -618,13 +618,11 @@ pub fn InBoundsGEP(cx: block, Pointer: ValueRef, Indices: &[ValueRef]) ->
    ValueRef {
     unsafe {
         if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_nil())); }
-        unsafe {
-            count_insn(cx, "inboundsgep");
+        count_insn(cx, "inboundsgep");
         return llvm::LLVMBuildInBoundsGEP(B(cx), Pointer,
                                            vec::raw::to_ptr(Indices),
                                            Indices.len() as c_uint,
                                            noname());
-        }
     }
 }
 
@@ -1072,11 +1070,9 @@ pub fn Trap(cx: block) {
         });
         assert!((T as int != 0));
         let Args: ~[ValueRef] = ~[];
-        unsafe {
-            count_insn(cx, "trap");
-            llvm::LLVMBuildCall(b, T, vec::raw::to_ptr(Args),
-                                Args.len() as c_uint, noname());
-        }
+        count_insn(cx, "trap");
+        llvm::LLVMBuildCall(b, T, vec::raw::to_ptr(Args),
+                            Args.len() as c_uint, noname());
     }
 }
 
diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs
index 1440d3856f0..c368ab5c9bd 100644
--- a/src/librustc/middle/trans/closure.rs
+++ b/src/librustc/middle/trans/closure.rs
@@ -553,7 +553,7 @@ pub fn make_opaque_cbox_drop_glue(
         ast::BorrowedSigil => bcx,
         ast::ManagedSigil => {
             glue::decr_refcnt_maybe_free(
-                bcx, Load(bcx, cboxptr),
+                bcx, Load(bcx, cboxptr), Some(cboxptr),
                 ty::mk_opaque_closure_ptr(bcx.tcx(), sigil))
         }
         ast::OwnedSigil => {
diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs
index f5919ca2586..ff98e5a177f 100644
--- a/src/librustc/middle/trans/common.rs
+++ b/src/librustc/middle/trans/common.rs
@@ -325,11 +325,17 @@ pub enum cleanup {
 // target: none means the path ends in an resume instruction
 pub struct cleanup_path {
     target: Option<BasicBlockRef>,
+    size: uint,
     dest: BasicBlockRef
 }
 
-pub fn scope_clean_changed(scope_info: &mut scope_info) {
-    if scope_info.cleanup_paths.len() > 0u { scope_info.cleanup_paths = ~[]; }
+pub fn shrink_scope_clean(scope_info: &mut scope_info, size: uint) {
+    scope_info.landing_pad = None;
+    scope_info.cleanup_paths = scope_info.cleanup_paths.iter()
+            .take_while(|&cu| cu.size <= size).transform(|&x|x).collect();
+}
+
+pub fn grow_scope_clean(scope_info: &mut scope_info) {
     scope_info.landing_pad = None;
 }
 
@@ -374,7 +380,7 @@ pub fn add_clean(bcx: block, val: ValueRef, t: ty::t) {
         scope_info.cleanups.push(
             clean(|a| glue::drop_ty_root(a, root, rooted, t),
                   cleanup_type));
-        scope_clean_changed(scope_info);
+        grow_scope_clean(scope_info);
     }
 }
 
@@ -388,7 +394,7 @@ pub fn add_clean_temp_immediate(cx: block, val: ValueRef, ty: ty::t) {
         scope_info.cleanups.push(
             clean_temp(val, |a| glue::drop_ty_immediate(a, val, ty),
                        cleanup_type));
-        scope_clean_changed(scope_info);
+        grow_scope_clean(scope_info);
     }
 }
 pub fn add_clean_temp_mem(bcx: block, val: ValueRef, t: ty::t) {
@@ -402,7 +408,7 @@ pub fn add_clean_temp_mem(bcx: block, val: ValueRef, t: ty::t) {
         scope_info.cleanups.push(
             clean_temp(val, |a| glue::drop_ty_root(a, root, rooted, t),
                        cleanup_type));
-        scope_clean_changed(scope_info);
+        grow_scope_clean(scope_info);
     }
 }
 pub fn add_clean_return_to_mut(bcx: block,
@@ -434,7 +440,7 @@ pub fn add_clean_return_to_mut(bcx: block,
                                                  filename_val,
                                                  line_val),
                 normal_exit_only));
-        scope_clean_changed(scope_info);
+        grow_scope_clean(scope_info);
     }
 }
 pub fn add_clean_free(cx: block, ptr: ValueRef, heap: heap) {
@@ -451,7 +457,7 @@ pub fn add_clean_free(cx: block, ptr: ValueRef, heap: heap) {
     do in_scope_cx(cx) |scope_info| {
         scope_info.cleanups.push(clean_temp(ptr, free_fn,
                                       normal_exit_and_unwind));
-        scope_clean_changed(scope_info);
+        grow_scope_clean(scope_info);
     }
 }
 
@@ -474,7 +480,7 @@ pub fn revoke_clean(cx: block, val: ValueRef) {
                             vec::slice(scope_info.cleanups,
                                       *i + 1u,
                                       scope_info.cleanups.len()));
-            scope_clean_changed(scope_info);
+            shrink_scope_clean(scope_info, *i);
         }
     }
 }
diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs
index 75d7aaa88a6..d6c7472424f 100644
--- a/src/librustc/middle/trans/context.rs
+++ b/src/librustc/middle/trans/context.rs
@@ -148,7 +148,7 @@ impl CrateContext {
             lib::llvm::associate_type(tn, @"tydesc", tydesc_type);
             let crate_map = decl_crate_map(sess, link_meta, llmod);
             let dbg_cx = if sess.opts.debuginfo {
-                Some(debuginfo::mk_ctxt(name.to_owned()))
+                Some(debuginfo::DebugContext::new(llmod, name.to_owned()))
             } else {
                 None
             };
@@ -211,9 +211,7 @@ impl CrateContext {
                   int_type: int_type,
                   float_type: float_type,
                   opaque_vec_type: T_opaque_vec(targ_cfg),
-                  builder: BuilderRef_res(unsafe {
-                      llvm::LLVMCreateBuilderInContext(llcx)
-                  }),
+                  builder: BuilderRef_res(llvm::LLVMCreateBuilderInContext(llcx)),
                   shape_cx: mk_ctxt(llmod),
                   crate_map: crate_map,
                   uses_gc: false,
diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs
index 7a8ebb4abfd..269451b1307 100644
--- a/src/librustc/middle/trans/debuginfo.rs
+++ b/src/librustc/middle/trans/debuginfo.rs
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -11,9 +11,9 @@
 use core::prelude::*;
 
 use driver::session;
-use lib::llvm::ValueRef;
 use lib::llvm::llvm;
-use middle::trans::context::task_llcx;
+use lib::llvm::{ValueRef, ModuleRef, ContextRef};
+use lib::llvm::debuginfo::*;
 use middle::trans::common::*;
 use middle::trans::machine;
 use middle::trans::type_of;
@@ -21,21 +21,18 @@ use middle::trans;
 use middle::ty;
 use util::ppaux::ty_to_str;
 
-use core::cast;
 use core::hashmap::HashMap;
 use core::libc;
-use core::option;
+use core::libc::c_uint;
+use core::cmp;
 use core::ptr;
-use core::str;
+use core::str::as_c_str;
 use core::sys;
 use core::vec;
 use syntax::codemap::span;
 use syntax::{ast, codemap, ast_util, ast_map};
 
-static LLVMDebugVersion: int = (9 << 16);
-
 static DW_LANG_RUST: int = 0x9000;
-static DW_VIRTUALITY_none: int = 0;
 
 static CompileUnitTag: int = 17;
 static FileDescriptorTag: int = 41;
@@ -59,302 +56,169 @@ static DW_ATE_signed_char: int = 0x06;
 static DW_ATE_unsigned: int = 0x07;
 static DW_ATE_unsigned_char: int = 0x08;
 
-fn llstr(s: &str) -> ValueRef {
-    do str::as_c_str(s) |sbuf| {
-        unsafe {
-            llvm::LLVMMDStringInContext(task_llcx(),
-                                        sbuf,
-                                        s.len() as libc::c_uint)
-        }
-    }
-}
-fn lltag(lltag: int) -> ValueRef {
-    lli32(LLVMDebugVersion | lltag)
-}
-fn lli32(val: int) -> ValueRef {
-    C_i32(val as i32)
-}
-fn lli64(val: int) -> ValueRef {
-    C_i64(val as i64)
-}
-fn lli1(bval: bool) -> ValueRef {
-    C_i1(bval)
-}
-fn llmdnode(elems: &[ValueRef]) -> ValueRef {
-    unsafe {
-        llvm::LLVMMDNodeInContext(task_llcx(),
-                                  vec::raw::to_ptr(elems),
-                                  elems.len() as libc::c_uint)
-    }
-}
-fn llunused() -> ValueRef {
-    lli32(0x0)
-}
-fn llnull() -> ValueRef {
-    unsafe {
-        cast::transmute(ptr::null::<ValueRef>())
-    }
-}
-
-fn add_named_metadata(cx: &CrateContext, name: ~str, val: ValueRef) {
-    str::as_c_str(name, |sbuf| {
-        unsafe {
-            llvm::LLVMAddNamedMetadataOperand(cx.llmod, sbuf, val)
-        }
-    })
-}
-
 ////////////////
 
 pub struct DebugContext {
-    llmetadata: metadata_cache,
     names: namegen,
-    crate_file: ~str
-}
-
-pub fn mk_ctxt(crate: ~str) -> DebugContext {
-    DebugContext {
-        llmetadata: @mut HashMap::new(),
-        names: new_namegen(),
-        crate_file: crate
+    crate_file: ~str,
+    llcontext: ContextRef,
+    builder: DIBuilderRef,
+    curr_loc: (uint, uint),
+    created_files: HashMap<~str, DIFile>,
+    created_functions: HashMap<ast::node_id, DISubprogram>,
+    created_blocks: HashMap<ast::node_id, DILexicalBlock>,
+    created_types: HashMap<uint, DIType>
+}
+
+impl DebugContext {
+    pub fn new(llmod: ModuleRef, crate: ~str) -> DebugContext {
+        debug!("DebugContext::new");
+        let builder = unsafe { llvm::LLVMDIBuilderCreate(llmod) };
+        // DIBuilder inherits context from the module, so we'd better use the same one
+        let llcontext = unsafe { llvm::LLVMGetModuleContext(llmod) };
+        return DebugContext {
+            names: new_namegen(),
+            crate_file: crate,
+            llcontext: llcontext,
+            builder: builder,
+            curr_loc: (0, 0),
+            created_files: HashMap::new(),
+            created_functions: HashMap::new(),
+            created_blocks: HashMap::new(),
+            created_types: HashMap::new(),
+        };
     }
 }
 
-fn update_cache(cache: metadata_cache, mdtag: int, val: debug_metadata) {
-    let mut existing = match cache.pop(&mdtag) {
-        Some(arr) => arr, None => ~[]
-    };
-    existing.push(val);
-    cache.insert(mdtag, existing);
-}
-
-struct Metadata<T> {
-    node: ValueRef,
-    data: T
-}
-
-struct FileMetadata {
-    path: ~str
-}
-struct CompileUnitMetadata {
-    name: ~str
-}
-struct SubProgramMetadata {
-    id: ast::node_id
-}
-struct LocalVarMetadata {
-    id: ast::node_id
-}
-struct TyDescMetadata {
-    hash: uint
-}
-struct BlockMetadata {
-    start: codemap::Loc,
-    end: codemap::Loc
-}
-struct ArgumentMetadata {
-    id: ast::node_id
-}
-struct RetvalMetadata {
-    id: ast::node_id
+#[inline]
+fn dbg_cx<'a>(cx: &'a mut CrateContext) -> &'a mut DebugContext {
+    cx.dbg_cx.get_mut_ref()
 }
 
-type metadata_cache = @mut HashMap<int, ~[debug_metadata]>;
-
-enum debug_metadata {
-    file_metadata(@Metadata<FileMetadata>),
-    compile_unit_metadata(@Metadata<CompileUnitMetadata>),
-    subprogram_metadata(@Metadata<SubProgramMetadata>),
-    local_var_metadata(@Metadata<LocalVarMetadata>),
-    tydesc_metadata(@Metadata<TyDescMetadata>),
-    block_metadata(@Metadata<BlockMetadata>),
-    argument_metadata(@Metadata<ArgumentMetadata>),
-    retval_metadata(@Metadata<RetvalMetadata>),
+#[inline]
+fn DIB(cx: &CrateContext) -> DIBuilderRef {
+    cx.dbg_cx.get_ref().builder
 }
 
-fn cast_safely<T:Copy,U>(val: T) -> U {
+/// Create any deferred debug metadata nodes
+pub fn finalize(cx: @mut CrateContext) {
+    debug!("finalize");
+    create_compile_unit(cx);
     unsafe {
-        let val2 = val;
-        return cast::transmute(val2);
-    }
-}
-
-fn md_from_metadata<T>(val: debug_metadata) -> T {
-    match val {
-      file_metadata(md) => cast_safely(md),
-      compile_unit_metadata(md) => cast_safely(md),
-      subprogram_metadata(md) => cast_safely(md),
-      local_var_metadata(md) => cast_safely(md),
-      tydesc_metadata(md) => cast_safely(md),
-      block_metadata(md) => cast_safely(md),
-      argument_metadata(md) => cast_safely(md),
-      retval_metadata(md) => cast_safely(md)
-    }
+        llvm::LLVMDIBuilderFinalize(DIB(cx));
+        llvm::LLVMDIBuilderDispose(DIB(cx));
+    };
 }
 
-fn cached_metadata<T:Copy>(cache: metadata_cache,
-                            mdtag: int,
-                            eq_fn: &fn(md: T) -> bool)
-                         -> Option<T> {
-    if cache.contains_key(&mdtag) {
-        let items = cache.get(&mdtag);
-        for items.each |item| {
-            let md: T = md_from_metadata::<T>(*item);
-            if eq_fn(md) {
-                return option::Some(md);
-            }
-        }
-    }
-    return option::None;
+fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray {
+    return unsafe {
+        llvm::LLVMDIBuilderGetOrCreateArray(builder, vec::raw::to_ptr(arr), arr.len() as u32)
+    };
 }
 
-fn create_compile_unit(cx: &mut CrateContext) -> @Metadata<CompileUnitMetadata> {
-    let cache = get_cache(cx);
-    let crate_name = /*bad*/copy (/*bad*/copy cx.dbg_cx).get().crate_file;
-    let tg = CompileUnitTag;
-    match cached_metadata::<@Metadata<CompileUnitMetadata>>(cache, tg,
-                        |md| md.data.name == crate_name) {
-      option::Some(md) => return md,
-      option::None => ()
+fn create_compile_unit(cx: @mut CrateContext) {
+    let dcx = dbg_cx(cx);
+    let crate_name: &str = dcx.crate_file;
+    let work_dir = cx.sess.working_dir.to_str();
+    let producer = fmt!("rustc version %s", env!("CFG_VERSION"));
+
+    do as_c_str(crate_name) |crate_name| {
+    do as_c_str(work_dir) |work_dir| {
+    do as_c_str(producer) |producer| {
+    do as_c_str("") |flags| {
+    do as_c_str("") |split_name| { unsafe {
+        llvm::LLVMDIBuilderCreateCompileUnit(dcx.builder,
+            DW_LANG_RUST as c_uint, crate_name, work_dir, producer,
+            cx.sess.opts.optimize != session::No,
+            flags, 0, split_name);
+    }}}}}};
+}
+
+fn create_file(cx: @mut CrateContext, full_path: &str) -> DIFile {
+    match dbg_cx(cx).created_files.find_equiv(&full_path) {
+        Some(file_md) => return *file_md,
+        None => ()
     }
 
-    let (_, work_dir) = get_file_path_and_dir(
-        cx.sess.working_dir.to_str(), crate_name);
-    let unit_metadata = ~[lltag(tg),
-                         llunused(),
-                         lli32(DW_LANG_RUST),
-                         llstr(crate_name),
-                         llstr(work_dir),
-                         llstr(env!("CFG_VERSION")),
-                         lli1(true), // deprecated: main compile unit
-                         lli1(cx.sess.opts.optimize != session::No),
-                         llstr(""), // flags (???)
-                         lli32(0) // runtime version (???)
-                        ];
-    let unit_node = llmdnode(unit_metadata);
-    add_named_metadata(cx, ~"llvm.dbg.cu", unit_node);
-    let mdval = @Metadata {
-        node: unit_node,
-        data: CompileUnitMetadata {
-            name: crate_name
-        }
-    };
-    update_cache(cache, tg, compile_unit_metadata(mdval));
+    debug!("create_file: %s", full_path);
 
-    return mdval;
-}
+    let work_dir = cx.sess.working_dir.to_str();
+    let file_name =
+        if full_path.starts_with(work_dir) {
+            full_path.slice(work_dir.len() + 1u, full_path.len())
+        } else {
+            full_path
+        };
 
-fn get_cache(cx: &CrateContext) -> metadata_cache {
-    cx.dbg_cx.get_ref().llmetadata
-}
+    let file_md =
+        do as_c_str(file_name) |file_name| {
+        do as_c_str(work_dir) |work_dir| { unsafe {
+            llvm::LLVMDIBuilderCreateFile(DIB(cx), file_name, work_dir)
+        }}};
 
-fn get_file_path_and_dir(work_dir: &str, full_path: &str) -> (~str, ~str) {
-    (if full_path.starts_with(work_dir) {
-        full_path.slice(work_dir.len() + 1u,
-                   full_path.len()).to_owned()
-    } else {
-        full_path.to_owned()
-    }, work_dir.to_owned())
+    dbg_cx(cx).created_files.insert(full_path.to_owned(), file_md);
+    return file_md;
 }
 
-fn create_file(cx: &mut CrateContext, full_path: ~str)
-    -> @Metadata<FileMetadata> {
-    let cache = get_cache(cx);;
-    let tg = FileDescriptorTag;
-    match cached_metadata::<@Metadata<FileMetadata>>(
-        cache, tg, |md| md.data.path == full_path) {
-        option::Some(md) => return md,
-        option::None => ()
-    }
-
-    let (file_path, work_dir) =
-        get_file_path_and_dir(cx.sess.working_dir.to_str(),
-                              full_path);
-    let unit_node = create_compile_unit(cx).node;
-    let file_md = ~[lltag(tg),
-                   llstr(file_path),
-                   llstr(work_dir),
-                   unit_node];
-    let val = llmdnode(file_md);
-    let mdval = @Metadata {
-        node: val,
-        data: FileMetadata {
-            path: full_path
-        }
-    };
-    update_cache(cache, tg, file_metadata(mdval));
-    return mdval;
+/// Return codemap::Loc corresponding to the beginning of the span
+fn span_start(cx: &CrateContext, span: span) -> codemap::Loc {
+    return cx.sess.codemap.lookup_char_pos(span.lo);
 }
 
-fn line_from_span(cm: @codemap::CodeMap, sp: span) -> uint {
-    cm.lookup_char_pos(sp.lo).line
-}
+fn create_block(bcx: block) -> DILexicalBlock {
+    let mut bcx = bcx;
+    let cx = bcx.ccx();
 
-fn create_block(mut cx: block) -> @Metadata<BlockMetadata> {
-    let cache = get_cache(cx.ccx());
-    while cx.node_info.is_none() {
-        match cx.parent {
-          Some(b) => cx = b,
+    while bcx.node_info.is_none() {
+        match bcx.parent {
+          Some(b) => bcx = b,
           None => fail!()
         }
     }
-    let sp = cx.node_info.get().span;
-
-    let start = cx.sess().codemap.lookup_char_pos(sp.lo);
-    let fname = /*bad*/copy start.file.name;
-    let end = cx.sess().codemap.lookup_char_pos(sp.hi);
-    let tg = LexicalBlockTag;
-    /*match cached_metadata::<@Metadata<BlockMetadata>>(
-        cache, tg,
-        {|md| start == md.data.start && end == md.data.end}) {
-      option::Some(md) { return md; }
-      option::None {}
-    }*/
-
-    let parent = match cx.parent {
-        None => create_function(cx.fcx).node,
-        Some(bcx) => create_block(bcx).node
-    };
-    let file_node = create_file(cx.ccx(), /* bad */ fname.to_owned());
-    let unique_id = match cache.find(&LexicalBlockTag) {
-      option::Some(v) => v.len() as int,
-      option::None => 0
+    let span = bcx.node_info.get().span;
+    let id = bcx.node_info.get().id;
+
+    match dbg_cx(cx).created_blocks.find(&id) {
+        Some(block) => return *block,
+        None => ()
+    }
+
+    debug!("create_block: %s", bcx.sess().codemap.span_to_str(span));
+
+    let parent = match bcx.parent {
+        None => create_function(bcx.fcx),
+        Some(b) => create_block(b)
     };
-    let lldata = ~[lltag(tg),
-                  parent,
-                  lli32(start.line.to_int()),
-                  lli32(start.col.to_int()),
-                  file_node.node,
-                  lli32(unique_id)
-                 ];
-    let val = llmdnode(lldata);
-    let mdval = @Metadata {
-        node: val,
-        data: BlockMetadata {
-            start: start,
-            end: end
-        }
+    let cx = bcx.ccx();
+    let loc = span_start(cx, span);
+    let file_md = create_file(cx, loc.file.name);
+
+    let block_md = unsafe {
+        llvm::LLVMDIBuilderCreateLexicalBlock(
+            DIB(cx),
+            parent, file_md,
+            loc.line as c_uint, loc.col.to_uint() as c_uint)
     };
-    //update_cache(cache, tg, block_metadata(mdval));
-    return mdval;
+
+    dbg_cx(cx).created_blocks.insert(id, block_md);
+
+    return block_md;
 }
 
-fn size_and_align_of(cx: &mut CrateContext, t: ty::t) -> (int, int) {
+fn size_and_align_of(cx: @mut CrateContext, t: ty::t) -> (uint, uint) {
     let llty = type_of::type_of(cx, t);
-    (machine::llsize_of_real(cx, llty) as int,
-     machine::llalign_of_pref(cx, llty) as int)
+    (machine::llsize_of_real(cx, llty), machine::llalign_of_min(cx, llty))
 }
 
-fn create_basic_type(cx: &mut CrateContext, t: ty::t, span: span)
-    -> @Metadata<TyDescMetadata> {
-    let cache = get_cache(cx);
-    let tg = BasicTypeDescriptorTag;
-    match cached_metadata::<@Metadata<TyDescMetadata>>(
-        cache, tg, |md| ty::type_id(t) == md.data.hash) {
-      option::Some(md) => return md,
-      option::None => ()
+fn create_basic_type(cx: @mut CrateContext, t: ty::t, _span: span) -> DIType {
+    let ty_id = ty::type_id(t);
+    match dbg_cx(cx).created_types.find(&ty_id) {
+        Some(ty_md) => return *ty_md,
+        None => ()
     }
 
+    debug!("create_basic_type: %?", ty::get(t));
+
     let (name, encoding) = match ty::get(t).sty {
         ty::ty_nil | ty::ty_bot => (~"uint", DW_ATE_unsigned),
         ty::ty_bool => (~"bool", DW_ATE_boolean),
@@ -381,380 +245,272 @@ fn create_basic_type(cx: &mut CrateContext, t: ty::t, span: span)
         _ => cx.sess.bug("debuginfo::create_basic_type - t is invalid type")
     };
 
-    let fname = filename_from_span(cx, span);
-    let file_node = create_file(cx, fname.to_owned());
-    let cu_node = create_compile_unit(cx);
     let (size, align) = size_and_align_of(cx, t);
-    let lldata = ~[lltag(tg),
-                  cu_node.node,
-                  llstr(name),
-                  file_node.node,
-                  lli32(0), //XXX source line
-                  lli64(size * 8),  // size in bits
-                  lli64(align * 8), // alignment in bits
-                  lli64(0), //XXX offset?
-                  lli32(0), //XXX flags?
-                  lli32(encoding)];
-    let llnode = llmdnode(lldata);
-    let mdval = @Metadata {
-        node: llnode,
-        data: TyDescMetadata {
-            hash: ty::type_id(t)
-        }
-    };
-    update_cache(cache, tg, tydesc_metadata(mdval));
-    add_named_metadata(cx, ~"llvm.dbg.ty", llnode);
-    return mdval;
+    let ty_md = do as_c_str(name) |name| { unsafe {
+            llvm::LLVMDIBuilderCreateBasicType(
+                DIB(cx), name,
+                size * 8 as u64, align * 8 as u64, encoding as c_uint)
+        }};
+
+    dbg_cx(cx).created_types.insert(ty_id, ty_md);
+    return ty_md;
 }
 
-fn create_pointer_type(cx: &mut CrateContext, t: ty::t, span: span,
-                       pointee: @Metadata<TyDescMetadata>)
-    -> @Metadata<TyDescMetadata> {
-    let tg = PointerTypeTag;
-    /*let cache = cx.llmetadata;
-    match cached_metadata::<@Metadata<TyDescMetadata>>(
-        cache, tg, {|md| ty::hash_ty(t) == ty::hash_ty(md.data.hash)}) {
-      option::Some(md) { return md; }
-      option::None {}
-    }*/
+fn create_pointer_type(cx: @mut CrateContext, t: ty::t, _span: span, pointee: DIType) -> DIType {
     let (size, align) = size_and_align_of(cx, t);
-    let fname = filename_from_span(cx, span);
-    let file_node = create_file(cx, fname.to_owned());
-    //let cu_node = create_compile_unit(cx, fname);
     let name = ty_to_str(cx.tcx, t);
-    let llnode = create_derived_type(tg, file_node.node, name, 0, size * 8,
-                                     align * 8, 0, pointee.node);
-    let mdval = @Metadata {
-        node: llnode,
-        data: TyDescMetadata {
-            hash: ty::type_id(t)
-        }
-    };
-    //update_cache(cache, tg, tydesc_metadata(mdval));
-    add_named_metadata(cx, ~"llvm.dbg.ty", llnode);
-    return mdval;
-}
-
-struct StructCtxt {
-    file: ValueRef,
-    name: @str,
-    line: int,
-    members: ~[ValueRef],
-    total_size: int,
-    align: int
-}
+    let ptr_md = do as_c_str(name) |name| { unsafe {
+        llvm::LLVMDIBuilderCreatePointerType(DIB(cx),
+                pointee, size * 8 as u64, align * 8 as u64, name)
+    }};
+    return ptr_md;
+}
+
+struct StructContext {
+    builder: DIBuilderRef,
+    file: DIFile,
+    name: ~str,
+    line: uint,
+    members: ~[DIDerivedType],
+    total_size: uint,
+    align: uint
+}
+
+impl StructContext {
+    fn new(cx: &CrateContext, name: ~str, file: DIFile, line: uint) -> ~StructContext {
+        debug!("StructContext::create: %s", name);
+        let scx = ~StructContext {
+            builder: DIB(cx),
+            file: file,
+            name: name,
+            line: line,
+            members: ~[],
+            total_size: 0,
+            align: 1
+        };
+        return scx;
+    }
 
-fn finish_structure(cx: @mut StructCtxt) -> ValueRef {
-    return create_composite_type(StructureTypeTag,
-                                 cx.name,
-                                 cx.file,
-                                 cx.line,
-                                 cx.total_size,
-                                 cx.align,
-                                 0,
-                                 None,
-                                 Some(/*bad*/copy cx.members));
-}
+    fn add_member(&mut self, name: &str, line: uint, size: uint, align: uint, ty: DIType) {
+        debug!("StructContext(%s)::add_member: %s, size=%u, align=%u",
+                self.name, name, size, align);
+        let offset = roundup(self.total_size, align);
+        let mem_t = do as_c_str(name) |name| { unsafe {
+            llvm::LLVMDIBuilderCreateMemberType(
+                self.builder, ptr::null(), name, self.file, line as c_uint,
+                size * 8 as u64, align * 8 as u64, offset * 8 as u64,
+                0, ty)
+            }};
+        self.members.push(mem_t);
+        self.total_size = offset + size;
+        // struct alignment is the max alignment of its' members
+        self.align = cmp::max(self.align, align);
+    }
 
-fn create_structure(file: @Metadata<FileMetadata>, name: @str, line: int)
-                 -> @mut StructCtxt {
-    let cx = @mut StructCtxt {
-        file: file.node,
-        name: name,
-        line: line,
-        members: ~[],
-        total_size: 0,
-        align: 64 //XXX different alignment per arch?
-    };
-    return cx;
+    fn finalize(&self) -> DICompositeType {
+        debug!("StructContext(%s)::finalize: total_size=%u, align=%u",
+                self.name, self.total_size, self.align);
+        let members_md = create_DIArray(self.builder, self.members);
+
+        let struct_md =
+            do as_c_str(self.name) |name| { unsafe {
+                llvm::LLVMDIBuilderCreateStructType(
+                    self.builder, self.file, name,
+                    self.file, self.line as c_uint,
+                    self.total_size * 8 as u64, self.align * 8 as u64, 0, ptr::null(),
+                    members_md, 0, ptr::null())
+            }};
+        return struct_md;
+    }
 }
 
-fn create_derived_type(type_tag: int, file: ValueRef, name: &str, line: int,
-                       size: int, align: int, offset: int, ty: ValueRef)
-    -> ValueRef {
-    let lldata = ~[lltag(type_tag),
-                  file,
-                  llstr(name),
-                  file,
-                  lli32(line),
-                  lli64(size),
-                  lli64(align),
-                  lli64(offset),
-                  lli32(0),
-                  ty];
-    return llmdnode(lldata);
+#[inline]
+fn roundup(x: uint, a: uint) -> uint {
+    ((x + (a - 1)) / a) * a
 }
 
-fn add_member(cx: @mut StructCtxt,
-              name: &str,
-              line: int,
-              size: int,
-              align: int,
-              ty: ValueRef) {
-    cx.members.push(create_derived_type(MemberTag, cx.file, name, line,
-                                        size * 8, align * 8, cx.total_size,
-                                        ty));
-    cx.total_size += size * 8;
-}
+fn create_struct(cx: @mut CrateContext, t: ty::t, fields: ~[ty::field], span: span)
+                -> DICompositeType {
+    let loc = span_start(cx, span);
+    let file_md = create_file(cx, loc.file.name);
 
-fn create_struct(cx: &mut CrateContext, t: ty::t, fields: ~[ty::field],
-                 span: span) -> @Metadata<TyDescMetadata> {
-    let fname = filename_from_span(cx, span);
-    let file_node = create_file(cx, fname.to_owned());
-    let scx = create_structure(file_node, (ty_to_str(cx.tcx, t)).to_managed(),
-                               line_from_span(cx.sess.codemap, span) as int);
+    let mut scx = StructContext::new(cx, ty_to_str(cx.tcx, t), file_md, loc.line);
     for fields.each |field| {
         let field_t = field.mt.ty;
         let ty_md = create_ty(cx, field_t, span);
         let (size, align) = size_and_align_of(cx, field_t);
-        add_member(scx, cx.sess.str_of(field.ident),
-                   line_from_span(cx.sess.codemap, span) as int,
-                   size as int, align as int, ty_md.node);
+        scx.add_member(cx.sess.str_of(field.ident), loc.line, size, align, ty_md);
     }
-    let mdval = @Metadata {
-        node: finish_structure(scx),
-        data: TyDescMetadata {
-            hash: ty::type_id(t)
-        }
-    };
-    return mdval;
+    return scx.finalize();
 }
 
-fn create_tuple(cx: &mut CrateContext, t: ty::t, elements: &[ty::t], span: span)
-    -> @Metadata<TyDescMetadata> {
-    let fname = filename_from_span(cx, span);
-    let file_node = create_file(cx, fname.to_owned());
-    let scx = create_structure(file_node,
-                               cx.sess.str_of(
-                                   ((/*bad*/copy cx.dbg_cx).get().names)
-                                   ("tuple")),
-                               line_from_span(cx.sess.codemap, span) as int);
+// returns (void* type as a ValueRef, size in bytes, align in bytes)
+fn voidptr(cx: @mut CrateContext) -> (DIDerivedType, uint, uint) {
+    let size = sys::size_of::<ValueRef>();
+    let align = sys::min_align_of::<ValueRef>();
+    let vp = do as_c_str("*void") |name| { unsafe {
+            llvm::LLVMDIBuilderCreatePointerType(DIB(cx), ptr::null(),
+                size*8 as u64, align*8 as u64, name)
+        }};
+    return (vp, size, align);
+}
+
+fn create_tuple(cx: @mut CrateContext, _t: ty::t, elements: &[ty::t], span: span)
+                -> DICompositeType {
+    let loc = span_start(cx, span);
+    let file_md = create_file(cx, loc.file.name);
+
+    let name = (cx.sess.str_of((dbg_cx(cx).names)("tuple"))).to_owned();
+    let mut scx = StructContext::new(cx, name, file_md, loc.line);
     for elements.each |element| {
         let ty_md = create_ty(cx, *element, span);
         let (size, align) = size_and_align_of(cx, *element);
-        add_member(scx, "", line_from_span(cx.sess.codemap, span) as int,
-                   size as int, align as int, ty_md.node);
+        scx.add_member("", loc.line, size, align, ty_md);
     }
-    let mdval = @Metadata {
-        node: finish_structure(scx),
-        data: TyDescMetadata {
-            hash: ty::type_id(t)
-        }
-    };
-    return mdval;
+    return scx.finalize();
 }
 
-// returns (void* type as a ValueRef, size in bytes, align in bytes)
-fn voidptr() -> (ValueRef, int, int) {
-    let null = ptr::null();
-    let size = sys::size_of::<ValueRef>() as int;
-    let align = sys::min_align_of::<ValueRef>() as int;
-    let vp = create_derived_type(PointerTypeTag, null, "", 0,
-                                 size, align, 0, null);
-    return (vp, size, align);
-}
-
-fn create_boxed_type(cx: &mut CrateContext, contents: ty::t,
-                     span: span, boxed: @Metadata<TyDescMetadata>)
-    -> @Metadata<TyDescMetadata> {
-    //let tg = StructureTypeTag;
-    /*let cache = cx.llmetadata;
-    match cached_metadata::<@Metadata<TyDescMetadata>>(
-        cache, tg, {|md| ty::hash_ty(contents) == ty::hash_ty(md.data.hash)}) {
-      option::Some(md) { return md; }
-      option::None {}
-    }*/
-    let fname = filename_from_span(cx, span);
-    let file_node = create_file(cx, fname.to_owned());
-    //let cu_node = create_compile_unit_metadata(cx, fname);
+fn create_boxed_type(cx: @mut CrateContext, contents: ty::t,
+                     span: span, boxed: DIType) -> DICompositeType {
+    let loc = span_start(cx, span);
+    let file_md = create_file(cx, loc.file.name);
     let int_t = ty::mk_int();
     let refcount_type = create_basic_type(cx, int_t, span);
     let name = ty_to_str(cx.tcx, contents);
-    let scx = create_structure(file_node, (fmt!("box<%s>", name)).to_managed(), 0);
-    add_member(scx, "refcnt", 0, sys::size_of::<uint>() as int,
-               sys::min_align_of::<uint>() as int, refcount_type.node);
+
+    let mut scx = StructContext::new(cx, fmt!("box<%s>", name), file_md, 0);
+    scx.add_member("refcnt", 0, sys::size_of::<uint>(),
+               sys::min_align_of::<uint>(), refcount_type);
     // the tydesc and other pointers should be irrelevant to the
     // debugger, so treat them as void* types
-    let (vp, vpsize, vpalign) = voidptr();
-    add_member(scx, "tydesc", 0, vpsize, vpalign, vp);
-    add_member(scx, "prev", 0, vpsize, vpalign, vp);
-    add_member(scx, "next", 0, vpsize, vpalign, vp);
+    let (vp, vpsize, vpalign) = voidptr(cx);
+    scx.add_member("tydesc", 0, vpsize, vpalign, vp);
+    scx.add_member("prev", 0, vpsize, vpalign, vp);
+    scx.add_member("next", 0, vpsize, vpalign, vp);
     let (size, align) = size_and_align_of(cx, contents);
-    add_member(scx, "boxed", 0, size, align, boxed.node);
-    let llnode = finish_structure(scx);
-    let mdval = @Metadata {
-        node: llnode,
-        data: TyDescMetadata {
-            hash: ty::type_id(contents)
-        }
-    };
-    //update_cache(cache, tg, tydesc_metadata(mdval));
-    add_named_metadata(cx, ~"llvm.dbg.ty", llnode);
-    return mdval;
-}
-
-fn create_composite_type(type_tag: int, name: &str, file: ValueRef,
-                         line: int, size: int, align: int, offset: int,
-                         derived: Option<ValueRef>,
-                         members: Option<~[ValueRef]>)
-    -> ValueRef {
-    let lldata = ~[lltag(type_tag),
-                  file,
-                  llstr(name), // type name
-                  file, // source file definition
-                  lli32(line), // source line definition
-                  lli64(size), // size of members
-                  lli64(align), // align
-                  lli32/*64*/(offset), // offset
-                  lli32(0), // flags
-                  if derived.is_none() {
-                      llnull()
-                  } else { // derived from
-                      derived.get()
-                  },
-                  if members.is_none() {
-                      llnull()
-                  } else { //members
-                      llmdnode(members.get())
-                  },
-                  lli32(0),  // runtime language
-                  llnull()
-                 ];
-    return llmdnode(lldata);
+    scx.add_member("boxed", 0, size, align, boxed);
+    return scx.finalize();
 }
 
-fn create_fixed_vec(cx: &mut CrateContext, vec_t: ty::t, elem_t: ty::t,
-                    len: int, span: span) -> @Metadata<TyDescMetadata> {
-    let t_md = create_ty(cx, elem_t, span);
-    let fname = filename_from_span(cx, span);
-    let file_node = create_file(cx, fname.to_owned());
+fn create_fixed_vec(cx: @mut CrateContext, _vec_t: ty::t, elem_t: ty::t,
+                    len: uint, span: span) -> DIType {
+    let elem_ty_md = create_ty(cx, elem_t, span);
     let (size, align) = size_and_align_of(cx, elem_t);
-    let subrange = llmdnode([lltag(SubrangeTag), lli64(0), lli64(len - 1)]);
-    let name = fmt!("[%s]", ty_to_str(cx.tcx, elem_t));
-    let array = create_composite_type(ArrayTypeTag, name, file_node.node, 0,
-                                      size * len, align, 0, Some(t_md.node),
-                                      Some(~[subrange]));
-    @Metadata {
-        node: array,
-        data: TyDescMetadata {
-            hash: ty::type_id(vec_t)
-        }
-    }
+
+    let subrange = unsafe {
+        llvm::LLVMDIBuilderGetOrCreateSubrange(DIB(cx), 0_i64, len as i64)
+    };
+
+    let subscripts = create_DIArray(DIB(cx), [subrange]);
+    return unsafe {
+        llvm::LLVMDIBuilderCreateArrayType(DIB(cx),
+            size * len * 8 as u64, align * 8 as u64, elem_ty_md, subscripts)
+    };
 }
 
-fn create_boxed_vec(cx: &mut CrateContext, vec_t: ty::t, elem_t: ty::t,
-                    vec_ty_span: codemap::span)
-    -> @Metadata<TyDescMetadata> {
-    let fname = filename_from_span(cx, vec_ty_span);
-    let file_node = create_file(cx, fname.to_owned());
+fn create_boxed_vec(cx: @mut CrateContext, vec_t: ty::t, elem_t: ty::t,
+                    vec_ty_span: span) -> DICompositeType {
+    let loc = span_start(cx, vec_ty_span);
+    let file_md = create_file(cx, loc.file.name);
     let elem_ty_md = create_ty(cx, elem_t, vec_ty_span);
-    let vec_scx = create_structure(file_node,
-                               ty_to_str(cx.tcx, vec_t).to_managed(), 0);
+
+    let mut vec_scx = StructContext::new(cx, ty_to_str(cx.tcx, vec_t), file_md, 0);
     let size_t_type = create_basic_type(cx, ty::mk_uint(), vec_ty_span);
-    add_member(vec_scx, "fill", 0, sys::size_of::<libc::size_t>() as int,
-               sys::min_align_of::<libc::size_t>() as int, size_t_type.node);
-    add_member(vec_scx, "alloc", 0, sys::size_of::<libc::size_t>() as int,
-               sys::min_align_of::<libc::size_t>() as int, size_t_type.node);
-    let subrange = llmdnode([lltag(SubrangeTag), lli64(0), lli64(0)]);
+    vec_scx.add_member("fill", 0, sys::size_of::<libc::size_t>(),
+               sys::min_align_of::<libc::size_t>(), size_t_type);
+    vec_scx.add_member("alloc", 0, sys::size_of::<libc::size_t>(),
+               sys::min_align_of::<libc::size_t>(), size_t_type);
+    let subrange = unsafe {
+        llvm::LLVMDIBuilderGetOrCreateSubrange(DIB(cx), 0_i64, 0_i64)
+    };
     let (arr_size, arr_align) = size_and_align_of(cx, elem_t);
     let name = fmt!("[%s]", ty_to_str(cx.tcx, elem_t));
-    let data_ptr = create_composite_type(ArrayTypeTag, name, file_node.node, 0,
-                                         arr_size, arr_align, 0,
-                                         Some(elem_ty_md.node),
-                                         Some(~[subrange]));
-    add_member(vec_scx, "data", 0, 0, // clang says the size should be 0
-               sys::min_align_of::<u8>() as int, data_ptr);
-    let llnode = finish_structure(vec_scx);
-    let vec_md = @Metadata {
-        node: llnode,
-        data: TyDescMetadata {
-            hash: ty::type_id(vec_t)
-        }
+
+    let subscripts = create_DIArray(DIB(cx), [subrange]);
+    let data_ptr = unsafe {
+        llvm::LLVMDIBuilderCreateArrayType(DIB(cx),
+            arr_size * 8 as u64, arr_align * 8 as u64, elem_ty_md, subscripts)
     };
+    vec_scx.add_member("data", 0, 0, // clang says the size should be 0
+               sys::min_align_of::<u8>(), data_ptr);
+    let vec_md = vec_scx.finalize();
 
-    let box_scx = create_structure(file_node, (fmt!("box<%s>", name)).to_managed(), 0);
+    let mut box_scx = StructContext::new(cx, fmt!("box<%s>", name), file_md, 0);
     let int_t = ty::mk_int();
     let refcount_type = create_basic_type(cx, int_t, vec_ty_span);
-    add_member(box_scx, "refcnt", 0, sys::size_of::<uint>() as int,
-               sys::min_align_of::<uint>() as int, refcount_type.node);
-    let (vp, vpsize, vpalign) = voidptr();
-    add_member(box_scx, "tydesc", 0, vpsize, vpalign, vp);
-    add_member(box_scx, "prev", 0, vpsize, vpalign, vp);
-    add_member(box_scx, "next", 0, vpsize, vpalign, vp);
-    let size = 2 * sys::size_of::<int>() as int;
-    let align = sys::min_align_of::<int>() as int;
-    add_member(box_scx, "boxed", 0, size, align, vec_md.node);
-    let llnode = finish_structure(box_scx);
-    let mdval = @Metadata {
-        node: llnode,
-        data: TyDescMetadata {
-            hash: ty::type_id(elem_t)
-        }
-    };
+    box_scx.add_member("refcnt", 0, sys::size_of::<uint>(),
+               sys::min_align_of::<uint>(), refcount_type);
+    let (vp, vpsize, vpalign) = voidptr(cx);
+    box_scx.add_member("tydesc", 0, vpsize, vpalign, vp);
+    box_scx.add_member("prev", 0, vpsize, vpalign, vp);
+    box_scx.add_member("next", 0, vpsize, vpalign, vp);
+    let size = 2 * sys::size_of::<int>();
+    let align = sys::min_align_of::<int>();
+    box_scx.add_member("boxed", 0, size, align, vec_md);
+    let mdval = box_scx.finalize();
     return mdval;
 }
 
-fn create_vec_slice(cx: &mut CrateContext, vec_t: ty::t, elem_t: ty::t, span: span)
-    -> @Metadata<TyDescMetadata> {
-    let fname = filename_from_span(cx, span);
-    let file_node = create_file(cx, fname.to_owned());
+fn create_vec_slice(cx: @mut CrateContext, vec_t: ty::t, elem_t: ty::t, span: span)
+                    -> DICompositeType {
+    let loc = span_start(cx, span);
+    let file_md = create_file(cx, loc.file.name);
     let elem_ty_md = create_ty(cx, elem_t, span);
     let uint_type = create_basic_type(cx, ty::mk_uint(), span);
     let elem_ptr = create_pointer_type(cx, elem_t, span, elem_ty_md);
-    let scx = create_structure(file_node, ty_to_str(cx.tcx, vec_t).to_managed(), 0);
-    let (_, ptr_size, ptr_align) = voidptr();
-    add_member(scx, "vec", 0, ptr_size, ptr_align, elem_ptr.node);
-    add_member(scx, "length", 0, sys::size_of::<uint>() as int,
-               sys::min_align_of::<uint>() as int, uint_type.node);
-    let llnode = finish_structure(scx);
-    let mdval = @Metadata {
-        node: llnode,
-        data: TyDescMetadata {
-            hash: ty::type_id(vec_t)
-        }
-    };
-    return mdval;
+
+    let mut scx = StructContext::new(cx, ty_to_str(cx.tcx, vec_t), file_md, 0);
+    let (_, ptr_size, ptr_align) = voidptr(cx);
+    scx.add_member("vec", 0, ptr_size, ptr_align, elem_ptr);
+    scx.add_member("length", 0, sys::size_of::<uint>(),
+                    sys::min_align_of::<uint>(), uint_type);
+    return scx.finalize();
 }
 
-fn create_fn_ty(cx: &mut CrateContext, fn_ty: ty::t, inputs: ~[ty::t], output: ty::t,
-                span: span) -> @Metadata<TyDescMetadata> {
-    let fname = filename_from_span(cx, span);
-    let file_node = create_file(cx, fname.to_owned());
-    let (vp, _, _) = voidptr();
+fn create_fn_ty(cx: @mut CrateContext, _fn_ty: ty::t, inputs: ~[ty::t], output: ty::t,
+                span: span) -> DICompositeType {
+    let loc = span_start(cx, span);
+    let file_md = create_file(cx, loc.file.name);
+    let (vp, _, _) = voidptr(cx);
     let output_md = create_ty(cx, output, span);
     let output_ptr_md = create_pointer_type(cx, output, span, output_md);
-    let inputs_vals = do inputs.map |arg| { create_ty(cx, *arg, span).node };
-    let members = ~[output_ptr_md.node, vp] + inputs_vals;
-    let llnode = create_composite_type(SubroutineTag, "", file_node.node,
-                                       0, 0, 0, 0, None, Some(members));
-    let mdval = @Metadata {
-        node: llnode,
-        data: TyDescMetadata {
-            hash: ty::type_id(fn_ty)
-        }
+    let inputs_vals = do inputs.map |arg| { create_ty(cx, *arg, span) };
+    let members = ~[output_ptr_md, vp] + inputs_vals;
+
+    return unsafe {
+        llvm::LLVMDIBuilderCreateSubroutineType(DIB(cx), file_md,
+            create_DIArray(DIB(cx), members))
     };
-    return mdval;
 }
 
-fn create_ty(cx: &mut CrateContext, t: ty::t, span: span)
-    -> @Metadata<TyDescMetadata> {
+fn create_unimpl_ty(cx: @mut CrateContext, t: ty::t) -> DIType {
+    let name = ty_to_str(cx.tcx, t);
+    let md = do as_c_str(fmt!("NYI<%s>", name)) |name| { unsafe {
+        llvm::LLVMDIBuilderCreateBasicType(
+            DIB(cx), name,
+            0_u64, 8_u64, DW_ATE_unsigned as c_uint)
+        }};
+    return md;
+}
+
+fn create_ty(cx: @mut CrateContext, t: ty::t, span: span) -> DIType {
+    let ty_id = ty::type_id(t);
+    match dbg_cx(cx).created_types.find(&ty_id) {
+        Some(ty_md) => return *ty_md,
+        None => ()
+    }
+
     debug!("create_ty: %?", ty::get(t));
-    /*let cache = get_cache(cx);
-    match cached_metadata::<@Metadata<TyDescMetadata>>(
-        cache, tg, {|md| t == md.data.hash}) {
-      option::Some(md) { return md; }
-      option::None {}
-    }*/
 
     let sty = copy ty::get(t).sty;
-    match sty {
+    let ty_md = match sty {
         ty::ty_nil | ty::ty_bot | ty::ty_bool | ty::ty_int(_) | ty::ty_uint(_)
         | ty::ty_float(_) => create_basic_type(cx, t, span),
         ty::ty_estr(ref vstore) => {
             let i8_t = ty::mk_i8();
             match *vstore {
                 ty::vstore_fixed(len) => {
-                    create_fixed_vec(cx, t, i8_t, len as int + 1, span)
+                    create_fixed_vec(cx, t, i8_t, len + 1, span)
                 },
                 ty::vstore_uniq | ty::vstore_box => {
                     let box_md = create_boxed_vec(cx, t, i8_t, span);
@@ -766,7 +522,8 @@ fn create_ty(cx: &mut CrateContext, t: ty::t, span: span)
             }
         },
         ty::ty_enum(_did, ref _substs) => {
-            cx.sess.span_bug(span, "debuginfo for enum NYI")
+            cx.sess.span_note(span, "debuginfo for enum NYI");
+            create_unimpl_ty(cx, t)
         }
         ty::ty_box(ref mt) | ty::ty_uniq(ref mt) => {
             let boxed = create_ty(cx, mt.ty, span);
@@ -776,7 +533,7 @@ fn create_ty(cx: &mut CrateContext, t: ty::t, span: span)
         ty::ty_evec(ref mt, ref vstore) => {
             match *vstore {
                 ty::vstore_fixed(len) => {
-                    create_fixed_vec(cx, t, mt.ty, len as int, span)
+                    create_fixed_vec(cx, t, mt.ty, len, span)
                 },
                 ty::vstore_uniq | ty::vstore_box => {
                     let box_md = create_boxed_vec(cx, t, mt.ty, span);
@@ -792,7 +549,8 @@ fn create_ty(cx: &mut CrateContext, t: ty::t, span: span)
             create_pointer_type(cx, t, span, pointee)
         },
         ty::ty_rptr(ref _region, ref _mt) => {
-            cx.sess.span_bug(span, "debuginfo for rptr NYI")
+            cx.sess.span_note(span, "debuginfo for rptr NYI");
+            create_unimpl_ty(cx, t)
         },
         ty::ty_bare_fn(ref barefnty) => {
             let inputs = barefnty.sig.inputs.map(|a| *a);
@@ -800,10 +558,12 @@ fn create_ty(cx: &mut CrateContext, t: ty::t, span: span)
             create_fn_ty(cx, t, inputs, output, span)
         },
         ty::ty_closure(ref _closurety) => {
-            cx.sess.span_bug(span, "debuginfo for closure NYI")
+            cx.sess.span_note(span, "debuginfo for closure NYI");
+            create_unimpl_ty(cx, t)
         },
         ty::ty_trait(_did, ref _substs, ref _vstore, _) => {
-            cx.sess.span_bug(span, "debuginfo for trait NYI")
+            cx.sess.span_note(span, "debuginfo for trait NYI");
+            create_unimpl_ty(cx, t)
         },
         ty::ty_struct(did, ref substs) => {
             let fields = ty::struct_fields(cx.tcx, did, substs);
@@ -813,59 +573,41 @@ fn create_ty(cx: &mut CrateContext, t: ty::t, span: span)
             create_tuple(cx, t, *elements, span)
         },
         _ => cx.sess.bug("debuginfo: unexpected type in create_ty")
-    }
-}
-
-fn filename_from_span(cx: &CrateContext, sp: codemap::span) -> @str {
-    cx.sess.codemap.lookup_char_pos(sp.lo).file.name
-}
+    };
 
-fn create_var(type_tag: int, context: ValueRef, name: &str, file: ValueRef,
-              line: int, ret_ty: ValueRef) -> ValueRef {
-    let lldata = ~[lltag(type_tag),
-                  context,
-                  llstr(name),
-                  file,
-                  lli32(line),
-                  ret_ty,
-                  lli32(0)
-                 ];
-    return llmdnode(lldata);
+    dbg_cx(cx).created_types.insert(ty_id, ty_md);
+    return ty_md;
 }
 
-pub fn create_local_var(bcx: block, local: @ast::local)
-    -> @Metadata<LocalVarMetadata> {
+pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable {
     let cx = bcx.ccx();
-    let cache = get_cache(cx);
-    let tg = AutoVariableTag;
-    match cached_metadata::<@Metadata<LocalVarMetadata>>(
-        cache, tg, |md| md.data.id == local.node.id) {
-      option::Some(md) => return md,
-      option::None => ()
-    }
 
-    let name = match local.node.pat.node {
+    let ident = match local.node.pat.node {
       ast::pat_ident(_, pth, _) => ast_util::path_to_ident(pth),
       // FIXME this should be handled (#2533)
-      _ => fail!("no single variable name for local")
+      _ => {
+        bcx.sess().span_note(local.span, "debuginfo for pattern bindings NYI");
+        return ptr::null();
+      }
     };
-    let loc = cx.sess.codemap.lookup_char_pos(local.span.lo);
+    let name: &str = cx.sess.str_of(ident);
+    debug!("create_local_var: %s", name);
+
+    let loc = span_start(cx, local.span);
     let ty = node_id_type(bcx, local.node.id);
     let tymd = create_ty(cx, ty, local.node.ty.span);
-    let filemd = create_file(cx, /*bad*/ loc.file.name.to_owned());
+    let filemd = create_file(cx, loc.file.name);
     let context = match bcx.parent {
-        None => create_function(bcx.fcx).node,
-        Some(_) => create_block(bcx).node
+        None => create_function(bcx.fcx),
+        Some(_) => create_block(bcx)
     };
-    let mdnode = create_var(tg, context, cx.sess.str_of(name),
-                            filemd.node, loc.line as int, tymd.node);
-    let mdval = @Metadata {
-        node: mdnode,
-        data: LocalVarMetadata {
-            id: local.node.id
-        }
-    };
-    update_cache(cache, AutoVariableTag, local_var_metadata(mdval));
+
+    let var_md = do as_c_str(name) |name| { unsafe {
+        llvm::LLVMDIBuilderCreateLocalVariable(
+            DIB(cx), AutoVariableTag as u32,
+            context, name, filemd,
+            loc.line as c_uint, tymd, false, 0, 0)
+        }};
 
     // FIXME(#6814) Should use `pat_util::pat_bindings` for pats like (a, b) etc
     let llptr = match bcx.fcx.lllocals.find_copy(&local.node.pat.id) {
@@ -876,59 +618,57 @@ pub fn create_local_var(bcx: block, local: @ast::local)
                 fmt!("No entry in lllocals table for %?", local.node.id));
         }
     };
-    let declargs = ~[llmdnode([llptr]), mdnode];
-    trans::build::Call(bcx, cx.intrinsics.get_copy(&("llvm.dbg.declare")),
-                       declargs);
-    return mdval;
+
+    set_debug_location(cx, create_block(bcx), loc.line, loc.col.to_uint());
+    unsafe {
+        let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(DIB(cx), llptr, var_md, bcx.llbb);
+        llvm::LLVMSetInstDebugLocation(trans::build::B(bcx), instr);
+    }
+
+    return var_md;
 }
 
-pub fn create_arg(bcx: block, arg: ast::arg, sp: span)
-    -> Option<@Metadata<ArgumentMetadata>> {
+pub fn create_arg(bcx: block, arg: ast::arg, span: span) -> Option<DIVariable> {
+    debug!("create_arg");
+    if true {
+        // XXX create_arg disabled for now because "node_id_type(bcx, arg.id)" below blows
+        // up: "error: internal compiler error: node_id_to_type: no type for node `arg (id=10)`"
+        return None;
+    }
+
     let fcx = bcx.fcx;
     let cx = fcx.ccx;
-    let cache = get_cache(cx);
-    let tg = ArgVariableTag;
-    match cached_metadata::<@Metadata<ArgumentMetadata>>(
-        cache, ArgVariableTag, |md| md.data.id == arg.id) {
-      option::Some(md) => return Some(md),
-      option::None => ()
-    }
 
-    let loc = cx.sess.codemap.lookup_char_pos(sp.lo);
+    let loc = span_start(cx, span);
     if "<intrinsic>" == loc.file.name {
         return None;
     }
+
     let ty = node_id_type(bcx, arg.id);
     let tymd = create_ty(cx, ty, arg.ty.span);
-    let filemd = create_file(cx, /* bad */ loc.file.name.to_owned());
-    let context = create_function(bcx.fcx);
+    let filemd = create_file(cx, loc.file.name);
+    let context = create_function(fcx);
 
     match arg.pat.node {
         ast::pat_ident(_, path, _) => {
             // XXX: This is wrong; it should work for multiple bindings.
-            let mdnode = create_var(
-                tg,
-                context.node,
-                cx.sess.str_of(*path.idents.last()),
-                filemd.node,
-                loc.line as int,
-                tymd.node
-            );
-
-            let mdval = @Metadata {
-                node: mdnode,
-                data: ArgumentMetadata {
-                    id: arg.id
-                }
-            };
-            update_cache(cache, tg, argument_metadata(mdval));
+            let ident = path.idents.last();
+            let name: &str = cx.sess.str_of(*ident);
+            let mdnode = do as_c_str(name) |name| { unsafe {
+                llvm::LLVMDIBuilderCreateLocalVariable(DIB(cx),
+                    ArgVariableTag as u32, context, name,
+                    filemd, loc.line as c_uint, tymd, false, 0, 0)
+                    // XXX need to pass in a real argument number
+            }};
 
             let llptr = fcx.llargs.get_copy(&arg.id);
-            let declargs = ~[llmdnode([llptr]), mdnode];
-            trans::build::Call(bcx,
-                               cx.intrinsics.get_copy(&("llvm.dbg.declare")),
-                               declargs);
-            return Some(mdval);
+            set_debug_location(cx, create_block(bcx), loc.line, loc.col.to_uint());
+            unsafe {
+                let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(
+                        DIB(cx), llptr, mdnode, bcx.llbb);
+                llvm::LLVMSetInstDebugLocation(trans::build::B(bcx), instr);
+            }
+            return Some(mdnode);
         }
         _ => {
             return None;
@@ -936,32 +676,36 @@ pub fn create_arg(bcx: block, arg: ast::arg, sp: span)
     }
 }
 
-pub fn update_source_pos(cx: block, s: span) {
-    if !cx.sess().opts.debuginfo || (*s.lo == 0 && *s.hi == 0) {
+fn set_debug_location(cx: @mut CrateContext, scope: DIScope, line: uint, col: uint) {
+    if dbg_cx(cx).curr_loc == (line, col) {
         return;
     }
-    let cm = cx.sess().codemap;
-    let blockmd = create_block(cx);
-    let loc = cm.lookup_char_pos(s.lo);
-    let scopedata = ~[lli32(loc.line.to_int()),
-                     lli32(loc.col.to_int()),
-                     blockmd.node,
-                     llnull()];
-    let dbgscope = llmdnode(scopedata);
+    debug!("setting debug location to %u %u", line, col);
+    dbg_cx(cx).curr_loc = (line, col);
+
+    let elems = ~[C_i32(line as i32), C_i32(col as i32), scope, ptr::null()];
     unsafe {
-        llvm::LLVMSetCurrentDebugLocation(trans::build::B(cx), dbgscope);
+        let dbg_loc = llvm::LLVMMDNodeInContext(
+                dbg_cx(cx).llcontext, vec::raw::to_ptr(elems),
+                elems.len() as libc::c_uint);
+        llvm::LLVMSetCurrentDebugLocation(cx.builder.B, dbg_loc);
     }
 }
 
-pub fn create_function(fcx: fn_ctxt) -> @Metadata<SubProgramMetadata> {
-    let mut cx = fcx.ccx;
-
-    debug!("~~");
+/// Set current debug location at the beginning of the span
+pub fn update_source_pos(bcx: block, span: span) {
+    if !bcx.sess().opts.debuginfo || (*span.lo == 0 && *span.hi == 0) {
+        return;
+    }
+    debug!("update_source_pos: %s", bcx.sess().codemap.span_to_str(span));
+    let loc = span_start(bcx.ccx(), span);
+    set_debug_location(bcx.ccx(), create_block(bcx), loc.line, loc.col.to_uint())
+}
 
+pub fn create_function(fcx: fn_ctxt) -> DISubprogram {
+    let cx = fcx.ccx;
     let fcx = &mut *fcx;
-
-    let sp = fcx.span.get();
-    debug!("%s", cx.sess.codemap.span_to_str(sp));
+    let span = fcx.span.get();
 
     let (ident, ret_ty, id) = match cx.tcx.items.get_copy(&fcx.id) {
       ast_map::node_item(item, _) => {
@@ -978,8 +722,7 @@ pub fn create_function(fcx: fn_ctxt) -> @Metadata<SubProgramMetadata> {
       ast_map::node_expr(expr) => {
         match expr.node {
           ast::expr_fn_block(ref decl, _) => {
-            let dbg_cx = cx.dbg_cx.get_ref();
-            ((dbg_cx.names)("fn"), decl.output, expr.id)
+            ((dbg_cx(cx).names)("fn"), decl.output, expr.id)
           }
           _ => fcx.ccx.sess.span_bug(expr.span,
                   "create_function: expected an expr_fn_block here")
@@ -988,62 +731,46 @@ pub fn create_function(fcx: fn_ctxt) -> @Metadata<SubProgramMetadata> {
       _ => fcx.ccx.sess.bug("create_function: unexpected sort of node")
     };
 
-    debug!("%?", ident);
-    debug!("%?", id);
-
-    let cache = get_cache(cx);
-    match cached_metadata::<@Metadata<SubProgramMetadata>>(
-        cache, SubprogramTag, |md| md.data.id == id) {
-      option::Some(md) => return md,
-      option::None => ()
+    match dbg_cx(cx).created_functions.find(&id) {
+        Some(fn_md) => return *fn_md,
+        None => ()
     }
 
-    let loc = cx.sess.codemap.lookup_char_pos(sp.lo);
-    let file_node = create_file(cx, loc.file.name.to_owned()).node;
-    let ty_node = if cx.sess.opts.extra_debuginfo {
+    debug!("create_function: %s, %s", cx.sess.str_of(ident), cx.sess.codemap.span_to_str(span));
+
+    let loc = span_start(cx, span);
+    let file_md = create_file(cx, loc.file.name);
+
+    let ret_ty_md = if cx.sess.opts.extra_debuginfo {
         match ret_ty.node {
-          ast::ty_nil => llnull(),
+          ast::ty_nil => ptr::null(),
           _ => create_ty(cx, ty::node_id_to_type(cx.tcx, id),
-                         ret_ty.span).node
+                         ret_ty.span)
         }
     } else {
-        llnull()
+        ptr::null()
     };
-    let sub_node = create_composite_type(SubroutineTag, "", file_node, 0, 0,
-                                         0, 0, option::None,
-                                         option::Some(~[ty_node]));
-
-    let fn_metadata = ~[lltag(SubprogramTag),
-                       llunused(),
-                       file_node,
-                       llstr(cx.sess.str_of(ident)),
-                        //XXX fully-qualified C++ name:
-                       llstr(cx.sess.str_of(ident)),
-                       llstr(""), //XXX MIPS name?????
-                       file_node,
-                       lli32(loc.line as int),
-                       sub_node,
-                       lli1(false), //XXX static (check export)
-                       lli1(true), // defined in compilation unit
-                       lli32(DW_VIRTUALITY_none), // virtual-ness
-                       lli32(0i), //index into virt func
-                       /*llnull()*/ lli32(0), // base type with vtbl
-                       lli32(256), // flags
-                       lli1(cx.sess.opts.optimize != session::No),
-                       fcx.llfn
-                       //list of template params
-                       //func decl descriptor
-                       //list of func vars
-                      ];
-    let val = llmdnode(fn_metadata);
-    add_named_metadata(cx, ~"llvm.dbg.sp", val);
-    let mdval = @Metadata {
-        node: val,
-        data: SubProgramMetadata {
-            id: id
-        }
+
+    let fn_ty = unsafe {
+        llvm::LLVMDIBuilderCreateSubroutineType(DIB(cx),
+            file_md, create_DIArray(DIB(cx), [ret_ty_md]))
     };
-    update_cache(cache, SubprogramTag, subprogram_metadata(mdval));
 
-    return mdval;
+    let fn_md =
+        do as_c_str(cx.sess.str_of(ident)) |name| {
+        do as_c_str(cx.sess.str_of(ident)) |linkage| { unsafe {
+            llvm::LLVMDIBuilderCreateFunction(
+                DIB(cx),
+                file_md,
+                name, linkage,
+                file_md, loc.line as c_uint,
+                fn_ty, false, true,
+                loc.line as c_uint,
+                FlagPrototyped as c_uint,
+                cx.sess.opts.optimize != session::No,
+                fcx.llfn, ptr::null(), ptr::null())
+            }}};
+
+    dbg_cx(cx).created_functions.insert(id, fn_md);
+    return fn_md;
 }
diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs
index 3c43e8535f4..05461c93631 100644
--- a/src/librustc/middle/trans/glue.rs
+++ b/src/librustc/middle/trans/glue.rs
@@ -103,7 +103,7 @@ pub fn drop_ty_immediate(bcx: block, v: ValueRef, t: ty::t) -> block {
       ty::ty_box(_) | ty::ty_opaque_box |
       ty::ty_evec(_, ty::vstore_box) |
       ty::ty_estr(ty::vstore_box) => {
-        decr_refcnt_maybe_free(bcx, v, t)
+        decr_refcnt_maybe_free(bcx, v, None, t)
       }
       _ => bcx.tcx().sess.bug("drop_ty_immediate: non-box ty")
     }
@@ -419,15 +419,6 @@ pub fn make_free_glue(bcx: block, v: ValueRef, t: ty::t) {
       ty::ty_opaque_closure_ptr(ck) => {
         closure::make_opaque_cbox_free_glue(bcx, ck, v)
       }
-      ty::ty_struct(did, ref substs) => {
-        // Call the dtor if there is one
-        match ty::ty_dtor(bcx.tcx(), did) {
-            ty::NoDtor => bcx,
-            ty::TraitDtor(ref dt_id) => {
-                trans_struct_drop(bcx, t, v, *dt_id, did, substs)
-            }
-        }
-      }
       _ => bcx
     };
     build_return(bcx);
@@ -489,7 +480,7 @@ pub fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) {
     let bcx = match ty::get(t).sty {
       ty::ty_box(_) | ty::ty_opaque_box |
       ty::ty_estr(ty::vstore_box) | ty::ty_evec(_, ty::vstore_box) => {
-        decr_refcnt_maybe_free(bcx, Load(bcx, v0), t)
+        decr_refcnt_maybe_free(bcx, Load(bcx, v0), Some(v0), t)
       }
       ty::ty_uniq(_) |
       ty::ty_evec(_, ty::vstore_uniq) | ty::ty_estr(ty::vstore_uniq) => {
@@ -514,8 +505,10 @@ pub fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) {
         closure::make_closure_glue(bcx, v0, t, drop_ty)
       }
       ty::ty_trait(_, _, ty::BoxTraitStore, _) => {
-        let llbox = Load(bcx, GEPi(bcx, v0, [0u, abi::trt_field_box]));
-        decr_refcnt_maybe_free(bcx, llbox, ty::mk_opaque_box(ccx.tcx))
+          let llbox_ptr = GEPi(bcx, v0, [0u, abi::trt_field_box]);
+          let llbox = Load(bcx, llbox_ptr);
+          decr_refcnt_maybe_free(bcx, llbox, Some(llbox_ptr),
+                                 ty::mk_opaque_box(ccx.tcx))
       }
       ty::ty_trait(_, _, ty::UniqTraitStore, _) => {
           let lluniquevalue = GEPi(bcx, v0, [0, abi::trt_field_box]);
@@ -549,7 +542,10 @@ pub fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) {
     build_return(bcx);
 }
 
-pub fn decr_refcnt_maybe_free(bcx: block, box_ptr: ValueRef, t: ty::t)
+// box_ptr_ptr is optional, it is constructed if not supplied.
+pub fn decr_refcnt_maybe_free(bcx: block, box_ptr: ValueRef,
+                              box_ptr_ptr: Option<ValueRef>,
+                              t: ty::t)
                            -> block {
     let _icx = bcx.insn_ctxt("decr_refcnt_maybe_free");
     let ccx = bcx.ccx();
@@ -559,7 +555,12 @@ pub fn decr_refcnt_maybe_free(bcx: block, box_ptr: ValueRef, t: ty::t)
         let rc = Sub(bcx, Load(bcx, rc_ptr), C_int(ccx, 1));
         Store(bcx, rc, rc_ptr);
         let zero_test = ICmp(bcx, lib::llvm::IntEQ, C_int(ccx, 0), rc);
-        with_cond(bcx, zero_test, |bcx| free_ty_immediate(bcx, box_ptr, t))
+        do with_cond(bcx, zero_test) |bcx| {
+            match box_ptr_ptr {
+                Some(p) => free_ty(bcx, p, t),
+                None => free_ty_immediate(bcx, box_ptr, t)
+            }
+        }
     }
 }
 
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index b54f362c7d2..4fc431e0a54 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -1094,62 +1094,62 @@ fn mk_t(cx: ctxt, st: sty) -> t {
     }
 }
 
-#[inline(always)]
+#[inline]
 pub fn mk_prim_t(primitive: &'static t_box_) -> t {
     unsafe {
         cast::transmute::<&'static t_box_, t>(primitive)
     }
 }
 
-#[inline(always)]
+#[inline]
 pub fn mk_nil() -> t { mk_prim_t(&primitives::TY_NIL) }
 
-#[inline(always)]
+#[inline]
 pub fn mk_err() -> t { mk_prim_t(&primitives::TY_ERR) }
 
-#[inline(always)]
+#[inline]
 pub fn mk_bot() -> t { mk_prim_t(&primitives::TY_BOT) }
 
-#[inline(always)]
+#[inline]
 pub fn mk_bool() -> t { mk_prim_t(&primitives::TY_BOOL) }
 
-#[inline(always)]
+#[inline]
 pub fn mk_int() -> t { mk_prim_t(&primitives::TY_INT) }
 
-#[inline(always)]
+#[inline]
 pub fn mk_i8() -> t { mk_prim_t(&primitives::TY_I8) }
 
-#[inline(always)]
+#[inline]
 pub fn mk_i16() -> t { mk_prim_t(&primitives::TY_I16) }
 
-#[inline(always)]
+#[inline]
 pub fn mk_i32() -> t { mk_prim_t(&primitives::TY_I32) }
 
-#[inline(always)]
+#[inline]
 pub fn mk_i64() -> t { mk_prim_t(&primitives::TY_I64) }
 
-#[inline(always)]
+#[inline]
 pub fn mk_float() -> t { mk_prim_t(&primitives::TY_FLOAT) }
 
-#[inline(always)]
+#[inline]
 pub fn mk_f32() -> t { mk_prim_t(&primitives::TY_F32) }
 
-#[inline(always)]
+#[inline]
 pub fn mk_f64() -> t { mk_prim_t(&primitives::TY_F64) }
 
-#[inline(always)]
+#[inline]
 pub fn mk_uint() -> t { mk_prim_t(&primitives::TY_UINT) }
 
-#[inline(always)]
+#[inline]
 pub fn mk_u8() -> t { mk_prim_t(&primitives::TY_U8) }
 
-#[inline(always)]
+#[inline]
 pub fn mk_u16() -> t { mk_prim_t(&primitives::TY_U16) }
 
-#[inline(always)]
+#[inline]
 pub fn mk_u32() -> t { mk_prim_t(&primitives::TY_U32) }
 
-#[inline(always)]
+#[inline]
 pub fn mk_u64() -> t { mk_prim_t(&primitives::TY_U64) }
 
 pub fn mk_mach_int(tm: ast::int_ty) -> t {
@@ -1181,7 +1181,7 @@ pub fn mk_mach_float(tm: ast::float_ty) -> t {
     }
 }
 
-#[inline(always)]
+#[inline]
 pub fn mk_char() -> t { mk_prim_t(&primitives::TY_CHAR) }
 
 pub fn mk_estr(cx: ctxt, t: vstore) -> t {
@@ -2273,7 +2273,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
         for type_param_def.bounds.builtin_bounds.each |bound| {
             debug!("tc = %s, bound = %?", tc.to_str(), bound);
             tc = tc - match bound {
-                BoundCopy => TypeContents::nonimplicitly_copyable(cx),
+                BoundCopy => TypeContents::noncopyable(cx),
                 BoundStatic => TypeContents::nonstatic(cx),
                 BoundOwned => TypeContents::nonowned(cx),
                 BoundConst => TypeContents::nonconst(cx),
@@ -3694,7 +3694,7 @@ fn lookup_locally_or_in_crate_store<V:Copy>(
      */
 
     match map.find(&def_id) {
-        Some(&v) => { return v; }
+        Some(&ref v) => { return copy *v; }
         None => { }
     }
 
@@ -3702,8 +3702,8 @@ fn lookup_locally_or_in_crate_store<V:Copy>(
         fail!("No def'n found for %? in tcx.%s", def_id, descr);
     }
     let v = load_external();
-    map.insert(def_id, v);
-    return v;
+    map.insert(def_id, copy v);
+    return copy v;
 }
 
 pub fn trait_method(cx: ctxt, trait_did: ast::def_id, idx: uint) -> @Method {
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index ea41dff99b8..12b413bc5af 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -725,7 +725,7 @@ impl FnCtxt {
         ty::re_scope(self.region_lb)
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn write_ty(&self, node_id: ast::node_id, ty: ty::t) {
         debug!("write_ty(%d, %s) in fcx %s",
                node_id, ppaux::ty_to_str(self.tcx(), ty), self.tag());
diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs
index 99e68e3330b..197bf5d82cc 100644
--- a/src/librustc/middle/typeck/check/vtable.rs
+++ b/src/librustc/middle/typeck/check/vtable.rs
@@ -10,7 +10,6 @@
 
 use core::prelude::*;
 
-use middle::resolve::Impl;
 use middle::ty::param_ty;
 use middle::ty;
 use middle::typeck::check::{FnCtxt, impl_self_ty};
@@ -27,7 +26,6 @@ use util::ppaux;
 
 use core::hashmap::HashSet;
 use core::result;
-use core::uint;
 use syntax::ast;
 use syntax::ast_util;
 use syntax::codemap::span;
@@ -248,16 +246,9 @@ fn lookup_vtable(vcx: &VtableContext,
                     // Nothing found. Continue.
                 }
                 Some(implementations) => {
-                    let len = { // FIXME(#5074): stage0 requires it
-                        let implementations: &mut ~[@Impl] = *implementations;
-                        implementations.len()
-                    };
-
                     // implementations is the list of all impls in scope for
                     // trait_ref. (Usually, there's just one.)
-                    for uint::range(0, len) |i| {
-                        let im = implementations[i];
-
+                    for implementations.iter().advance |im| {
                         // im is one specific impl of trait_ref.
 
                         // First, ensure we haven't processed this impl yet.
diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs
index 9528c825fbe..d71820a67b3 100644
--- a/src/librustc/middle/typeck/coherence.rs
+++ b/src/librustc/middle/typeck/coherence.rs
@@ -520,12 +520,8 @@ impl CoherenceChecker {
 
         match extension_methods.find(&trait_def_id) {
             Some(impls) => {
-                let len = { // FIXME(#5074) stage0 requires this
-                    let impls: &mut ~[@Impl] = *impls;
-                    impls.len()
-                };
-                for uint::range(0, len) |i| {
-                    f(impls[i]);
+                for impls.iter().advance |&im| {
+                    f(im);
                 }
             }
             None => { /* no impls? */ }
diff --git a/src/librustc/middle/typeck/infer/lattice.rs b/src/librustc/middle/typeck/infer/lattice.rs
index 820bb2f86b0..7a3230079ee 100644
--- a/src/librustc/middle/typeck/infer/lattice.rs
+++ b/src/librustc/middle/typeck/infer/lattice.rs
@@ -89,10 +89,10 @@ impl CombineFields {
         // Need to make sub_id a subtype of sup_id.
         let node_a = self.infcx.get(a_id);
         let node_b = self.infcx.get(b_id);
-        let a_id = node_a.root;
-        let b_id = node_b.root;
-        let a_bounds = node_a.possible_types;
-        let b_bounds = node_b.possible_types;
+        let a_id = copy node_a.root;
+        let b_id = copy node_b.root;
+        let a_bounds = copy node_a.possible_types;
+        let b_bounds = copy node_b.possible_types;
 
         debug!("vars(%s=%s <: %s=%s)",
                a_id.to_str(), a_bounds.inf_str(self.infcx),
@@ -102,8 +102,8 @@ impl CombineFields {
 
         // If both A's UB and B's LB have already been bound to types,
         // see if we can make those types subtypes.
-        match (a_bounds.ub, b_bounds.lb) {
-            (Some(ref a_ub), Some(ref b_lb)) => {
+        match (&a_bounds.ub, &b_bounds.lb) {
+            (&Some(ref a_ub), &Some(ref b_lb)) => {
                 let r = self.infcx.try(
                     || LatticeValue::sub(self, a_ub, b_lb));
                 match r {
@@ -138,9 +138,9 @@ impl CombineFields {
          * Make a variable (`a_id`) a subtype of the concrete type `b` */
 
         let node_a = self.infcx.get(a_id);
-        let a_id = node_a.root;
+        let a_id = copy node_a.root;
         let a_bounds = &node_a.possible_types;
-        let b_bounds = &Bounds { lb: None, ub: Some(b) };
+        let b_bounds = &Bounds { lb: None, ub: Some(copy b) };
 
         debug!("var_sub_t(%s=%s <: %s)",
                a_id.to_str(),
@@ -161,9 +161,9 @@ impl CombineFields {
          *
          * Make a concrete type (`a`) a subtype of the variable `b_id` */
 
-        let a_bounds = &Bounds { lb: Some(a), ub: None };
+        let a_bounds = &Bounds { lb: Some(copy a), ub: None };
         let node_b = self.infcx.get(b_id);
-        let b_id = node_b.root;
+        let b_id = copy node_b.root;
         let b_bounds = &node_b.possible_types;
 
         debug!("t_sub_var(%s <: %s=%s)",
@@ -190,11 +190,11 @@ impl CombineFields {
                b.inf_str(self.infcx));
         let _r = indenter();
 
-        match (*a, *b) {
-            (None,          None) => Ok(None),
-            (Some(_),       None) => Ok(*a),
-            (None,          Some(_)) => Ok(*b),
-            (Some(ref v_a), Some(ref v_b)) => {
+        match (a, b) {
+            (&None,          &None) => Ok(None),
+            (&Some(_),       &None) => Ok(copy *a),
+            (&None,          &Some(_)) => Ok(copy *b),
+            (&Some(ref v_a), &Some(ref v_b)) => {
                 do lattice_op(self, v_a, v_b).chain |v| {
                     Ok(Some(v))
                 }
@@ -272,13 +272,13 @@ impl CombineFields {
                b.inf_str(self.infcx));
         let _r = indenter();
 
-        match (*a, *b) {
-            (None, None) |
-            (Some(_), None) |
-            (None, Some(_)) => {
+        match (a, b) {
+            (&None, &None) |
+            (&Some(_), &None) |
+            (&None, &Some(_)) => {
                 uok()
             }
-            (Some(ref t_a), Some(ref t_b)) => {
+            (&Some(ref t_a), &Some(ref t_b)) => {
                 LatticeValue::sub(self, t_a, t_b)
             }
         }
@@ -303,9 +303,9 @@ pub trait TyLatticeDir {
 
 impl LatticeDir for Lub {
     fn combine_fields(&self) -> CombineFields { **self }
-    fn bnd<T:Copy>(&self, b: &Bounds<T>) -> Option<T> { b.ub }
+    fn bnd<T:Copy>(&self, b: &Bounds<T>) -> Option<T> { copy b.ub }
     fn with_bnd<T:Copy>(&self, b: &Bounds<T>, t: T) -> Bounds<T> {
-        Bounds { ub: Some(t), ..*b }
+        Bounds { ub: Some(t), ..copy *b }
     }
 }
 
@@ -317,9 +317,9 @@ impl TyLatticeDir for Lub {
 
 impl LatticeDir for Glb {
     fn combine_fields(&self) -> CombineFields { **self }
-    fn bnd<T:Copy>(&self, b: &Bounds<T>) -> Option<T> { b.lb }
+    fn bnd<T:Copy>(&self, b: &Bounds<T>) -> Option<T> { copy b.lb }
     fn with_bnd<T:Copy>(&self, b: &Bounds<T>, t: T) -> Bounds<T> {
-        Bounds { lb: Some(t), ..*b }
+        Bounds { lb: Some(t), ..copy *b }
     }
 }
 
@@ -405,8 +405,8 @@ pub fn lattice_vars<L:LatticeDir + Combine,
     -> cres<LatticeVarResult<V,T>> {
     let nde_a = this.infcx().get(a_vid);
     let nde_b = this.infcx().get(b_vid);
-    let a_vid = nde_a.root;
-    let b_vid = nde_b.root;
+    let a_vid = copy nde_a.root;
+    let b_vid = copy nde_b.root;
     let a_bounds = &nde_a.possible_types;
     let b_bounds = &nde_b.possible_types;
 
@@ -436,8 +436,8 @@ pub fn lattice_vars<L:LatticeDir + Combine,
     // Otherwise, we need to merge A and B into one variable.  We can
     // then use either variable as an upper bound:
     let cf = this.combine_fields();
-    do cf.var_sub_var(a_vid, b_vid).then {
-        Ok(VarResult(a_vid))
+    do cf.var_sub_var(copy a_vid, copy b_vid).then {
+        Ok(VarResult(copy a_vid))
     }
 }
 
@@ -450,7 +450,7 @@ pub fn lattice_var_and_t<L:LatticeDir + Combine,
     lattice_dir_op: LatticeDirOp<T>)
     -> cres<T> {
     let nde_a = this.infcx().get(a_id);
-    let a_id = nde_a.root;
+    let a_id = copy nde_a.root;
     let a_bounds = &nde_a.possible_types;
 
     // The comments in this function are written for LUB, but they
@@ -472,10 +472,11 @@ pub fn lattice_var_and_t<L:LatticeDir + Combine,
             // If a does not have an upper bound, make b the upper bound of a
             // and then return b.
             debug!("bnd=None");
-            let a_bounds = this.with_bnd(a_bounds, *b);
+            let a_bounds = this.with_bnd(a_bounds, copy *b);
             do this.combine_fields().bnds(&a_bounds.lb, &a_bounds.ub).then {
-                this.infcx().set(a_id, Root(a_bounds, nde_a.rank));
-                Ok(*b)
+                this.infcx().set(copy a_id,
+                                 Root(copy a_bounds, copy nde_a.rank));
+                Ok(copy *b)
             }
         }
     }
diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs
index e0f3f0fa885..410e2fe23c1 100644
--- a/src/librustc/middle/typeck/infer/mod.rs
+++ b/src/librustc/middle/typeck/infer/mod.rs
@@ -504,9 +504,9 @@ trait CresCompare<T> {
 
 impl<T:Copy + Eq> CresCompare<T> for cres<T> {
     fn compare(&self, t: T, f: &fn() -> ty::type_err) -> cres<T> {
-        do self.chain |s| {
+        do (copy *self).chain |s| {
             if s == t {
-                *self
+                copy *self
             } else {
                 Err(f())
             }
diff --git a/src/librustc/middle/typeck/infer/unify.rs b/src/librustc/middle/typeck/infer/unify.rs
index c6e4b485d29..371d389f712 100644
--- a/src/librustc/middle/typeck/infer/unify.rs
+++ b/src/librustc/middle/typeck/infer/unify.rs
@@ -61,7 +61,7 @@ impl InferCtxt {
         {
             let vid_u = vid.to_uint();
             let var_val = match vb.vals.find(&vid_u) {
-                Some(&var_val) => var_val,
+                Some(&ref var_val) => copy *var_val,
                 None => {
                     tcx.sess.bug(fmt!(
                         "failed lookup of vid `%u`", vid_u));
@@ -69,11 +69,11 @@ impl InferCtxt {
             };
             match var_val {
                 Redirect(vid) => {
-                    let node: Node<V,T> = helper(tcx, vb, vid);
+                    let node: Node<V,T> = helper(tcx, vb, copy vid);
                     if node.root != vid {
                         // Path compression
                         vb.vals.insert(vid.to_uint(),
-                                       Redirect(node.root));
+                                       Redirect(copy node.root));
                     }
                     node
                 }
@@ -96,12 +96,10 @@ impl InferCtxt {
         debug!("Updating variable %s to %s",
                vid.to_str(), new_v.inf_str(self));
 
-        { // FIXME(#4903)---borrow checker is not flow sensitive
-            let vb = UnifyVid::appropriate_vals_and_bindings(self);
-            let old_v = { *vb.vals.get(&vid.to_uint()) }; // FIXME(#4903)
-            vb.bindings.push((vid, old_v));
-            vb.vals.insert(vid.to_uint(), new_v);
-        }
+        let vb = UnifyVid::appropriate_vals_and_bindings(self);
+        let old_v = copy *vb.vals.get(&vid.to_uint());
+        vb.bindings.push((copy vid, old_v));
+        vb.vals.insert(vid.to_uint(), new_v);
     }
 
     pub fn unify<T:Copy + InferStr,
@@ -120,18 +118,18 @@ impl InferCtxt {
         if node_a.rank > node_b.rank {
             // a has greater rank, so a should become b's parent,
             // i.e., b should redirect to a.
-            self.set(node_b.root, Redirect(node_a.root));
-            (node_a.root, node_a.rank)
+            self.set(copy node_b.root, Redirect(copy node_a.root));
+            (copy node_a.root, node_a.rank)
         } else if node_a.rank < node_b.rank {
             // b has greater rank, so a should redirect to b.
-            self.set(node_a.root, Redirect(node_b.root));
-            (node_b.root, node_b.rank)
+            self.set(copy node_a.root, Redirect(copy node_b.root));
+            (copy node_b.root, node_b.rank)
         } else {
             // If equal, redirect one to the other and increment the
             // other's rank.
             assert_eq!(node_a.rank, node_b.rank);
-            self.set(node_b.root, Redirect(node_a.root));
-            (node_a.root, node_a.rank + 1)
+            self.set(copy node_b.root, Redirect(copy node_a.root));
+            (copy node_a.root, node_a.rank + 1)
         }
     }
 
@@ -174,20 +172,20 @@ impl InferCtxt {
 
         let node_a = self.get(a_id);
         let node_b = self.get(b_id);
-        let a_id = node_a.root;
-        let b_id = node_b.root;
+        let a_id = copy node_a.root;
+        let b_id = copy node_b.root;
 
         if a_id == b_id { return uok(); }
 
         let combined = match (&node_a.possible_types, &node_b.possible_types)
         {
             (&None, &None) => None,
-            (&Some(ref v), &None) | (&None, &Some(ref v)) => Some(*v),
+            (&Some(ref v), &None) | (&None, &Some(ref v)) => Some(copy *v),
             (&Some(ref v1), &Some(ref v2)) => {
                 if *v1 != *v2 {
-                    return mk_err(a_is_expected, *v1, *v2);
+                    return mk_err(a_is_expected, copy *v1, copy *v2);
                 }
-                Some(*v1)
+                Some(copy *v1)
             }
         };
 
@@ -211,7 +209,7 @@ impl InferCtxt {
          * `b`. */
 
         let node_a = self.get(a_id);
-        let a_id = node_a.root;
+        let a_id = copy node_a.root;
 
         match node_a.possible_types {
             None => {
@@ -223,7 +221,7 @@ impl InferCtxt {
                 if *a_t == b {
                     return uok();
                 } else {
-                    return mk_err(a_is_expected, *a_t, b);
+                    return mk_err(a_is_expected, copy *a_t, b);
                 }
             }
         }
diff --git a/src/librustc/rustc.rc b/src/librustc/rustc.rc
index 1197693d1b6..021dd6648cb 100644
--- a/src/librustc/rustc.rc
+++ b/src/librustc/rustc.rc
@@ -28,16 +28,8 @@ extern mod core(name = "std");
 extern mod extra(name = "extra");
 extern mod syntax;
 
-// For deriving(Encodable) purposes...
-#[cfg(stage0)]
-extern mod std(name = "extra", vers = "0.7-pre");
-#[cfg(not(stage0))]
 extern mod std(name = "std", vers = "0.7-pre");
 
-// For bootstrapping purposes.
-#[cfg(stage0)]
-pub use core::unstable;
-
 use core::prelude::*;
 
 use driver::driver::{host_triple, optgroups, early_error};
diff --git a/src/librustdoc/astsrv.rs b/src/librustdoc/astsrv.rs
index 9d8f750a350..3775aafb569 100644
--- a/src/librustdoc/astsrv.rs
+++ b/src/librustdoc/astsrv.rs
@@ -32,8 +32,6 @@ use syntax::ast;
 use syntax::ast_map;
 use syntax;
 
-#[cfg(test)] use core::vec;
-
 pub struct Ctxt {
     ast: @ast::crate,
     ast_map: ast_map::map
diff --git a/src/librustdoc/attr_parser.rs b/src/librustdoc/attr_parser.rs
index a86a7f38a8c..1abdae113c5 100644
--- a/src/librustdoc/attr_parser.rs
+++ b/src/librustdoc/attr_parser.rs
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -152,6 +152,6 @@ mod test {
     fn should_concatenate_multiple_doc_comments() {
         let source = @"/// foo\n/// bar";
         let desc = parse_desc(parse_attributes(source));
-        assert!(desc == Some(~"foo\nbar"));
+        assert!(desc == Some(~" foo\n bar"));
     }
 }
diff --git a/src/librustdoc/desc_to_brief_pass.rs b/src/librustdoc/desc_to_brief_pass.rs
index 51fea9b46b3..dbaa5e8532c 100644
--- a/src/librustdoc/desc_to_brief_pass.rs
+++ b/src/librustdoc/desc_to_brief_pass.rs
@@ -24,7 +24,6 @@ use fold::Fold;
 use fold;
 use pass::Pass;
 
-use core::str;
 use core::util;
 
 pub fn mk_pass() -> Pass {
@@ -129,25 +128,21 @@ fn first_sentence_(s: &str) -> ~str {
         }
     });
     match idx {
-        Some(idx) if idx > 2u => {
-            str::to_owned(s.slice(0, idx - 1))
-        }
+        Some(idx) if idx > 2u => s.slice(0, idx - 1).to_owned(),
         _ => {
             if s.ends_with(".") {
-                str::to_owned(s)
+                s.to_owned()
             } else {
-                str::to_owned(s)
+                s.to_owned()
             }
         }
     }
 }
 
 pub fn paragraphs(s: &str) -> ~[~str] {
-    let mut lines = ~[];
-    for str::each_line_any(s) |line| { lines.push(line.to_owned()); }
     let mut whitespace_lines = 0;
     let mut accum = ~"";
-    let paras = do lines.iter().fold(~[]) |paras, line| {
+    let paras = do s.any_line_iter().fold(~[]) |paras, line| {
         let mut res = paras;
 
         if line.is_whitespace() {
@@ -163,9 +158,9 @@ pub fn paragraphs(s: &str) -> ~[~str] {
             whitespace_lines = 0;
 
             accum = if accum.is_empty() {
-                copy *line
+                line.to_owned()
             } else {
-                accum + "\n" + *line
+                fmt!("%s\n%s", accum, line)
             }
         }
 
diff --git a/src/librustdoc/extract.rs b/src/librustdoc/extract.rs
index f4b6ae8fb32..f8c49f544bc 100644
--- a/src/librustdoc/extract.rs
+++ b/src/librustdoc/extract.rs
@@ -285,8 +285,6 @@ mod test {
     use extract::{extract, from_srv};
     use parse;
 
-    use core::vec;
-
     fn mk_doc(source: @str) -> doc::Doc {
         let ast = parse::from_str(source);
         extract(ast, ~"")
diff --git a/src/librustdoc/markdown_pass.rs b/src/librustdoc/markdown_pass.rs
index 17db7c24a7c..075b64a674c 100644
--- a/src/librustdoc/markdown_pass.rs
+++ b/src/librustdoc/markdown_pass.rs
@@ -466,10 +466,7 @@ fn write_variant(ctxt: &Ctxt, doc: doc::VariantDoc) {
 }
 
 fn list_item_indent(item: &str) -> ~str {
-    let mut indented = ~[];
-    for str::each_line_any(item) |line| {
-        indented.push(line);
-    }
+    let indented = item.any_line_iter().collect::<~[&str]>();
 
     // separate markdown elements within `*` lists must be indented by four
     // spaces, or they will escape the list context. indenting everything
@@ -539,8 +536,6 @@ mod test {
     use tystr_pass;
     use unindent_pass;
 
-    use core::str;
-
     fn render(source: ~str) -> ~str {
         let (srv, doc) = create_doc_srv(source);
         let markdown = write_markdown_str_srv(srv, doc);
diff --git a/src/librustdoc/page_pass.rs b/src/librustdoc/page_pass.rs
index bb5d71e8db1..584e6ccc887 100644
--- a/src/librustdoc/page_pass.rs
+++ b/src/librustdoc/page_pass.rs
@@ -157,7 +157,6 @@ mod test {
     use doc;
     use extract;
     use page_pass::run;
-    use core::vec;
 
     fn mk_doc_(
         output_style: config::OutputStyle,
diff --git a/src/librustdoc/prune_hidden_pass.rs b/src/librustdoc/prune_hidden_pass.rs
index 8a90d3f74d3..484eb8c7980 100644
--- a/src/librustdoc/prune_hidden_pass.rs
+++ b/src/librustdoc/prune_hidden_pass.rs
@@ -77,8 +77,6 @@ mod test {
 
     #[test]
     fn should_prune_hidden_items() {
-        use core::vec;
-
         let doc = mk_doc(~"#[doc(hidden)] mod a { }");
         assert!(doc.cratemod().mods().is_empty())
     }
diff --git a/src/librustdoc/prune_private_pass.rs b/src/librustdoc/prune_private_pass.rs
index e861939c2dd..741da3e265e 100644
--- a/src/librustdoc/prune_private_pass.rs
+++ b/src/librustdoc/prune_private_pass.rs
@@ -162,7 +162,6 @@ mod test {
     use extract;
     use tystr_pass;
     use prune_private_pass::run;
-    use core::vec;
 
     fn mk_doc(source: ~str) -> doc::Doc {
         do astsrv::from_str(copy source) |srv| {
diff --git a/src/librustdoc/sectionalize_pass.rs b/src/librustdoc/sectionalize_pass.rs
index 8716f823848..ba433bf479d 100644
--- a/src/librustdoc/sectionalize_pass.rs
+++ b/src/librustdoc/sectionalize_pass.rs
@@ -19,7 +19,7 @@ use fold::Fold;
 use fold;
 use pass::Pass;
 
-use core::str;
+use core::iterator::IteratorUtil;
 
 pub fn mk_pass() -> Pass {
     Pass {
@@ -104,21 +104,19 @@ fn sectionalize(desc: Option<~str>) -> (Option<~str>, ~[doc::Section]) {
     if desc.is_none() {
         return (None, ~[]);
     }
-    let mut lines = ~[];
-    for str::each_line_any(*desc.get_ref()) |line| { lines.push(line.to_owned()); }
 
     let mut new_desc = None::<~str>;
     let mut current_section = None;
     let mut sections = ~[];
 
-    for lines.each |line| {
-        match parse_header(copy *line) {
+    for desc.get_ref().any_line_iter().advance |line| {
+        match parse_header(line) {
           Some(header) => {
             if current_section.is_some() {
-                sections += [copy *current_section.get_ref()];
+                sections.push(copy *current_section.get_ref());
             }
             current_section = Some(doc::Section {
-                header: header,
+                header: header.to_owned(),
                 body: ~""
             });
           }
@@ -126,17 +124,17 @@ fn sectionalize(desc: Option<~str>) -> (Option<~str>, ~[doc::Section]) {
             match copy current_section {
               Some(section) => {
                 current_section = Some(doc::Section {
-                    body: section.body + "\n" + *line,
+                    body: fmt!("%s\n%s", section.body, line),
                     .. section
                 });
               }
               None => {
                 new_desc = match copy new_desc {
                   Some(desc) => {
-                    Some(desc + "\n" + *line)
+                    Some(fmt!("%s\n%s", desc, line))
                   }
                   None => {
-                    Some(copy *line)
+                    Some(line.to_owned())
                   }
                 };
               }
@@ -146,15 +144,15 @@ fn sectionalize(desc: Option<~str>) -> (Option<~str>, ~[doc::Section]) {
     }
 
     if current_section.is_some() {
-        sections += [current_section.get()];
+        sections.push(current_section.unwrap());
     }
 
     (new_desc, sections)
 }
 
-fn parse_header(line: ~str) -> Option<~str> {
+fn parse_header<'a>(line: &'a str) -> Option<&'a str> {
     if line.starts_with("# ") {
-        Some(line.slice(2u, line.len()).to_owned())
+        Some(line.slice_from(2))
     } else {
         None
     }
@@ -172,9 +170,6 @@ mod test {
     use extract;
     use sectionalize_pass::run;
 
-    use core::str;
-    use core::vec;
-
     fn mk_doc(source: ~str) -> doc::Doc {
         do astsrv::from_str(copy source) |srv| {
             let doc = extract::from_srv(srv.clone(), ~"");
diff --git a/src/librustdoc/text_pass.rs b/src/librustdoc/text_pass.rs
index 1f7a71e0fd8..6db582a60e9 100644
--- a/src/librustdoc/text_pass.rs
+++ b/src/librustdoc/text_pass.rs
@@ -149,8 +149,6 @@ mod test {
     use sectionalize_pass;
     use text_pass::mk_pass;
 
-    use core::str;
-
     fn mk_doc(source: ~str) -> doc::Doc {
         do astsrv::from_str(copy source) |srv| {
             let doc = extract::from_srv(srv.clone(), ~"");
diff --git a/src/librustdoc/unindent_pass.rs b/src/librustdoc/unindent_pass.rs
index caf0e5376d1..2bcf04c0262 100644
--- a/src/librustdoc/unindent_pass.rs
+++ b/src/librustdoc/unindent_pass.rs
@@ -21,7 +21,6 @@ middle of a line, and each of the following lines is indented.
 
 use core::prelude::*;
 
-use core::str;
 use core::uint;
 use pass::Pass;
 use text_pass;
@@ -31,8 +30,7 @@ pub fn mk_pass() -> Pass {
 }
 
 fn unindent(s: &str) -> ~str {
-    let mut lines = ~[];
-    for str::each_line_any(s) |line| { lines.push(line.to_owned()); }
+    let lines = s.any_line_iter().collect::<~[&str]>();
     let mut saw_first_line = false;
     let mut saw_second_line = false;
     let min_indent = do lines.iter().fold(uint::max_value)
@@ -76,19 +74,20 @@ fn unindent(s: &str) -> ~str {
         }
     };
 
-    if !lines.is_empty() {
-        let unindented = ~[lines.head().trim().to_owned()]
-            + do lines.tail().map |line| {
-            if line.is_whitespace() {
-                copy *line
-            } else {
-                assert!(line.len() >= min_indent);
-                line.slice(min_indent, line.len()).to_owned()
-            }
-        };
-        unindented.connect("\n")
-    } else {
-        s.to_str()
+    match lines {
+        [head, .. tail] => {
+            let mut unindented = ~[ head.trim() ];
+            unindented.push_all(do tail.map |&line| {
+                if line.is_whitespace() {
+                    line
+                } else {
+                    assert!(line.len() >= min_indent);
+                    line.slice_from(min_indent)
+                }
+            });
+            unindented.connect("\n")
+        }
+        [] => s.to_owned()
     }
 }
 
diff --git a/src/librusti/rusti.rc b/src/librusti/rusti.rc
index 06ec6769385..c618623a2cb 100644
--- a/src/librusti/rusti.rc
+++ b/src/librusti/rusti.rc
@@ -370,7 +370,7 @@ fn run_cmd(repl: &mut Repl, _in: @io::Reader, _out: @io::Writer,
                     if arg.ends_with(".rs") || arg.ends_with(".rc") {
                     (arg.slice_to(arg.len() - 3).to_owned(), copy *arg)
                 } else {
-                    (copy *arg, arg + ".rs")
+                    (copy *arg, *arg + ".rs")
                 };
                 match compile_crate(filename, copy repl.binary) {
                     Some(_) => loaded_crates.push(crate),
@@ -537,6 +537,9 @@ mod tests {
     }
 
     #[test]
+    // FIXME: #7220 rusti on 32bit mac doesn't work.
+    #[cfg(not(target_word_size="32",
+              target_os="macos"))]
     fn run_all() {
         // FIXME(#7071):
         // By default, unit tests are run in parallel. Rusti, on the other hand,
@@ -648,6 +651,9 @@ mod tests {
     }
 
     #[test]
+    // FIXME: #7220 rusti on 32bit mac doesn't work.
+    #[cfg(not(target_word_size="32",
+              target_os="macos"))]
     fn exit_quits() {
         let mut r = repl();
         assert!(r.running);
diff --git a/src/librustpkg/tests.rs b/src/librustpkg/tests.rs
index 6ec14e2aecf..8b915873269 100644
--- a/src/librustpkg/tests.rs
+++ b/src/librustpkg/tests.rs
@@ -309,7 +309,7 @@ fn frob_source_file(workspace: &Path, pkgid: &PkgId) {
     }
 }
 
-#[test]
+#[test] #[ignore] //FIXME(#7249)
 fn test_all() {
     // FIXME(#7071): these tests use rustc, so they can't be run in parallel
     //               until this issue is resolved
diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs
index a118e445fe2..18dfbd82c5a 100644
--- a/src/libstd/at_vec.rs
+++ b/src/libstd/at_vec.rs
@@ -23,22 +23,8 @@ use vec;
 /// Code for dealing with @-vectors. This is pretty incomplete, and
 /// contains a bunch of duplication from the code for ~-vectors.
 
-pub mod rustrt {
-    use libc;
-    use sys;
-    use vec;
-
-    #[abi = "cdecl"]
-    #[link_name = "rustrt"]
-    pub extern {
-        pub unsafe fn vec_reserve_shared_actual(t: *sys::TypeDesc,
-                                                v: **vec::raw::VecRepr,
-                                                n: libc::size_t);
-    }
-}
-
 /// Returns the number of elements the vector can hold without reallocating
-#[inline(always)]
+#[inline]
 pub fn capacity<T>(v: @[T]) -> uint {
     unsafe {
         let repr: **raw::VecRepr = transmute(&v);
@@ -58,7 +44,7 @@ pub fn capacity<T>(v: @[T]) -> uint {
  *             as an argument a function that will push an element
  *             onto the vector being constructed.
  */
-#[inline(always)]
+#[inline]
 pub fn build_sized<A>(size: uint, builder: &fn(push: &fn(v: A))) -> @[A] {
     let mut vec: @[A] = @[];
     unsafe { raw::reserve(&mut vec, size); }
@@ -76,7 +62,7 @@ pub fn build_sized<A>(size: uint, builder: &fn(push: &fn(v: A))) -> @[A] {
  *             as an argument a function that will push an element
  *             onto the vector being constructed.
  */
-#[inline(always)]
+#[inline]
 pub fn build<A>(builder: &fn(push: &fn(v: A))) -> @[A] {
     build_sized(4, builder)
 }
@@ -93,7 +79,7 @@ pub fn build<A>(builder: &fn(push: &fn(v: A))) -> @[A] {
  *             as an argument a function that will push an element
  *             onto the vector being constructed.
  */
-#[inline(always)]
+#[inline]
 pub fn build_sized_opt<A>(size: Option<uint>,
                           builder: &fn(push: &fn(v: A)))
                        -> @[A] {
@@ -104,11 +90,11 @@ pub fn build_sized_opt<A>(size: Option<uint>,
 
 /// Iterates over the `rhs` vector, copying each element and appending it to the
 /// `lhs`. Afterwards, the `lhs` is then returned for use again.
-#[inline(always)]
+#[inline]
 pub fn append<T:Copy>(lhs: @[T], rhs: &const [T]) -> @[T] {
     do build_sized(lhs.len() + rhs.len()) |push| {
-        for lhs.each |x| { push(*x); }
-        for uint::range(0, rhs.len()) |i| { push(rhs[i]); }
+        for lhs.each |x| { push(copy *x); }
+        for uint::range(0, rhs.len()) |i| { push(copy rhs[i]); }
     }
 }
 
@@ -168,7 +154,7 @@ pub fn to_managed_consume<T>(v: ~[T]) -> @[T] {
  * elements of a slice.
  */
 pub fn to_managed<T:Copy>(v: &[T]) -> @[T] {
-    from_fn(v.len(), |i| v[i])
+    from_fn(v.len(), |i| copy v[i])
 }
 
 #[cfg(not(test))]
@@ -178,7 +164,7 @@ pub mod traits {
     use ops::Add;
 
     impl<'self,T:Copy> Add<&'self const [T],@[T]> for @[T] {
-        #[inline(always)]
+        #[inline]
         fn add(&self, rhs: & &'self const [T]) -> @[T] {
             append(*self, (*rhs))
         }
@@ -189,7 +175,7 @@ pub mod traits {
 pub mod traits {}
 
 pub mod raw {
-    use at_vec::{capacity, rustrt};
+    use at_vec::capacity;
     use cast::{transmute, transmute_copy};
     use libc;
     use ptr;
@@ -197,6 +183,8 @@ pub mod raw {
     use uint;
     use unstable::intrinsics::{move_val_init};
     use vec;
+    use vec::UnboxedVecRepr;
+    use sys::TypeDesc;
 
     pub type VecRepr = vec::raw::VecRepr;
     pub type SliceRepr = vec::raw::SliceRepr;
@@ -208,7 +196,7 @@ pub mod raw {
      * modifing its buffers, so it is up to the caller to ensure that
      * the vector is actually the specified size.
      */
-    #[inline(always)]
+    #[inline]
     pub unsafe fn set_len<T>(v: @[T], new_len: uint) {
         let repr: **mut VecRepr = transmute(&v);
         (**repr).unboxed.fill = new_len * sys::size_of::<T>();
@@ -217,7 +205,7 @@ pub mod raw {
     /**
      * Pushes a new value onto this vector.
      */
-    #[inline(always)]
+    #[inline]
     pub unsafe fn push<T>(v: &mut @[T], initval: T) {
         let repr: **VecRepr = transmute_copy(&v);
         let fill = (**repr).unboxed.fill;
@@ -228,7 +216,7 @@ pub mod raw {
         }
     }
 
-    #[inline(always)] // really pretty please
+    #[inline] // really pretty please
     unsafe fn push_fast<T>(v: &mut @[T], initval: T) {
         let repr: **mut VecRepr = ::cast::transmute(v);
         let fill = (**repr).unboxed.fill;
@@ -257,9 +245,47 @@ pub mod raw {
     pub unsafe fn reserve<T>(v: &mut @[T], n: uint) {
         // Only make the (slow) call into the runtime if we have to
         if capacity(*v) < n {
-            let ptr: **VecRepr = transmute(v);
-            rustrt::vec_reserve_shared_actual(sys::get_type_desc::<T>(),
-                                              ptr, n as libc::size_t);
+            let ptr: *mut *mut VecRepr = transmute(v);
+            let ty = sys::get_type_desc::<T>();
+            return reserve_raw(ty, ptr, n);
+        }
+    }
+
+    // Implementation detail. Shouldn't be public
+    #[allow(missing_doc)]
+    pub fn reserve_raw(ty: *TypeDesc, ptr: *mut *mut VecRepr, n: uint) {
+
+        unsafe {
+            let size_in_bytes = n * (*ty).size;
+            if size_in_bytes > (**ptr).unboxed.alloc {
+                let total_size = size_in_bytes + sys::size_of::<UnboxedVecRepr>();
+                // XXX: UnboxedVecRepr has an extra u8 at the end
+                let total_size = total_size - sys::size_of::<u8>();
+                (*ptr) = local_realloc(*ptr as *(), total_size) as *mut VecRepr;
+                (**ptr).unboxed.alloc = size_in_bytes;
+            }
+        }
+
+        fn local_realloc(ptr: *(), size: uint) -> *() {
+            use rt;
+            use rt::OldTaskContext;
+            use rt::local::Local;
+            use rt::task::Task;
+
+            if rt::context() == OldTaskContext {
+                unsafe {
+                    return rust_local_realloc(ptr, size as libc::size_t);
+                }
+
+                extern {
+                    #[fast_ffi]
+                    fn rust_local_realloc(ptr: *(), size: libc::size_t) -> *();
+                }
+            } else {
+                do Local::borrow::<Task, *()> |task| {
+                    task.heap.realloc(ptr as *libc::c_void, size) as *()
+                }
+            }
         }
     }
 
diff --git a/src/libstd/bool.rs b/src/libstd/bool.rs
index 66a5bfa944f..e6be164099b 100644
--- a/src/libstd/bool.rs
+++ b/src/libstd/bool.rs
@@ -212,7 +212,7 @@ impl FromStr for bool {
 * ~~~
 */
 impl ToStr for bool {
-    #[inline(always)]
+    #[inline]
     fn to_str(&self) -> ~str {
         if *self { ~"true" } else { ~"false" }
     }
@@ -250,24 +250,24 @@ pub fn all_values(blk: &fn(v: bool)) {
 * 0
 * ~~~
 */
-#[inline(always)]
+#[inline]
 pub fn to_bit(v: bool) -> u8 { if v { 1u8 } else { 0u8 } }
 
 #[cfg(not(test))]
 impl Ord for bool {
-    #[inline(always)]
+    #[inline]
     fn lt(&self, other: &bool) -> bool { to_bit(*self) < to_bit(*other) }
-    #[inline(always)]
+    #[inline]
     fn le(&self, other: &bool) -> bool { to_bit(*self) <= to_bit(*other) }
-    #[inline(always)]
+    #[inline]
     fn gt(&self, other: &bool) -> bool { to_bit(*self) > to_bit(*other) }
-    #[inline(always)]
+    #[inline]
     fn ge(&self, other: &bool) -> bool { to_bit(*self) >= to_bit(*other) }
 }
 
 #[cfg(not(test))]
 impl TotalOrd for bool {
-    #[inline(always)]
+    #[inline]
     fn cmp(&self, other: &bool) -> Ordering { to_bit(*self).cmp(&to_bit(*other)) }
 }
 
@@ -298,9 +298,9 @@ impl TotalOrd for bool {
 */
 #[cfg(not(test))]
 impl Eq for bool {
-    #[inline(always)]
+    #[inline]
     fn eq(&self, other: &bool) -> bool { (*self) == (*other) }
-    #[inline(always)]
+    #[inline]
     fn ne(&self, other: &bool) -> bool { (*self) != (*other) }
 }
 
diff --git a/src/libstd/borrow.rs b/src/libstd/borrow.rs
index 703011aea7f..9e3a3a28fe8 100644
--- a/src/libstd/borrow.rs
+++ b/src/libstd/borrow.rs
@@ -14,13 +14,13 @@
 use prelude::*;
 
 /// Cast a region pointer - &T - to a uint.
-#[inline(always)]
+#[inline]
 pub fn to_uint<T>(thing: &T) -> uint {
     thing as *T as uint
 }
 
 /// Determine if two borrowed pointers point to the same thing.
-#[inline(always)]
+#[inline]
 pub fn ref_eq<'a, 'b, T>(thing: &'a T, other: &'b T) -> bool {
     to_uint(thing) == to_uint(other)
 }
@@ -28,11 +28,11 @@ pub fn ref_eq<'a, 'b, T>(thing: &'a T, other: &'b T) -> bool {
 // Equality for region pointers
 #[cfg(not(test))]
 impl<'self, T: Eq> Eq for &'self T {
-    #[inline(always)]
+    #[inline]
     fn eq(&self, other: & &'self T) -> bool {
         *(*self) == *(*other)
     }
-    #[inline(always)]
+    #[inline]
     fn ne(&self, other: & &'self T) -> bool {
         *(*self) != *(*other)
     }
@@ -41,19 +41,19 @@ impl<'self, T: Eq> Eq for &'self T {
 // Comparison for region pointers
 #[cfg(not(test))]
 impl<'self, T: Ord> Ord for &'self T {
-    #[inline(always)]
+    #[inline]
     fn lt(&self, other: & &'self T) -> bool {
         *(*self) < *(*other)
     }
-    #[inline(always)]
+    #[inline]
     fn le(&self, other: & &'self T) -> bool {
         *(*self) <= *(*other)
     }
-    #[inline(always)]
+    #[inline]
     fn ge(&self, other: & &'self T) -> bool {
         *(*self) >= *(*other)
     }
-    #[inline(always)]
+    #[inline]
     fn gt(&self, other: & &'self T) -> bool {
         *(*self) > *(*other)
     }
diff --git a/src/libstd/cast.rs b/src/libstd/cast.rs
index 2109568a0a4..30b6b030dba 100644
--- a/src/libstd/cast.rs
+++ b/src/libstd/cast.rs
@@ -14,22 +14,9 @@ use sys;
 use unstable::intrinsics;
 
 /// Casts the value at `src` to U. The two types must have the same length.
-#[cfg(stage0)]
-pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
-    let mut dest: U = intrinsics::uninit();
-    {
-        let dest_ptr: *mut u8 = transmute(&mut dest);
-        let src_ptr: *u8 = transmute(src);
-        intrinsics::memmove64(dest_ptr,
-                              src_ptr,
-                              sys::size_of::<U>() as u64);
-    }
-    dest
-}
-
 /// Casts the value at `src` to U. The two types must have the same length.
-#[cfg(target_word_size = "32", not(stage0))]
-#[inline(always)]
+#[cfg(target_word_size = "32")]
+#[inline]
 pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
     let mut dest: U = intrinsics::uninit();
     let dest_ptr: *mut u8 = transmute(&mut dest);
@@ -39,8 +26,8 @@ pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
 }
 
 /// Casts the value at `src` to U. The two types must have the same length.
-#[cfg(target_word_size = "64", not(stage0))]
-#[inline(always)]
+#[cfg(target_word_size = "64")]
+#[inline]
 pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
     let mut dest: U = intrinsics::uninit();
     let dest_ptr: *mut u8 = transmute(&mut dest);
@@ -54,19 +41,16 @@ pub unsafe fn transmute_copy<T, U>(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 pointer types.
+ * can be used for various acts of magick.
  */
-#[inline(always)]
+#[inline]
 pub unsafe fn forget<T>(thing: T) { intrinsics::forget(thing); }
 
 /**
  * Force-increment the reference count on a shared box. If used
- * carelessly, this can leak the box. Use this in conjunction with transmute
- * and/or reinterpret_cast when such calls would otherwise scramble a box's
- * reference count
+ * carelessly, this can leak the box.
  */
-#[inline(always)]
+#[inline]
 pub unsafe fn bump_box_refcount<T>(t: @T) { forget(t); }
 
 /**
@@ -77,59 +61,59 @@ pub unsafe fn bump_box_refcount<T>(t: @T) { forget(t); }
  *
  *     assert!(transmute("L") == ~[76u8, 0u8]);
  */
-#[inline(always)]
+#[inline]
 pub unsafe fn transmute<L, G>(thing: L) -> G {
     intrinsics::transmute(thing)
 }
 
 /// Coerce an immutable reference to be mutable.
-#[inline(always)]
+#[inline]
 pub unsafe fn transmute_mut<'a,T>(ptr: &'a T) -> &'a mut T { transmute(ptr) }
 
 /// Coerce a mutable reference to be immutable.
-#[inline(always)]
+#[inline]
 pub unsafe fn transmute_immut<'a,T>(ptr: &'a mut T) -> &'a T {
     transmute(ptr)
 }
 
 /// Coerce a borrowed pointer to have an arbitrary associated region.
-#[inline(always)]
+#[inline]
 pub unsafe fn transmute_region<'a,'b,T>(ptr: &'a T) -> &'b T {
     transmute(ptr)
 }
 
 /// Coerce an immutable reference to be mutable.
-#[inline(always)]
+#[inline]
 pub unsafe fn transmute_mut_unsafe<T>(ptr: *const T) -> *mut T {
     transmute(ptr)
 }
 
 /// Coerce an immutable reference to be mutable.
-#[inline(always)]
+#[inline]
 pub unsafe fn transmute_immut_unsafe<T>(ptr: *const T) -> *T {
     transmute(ptr)
 }
 
 /// Coerce a borrowed mutable pointer to have an arbitrary associated region.
-#[inline(always)]
+#[inline]
 pub unsafe fn transmute_mut_region<'a,'b,T>(ptr: &'a mut T) -> &'b mut T {
     transmute(ptr)
 }
 
 /// Transforms lifetime of the second pointer to match the first.
-#[inline(always)]
+#[inline]
 pub unsafe fn copy_lifetime<'a,S,T>(_ptr: &'a S, ptr: &T) -> &'a T {
     transmute_region(ptr)
 }
 
 /// Transforms lifetime of the second pointer to match the first.
-#[inline(always)]
+#[inline]
 pub unsafe fn copy_mut_lifetime<'a,S,T>(_ptr: &'a mut S, ptr: &mut T) -> &'a mut T {
     transmute_mut_region(ptr)
 }
 
 /// Transforms lifetime of the second pointer to match the first.
-#[inline(always)]
+#[inline]
 pub unsafe fn copy_lifetime_vec<'a,S,T>(_ptr: &'a [S], ptr: &T) -> &'a T {
     transmute_region(ptr)
 }
diff --git a/src/libstd/char.rs b/src/libstd/char.rs
index 073ced8988a..797fd9e8c02 100644
--- a/src/libstd/char.rs
+++ b/src/libstd/char.rs
@@ -17,8 +17,8 @@ use u32;
 use uint;
 use unicode::{derived_property, general_category};
 
-#[cfg(not(test))]
-use cmp::{Eq, Ord};
+#[cfg(not(test))] use cmp::{Eq, Ord};
+#[cfg(not(test))] use num::Zero;
 
 /*
     Lu  Uppercase_Letter        an uppercase letter
@@ -65,14 +65,14 @@ pub fn is_XID_continue(c: char) -> bool { derived_property::XID_Continue(c) }
 /// Indicates whether a character is in lower case, defined
 /// in terms of the Unicode General Category 'Ll'
 ///
-#[inline(always)]
+#[inline]
 pub fn is_lowercase(c: char) -> bool { general_category::Ll(c) }
 
 ///
 /// Indicates whether a character is in upper case, defined
 /// in terms of the Unicode General Category 'Lu'.
 ///
-#[inline(always)]
+#[inline]
 pub fn is_uppercase(c: char) -> bool { general_category::Lu(c) }
 
 ///
@@ -80,7 +80,7 @@ pub fn is_uppercase(c: char) -> bool { general_category::Lu(c) }
 /// terms of the Unicode General Categories 'Zs', 'Zl', 'Zp'
 /// additional 'Cc'-category control codes in the range [0x09, 0x0d]
 ///
-#[inline(always)]
+#[inline]
 pub fn is_whitespace(c: char) -> bool {
     ('\x09' <= c && c <= '\x0d')
         || general_category::Zs(c)
@@ -93,7 +93,7 @@ pub fn is_whitespace(c: char) -> bool {
 /// defined in terms of the Unicode General Categories 'Nd', 'Nl', 'No'
 /// and the Derived Core Property 'Alphabetic'.
 ///
-#[inline(always)]
+#[inline]
 pub fn is_alphanumeric(c: char) -> bool {
     derived_property::Alphabetic(c)
         || general_category::Nd(c)
@@ -102,7 +102,7 @@ pub fn is_alphanumeric(c: char) -> bool {
 }
 
 /// Indicates whether the character is numeric (Nd, Nl, or No)
-#[inline(always)]
+#[inline]
 pub fn is_digit(c: char) -> bool {
     general_category::Nd(c)
         || general_category::Nl(c)
@@ -127,7 +127,7 @@ pub fn is_digit(c: char) -> bool {
 ///
 /// This just wraps `to_digit()`.
 ///
-#[inline(always)]
+#[inline]
 pub fn is_digit_radix(c: char, radix: uint) -> bool {
     match to_digit(c, radix) {
         Some(_) => true,
@@ -310,24 +310,30 @@ impl Char for char {
 
 #[cfg(not(test))]
 impl Eq for char {
-    #[inline(always)]
+    #[inline]
     fn eq(&self, other: &char) -> bool { (*self) == (*other) }
-    #[inline(always)]
+    #[inline]
     fn ne(&self, other: &char) -> bool { (*self) != (*other) }
 }
 
 #[cfg(not(test))]
 impl Ord for char {
-    #[inline(always)]
+    #[inline]
     fn lt(&self, other: &char) -> bool { *self < *other }
-    #[inline(always)]
+    #[inline]
     fn le(&self, other: &char) -> bool { *self <= *other }
-    #[inline(always)]
+    #[inline]
     fn gt(&self, other: &char) -> bool { *self > *other }
-    #[inline(always)]
+    #[inline]
     fn ge(&self, other: &char) -> bool { *self >= *other }
 }
 
+#[cfg(not(test))]
+impl Zero for char {
+    fn zero() -> char { 0 as char }
+    fn is_zero(&self) -> bool { *self == 0 as char }
+}
+
 #[test]
 fn test_is_lowercase() {
     assert!('a'.is_lowercase());
diff --git a/src/libstd/cleanup.rs b/src/libstd/cleanup.rs
index d1460b7a3c9..36c1fdf781b 100644
--- a/src/libstd/cleanup.rs
+++ b/src/libstd/cleanup.rs
@@ -13,107 +13,14 @@
 use libc::{c_char, c_void, intptr_t, uintptr_t};
 use ptr::mut_null;
 use repr::BoxRepr;
+use rt;
+use rt::OldTaskContext;
 use sys::TypeDesc;
 use cast::transmute;
-#[cfg(not(test))] use unstable::lang::clear_task_borrow_list;
 
 #[cfg(not(test))] use ptr::to_unsafe_ptr;
 
-/**
- * Runtime structures
- *
- * NB: These must match the representation in the C++ runtime.
- */
-
 type DropGlue<'self> = &'self fn(**TypeDesc, *c_void);
-type FreeGlue<'self> = &'self fn(**TypeDesc, *c_void);
-
-type TaskID = uintptr_t;
-
-struct StackSegment { priv opaque: () }
-struct Scheduler { priv opaque: () }
-struct SchedulerLoop { priv opaque: () }
-struct Kernel { priv opaque: () }
-struct Env { priv opaque: () }
-struct AllocHeader { priv opaque: () }
-struct MemoryRegion { priv opaque: () }
-
-#[cfg(target_arch="x86")]
-struct Registers {
-    data: [u32, ..16]
-}
-
-#[cfg(target_arch="arm")]
-#[cfg(target_arch="mips")]
-struct Registers {
-    data: [u32, ..32]
-}
-
-#[cfg(target_arch="x86")]
-#[cfg(target_arch="arm")]
-#[cfg(target_arch="mips")]
-struct Context {
-    regs: Registers,
-    next: *Context,
-    pad: [u32, ..3]
-}
-
-#[cfg(target_arch="x86_64")]
-struct Registers {
-    data: [u64, ..22]
-}
-
-#[cfg(target_arch="x86_64")]
-struct Context {
-    regs: Registers,
-    next: *Context,
-    pad: uintptr_t
-}
-
-struct BoxedRegion {
-    env: *Env,
-    backing_region: *MemoryRegion,
-    live_allocs: *BoxRepr
-}
-
-#[cfg(target_arch="x86")]
-#[cfg(target_arch="arm")]
-#[cfg(target_arch="mips")]
-struct Task {
-    // Public fields
-    refcount: intptr_t,                 // 0
-    id: TaskID,                         // 4
-    pad: [u32, ..2],                    // 8
-    ctx: Context,                       // 16
-    stack_segment: *StackSegment,       // 96
-    runtime_sp: uintptr_t,              // 100
-    scheduler: *Scheduler,              // 104
-    scheduler_loop: *SchedulerLoop,     // 108
-
-    // Fields known only to the runtime
-    kernel: *Kernel,                    // 112
-    name: *c_char,                      // 116
-    list_index: i32,                    // 120
-    boxed_region: BoxedRegion           // 128
-}
-
-#[cfg(target_arch="x86_64")]
-struct Task {
-    // Public fields
-    refcount: intptr_t,
-    id: TaskID,
-    ctx: Context,
-    stack_segment: *StackSegment,
-    runtime_sp: uintptr_t,
-    scheduler: *Scheduler,
-    scheduler_loop: *SchedulerLoop,
-
-    // Fields known only to the runtime
-    kernel: *Kernel,
-    name: *c_char,
-    list_index: i32,
-    boxed_region: BoxedRegion
-}
 
 /*
  * Box annihilation
@@ -132,9 +39,9 @@ unsafe fn each_live_alloc(read_next_before: bool,
     //! Walks the internal list of allocations
 
     use managed;
+    use rt::local_heap;
 
-    let task: *Task = transmute(rustrt::rust_get_task());
-    let box = (*task).boxed_region.live_allocs;
+    let box = local_heap::live_allocs();
     let mut box: *mut BoxRepr = transmute(copy box);
     while box != mut_null() {
         let next_before = transmute(copy (*box).header.next);
@@ -156,7 +63,11 @@ unsafe fn each_live_alloc(read_next_before: bool,
 
 #[cfg(unix)]
 fn debug_mem() -> bool {
-    ::rt::env::get().debug_mem
+    // XXX: Need to port the environment struct to newsched
+    match rt::context() {
+        OldTaskContext => ::rt::env::get().debug_mem,
+        _ => false
+    }
 }
 
 #[cfg(windows)]
@@ -165,13 +76,12 @@ fn debug_mem() -> bool {
 }
 
 /// Destroys all managed memory (i.e. @ boxes) held by the current task.
-#[cfg(not(test))]
-#[lang="annihilate"]
 pub unsafe fn annihilate() {
-    use unstable::lang::local_free;
+    use rt::local_heap::local_free;
     use io::WriterUtil;
     use io;
     use libc;
+    use rt::borrowck;
     use sys;
     use managed;
 
@@ -183,7 +93,7 @@ pub unsafe fn annihilate() {
 
     // Quick hack: we need to free this list upon task exit, and this
     // is a convenient place to do it.
-    clear_task_borrow_list();
+    borrowck::clear_task_borrow_list();
 
     // Pass 1: Make all boxes immortal.
     //
@@ -207,7 +117,7 @@ pub unsafe fn annihilate() {
         if !uniq {
             let tydesc: *TypeDesc = transmute(copy (*box).header.type_desc);
             let drop_glue: DropGlue = transmute(((*tydesc).drop_glue, 0));
-            drop_glue(to_unsafe_ptr(&tydesc), transmute(&(*box).data));
+            drop_glue(&tydesc, transmute(&(*box).data));
         }
     }
 
diff --git a/src/libstd/clone.rs b/src/libstd/clone.rs
index 266dd1a35e3..5ec594cef7e 100644
--- a/src/libstd/clone.rs
+++ b/src/libstd/clone.rs
@@ -34,25 +34,25 @@ pub trait Clone {
 
 impl<T: Clone> Clone for ~T {
     /// Return a deep copy of the owned box.
-    #[inline(always)]
+    #[inline]
     fn clone(&self) -> ~T { ~(**self).clone() }
 }
 
 impl<T> Clone for @T {
     /// Return a shallow copy of the managed box.
-    #[inline(always)]
+    #[inline]
     fn clone(&self) -> @T { *self }
 }
 
 impl<T> Clone for @mut T {
     /// Return a shallow copy of the managed box.
-    #[inline(always)]
+    #[inline]
     fn clone(&self) -> @mut T { *self }
 }
 
 impl<'self, T> Clone for &'self T {
     /// Return a shallow copy of the borrowed pointer.
-    #[inline(always)]
+    #[inline]
     fn clone(&self) -> &'self T { *self }
 }
 
@@ -60,7 +60,7 @@ macro_rules! clone_impl(
     ($t:ty) => {
         impl Clone for $t {
             /// Return a deep copy of the value.
-            #[inline(always)]
+            #[inline]
             fn clone(&self) -> $t { *self }
         }
     }
@@ -96,7 +96,7 @@ pub trait DeepClone {
 
 impl<T: DeepClone> DeepClone for ~T {
     /// Return a deep copy of the owned box.
-    #[inline(always)]
+    #[inline]
     fn deep_clone(&self) -> ~T { ~(**self).deep_clone() }
 }
 
@@ -104,7 +104,7 @@ impl<T: DeepClone> DeepClone for ~T {
 impl<T: Const + DeepClone> DeepClone for @T {
     /// Return a deep copy of the managed box. The `Const` trait is required to prevent performing
     /// a deep clone of a potentially cyclical type.
-    #[inline(always)]
+    #[inline]
     fn deep_clone(&self) -> @T { @(**self).deep_clone() }
 }
 
@@ -112,7 +112,7 @@ impl<T: Const + DeepClone> DeepClone for @T {
 impl<T: Const + DeepClone> DeepClone for @mut T {
     /// Return a deep copy of the managed box. The `Const` trait is required to prevent performing
     /// a deep clone of a potentially cyclical type.
-    #[inline(always)]
+    #[inline]
     fn deep_clone(&self) -> @mut T { @mut (**self).deep_clone() }
 }
 
@@ -120,7 +120,7 @@ macro_rules! deep_clone_impl(
     ($t:ty) => {
         impl DeepClone for $t {
             /// Return a deep copy of the value.
-            #[inline(always)]
+            #[inline]
             fn deep_clone(&self) -> $t { *self }
         }
     }
diff --git a/src/libstd/cmp.rs b/src/libstd/cmp.rs
index ce6a04c3688..2c4bb46b23b 100644
--- a/src/libstd/cmp.rs
+++ b/src/libstd/cmp.rs
@@ -45,7 +45,7 @@ pub trait TotalEq {
 macro_rules! totaleq_impl(
     ($t:ty) => {
         impl TotalEq for $t {
-            #[inline(always)]
+            #[inline]
             fn equals(&self, other: &$t) -> bool { *self == *other }
         }
     }
@@ -84,27 +84,27 @@ pub trait TotalOrd: TotalEq {
 }
 
 impl TotalOrd for Ordering {
-    #[inline(always)]
+    #[inline]
     fn cmp(&self, other: &Ordering) -> Ordering {
         (*self as int).cmp(&(*other as int))
     }
 }
 
 impl Ord for Ordering {
-    #[inline(always)]
+    #[inline]
     fn lt(&self, other: &Ordering) -> bool { (*self as int) < (*other as int) }
-    #[inline(always)]
+    #[inline]
     fn le(&self, other: &Ordering) -> bool { (*self as int) <= (*other as int) }
-    #[inline(always)]
+    #[inline]
     fn gt(&self, other: &Ordering) -> bool { (*self as int) > (*other as int) }
-    #[inline(always)]
+    #[inline]
     fn ge(&self, other: &Ordering) -> bool { (*self as int) >= (*other as int) }
 }
 
 macro_rules! totalord_impl(
     ($t:ty) => {
         impl TotalOrd for $t {
-            #[inline(always)]
+            #[inline]
             fn cmp(&self, other: &$t) -> Ordering {
                 if *self < *other { Less }
                 else if *self > *other { Greater }
@@ -146,7 +146,7 @@ Return `o1` if it is not `Equal`, otherwise `o2`. Simulates the
 lexical ordering on a type `(int, int)`.
 */
 // used in deriving code in libsyntax
-#[inline(always)]
+#[inline]
 pub fn lexical_ordering(o1: Ordering, o2: Ordering) -> Ordering {
     match o1 {
         Equal => o2,
@@ -180,12 +180,12 @@ pub trait Equiv<T> {
     fn equiv(&self, other: &T) -> bool;
 }
 
-#[inline(always)]
+#[inline]
 pub fn min<T:Ord>(v1: T, v2: T) -> T {
     if v1 < v2 { v1 } else { v2 }
 }
 
-#[inline(always)]
+#[inline]
 pub fn max<T:Ord>(v1: T, v2: T) -> T {
     if v1 > v2 { v1 } else { v2 }
 }
diff --git a/src/libstd/comm.rs b/src/libstd/comm.rs
index f0c353c8d62..00c33c8ab32 100644
--- a/src/libstd/comm.rs
+++ b/src/libstd/comm.rs
@@ -20,7 +20,6 @@ use either::{Either, Left, Right};
 use kinds::Owned;
 use option::{Option, Some, None};
 use uint;
-use vec;
 use vec::OwnedVector;
 use util::replace;
 use unstable::sync::{Exclusive, exclusive};
@@ -209,7 +208,7 @@ impl<T: Owned> Peekable<T> for PortSet<T> {
     fn peek(&self) -> bool {
         // It'd be nice to use self.port.each, but that version isn't
         // pure.
-        for uint::range(0, vec::uniq_len(&const self.ports)) |i| {
+        for uint::range(0, self.ports.len()) |i| {
             let port: &pipesy::Port<T> = &self.ports[i];
             if port.peek() {
                 return true;
@@ -221,7 +220,7 @@ impl<T: Owned> Peekable<T> for PortSet<T> {
 
 /// A channel that can be shared between many senders.
 pub struct SharedChan<T> {
-    ch: Exclusive<pipesy::Chan<T>>
+    inner: Either<Exclusive<pipesy::Chan<T>>, rtcomm::SharedChan<T>>
 }
 
 impl<T: Owned> SharedChan<T> {
@@ -229,40 +228,50 @@ impl<T: Owned> SharedChan<T> {
     pub fn new(c: Chan<T>) -> SharedChan<T> {
         let Chan { inner } = c;
         let c = match inner {
-            Left(c) => c,
-            Right(_) => fail!("SharedChan not implemented")
+            Left(c) => Left(exclusive(c)),
+            Right(c) => Right(rtcomm::SharedChan::new(c))
         };
-        SharedChan { ch: exclusive(c) }
+        SharedChan { inner: c }
     }
 }
 
 impl<T: Owned> GenericChan<T> for SharedChan<T> {
     fn send(&self, x: T) {
-        unsafe {
-            let mut xx = Some(x);
-            do self.ch.with_imm |chan| {
-                let x = replace(&mut xx, None);
-                chan.send(x.unwrap())
+        match self.inner {
+            Left(ref chan) => {
+                unsafe {
+                    let mut xx = Some(x);
+                    do chan.with_imm |chan| {
+                        let x = replace(&mut xx, None);
+                        chan.send(x.unwrap())
+                    }
+                }
             }
+            Right(ref chan) => chan.send(x)
         }
     }
 }
 
 impl<T: Owned> GenericSmartChan<T> for SharedChan<T> {
     fn try_send(&self, x: T) -> bool {
-        unsafe {
-            let mut xx = Some(x);
-            do self.ch.with_imm |chan| {
-                let x = replace(&mut xx, None);
-                chan.try_send(x.unwrap())
+        match self.inner {
+            Left(ref chan) => {
+                unsafe {
+                    let mut xx = Some(x);
+                    do chan.with_imm |chan| {
+                        let x = replace(&mut xx, None);
+                        chan.try_send(x.unwrap())
+                    }
+                }
             }
+            Right(ref chan) => chan.try_send(x)
         }
     }
 }
 
 impl<T: Owned> ::clone::Clone for SharedChan<T> {
     fn clone(&self) -> SharedChan<T> {
-        SharedChan { ch: self.ch.clone() }
+        SharedChan { inner: self.inner.clone() }
     }
 }
 
@@ -625,7 +634,7 @@ mod pipesy {
     }
 
     impl<T: Owned> GenericChan<T> for Chan<T> {
-        #[inline(always)]
+        #[inline]
         fn send(&self, x: T) {
             unsafe {
                 let self_endp = transmute_mut(&self.endp);
@@ -636,7 +645,7 @@ mod pipesy {
     }
 
     impl<T: Owned> GenericSmartChan<T> for Chan<T> {
-        #[inline(always)]
+        #[inline]
         fn try_send(&self, x: T) -> bool {
             unsafe {
                 let self_endp = transmute_mut(&self.endp);
@@ -653,7 +662,7 @@ mod pipesy {
     }
 
     impl<T: Owned> GenericPort<T> for Port<T> {
-        #[inline(always)]
+        #[inline]
         fn recv(&self) -> T {
             unsafe {
                 let self_endp = transmute_mut(&self.endp);
@@ -664,7 +673,7 @@ mod pipesy {
             }
         }
 
-        #[inline(always)]
+        #[inline]
         fn try_recv(&self) -> Option<T> {
             unsafe {
                 let self_endp = transmute_mut(&self.endp);
@@ -681,7 +690,7 @@ mod pipesy {
     }
 
     impl<T: Owned> Peekable<T> for Port<T> {
-        #[inline(always)]
+        #[inline]
         fn peek(&self) -> bool {
             unsafe {
                 let self_endp = transmute_mut(&self.endp);
diff --git a/src/libstd/container.rs b/src/libstd/container.rs
index 065582e2e0d..c1b656f1cd9 100644
--- a/src/libstd/container.rs
+++ b/src/libstd/container.rs
@@ -16,10 +16,10 @@ use option::Option;
 /// knowledge known is the number of elements contained within.
 pub trait Container {
     /// Return the number of elements in the container
-    fn len(&const self) -> uint;
+    fn len(&self) -> uint;
 
     /// Return true if the container contains no elements
-    fn is_empty(&const self) -> bool;
+    fn is_empty(&self) -> bool;
 }
 
 /// A trait to represent mutable containers
diff --git a/src/libstd/core.rc b/src/libstd/core.rc
index 8e09a9b17fd..6911c00e55b 100644
--- a/src/libstd/core.rc
+++ b/src/libstd/core.rc
@@ -12,19 +12,20 @@
 
 # The Rust standard library
 
-The Rust standard library provides runtime features required by the language,
-including the task scheduler and memory allocators, as well as library
-support for Rust built-in types, platform abstractions, and other commonly
-used features.
-
-`std` includes modules corresponding to each of the integer types, each of
-the floating point types, the `bool` type, tuples, characters, strings
-(`str`), vectors (`vec`), managed boxes (`managed`), owned boxes (`owned`),
-and unsafe and borrowed pointers (`ptr`).  Additionally, `std` provides
-pervasive types (`option` and `result`), task creation and communication
-primitives (`task`, `comm`), platform abstractions (`os` and `path`), basic
-I/O abstractions (`io`), common traits (`kinds`, `ops`, `cmp`, `num`,
-`to_str`), and complete bindings to the C standard library (`libc`).
+The Rust standard library is a group of interrelated modules defining
+the core language traits, operations on built-in data types, collections,
+platform abstractions, the task scheduler, runtime support for language
+features and other common functionality.
+
+`std` includes modules corresponding to each of the integer types,
+each of the floating point types, the `bool` type, tuples, characters,
+strings (`str`), vectors (`vec`), managed boxes (`managed`), owned
+boxes (`owned`), and unsafe and borrowed pointers (`ptr`, `borrowed`).
+Additionally, `std` provides pervasive types (`option` and `result`),
+task creation and communication primitives (`task`, `comm`), platform
+abstractions (`os` and `path`), basic I/O abstractions (`io`), common
+traits (`kinds`, `ops`, `cmp`, `num`, `to_str`), and complete bindings
+to the C standard library (`libc`).
 
 # Standard library injection and the Rust prelude
 
@@ -38,7 +39,7 @@ with the `std::` path prefix, as in `use std::vec`, `use std::task::spawn`,
 etc.
 
 Additionally, `std` contains a `prelude` module that reexports many of the
-most common std modules, types and traits. The contents of the prelude are
+most common types, traits and functions. The contents of the prelude are
 imported into every *module* by default.  Implicitly, all modules behave as if
 they contained the following prologue:
 
@@ -56,17 +57,13 @@ they contained the following prologue:
 #[license = "MIT/ASL2"];
 #[crate_type = "lib"];
 
-// NOTE: remove these two attributes after the next snapshot
-#[no_core]; // for stage0
-#[allow(unrecognized_lint)]; // otherwise stage0 is seriously ugly
-
 // Don't link to std. We are std.
 #[no_std];
 
 #[deny(non_camel_case_types)];
 #[deny(missing_doc)];
 
-// Make core testable by not duplicating lang items. See #2912
+// Make std testable by not duplicating lang items. See #2912
 #[cfg(test)] extern mod realstd(name = "std");
 #[cfg(test)] pub use kinds = realstd::kinds;
 #[cfg(test)] pub use ops = realstd::ops;
diff --git a/src/libstd/either.rs b/src/libstd/either.rs
index fac0866f17e..681a7fbc821 100644
--- a/src/libstd/either.rs
+++ b/src/libstd/either.rs
@@ -33,7 +33,7 @@ pub enum Either<T, U> {
 /// If `value` is left(T) then `f_left` is applied to its contents, if
 /// `value` is right(U) then `f_right` is applied to its contents, and the
 /// result is returned.
-#[inline(always)]
+#[inline]
 pub fn either<T, U, V>(f_left: &fn(&T) -> V,
                        f_right: &fn(&U) -> V, value: &Either<T, U>) -> V {
     match *value {
@@ -47,7 +47,7 @@ pub fn lefts<T:Copy,U>(eithers: &[Either<T, U>]) -> ~[T] {
     do vec::build_sized(eithers.len()) |push| {
         for eithers.each |elt| {
             match *elt {
-                Left(ref l) => { push(*l); }
+                Left(ref l) => { push(copy *l); }
                 _ => { /* fallthrough */ }
             }
         }
@@ -59,7 +59,7 @@ pub fn rights<T, U: Copy>(eithers: &[Either<T, U>]) -> ~[U] {
     do vec::build_sized(eithers.len()) |push| {
         for eithers.each |elt| {
             match *elt {
-                Right(ref r) => { push(*r); }
+                Right(ref r) => { push(copy *r); }
                 _ => { /* fallthrough */ }
             }
         }
@@ -83,7 +83,7 @@ pub fn partition<T, U>(eithers: ~[Either<T, U>]) -> (~[T], ~[U]) {
 }
 
 /// Flips between left and right of a given either
-#[inline(always)]
+#[inline]
 pub fn flip<T, U>(eith: Either<T, U>) -> Either<U, T> {
     match eith {
         Right(r) => Left(r),
@@ -95,7 +95,7 @@ pub fn flip<T, U>(eith: Either<T, U>) -> Either<U, T> {
 ///
 /// Converts an `either` type to a `result` type, making the "right" choice
 /// an ok result, and the "left" choice a fail
-#[inline(always)]
+#[inline]
 pub fn to_result<T, U>(eith: Either<T, U>) -> Result<U, T> {
     match eith {
         Right(r) => result::Ok(r),
@@ -104,7 +104,7 @@ pub fn to_result<T, U>(eith: Either<T, U>) -> Result<U, T> {
 }
 
 /// Checks whether the given value is a left
-#[inline(always)]
+#[inline]
 pub fn is_left<T, U>(eith: &Either<T, U>) -> bool {
     match *eith {
         Left(_) => true,
@@ -113,7 +113,7 @@ pub fn is_left<T, U>(eith: &Either<T, U>) -> bool {
 }
 
 /// Checks whether the given value is a right
-#[inline(always)]
+#[inline]
 pub fn is_right<T, U>(eith: &Either<T, U>) -> bool {
     match *eith {
         Right(_) => true,
@@ -122,7 +122,7 @@ pub fn is_right<T, U>(eith: &Either<T, U>) -> bool {
 }
 
 /// Retrieves the value in the left branch. Fails if the either is Right.
-#[inline(always)]
+#[inline]
 pub fn unwrap_left<T,U>(eith: Either<T,U>) -> T {
     match eith {
         Left(x) => x,
@@ -131,7 +131,7 @@ pub fn unwrap_left<T,U>(eith: Either<T,U>) -> T {
 }
 
 /// Retrieves the value in the right branch. Fails if the either is Left.
-#[inline(always)]
+#[inline]
 pub fn unwrap_right<T,U>(eith: Either<T,U>) -> U {
     match eith {
         Right(x) => x,
@@ -140,27 +140,27 @@ pub fn unwrap_right<T,U>(eith: Either<T,U>) -> U {
 }
 
 impl<T, U> Either<T, U> {
-    #[inline(always)]
+    #[inline]
     pub fn either<V>(&self, f_left: &fn(&T) -> V, f_right: &fn(&U) -> V) -> V {
         either(f_left, f_right, self)
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn flip(self) -> Either<U, T> { flip(self) }
 
-    #[inline(always)]
+    #[inline]
     pub fn to_result(self) -> Result<U, T> { to_result(self) }
 
-    #[inline(always)]
+    #[inline]
     pub fn is_left(&self) -> bool { is_left(self) }
 
-    #[inline(always)]
+    #[inline]
     pub fn is_right(&self) -> bool { is_right(self) }
 
-    #[inline(always)]
+    #[inline]
     pub fn unwrap_left(self) -> T { unwrap_left(self) }
 
-    #[inline(always)]
+    #[inline]
     pub fn unwrap_right(self) -> U { unwrap_right(self) }
 }
 
diff --git a/src/libstd/hash.rs b/src/libstd/hash.rs
index e9022445786..1967a57e867 100644
--- a/src/libstd/hash.rs
+++ b/src/libstd/hash.rs
@@ -64,7 +64,7 @@ pub trait HashUtil {
 }
 
 impl<A:Hash> HashUtil for A {
-    #[inline(always)]
+    #[inline]
     fn hash(&self) -> u64 { self.hash_keyed(0,0) }
 }
 
@@ -79,7 +79,7 @@ pub trait Streaming {
 }
 
 impl<A:IterBytes> Hash for A {
-    #[inline(always)]
+    #[inline]
     fn hash_keyed(&self, k0: u64, k1: u64) -> u64 {
         let mut s = State::new(k0, k1);
         for self.iter_bytes(true) |bytes| {
@@ -176,7 +176,7 @@ fn hash_keyed_5<A: IterBytes,
     s.result_u64()
 }
 
-#[inline(always)]
+#[inline]
 pub fn default_state() -> State {
     State::new(0, 0)
 }
@@ -194,7 +194,7 @@ struct SipState {
 }
 
 impl SipState {
-    #[inline(always)]
+    #[inline]
     fn new(key0: u64, key1: u64) -> SipState {
         let mut state = SipState {
             k0: key0,
@@ -248,7 +248,7 @@ macro_rules! compress (
 
 impl Writer for SipState {
     // Methods for io::writer
-    #[inline(always)]
+    #[inline]
     fn write(&mut self, msg: &[u8]) {
         let length = msg.len();
         self.length += length;
@@ -315,12 +315,12 @@ impl Writer for SipState {
 }
 
 impl Streaming for SipState {
-    #[inline(always)]
+    #[inline]
     fn input(&mut self, buf: &[u8]) {
         self.write(buf);
     }
 
-    #[inline(always)]
+    #[inline]
     fn result_u64(&mut self) -> u64 {
         let mut v0 = self.v0;
         let mut v1 = self.v1;
@@ -373,7 +373,7 @@ impl Streaming for SipState {
         s
     }
 
-    #[inline(always)]
+    #[inline]
     fn reset(&mut self) {
         self.length = 0;
         self.v0 = self.k0 ^ 0x736f6d6570736575;
@@ -558,4 +558,15 @@ mod tests {
             val & !(0xff << (byte * 8))
         }
     }
+
+    #[test]
+    fn test_float_hashes_differ() {
+        assert!(0.0.hash() != 1.0.hash());
+        assert!(1.0.hash() != (-1.0).hash());
+    }
+
+    #[test]
+    fn test_float_hashes_of_zero() {
+        assert_eq!(0.0.hash(), (-0.0).hash());
+    }
 }
diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs
index 85156d6996d..d05fa63a6f9 100644
--- a/src/libstd/hashmap.rs
+++ b/src/libstd/hashmap.rs
@@ -59,7 +59,7 @@ enum SearchResult {
     FoundEntry(uint), FoundHole(uint), TableFull
 }
 
-#[inline(always)]
+#[inline]
 fn resize_at(capacity: uint) -> uint {
     ((capacity as float) * 3. / 4.) as uint
 }
@@ -85,19 +85,19 @@ fn linear_map_with_capacity_and_keys<K:Eq + Hash,V>(
 }
 
 impl<K:Hash + Eq,V> HashMap<K, V> {
-    #[inline(always)]
+    #[inline]
     fn to_bucket(&self, h: uint) -> uint {
         // A good hash function with entropy spread over all of the
         // bits is assumed. SipHash is more than good enough.
         h % self.buckets.len()
     }
 
-    #[inline(always)]
+    #[inline]
     fn next_bucket(&self, idx: uint, len_buckets: uint) -> uint {
         (idx + 1) % len_buckets
     }
 
-    #[inline(always)]
+    #[inline]
     fn bucket_sequence(&self, hash: uint,
                        op: &fn(uint) -> bool) -> bool {
         let start_idx = self.to_bucket(hash);
@@ -112,20 +112,20 @@ impl<K:Hash + Eq,V> HashMap<K, V> {
         }
     }
 
-    #[inline(always)]
+    #[inline]
     fn bucket_for_key(&self, k: &K) -> SearchResult {
         let hash = k.hash_keyed(self.k0, self.k1) as uint;
         self.bucket_for_key_with_hash(hash, k)
     }
 
-    #[inline(always)]
+    #[inline]
     fn bucket_for_key_equiv<Q:Hash + Equiv<K>>(&self, k: &Q)
                                                -> SearchResult {
         let hash = k.hash_keyed(self.k0, self.k1) as uint;
         self.bucket_for_key_with_hash_equiv(hash, k)
     }
 
-    #[inline(always)]
+    #[inline]
     fn bucket_for_key_with_hash(&self,
                                 hash: uint,
                                 k: &K)
@@ -141,7 +141,7 @@ impl<K:Hash + Eq,V> HashMap<K, V> {
         TableFull
     }
 
-    #[inline(always)]
+    #[inline]
     fn bucket_for_key_with_hash_equiv<Q:Equiv<K>>(&self,
                                                   hash: uint,
                                                   k: &Q)
@@ -161,7 +161,7 @@ impl<K:Hash + Eq,V> HashMap<K, V> {
 
     /// Expand the capacity of the array to the next power of two
     /// and re-insert each of the existing buckets.
-    #[inline(always)]
+    #[inline]
     fn expand(&mut self) {
         let new_capacity = self.buckets.len() * 2;
         self.resize(new_capacity);
@@ -190,7 +190,7 @@ impl<K:Hash + Eq,V> HashMap<K, V> {
         }
     }
 
-    #[inline(always)]
+    #[inline]
     fn value_for_bucket<'a>(&'a self, idx: uint) -> &'a V {
         match self.buckets[idx] {
             Some(ref bkt) => &bkt.value,
@@ -198,7 +198,7 @@ impl<K:Hash + Eq,V> HashMap<K, V> {
         }
     }
 
-    #[inline(always)]
+    #[inline]
     fn mut_value_for_bucket<'a>(&'a mut self, idx: uint) -> &'a mut V {
         match self.buckets[idx] {
             Some(ref mut bkt) => &mut bkt.value,
diff --git a/src/libstd/io.rs b/src/libstd/io.rs
index 6f065d74fa2..e5e8a4cb601 100644
--- a/src/libstd/io.rs
+++ b/src/libstd/io.rs
@@ -1654,9 +1654,7 @@ impl Writer for BytesWriter {
         vec::reserve(bytes, count);
 
         unsafe {
-            // Silly stage0 borrow check workaround...
-            let casted: &mut ~[u8] = cast::transmute_copy(&bytes);
-            vec::raw::set_len(casted, count);
+            vec::raw::set_len(bytes, count);
 
             let view = vec::mut_slice(*bytes, *self.pos, count);
             vec::bytes::copy_memory(view, v, v_len);
@@ -1667,7 +1665,7 @@ impl Writer for BytesWriter {
 
     fn seek(&self, offset: int, whence: SeekStyle) {
         let pos = *self.pos;
-        let len = vec::uniq_len(&const *self.bytes);
+        let len = self.bytes.len();
         *self.pos = seek_in_buf(offset, pos, len, whence);
     }
 
@@ -1779,7 +1777,7 @@ pub mod fsync {
                 None => (),
                 Some(level) => {
                   // fail hard if not succesful
-                  assert!(((self.arg.fsync_fn)(self.arg.val, level)
+                  assert!(((self.arg.fsync_fn)(copy self.arg.val, level)
                     != -1));
                 }
             }
diff --git a/src/libstd/iter.rs b/src/libstd/iter.rs
index 2197feea452..7053cbe0df5 100644
--- a/src/libstd/iter.rs
+++ b/src/libstd/iter.rs
@@ -73,7 +73,7 @@ pub trait FromIter<T> {
  * assert!(!any(|&x: &uint| x > 5, |f| xs.each(f)));
  * ~~~
  */
-#[inline(always)]
+#[inline]
 pub fn any<T>(predicate: &fn(T) -> bool,
               iter: &fn(f: &fn(T) -> bool) -> bool) -> bool {
     for iter |x| {
@@ -94,7 +94,7 @@ pub fn any<T>(predicate: &fn(T) -> bool,
  * assert!(!all(|&x: &uint| x < 5, |f| uint::range(1, 6, f)));
  * ~~~
  */
-#[inline(always)]
+#[inline]
 pub fn all<T>(predicate: &fn(T) -> bool,
               iter: &fn(f: &fn(T) -> bool) -> bool) -> bool {
     // If we ever break, iter will return false, so this will only return true
@@ -112,7 +112,7 @@ pub fn all<T>(predicate: &fn(T) -> bool,
  * assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.each(f)).unwrap(), 4);
  * ~~~
  */
-#[inline(always)]
+#[inline]
 pub fn find<T>(predicate: &fn(&T) -> bool,
                iter: &fn(f: &fn(T) -> bool) -> bool) -> Option<T> {
     for iter |x| {
@@ -226,7 +226,7 @@ pub fn fold_ref<T, U>(start: T, iter: &fn(f: &fn(&U) -> bool) -> bool, f: &fn(&m
  * assert_eq!(do sum |f| { xs.each(f) }, 10);
  * ~~~
  */
-#[inline(always)]
+#[inline]
 pub fn sum<T: Zero + Add<T, T>>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T {
     fold_ref(Zero::zero::<T>(), iter, |a, x| *a = a.add(x))
 }
@@ -241,7 +241,7 @@ pub fn sum<T: Zero + Add<T, T>>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T {
  * assert_eq!(do product |f| { xs.each(f) }, 24);
  * ~~~
  */
-#[inline(always)]
+#[inline]
 pub fn product<T: One + Mul<T, T>>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T {
     fold_ref(One::one::<T>(), iter, |a, x| *a = a.mul(x))
 }
diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs
index e65904a6899..eefad1a03dc 100644
--- a/src/libstd/iterator.rs
+++ b/src/libstd/iterator.rs
@@ -308,6 +308,12 @@ pub trait IteratorUtil<A> {
     /// assert!(!it.any_(|&x| *x == 3));
     /// ~~~
     fn any_(&mut self, f: &fn(A) -> bool) -> bool;
+
+    /// Return the first element satisfying the specified predicate
+    fn find_(&mut self, predicate: &fn(&A) -> bool) -> Option<A>;
+
+    /// Return the index of the first element satisfying the specified predicate
+    fn position_(&mut self, predicate: &fn(A) -> bool) -> Option<uint>;
 }
 
 /// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also
@@ -315,59 +321,59 @@ pub trait IteratorUtil<A> {
 ///
 /// In the future these will be default methods instead of a utility trait.
 impl<A, T: Iterator<A>> IteratorUtil<A> for T {
-    #[inline(always)]
+    #[inline]
     fn chain_<U: Iterator<A>>(self, other: U) -> ChainIterator<A, T, U> {
         ChainIterator{a: self, b: other, flag: false}
     }
 
-    #[inline(always)]
+    #[inline]
     fn zip<B, U: Iterator<B>>(self, other: U) -> ZipIterator<A, T, B, U> {
         ZipIterator{a: self, b: other}
     }
 
     // FIXME: #5898: should be called map
-    #[inline(always)]
+    #[inline]
     fn transform<'r, B>(self, f: &'r fn(A) -> B) -> MapIterator<'r, A, B, T> {
         MapIterator{iter: self, f: f}
     }
 
-    #[inline(always)]
+    #[inline]
     fn filter<'r>(self, predicate: &'r fn(&A) -> bool) -> FilterIterator<'r, A, T> {
         FilterIterator{iter: self, predicate: predicate}
     }
 
-    #[inline(always)]
+    #[inline]
     fn filter_map<'r, B>(self, f: &'r fn(A) -> Option<B>) -> FilterMapIterator<'r, A, B, T> {
         FilterMapIterator { iter: self, f: f }
     }
 
-    #[inline(always)]
+    #[inline]
     fn enumerate(self) -> EnumerateIterator<A, T> {
         EnumerateIterator{iter: self, count: 0}
     }
 
-    #[inline(always)]
+    #[inline]
     fn skip_while<'r>(self, predicate: &'r fn(&A) -> bool) -> SkipWhileIterator<'r, A, T> {
         SkipWhileIterator{iter: self, flag: false, predicate: predicate}
     }
 
-    #[inline(always)]
+    #[inline]
     fn take_while<'r>(self, predicate: &'r fn(&A) -> bool) -> TakeWhileIterator<'r, A, T> {
         TakeWhileIterator{iter: self, flag: false, predicate: predicate}
     }
 
-    #[inline(always)]
+    #[inline]
     fn skip(self, n: uint) -> SkipIterator<A, T> {
         SkipIterator{iter: self, n: n}
     }
 
     // FIXME: #5898: should be called take
-    #[inline(always)]
+    #[inline]
     fn take_(self, n: uint) -> TakeIterator<A, T> {
         TakeIterator{iter: self, n: n}
     }
 
-    #[inline(always)]
+    #[inline]
     fn scan<'r, St, B>(self, initial_state: St, f: &'r fn(&mut St, A) -> Option<B>)
         -> ScanIterator<'r, A, B, T, St> {
         ScanIterator{iter: self, f: f, state: initial_state}
@@ -386,13 +392,13 @@ impl<A, T: Iterator<A>> IteratorUtil<A> for T {
         }
     }
 
-    #[inline(always)]
+    #[inline]
     fn collect<B: FromIter<A>>(&mut self) -> B {
         FromIter::from_iter::<A, B>(|f| self.advance(f))
     }
 
     /// Return the `n`th item yielded by an iterator.
-    #[inline(always)]
+    #[inline]
     fn nth(&mut self, mut n: uint) -> Option<A> {
         loop {
             match self.next() {
@@ -404,7 +410,7 @@ impl<A, T: Iterator<A>> IteratorUtil<A> for T {
     }
 
     /// Return the last item yielded by an iterator.
-    #[inline(always)]
+    #[inline]
     fn last_(&mut self) -> Option<A> {
         let mut last = None;
         for self.advance |x| { last = Some(x); }
@@ -421,23 +427,45 @@ impl<A, T: Iterator<A>> IteratorUtil<A> for T {
                 None    => { break; }
             }
         }
-        return accum;
+        accum
     }
 
     /// Count the number of items yielded by an iterator
-    #[inline(always)]
+    #[inline]
     fn count(&mut self) -> uint { self.fold(0, |cnt, _x| cnt + 1) }
 
-    #[inline(always)]
+    #[inline]
     fn all(&mut self, f: &fn(A) -> bool) -> bool {
         for self.advance |x| { if !f(x) { return false; } }
-        return true;
+        true
     }
 
-    #[inline(always)]
+    #[inline]
     fn any_(&mut self, f: &fn(A) -> bool) -> bool {
         for self.advance |x| { if f(x) { return true; } }
-        return false;
+        false
+    }
+
+    /// Return the first element satisfying the specified predicate
+    #[inline]
+    fn find_(&mut self, predicate: &fn(&A) -> bool) -> Option<A> {
+        for self.advance |x| {
+            if predicate(&x) { return Some(x) }
+        }
+        None
+    }
+
+    /// Return the index of the first element satisfying the specified predicate
+    #[inline]
+    fn position_(&mut self, predicate: &fn(A) -> bool) -> Option<uint> {
+        let mut i = 0;
+        for self.advance |x| {
+            if predicate(x) {
+                return Some(i);
+            }
+            i += 1;
+        }
+        None
     }
 }
 
@@ -456,7 +484,7 @@ pub trait AdditiveIterator<A> {
 }
 
 impl<A: Add<A, A> + Zero, T: Iterator<A>> AdditiveIterator<A> for T {
-    #[inline(always)]
+    #[inline]
     fn sum(&mut self) -> A { self.fold(Zero::zero::<A>(), |s, x| s + x) }
 }
 
@@ -481,7 +509,7 @@ pub trait MultiplicativeIterator<A> {
 }
 
 impl<A: Mul<A, A> + One, T: Iterator<A>> MultiplicativeIterator<A> for T {
-    #[inline(always)]
+    #[inline]
     fn product(&mut self) -> A { self.fold(One::one::<A>(), |p, x| p * x) }
 }
 
@@ -510,7 +538,7 @@ pub trait OrdIterator<A> {
 }
 
 impl<A: Ord, T: Iterator<A>> OrdIterator<A> for T {
-    #[inline(always)]
+    #[inline]
     fn max(&mut self) -> Option<A> {
         self.fold(None, |max, x| {
             match max {
@@ -520,7 +548,7 @@ impl<A: Ord, T: Iterator<A>> OrdIterator<A> for T {
         })
     }
 
-    #[inline(always)]
+    #[inline]
     fn min(&mut self) -> Option<A> {
         self.fold(None, |min, x| {
             match min {
@@ -788,8 +816,8 @@ impl<'self, A, St> UnfoldrIterator<'self, A, St> {
     /// Creates a new iterator with the specified closure as the "iterator
     /// function" and an initial state to eventually pass to the iterator
     #[inline]
-    pub fn new(f: &'self fn(&mut St) -> Option<A>, initial_state: St)
-        -> UnfoldrIterator<'self, A, St> {
+    pub fn new<'a>(f: &'a fn(&mut St) -> Option<A>, initial_state: St)
+        -> UnfoldrIterator<'a, A, St> {
         UnfoldrIterator {
             f: f,
             state: initial_state
@@ -815,14 +843,14 @@ pub struct Counter<A> {
 
 impl<A> Counter<A> {
     /// Creates a new counter with the specified start/step
-    #[inline(always)]
+    #[inline]
     pub fn new(start: A, step: A) -> Counter<A> {
         Counter{state: start, step: step}
     }
 }
 
 impl<A: Add<A, A> + Clone> Iterator<A> for Counter<A> {
-    #[inline(always)]
+    #[inline]
     fn next(&mut self) -> Option<A> {
         let result = self.state.clone();
         self.state = self.state.add(&self.step); // FIXME: #6050
@@ -1055,4 +1083,20 @@ mod tests {
         assert!(!v.iter().any_(|&x| x > 100));
         assert!(!v.slice(0, 0).iter().any_(|_| fail!()));
     }
+
+    #[test]
+    fn test_find() {
+        let v = &[1, 3, 9, 27, 103, 14, 11];
+        assert_eq!(*v.iter().find_(|x| *x & 1 == 0).unwrap(), 14);
+        assert_eq!(*v.iter().find_(|x| *x % 3 == 0).unwrap(), 3);
+        assert!(v.iter().find_(|x| *x % 12 == 0).is_none());
+    }
+
+    #[test]
+    fn test_position() {
+        let v = &[1, 3, 9, 27, 103, 14, 11];
+        assert_eq!(v.iter().position_(|x| *x & 1 == 0).unwrap(), 5);
+        assert_eq!(v.iter().position_(|x| *x % 3 == 0).unwrap(), 1);
+        assert!(v.iter().position_(|x| *x % 12 == 0).is_none());
+    }
 }
diff --git a/src/libstd/libc.rs b/src/libstd/libc.rs
index 26205c930f0..07b2ac6ed01 100644
--- a/src/libstd/libc.rs
+++ b/src/libstd/libc.rs
@@ -14,8 +14,8 @@
 * This module contains bindings to the C standard library,
 * organized into modules by their defining standard.
 * Additionally, it contains some assorted platform-specific definitions.
-* For convenience, most functions and types are reexported from `core::libc`,
-* so `pub use core::libc::*` will import the available
+* For convenience, most functions and types are reexported from `std::libc`,
+* so `pub use std::libc::*` will import the available
 * C bindings as appropriate for the target platform. The exact
 * set of functions available are platform specific.
 *
@@ -1457,11 +1457,11 @@ pub mod funcs {
                 // These are fine to execute on the Rust stack. They must be,
                 // in fact, because LLVM generates calls to them!
                 #[rust_stack]
-                #[inline(always)]
+                #[inline]
                 unsafe fn memcmp(cx: *c_void, ct: *c_void, n: size_t)
                               -> c_int;
                 #[rust_stack]
-                #[inline(always)]
+                #[inline]
                 unsafe fn memchr(cx: *c_void, c: c_int, n: size_t) -> *c_void;
             }
         }
diff --git a/src/libstd/logging.rs b/src/libstd/logging.rs
index c2f854179b8..743b71e33ea 100644
--- a/src/libstd/logging.rs
+++ b/src/libstd/logging.rs
@@ -11,13 +11,20 @@
 //! Logging
 
 use option::*;
+use os;
 use either::*;
+use rt;
+use rt::OldTaskContext;
 use rt::logging::{Logger, StdErrLogger};
 
 /// Turns on logging to stdout globally
 pub fn console_on() {
-    unsafe {
-        rustrt::rust_log_console_on();
+    if rt::context() == OldTaskContext {
+        unsafe {
+            rustrt::rust_log_console_on();
+        }
+    } else {
+        rt::logging::console_on();
     }
 }
 
@@ -29,8 +36,17 @@ pub fn console_on() {
  * the RUST_LOG environment variable
  */
 pub fn console_off() {
-    unsafe {
-        rustrt::rust_log_console_off();
+    // If RUST_LOG is set then the console can't be turned off
+    if os::getenv("RUST_LOG").is_some() {
+        return;
+    }
+
+    if rt::context() == OldTaskContext {
+        unsafe {
+            rustrt::rust_log_console_off();
+        }
+    } else {
+        rt::logging::console_off();
     }
 }
 
diff --git a/src/libstd/managed.rs b/src/libstd/managed.rs
index 7d0defea05a..d514612b5af 100644
--- a/src/libstd/managed.rs
+++ b/src/libstd/managed.rs
@@ -38,14 +38,14 @@ pub mod raw {
 }
 
 /// Determine if two shared boxes point to the same object
-#[inline(always)]
+#[inline]
 pub fn ptr_eq<T>(a: @T, b: @T) -> bool {
     let (a_ptr, b_ptr): (*T, *T) = (to_unsafe_ptr(&*a), to_unsafe_ptr(&*b));
     a_ptr == b_ptr
 }
 
 /// Determine if two mutable shared boxes point to the same object
-#[inline(always)]
+#[inline]
 pub fn mut_ptr_eq<T>(a: @mut T, b: @mut T) -> bool {
     let (a_ptr, b_ptr): (*T, *T) = (to_unsafe_ptr(&*a), to_unsafe_ptr(&*b));
     a_ptr == b_ptr
@@ -53,41 +53,41 @@ pub fn mut_ptr_eq<T>(a: @mut T, b: @mut T) -> bool {
 
 #[cfg(not(test))]
 impl<T:Eq> Eq for @T {
-    #[inline(always)]
+    #[inline]
     fn eq(&self, other: &@T) -> bool { *(*self) == *(*other) }
-    #[inline(always)]
+    #[inline]
     fn ne(&self, other: &@T) -> bool { *(*self) != *(*other) }
 }
 
 #[cfg(not(test))]
 impl<T:Eq> Eq for @mut T {
-    #[inline(always)]
+    #[inline]
     fn eq(&self, other: &@mut T) -> bool { *(*self) == *(*other) }
-    #[inline(always)]
+    #[inline]
     fn ne(&self, other: &@mut T) -> bool { *(*self) != *(*other) }
 }
 
 #[cfg(not(test))]
 impl<T:Ord> Ord for @T {
-    #[inline(always)]
+    #[inline]
     fn lt(&self, other: &@T) -> bool { *(*self) < *(*other) }
-    #[inline(always)]
+    #[inline]
     fn le(&self, other: &@T) -> bool { *(*self) <= *(*other) }
-    #[inline(always)]
+    #[inline]
     fn ge(&self, other: &@T) -> bool { *(*self) >= *(*other) }
-    #[inline(always)]
+    #[inline]
     fn gt(&self, other: &@T) -> bool { *(*self) > *(*other) }
 }
 
 #[cfg(not(test))]
 impl<T:Ord> Ord for @mut T {
-    #[inline(always)]
+    #[inline]
     fn lt(&self, other: &@mut T) -> bool { *(*self) < *(*other) }
-    #[inline(always)]
+    #[inline]
     fn le(&self, other: &@mut T) -> bool { *(*self) <= *(*other) }
-    #[inline(always)]
+    #[inline]
     fn ge(&self, other: &@mut T) -> bool { *(*self) >= *(*other) }
-    #[inline(always)]
+    #[inline]
     fn gt(&self, other: &@mut T) -> bool { *(*self) > *(*other) }
 }
 
diff --git a/src/libstd/nil.rs b/src/libstd/nil.rs
index 833bd3459ce..40f6d53ed22 100644
--- a/src/libstd/nil.rs
+++ b/src/libstd/nil.rs
@@ -19,32 +19,32 @@ use prelude::*;
 
 #[cfg(not(test))]
 impl Eq for () {
-    #[inline(always)]
+    #[inline]
     fn eq(&self, _other: &()) -> bool { true }
-    #[inline(always)]
+    #[inline]
     fn ne(&self, _other: &()) -> bool { false }
 }
 
 #[cfg(not(test))]
 impl Ord for () {
-    #[inline(always)]
+    #[inline]
     fn lt(&self, _other: &()) -> bool { false }
-    #[inline(always)]
+    #[inline]
     fn le(&self, _other: &()) -> bool { true }
-    #[inline(always)]
+    #[inline]
     fn ge(&self, _other: &()) -> bool { true }
-    #[inline(always)]
+    #[inline]
     fn gt(&self, _other: &()) -> bool { false }
 }
 
 #[cfg(not(test))]
 impl TotalOrd for () {
-    #[inline(always)]
+    #[inline]
     fn cmp(&self, _other: &()) -> Ordering { Equal }
 }
 
 #[cfg(not(test))]
 impl TotalEq for () {
-    #[inline(always)]
+    #[inline]
     fn equals(&self, _other: &()) -> bool { true }
 }
diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs
index 7f981187300..117a474ffd7 100644
--- a/src/libstd/num/f32.rs
+++ b/src/libstd/num/f32.rs
@@ -20,7 +20,7 @@ use to_str;
 
 pub use cmath::c_float_targ_consts::*;
 
-// An inner module is required to get the #[inline(always)] attribute on the
+// An inner module is required to get the #[inline] attribute on the
 // functions.
 pub use self::delegated::*;
 
@@ -40,7 +40,7 @@ macro_rules! delegate(
             use unstable::intrinsics;
 
             $(
-                #[inline(always)]
+                #[inline]
                 pub fn $name($( $arg : $arg_ty ),*) -> $rv {
                     unsafe {
                         $bound_name($( $arg ),*)
@@ -115,45 +115,45 @@ pub static infinity: f32 = 1.0_f32/0.0_f32;
 
 pub static neg_infinity: f32 = -1.0_f32/0.0_f32;
 
-#[inline(always)]
+#[inline]
 pub fn add(x: f32, y: f32) -> f32 { return x + y; }
 
-#[inline(always)]
+#[inline]
 pub fn sub(x: f32, y: f32) -> f32 { return x - y; }
 
-#[inline(always)]
+#[inline]
 pub fn mul(x: f32, y: f32) -> f32 { return x * y; }
 
-#[inline(always)]
+#[inline]
 pub fn div(x: f32, y: f32) -> f32 { return x / y; }
 
-#[inline(always)]
+#[inline]
 pub fn rem(x: f32, y: f32) -> f32 { return x % y; }
 
-#[inline(always)]
+#[inline]
 pub fn lt(x: f32, y: f32) -> bool { return x < y; }
 
-#[inline(always)]
+#[inline]
 pub fn le(x: f32, y: f32) -> bool { return x <= y; }
 
-#[inline(always)]
+#[inline]
 pub fn eq(x: f32, y: f32) -> bool { return x == y; }
 
-#[inline(always)]
+#[inline]
 pub fn ne(x: f32, y: f32) -> bool { return x != y; }
 
-#[inline(always)]
+#[inline]
 pub fn ge(x: f32, y: f32) -> bool { return x >= y; }
 
-#[inline(always)]
+#[inline]
 pub fn gt(x: f32, y: f32) -> bool { return x > y; }
 
-#[inline(always)]
+#[inline]
 pub fn fmax(x: f32, y: f32) -> f32 {
     if x >= y || y.is_NaN() { x } else { y }
 }
 
-#[inline(always)]
+#[inline]
 pub fn fmin(x: f32, y: f32) -> f32 {
     if x <= y || y.is_NaN() { x } else { y }
 }
@@ -212,23 +212,23 @@ impl Num for f32 {}
 
 #[cfg(not(test))]
 impl Eq for f32 {
-    #[inline(always)]
+    #[inline]
     fn eq(&self, other: &f32) -> bool { (*self) == (*other) }
-    #[inline(always)]
+    #[inline]
     fn ne(&self, other: &f32) -> bool { (*self) != (*other) }
 }
 
 #[cfg(not(test))]
 impl ApproxEq<f32> for f32 {
-    #[inline(always)]
+    #[inline]
     fn approx_epsilon() -> f32 { 1.0e-6 }
 
-    #[inline(always)]
+    #[inline]
     fn approx_eq(&self, other: &f32) -> bool {
         self.approx_eq_eps(other, &ApproxEq::approx_epsilon::<f32, f32>())
     }
 
-    #[inline(always)]
+    #[inline]
     fn approx_eq_eps(&self, other: &f32, approx_epsilon: &f32) -> bool {
         (*self - *other).abs() < *approx_epsilon
     }
@@ -236,32 +236,32 @@ impl ApproxEq<f32> for f32 {
 
 #[cfg(not(test))]
 impl Ord for f32 {
-    #[inline(always)]
+    #[inline]
     fn lt(&self, other: &f32) -> bool { (*self) < (*other) }
-    #[inline(always)]
+    #[inline]
     fn le(&self, other: &f32) -> bool { (*self) <= (*other) }
-    #[inline(always)]
+    #[inline]
     fn ge(&self, other: &f32) -> bool { (*self) >= (*other) }
-    #[inline(always)]
+    #[inline]
     fn gt(&self, other: &f32) -> bool { (*self) > (*other) }
 }
 
 impl Orderable for f32 {
     /// Returns `NaN` if either of the numbers are `NaN`.
-    #[inline(always)]
+    #[inline]
     fn min(&self, other: &f32) -> f32 {
         if self.is_NaN() || other.is_NaN() { Float::NaN() } else { fmin(*self, *other) }
     }
 
     /// Returns `NaN` if either of the numbers are `NaN`.
-    #[inline(always)]
+    #[inline]
     fn max(&self, other: &f32) -> f32 {
         if self.is_NaN() || other.is_NaN() { Float::NaN() } else { fmax(*self, *other) }
     }
 
     /// Returns the number constrained within the range `mn <= self <= mx`.
     /// If any of the numbers are `NaN` then `NaN` is returned.
-    #[inline(always)]
+    #[inline]
     fn clamp(&self, mn: &f32, mx: &f32) -> f32 {
         cond!(
             (self.is_NaN())   { *self }
@@ -273,65 +273,65 @@ impl Orderable for f32 {
 }
 
 impl Zero for f32 {
-    #[inline(always)]
+    #[inline]
     fn zero() -> f32 { 0.0 }
 
     /// Returns true if the number is equal to either `0.0` or `-0.0`
-    #[inline(always)]
+    #[inline]
     fn is_zero(&self) -> bool { *self == 0.0 || *self == -0.0 }
 }
 
 impl One for f32 {
-    #[inline(always)]
+    #[inline]
     fn one() -> f32 { 1.0 }
 }
 
 #[cfg(not(test))]
 impl Add<f32,f32> for f32 {
-    #[inline(always)]
+    #[inline]
     fn add(&self, other: &f32) -> f32 { *self + *other }
 }
 
 #[cfg(not(test))]
 impl Sub<f32,f32> for f32 {
-    #[inline(always)]
+    #[inline]
     fn sub(&self, other: &f32) -> f32 { *self - *other }
 }
 
 #[cfg(not(test))]
 impl Mul<f32,f32> for f32 {
-    #[inline(always)]
+    #[inline]
     fn mul(&self, other: &f32) -> f32 { *self * *other }
 }
 
 #[cfg(not(test))]
 impl Div<f32,f32> for f32 {
-    #[inline(always)]
+    #[inline]
     fn div(&self, other: &f32) -> f32 { *self / *other }
 }
 
 #[cfg(not(test))]
 impl Rem<f32,f32> for f32 {
-    #[inline(always)]
+    #[inline]
     fn rem(&self, other: &f32) -> f32 { *self % *other }
 }
 
 #[cfg(not(test))]
 impl Neg<f32> for f32 {
-    #[inline(always)]
+    #[inline]
     fn neg(&self) -> f32 { -*self }
 }
 
 impl Signed for f32 {
     /// Computes the absolute value. Returns `NaN` if the number is `NaN`.
-    #[inline(always)]
+    #[inline]
     fn abs(&self) -> f32 { abs(*self) }
 
     ///
     /// The positive difference of two numbers. Returns `0.0` if the number is less than or
     /// equal to `other`, otherwise the difference between`self` and `other` is returned.
     ///
-    #[inline(always)]
+    #[inline]
     fn abs_sub(&self, other: &f32) -> f32 { abs_sub(*self, *other) }
 
     ///
@@ -341,35 +341,35 @@ impl Signed for f32 {
     /// - `-1.0` if the number is negative, `-0.0` or `neg_infinity`
     /// - `NaN` if the number is NaN
     ///
-    #[inline(always)]
+    #[inline]
     fn signum(&self) -> f32 {
         if self.is_NaN() { NaN } else { copysign(1.0, *self) }
     }
 
     /// Returns `true` if the number is positive, including `+0.0` and `infinity`
-    #[inline(always)]
+    #[inline]
     fn is_positive(&self) -> bool { *self > 0.0 || (1.0 / *self) == infinity }
 
     /// Returns `true` if the number is negative, including `-0.0` and `neg_infinity`
-    #[inline(always)]
+    #[inline]
     fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == neg_infinity }
 }
 
 impl Round for f32 {
     /// Round half-way cases toward `neg_infinity`
-    #[inline(always)]
+    #[inline]
     fn floor(&self) -> f32 { floor(*self) }
 
     /// Round half-way cases toward `infinity`
-    #[inline(always)]
+    #[inline]
     fn ceil(&self) -> f32 { ceil(*self) }
 
     /// Round half-way cases away from `0.0`
-    #[inline(always)]
+    #[inline]
     fn round(&self) -> f32 { round(*self) }
 
     /// The integer part of the number (rounds towards `0.0`)
-    #[inline(always)]
+    #[inline]
     fn trunc(&self) -> f32 { trunc(*self) }
 
     ///
@@ -379,57 +379,57 @@ impl Round for f32 {
     /// assert!(x == trunc(x) + fract(x))
     /// ~~~
     ///
-    #[inline(always)]
+    #[inline]
     fn fract(&self) -> f32 { *self - self.trunc() }
 }
 
 impl Fractional for f32 {
     /// The reciprocal (multiplicative inverse) of the number
-    #[inline(always)]
+    #[inline]
     fn recip(&self) -> f32 { 1.0 / *self }
 }
 
 impl Algebraic for f32 {
-    #[inline(always)]
+    #[inline]
     fn pow(&self, n: &f32) -> f32 { pow(*self, *n) }
 
-    #[inline(always)]
+    #[inline]
     fn sqrt(&self) -> f32 { sqrt(*self) }
 
-    #[inline(always)]
+    #[inline]
     fn rsqrt(&self) -> f32 { self.sqrt().recip() }
 
-    #[inline(always)]
+    #[inline]
     fn cbrt(&self) -> f32 { cbrt(*self) }
 
-    #[inline(always)]
+    #[inline]
     fn hypot(&self, other: &f32) -> f32 { hypot(*self, *other) }
 }
 
 impl Trigonometric for f32 {
-    #[inline(always)]
+    #[inline]
     fn sin(&self) -> f32 { sin(*self) }
 
-    #[inline(always)]
+    #[inline]
     fn cos(&self) -> f32 { cos(*self) }
 
-    #[inline(always)]
+    #[inline]
     fn tan(&self) -> f32 { tan(*self) }
 
-    #[inline(always)]
+    #[inline]
     fn asin(&self) -> f32 { asin(*self) }
 
-    #[inline(always)]
+    #[inline]
     fn acos(&self) -> f32 { acos(*self) }
 
-    #[inline(always)]
+    #[inline]
     fn atan(&self) -> f32 { atan(*self) }
 
-    #[inline(always)]
+    #[inline]
     fn atan2(&self, other: &f32) -> f32 { atan2(*self, *other) }
 
     /// Simultaneously computes the sine and cosine of the number
-    #[inline(always)]
+    #[inline]
     fn sin_cos(&self) -> (f32, f32) {
         (self.sin(), self.cos())
     }
@@ -437,38 +437,38 @@ impl Trigonometric for f32 {
 
 impl Exponential for f32 {
     /// Returns the exponential of the number
-    #[inline(always)]
+    #[inline]
     fn exp(&self) -> f32 { exp(*self) }
 
     /// Returns 2 raised to the power of the number
-    #[inline(always)]
+    #[inline]
     fn exp2(&self) -> f32 { exp2(*self) }
 
     /// Returns the natural logarithm of the number
-    #[inline(always)]
+    #[inline]
     fn ln(&self) -> f32 { ln(*self) }
 
     /// Returns the logarithm of the number with respect to an arbitrary base
-    #[inline(always)]
+    #[inline]
     fn log(&self, base: &f32) -> f32 { self.ln() / base.ln() }
 
     /// Returns the base 2 logarithm of the number
-    #[inline(always)]
+    #[inline]
     fn log2(&self) -> f32 { log2(*self) }
 
     /// Returns the base 10 logarithm of the number
-    #[inline(always)]
+    #[inline]
     fn log10(&self) -> f32 { log10(*self) }
 }
 
 impl Hyperbolic for f32 {
-    #[inline(always)]
+    #[inline]
     fn sinh(&self) -> f32 { sinh(*self) }
 
-    #[inline(always)]
+    #[inline]
     fn cosh(&self) -> f32 { cosh(*self) }
 
-    #[inline(always)]
+    #[inline]
     fn tanh(&self) -> f32 { tanh(*self) }
 
     ///
@@ -480,7 +480,7 @@ impl Hyperbolic for f32 {
     /// - `self` if `self` is `0.0`, `-0.0`, `infinity`, or `neg_infinity`
     /// - `NaN` if `self` is `NaN`
     ///
-    #[inline(always)]
+    #[inline]
     fn asinh(&self) -> f32 {
         match *self {
             neg_infinity => neg_infinity,
@@ -497,7 +497,7 @@ impl Hyperbolic for f32 {
     /// - `infinity` if `self` is `infinity`
     /// - `NaN` if `self` is `NaN` or `self < 1.0` (including `neg_infinity`)
     ///
-    #[inline(always)]
+    #[inline]
     fn acosh(&self) -> f32 {
         match *self {
             x if x < 1.0 => Float::NaN(),
@@ -517,7 +517,7 @@ impl Hyperbolic for f32 {
     /// - `NaN` if the `self` is `NaN` or outside the domain of `-1.0 <= self <= 1.0`
     ///   (including `infinity` and `neg_infinity`)
     ///
-    #[inline(always)]
+    #[inline]
     fn atanh(&self) -> f32 {
         0.5 * ((2.0 * *self) / (1.0 - *self)).ln_1p()
     }
@@ -525,129 +525,129 @@ impl Hyperbolic for f32 {
 
 impl Real for f32 {
     /// Archimedes' constant
-    #[inline(always)]
+    #[inline]
     fn pi() -> f32 { 3.14159265358979323846264338327950288 }
 
     /// 2.0 * pi
-    #[inline(always)]
+    #[inline]
     fn two_pi() -> f32 { 6.28318530717958647692528676655900576 }
 
     /// pi / 2.0
-    #[inline(always)]
+    #[inline]
     fn frac_pi_2() -> f32 { 1.57079632679489661923132169163975144 }
 
     /// pi / 3.0
-    #[inline(always)]
+    #[inline]
     fn frac_pi_3() -> f32 { 1.04719755119659774615421446109316763 }
 
     /// pi / 4.0
-    #[inline(always)]
+    #[inline]
     fn frac_pi_4() -> f32 { 0.785398163397448309615660845819875721 }
 
     /// pi / 6.0
-    #[inline(always)]
+    #[inline]
     fn frac_pi_6() -> f32 { 0.52359877559829887307710723054658381 }
 
     /// pi / 8.0
-    #[inline(always)]
+    #[inline]
     fn frac_pi_8() -> f32 { 0.39269908169872415480783042290993786 }
 
     /// 1 .0/ pi
-    #[inline(always)]
+    #[inline]
     fn frac_1_pi() -> f32 { 0.318309886183790671537767526745028724 }
 
     /// 2.0 / pi
-    #[inline(always)]
+    #[inline]
     fn frac_2_pi() -> f32 { 0.636619772367581343075535053490057448 }
 
     /// 2.0 / sqrt(pi)
-    #[inline(always)]
+    #[inline]
     fn frac_2_sqrtpi() -> f32 { 1.12837916709551257389615890312154517 }
 
     /// sqrt(2.0)
-    #[inline(always)]
+    #[inline]
     fn sqrt2() -> f32 { 1.41421356237309504880168872420969808 }
 
     /// 1.0 / sqrt(2.0)
-    #[inline(always)]
+    #[inline]
     fn frac_1_sqrt2() -> f32 { 0.707106781186547524400844362104849039 }
 
     /// Euler's number
-    #[inline(always)]
+    #[inline]
     fn e() -> f32 { 2.71828182845904523536028747135266250 }
 
     /// log2(e)
-    #[inline(always)]
+    #[inline]
     fn log2_e() -> f32 { 1.44269504088896340735992468100189214 }
 
     /// log10(e)
-    #[inline(always)]
+    #[inline]
     fn log10_e() -> f32 { 0.434294481903251827651128918916605082 }
 
     /// ln(2.0)
-    #[inline(always)]
+    #[inline]
     fn ln_2() -> f32 { 0.693147180559945309417232121458176568 }
 
     /// ln(10.0)
-    #[inline(always)]
+    #[inline]
     fn ln_10() -> f32 { 2.30258509299404568401799145468436421 }
 
     /// Converts to degrees, assuming the number is in radians
-    #[inline(always)]
+    #[inline]
     fn to_degrees(&self) -> f32 { *self * (180.0 / Real::pi::<f32>()) }
 
     /// Converts to radians, assuming the number is in degrees
-    #[inline(always)]
+    #[inline]
     fn to_radians(&self) -> f32 { *self * (Real::pi::<f32>() / 180.0) }
 }
 
 impl Bounded for f32 {
-    #[inline(always)]
+    #[inline]
     fn min_value() -> f32 { 1.17549435e-38 }
 
-    #[inline(always)]
+    #[inline]
     fn max_value() -> f32 { 3.40282347e+38 }
 }
 
 impl Primitive for f32 {
-    #[inline(always)]
+    #[inline]
     fn bits() -> uint { 32 }
 
-    #[inline(always)]
+    #[inline]
     fn bytes() -> uint { Primitive::bits::<f32>() / 8 }
 }
 
 impl Float for f32 {
-    #[inline(always)]
+    #[inline]
     fn NaN() -> f32 { 0.0 / 0.0 }
 
-    #[inline(always)]
+    #[inline]
     fn infinity() -> f32 { 1.0 / 0.0 }
 
-    #[inline(always)]
+    #[inline]
     fn neg_infinity() -> f32 { -1.0 / 0.0 }
 
-    #[inline(always)]
+    #[inline]
     fn neg_zero() -> f32 { -0.0 }
 
     /// Returns `true` if the number is NaN
-    #[inline(always)]
+    #[inline]
     fn is_NaN(&self) -> bool { *self != *self }
 
     /// Returns `true` if the number is infinite
-    #[inline(always)]
+    #[inline]
     fn is_infinite(&self) -> bool {
         *self == Float::infinity() || *self == Float::neg_infinity()
     }
 
     /// Returns `true` if the number is neither infinite or NaN
-    #[inline(always)]
+    #[inline]
     fn is_finite(&self) -> bool {
         !(self.is_NaN() || self.is_infinite())
     }
 
     /// Returns `true` if the number is neither zero, infinite, subnormal or NaN
-    #[inline(always)]
+    #[inline]
     fn is_normal(&self) -> bool {
         self.classify() == FPNormal
     }
@@ -670,29 +670,29 @@ impl Float for f32 {
         }
     }
 
-    #[inline(always)]
+    #[inline]
     fn mantissa_digits() -> uint { 24 }
 
-    #[inline(always)]
+    #[inline]
     fn digits() -> uint { 6 }
 
-    #[inline(always)]
+    #[inline]
     fn epsilon() -> f32 { 1.19209290e-07 }
 
-    #[inline(always)]
+    #[inline]
     fn min_exp() -> int { -125 }
 
-    #[inline(always)]
+    #[inline]
     fn max_exp() -> int { 128 }
 
-    #[inline(always)]
+    #[inline]
     fn min_10_exp() -> int { -37 }
 
-    #[inline(always)]
+    #[inline]
     fn max_10_exp() -> int { 38 }
 
     /// Constructs a floating point number by multiplying `x` by 2 raised to the power of `exp`
-    #[inline(always)]
+    #[inline]
     fn ldexp(x: f32, exp: int) -> f32 {
         ldexp(x, exp as c_int)
     }
@@ -703,7 +703,7 @@ impl Float for f32 {
     /// - `self = x * pow(2, exp)`
     /// - `0.5 <= abs(x) < 1.0`
     ///
-    #[inline(always)]
+    #[inline]
     fn frexp(&self) -> (f32, int) {
         let mut exp = 0;
         let x = frexp(*self, &mut exp);
@@ -714,14 +714,14 @@ impl Float for f32 {
     /// Returns the exponential of the number, minus `1`, in a way that is accurate
     /// even if the number is close to zero
     ///
-    #[inline(always)]
+    #[inline]
     fn exp_m1(&self) -> f32 { exp_m1(*self) }
 
     ///
     /// Returns the natural logarithm of the number plus `1` (`ln(1+n)`) more accurately
     /// than if the operations were performed separately
     ///
-    #[inline(always)]
+    #[inline]
     fn ln_1p(&self) -> f32 { ln_1p(*self) }
 
     ///
@@ -729,13 +729,13 @@ impl Float for f32 {
     /// produces a more accurate result with better performance than a separate multiplication
     /// operation followed by an add.
     ///
-    #[inline(always)]
+    #[inline]
     fn mul_add(&self, a: f32, b: f32) -> f32 {
         mul_add(*self, a, b)
     }
 
     /// Returns the next representable floating-point value in the direction of `other`
-    #[inline(always)]
+    #[inline]
     fn next_after(&self, other: f32) -> f32 {
         next_after(*self, other)
     }
@@ -752,7 +752,7 @@ impl Float for f32 {
 ///
 /// * num - The float value
 ///
-#[inline(always)]
+#[inline]
 pub fn to_str(num: f32) -> ~str {
     let (r, _) = strconv::to_str_common(
         &num, 10u, true, strconv::SignNeg, strconv::DigAll);
@@ -766,7 +766,7 @@ pub fn to_str(num: f32) -> ~str {
 ///
 /// * num - The float value
 ///
-#[inline(always)]
+#[inline]
 pub fn to_str_hex(num: f32) -> ~str {
     let (r, _) = strconv::to_str_common(
         &num, 16u, true, strconv::SignNeg, strconv::DigAll);
@@ -787,7 +787,7 @@ pub fn to_str_hex(num: f32) -> ~str {
 /// possible misinterpretation of the result at higher bases. If those values
 /// are expected, use `to_str_radix_special()` instead.
 ///
-#[inline(always)]
+#[inline]
 pub fn to_str_radix(num: f32, rdx: uint) -> ~str {
     let (r, special) = strconv::to_str_common(
         &num, rdx, true, strconv::SignNeg, strconv::DigAll);
@@ -805,7 +805,7 @@ pub fn to_str_radix(num: f32, rdx: uint) -> ~str {
 /// * num - The float value
 /// * radix - The base to use
 ///
-#[inline(always)]
+#[inline]
 pub fn to_str_radix_special(num: f32, rdx: uint) -> (~str, bool) {
     strconv::to_str_common(&num, rdx, true,
                            strconv::SignNeg, strconv::DigAll)
@@ -820,7 +820,7 @@ pub fn to_str_radix_special(num: f32, rdx: uint) -> (~str, bool) {
 /// * num - The float value
 /// * digits - The number of significant digits
 ///
-#[inline(always)]
+#[inline]
 pub fn to_str_exact(num: f32, dig: uint) -> ~str {
     let (r, _) = strconv::to_str_common(
         &num, 10u, true, strconv::SignNeg, strconv::DigExact(dig));
@@ -836,7 +836,7 @@ pub fn to_str_exact(num: f32, dig: uint) -> ~str {
 /// * num - The float value
 /// * digits - The number of significant digits
 ///
-#[inline(always)]
+#[inline]
 pub fn to_str_digits(num: f32, dig: uint) -> ~str {
     let (r, _) = strconv::to_str_common(
         &num, 10u, true, strconv::SignNeg, strconv::DigMax(dig));
@@ -844,12 +844,12 @@ pub fn to_str_digits(num: f32, dig: uint) -> ~str {
 }
 
 impl to_str::ToStr for f32 {
-    #[inline(always)]
+    #[inline]
     fn to_str(&self) -> ~str { to_str_digits(*self, 8) }
 }
 
 impl num::ToStrRadix for f32 {
-    #[inline(always)]
+    #[inline]
     fn to_str_radix(&self, rdx: uint) -> ~str {
         to_str_radix(*self, rdx)
     }
@@ -882,7 +882,7 @@ impl num::ToStrRadix for f32 {
 /// `none` if the string did not represent a valid number.  Otherwise,
 /// `Some(n)` where `n` is the floating-point number represented by `num`.
 ///
-#[inline(always)]
+#[inline]
 pub fn from_str(num: &str) -> Option<f32> {
     strconv::from_str_common(num, 10u, true, true, true,
                              strconv::ExpDec, false, false)
@@ -915,7 +915,7 @@ pub fn from_str(num: &str) -> Option<f32> {
 /// `none` if the string did not represent a valid number.  Otherwise,
 /// `Some(n)` where `n` is the floating-point number represented by `[num]`.
 ///
-#[inline(always)]
+#[inline]
 pub fn from_str_hex(num: &str) -> Option<f32> {
     strconv::from_str_common(num, 16u, true, true, true,
                              strconv::ExpBin, false, false)
@@ -940,19 +940,19 @@ pub fn from_str_hex(num: &str) -> Option<f32> {
 /// `none` if the string did not represent a valid number. Otherwise,
 /// `Some(n)` where `n` is the floating-point number represented by `num`.
 ///
-#[inline(always)]
+#[inline]
 pub fn from_str_radix(num: &str, rdx: uint) -> Option<f32> {
     strconv::from_str_common(num, rdx, true, true, false,
                              strconv::ExpNone, false, false)
 }
 
 impl FromStr for f32 {
-    #[inline(always)]
+    #[inline]
     fn from_str(val: &str) -> Option<f32> { from_str(val) }
 }
 
 impl num::FromStrRadix for f32 {
-    #[inline(always)]
+    #[inline]
     fn from_str_radix(val: &str, rdx: uint) -> Option<f32> {
         from_str_radix(val, rdx)
     }
diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs
index 6303e304576..e13dff1e623 100644
--- a/src/libstd/num/f64.rs
+++ b/src/libstd/num/f64.rs
@@ -22,7 +22,7 @@ use to_str;
 pub use cmath::c_double_targ_consts::*;
 pub use cmp::{min, max};
 
-// An inner module is required to get the #[inline(always)] attribute on the
+// An inner module is required to get the #[inline] attribute on the
 // functions.
 pub use self::delegated::*;
 
@@ -42,7 +42,7 @@ macro_rules! delegate(
             use unstable::intrinsics;
 
             $(
-                #[inline(always)]
+                #[inline]
                 pub fn $name($( $arg : $arg_ty ),*) -> $rv {
                     unsafe {
                         $bound_name($( $arg ),*)
@@ -141,45 +141,45 @@ pub static infinity: f64 = 1.0_f64/0.0_f64;
 
 pub static neg_infinity: f64 = -1.0_f64/0.0_f64;
 
-#[inline(always)]
+#[inline]
 pub fn add(x: f64, y: f64) -> f64 { return x + y; }
 
-#[inline(always)]
+#[inline]
 pub fn sub(x: f64, y: f64) -> f64 { return x - y; }
 
-#[inline(always)]
+#[inline]
 pub fn mul(x: f64, y: f64) -> f64 { return x * y; }
 
-#[inline(always)]
+#[inline]
 pub fn div(x: f64, y: f64) -> f64 { return x / y; }
 
-#[inline(always)]
+#[inline]
 pub fn rem(x: f64, y: f64) -> f64 { return x % y; }
 
-#[inline(always)]
+#[inline]
 pub fn lt(x: f64, y: f64) -> bool { return x < y; }
 
-#[inline(always)]
+#[inline]
 pub fn le(x: f64, y: f64) -> bool { return x <= y; }
 
-#[inline(always)]
+#[inline]
 pub fn eq(x: f64, y: f64) -> bool { return x == y; }
 
-#[inline(always)]
+#[inline]
 pub fn ne(x: f64, y: f64) -> bool { return x != y; }
 
-#[inline(always)]
+#[inline]
 pub fn ge(x: f64, y: f64) -> bool { return x >= y; }
 
-#[inline(always)]
+#[inline]
 pub fn gt(x: f64, y: f64) -> bool { return x > y; }
 
-#[inline(always)]
+#[inline]
 pub fn fmax(x: f64, y: f64) -> f64 {
     if x >= y || y.is_NaN() { x } else { y }
 }
 
-#[inline(always)]
+#[inline]
 pub fn fmin(x: f64, y: f64) -> f64 {
     if x <= y || y.is_NaN() { x } else { y }
 }
@@ -234,23 +234,23 @@ impl Num for f64 {}
 
 #[cfg(not(test))]
 impl Eq for f64 {
-    #[inline(always)]
+    #[inline]
     fn eq(&self, other: &f64) -> bool { (*self) == (*other) }
-    #[inline(always)]
+    #[inline]
     fn ne(&self, other: &f64) -> bool { (*self) != (*other) }
 }
 
 #[cfg(not(test))]
 impl ApproxEq<f64> for f64 {
-    #[inline(always)]
+    #[inline]
     fn approx_epsilon() -> f64 { 1.0e-6 }
 
-    #[inline(always)]
+    #[inline]
     fn approx_eq(&self, other: &f64) -> bool {
         self.approx_eq_eps(other, &ApproxEq::approx_epsilon::<f64, f64>())
     }
 
-    #[inline(always)]
+    #[inline]
     fn approx_eq_eps(&self, other: &f64, approx_epsilon: &f64) -> bool {
         (*self - *other).abs() < *approx_epsilon
     }
@@ -258,32 +258,32 @@ impl ApproxEq<f64> for f64 {
 
 #[cfg(not(test))]
 impl Ord for f64 {
-    #[inline(always)]
+    #[inline]
     fn lt(&self, other: &f64) -> bool { (*self) < (*other) }
-    #[inline(always)]
+    #[inline]
     fn le(&self, other: &f64) -> bool { (*self) <= (*other) }
-    #[inline(always)]
+    #[inline]
     fn ge(&self, other: &f64) -> bool { (*self) >= (*other) }
-    #[inline(always)]
+    #[inline]
     fn gt(&self, other: &f64) -> bool { (*self) > (*other) }
 }
 
 impl Orderable for f64 {
     /// Returns `NaN` if either of the numbers are `NaN`.
-    #[inline(always)]
+    #[inline]
     fn min(&self, other: &f64) -> f64 {
         if self.is_NaN() || other.is_NaN() { Float::NaN() } else { fmin(*self, *other) }
     }
 
     /// Returns `NaN` if either of the numbers are `NaN`.
-    #[inline(always)]
+    #[inline]
     fn max(&self, other: &f64) -> f64 {
         if self.is_NaN() || other.is_NaN() { Float::NaN() } else { fmax(*self, *other) }
     }
 
     /// Returns the number constrained within the range `mn <= self <= mx`.
     /// If any of the numbers are `NaN` then `NaN` is returned.
-    #[inline(always)]
+    #[inline]
     fn clamp(&self, mn: &f64, mx: &f64) -> f64 {
         cond!(
             (self.is_NaN())   { *self }
@@ -295,16 +295,16 @@ impl Orderable for f64 {
 }
 
 impl Zero for f64 {
-    #[inline(always)]
+    #[inline]
     fn zero() -> f64 { 0.0 }
 
     /// Returns true if the number is equal to either `0.0` or `-0.0`
-    #[inline(always)]
+    #[inline]
     fn is_zero(&self) -> bool { *self == 0.0 || *self == -0.0 }
 }
 
 impl One for f64 {
-    #[inline(always)]
+    #[inline]
     fn one() -> f64 { 1.0 }
 }
 
@@ -326,7 +326,7 @@ impl Div<f64,f64> for f64 {
 }
 #[cfg(not(test))]
 impl Rem<f64,f64> for f64 {
-    #[inline(always)]
+    #[inline]
     fn rem(&self, other: &f64) -> f64 { *self % *other }
 }
 #[cfg(not(test))]
@@ -336,14 +336,14 @@ impl Neg<f64> for f64 {
 
 impl Signed for f64 {
     /// Computes the absolute value. Returns `NaN` if the number is `NaN`.
-    #[inline(always)]
+    #[inline]
     fn abs(&self) -> f64 { abs(*self) }
 
     ///
     /// The positive difference of two numbers. Returns `0.0` if the number is less than or
     /// equal to `other`, otherwise the difference between`self` and `other` is returned.
     ///
-    #[inline(always)]
+    #[inline]
     fn abs_sub(&self, other: &f64) -> f64 { abs_sub(*self, *other) }
 
     ///
@@ -353,35 +353,35 @@ impl Signed for f64 {
     /// - `-1.0` if the number is negative, `-0.0` or `neg_infinity`
     /// - `NaN` if the number is NaN
     ///
-    #[inline(always)]
+    #[inline]
     fn signum(&self) -> f64 {
         if self.is_NaN() { NaN } else { copysign(1.0, *self) }
     }
 
     /// Returns `true` if the number is positive, including `+0.0` and `infinity`
-    #[inline(always)]
+    #[inline]
     fn is_positive(&self) -> bool { *self > 0.0 || (1.0 / *self) == infinity }
 
     /// Returns `true` if the number is negative, including `-0.0` and `neg_infinity`
-    #[inline(always)]
+    #[inline]
     fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == neg_infinity }
 }
 
 impl Round for f64 {
     /// Round half-way cases toward `neg_infinity`
-    #[inline(always)]
+    #[inline]
     fn floor(&self) -> f64 { floor(*self) }
 
     /// Round half-way cases toward `infinity`
-    #[inline(always)]
+    #[inline]
     fn ceil(&self) -> f64 { ceil(*self) }
 
     /// Round half-way cases away from `0.0`
-    #[inline(always)]
+    #[inline]
     fn round(&self) -> f64 { round(*self) }
 
     /// The integer part of the number (rounds towards `0.0`)
-    #[inline(always)]
+    #[inline]
     fn trunc(&self) -> f64 { trunc(*self) }
 
     ///
@@ -391,57 +391,57 @@ impl Round for f64 {
     /// assert!(x == trunc(x) + fract(x))
     /// ~~~
     ///
-    #[inline(always)]
+    #[inline]
     fn fract(&self) -> f64 { *self - self.trunc() }
 }
 
 impl Fractional for f64 {
     /// The reciprocal (multiplicative inverse) of the number
-    #[inline(always)]
+    #[inline]
     fn recip(&self) -> f64 { 1.0 / *self }
 }
 
 impl Algebraic for f64 {
-    #[inline(always)]
+    #[inline]
     fn pow(&self, n: &f64) -> f64 { pow(*self, *n) }
 
-    #[inline(always)]
+    #[inline]
     fn sqrt(&self) -> f64 { sqrt(*self) }
 
-    #[inline(always)]
+    #[inline]
     fn rsqrt(&self) -> f64 { self.sqrt().recip() }
 
-    #[inline(always)]
+    #[inline]
     fn cbrt(&self) -> f64 { cbrt(*self) }
 
-    #[inline(always)]
+    #[inline]
     fn hypot(&self, other: &f64) -> f64 { hypot(*self, *other) }
 }
 
 impl Trigonometric for f64 {
-    #[inline(always)]
+    #[inline]
     fn sin(&self) -> f64 { sin(*self) }
 
-    #[inline(always)]
+    #[inline]
     fn cos(&self) -> f64 { cos(*self) }
 
-    #[inline(always)]
+    #[inline]
     fn tan(&self) -> f64 { tan(*self) }
 
-    #[inline(always)]
+    #[inline]
     fn asin(&self) -> f64 { asin(*self) }
 
-    #[inline(always)]
+    #[inline]
     fn acos(&self) -> f64 { acos(*self) }
 
-    #[inline(always)]
+    #[inline]
     fn atan(&self) -> f64 { atan(*self) }
 
-    #[inline(always)]
+    #[inline]
     fn atan2(&self, other: &f64) -> f64 { atan2(*self, *other) }
 
     /// Simultaneously computes the sine and cosine of the number
-    #[inline(always)]
+    #[inline]
     fn sin_cos(&self) -> (f64, f64) {
         (self.sin(), self.cos())
     }
@@ -449,38 +449,38 @@ impl Trigonometric for f64 {
 
 impl Exponential for f64 {
     /// Returns the exponential of the number
-    #[inline(always)]
+    #[inline]
     fn exp(&self) -> f64 { exp(*self) }
 
     /// Returns 2 raised to the power of the number
-    #[inline(always)]
+    #[inline]
     fn exp2(&self) -> f64 { exp2(*self) }
 
     /// Returns the natural logarithm of the number
-    #[inline(always)]
+    #[inline]
     fn ln(&self) -> f64 { ln(*self) }
 
     /// Returns the logarithm of the number with respect to an arbitrary base
-    #[inline(always)]
+    #[inline]
     fn log(&self, base: &f64) -> f64 { self.ln() / base.ln() }
 
     /// Returns the base 2 logarithm of the number
-    #[inline(always)]
+    #[inline]
     fn log2(&self) -> f64 { log2(*self) }
 
     /// Returns the base 10 logarithm of the number
-    #[inline(always)]
+    #[inline]
     fn log10(&self) -> f64 { log10(*self) }
 }
 
 impl Hyperbolic for f64 {
-    #[inline(always)]
+    #[inline]
     fn sinh(&self) -> f64 { sinh(*self) }
 
-    #[inline(always)]
+    #[inline]
     fn cosh(&self) -> f64 { cosh(*self) }
 
-    #[inline(always)]
+    #[inline]
     fn tanh(&self) -> f64 { tanh(*self) }
 
     ///
@@ -492,7 +492,7 @@ impl Hyperbolic for f64 {
     /// - `self` if `self` is `0.0`, `-0.0`, `infinity`, or `neg_infinity`
     /// - `NaN` if `self` is `NaN`
     ///
-    #[inline(always)]
+    #[inline]
     fn asinh(&self) -> f64 {
         match *self {
             neg_infinity => neg_infinity,
@@ -509,7 +509,7 @@ impl Hyperbolic for f64 {
     /// - `infinity` if `self` is `infinity`
     /// - `NaN` if `self` is `NaN` or `self < 1.0` (including `neg_infinity`)
     ///
-    #[inline(always)]
+    #[inline]
     fn acosh(&self) -> f64 {
         match *self {
             x if x < 1.0 => Float::NaN(),
@@ -529,7 +529,7 @@ impl Hyperbolic for f64 {
     /// - `NaN` if the `self` is `NaN` or outside the domain of `-1.0 <= self <= 1.0`
     ///   (including `infinity` and `neg_infinity`)
     ///
-    #[inline(always)]
+    #[inline]
     fn atanh(&self) -> f64 {
         0.5 * ((2.0 * *self) / (1.0 - *self)).ln_1p()
     }
@@ -537,159 +537,159 @@ impl Hyperbolic for f64 {
 
 impl Real for f64 {
     /// Archimedes' constant
-    #[inline(always)]
+    #[inline]
     fn pi() -> f64 { 3.14159265358979323846264338327950288 }
 
     /// 2.0 * pi
-    #[inline(always)]
+    #[inline]
     fn two_pi() -> f64 { 6.28318530717958647692528676655900576 }
 
     /// pi / 2.0
-    #[inline(always)]
+    #[inline]
     fn frac_pi_2() -> f64 { 1.57079632679489661923132169163975144 }
 
     /// pi / 3.0
-    #[inline(always)]
+    #[inline]
     fn frac_pi_3() -> f64 { 1.04719755119659774615421446109316763 }
 
     /// pi / 4.0
-    #[inline(always)]
+    #[inline]
     fn frac_pi_4() -> f64 { 0.785398163397448309615660845819875721 }
 
     /// pi / 6.0
-    #[inline(always)]
+    #[inline]
     fn frac_pi_6() -> f64 { 0.52359877559829887307710723054658381 }
 
     /// pi / 8.0
-    #[inline(always)]
+    #[inline]
     fn frac_pi_8() -> f64 { 0.39269908169872415480783042290993786 }
 
     /// 1.0 / pi
-    #[inline(always)]
+    #[inline]
     fn frac_1_pi() -> f64 { 0.318309886183790671537767526745028724 }
 
     /// 2.0 / pi
-    #[inline(always)]
+    #[inline]
     fn frac_2_pi() -> f64 { 0.636619772367581343075535053490057448 }
 
     /// 2.0 / sqrt(pi)
-    #[inline(always)]
+    #[inline]
     fn frac_2_sqrtpi() -> f64 { 1.12837916709551257389615890312154517 }
 
     /// sqrt(2.0)
-    #[inline(always)]
+    #[inline]
     fn sqrt2() -> f64 { 1.41421356237309504880168872420969808 }
 
     /// 1.0 / sqrt(2.0)
-    #[inline(always)]
+    #[inline]
     fn frac_1_sqrt2() -> f64 { 0.707106781186547524400844362104849039 }
 
     /// Euler's number
-    #[inline(always)]
+    #[inline]
     fn e() -> f64 { 2.71828182845904523536028747135266250 }
 
     /// log2(e)
-    #[inline(always)]
+    #[inline]
     fn log2_e() -> f64 { 1.44269504088896340735992468100189214 }
 
     /// log10(e)
-    #[inline(always)]
+    #[inline]
     fn log10_e() -> f64 { 0.434294481903251827651128918916605082 }
 
     /// ln(2.0)
-    #[inline(always)]
+    #[inline]
     fn ln_2() -> f64 { 0.693147180559945309417232121458176568 }
 
     /// ln(10.0)
-    #[inline(always)]
+    #[inline]
     fn ln_10() -> f64 { 2.30258509299404568401799145468436421 }
 
     /// Converts to degrees, assuming the number is in radians
-    #[inline(always)]
+    #[inline]
     fn to_degrees(&self) -> f64 { *self * (180.0 / Real::pi::<f64>()) }
 
     /// Converts to radians, assuming the number is in degrees
-    #[inline(always)]
+    #[inline]
     fn to_radians(&self) -> f64 { *self * (Real::pi::<f64>() / 180.0) }
 }
 
 impl RealExt for f64 {
-    #[inline(always)]
+    #[inline]
     fn lgamma(&self) -> (int, f64) {
         let mut sign = 0;
         let result = lgamma(*self, &mut sign);
         (sign as int, result)
     }
 
-    #[inline(always)]
+    #[inline]
     fn tgamma(&self) -> f64 { tgamma(*self) }
 
-    #[inline(always)]
+    #[inline]
     fn j0(&self) -> f64 { j0(*self) }
 
-    #[inline(always)]
+    #[inline]
     fn j1(&self) -> f64 { j1(*self) }
 
-    #[inline(always)]
+    #[inline]
     fn jn(&self, n: int) -> f64 { jn(n as c_int, *self) }
 
-    #[inline(always)]
+    #[inline]
     fn y0(&self) -> f64 { y0(*self) }
 
-    #[inline(always)]
+    #[inline]
     fn y1(&self) -> f64 { y1(*self) }
 
-    #[inline(always)]
+    #[inline]
     fn yn(&self, n: int) -> f64 { yn(n as c_int, *self) }
 }
 
 impl Bounded for f64 {
-    #[inline(always)]
+    #[inline]
     fn min_value() -> f64 { 2.2250738585072014e-308 }
 
-    #[inline(always)]
+    #[inline]
     fn max_value() -> f64 { 1.7976931348623157e+308 }
 }
 
 impl Primitive for f64 {
-    #[inline(always)]
+    #[inline]
     fn bits() -> uint { 64 }
 
-    #[inline(always)]
+    #[inline]
     fn bytes() -> uint { Primitive::bits::<f64>() / 8 }
 }
 
 impl Float for f64 {
-    #[inline(always)]
+    #[inline]
     fn NaN() -> f64 { 0.0 / 0.0 }
 
-    #[inline(always)]
+    #[inline]
     fn infinity() -> f64 { 1.0 / 0.0 }
 
-    #[inline(always)]
+    #[inline]
     fn neg_infinity() -> f64 { -1.0 / 0.0 }
 
-    #[inline(always)]
+    #[inline]
     fn neg_zero() -> f64 { -0.0 }
 
     /// Returns `true` if the number is NaN
-    #[inline(always)]
+    #[inline]
     fn is_NaN(&self) -> bool { *self != *self }
 
     /// Returns `true` if the number is infinite
-    #[inline(always)]
+    #[inline]
     fn is_infinite(&self) -> bool {
         *self == Float::infinity() || *self == Float::neg_infinity()
     }
 
     /// Returns `true` if the number is neither infinite or NaN
-    #[inline(always)]
+    #[inline]
     fn is_finite(&self) -> bool {
         !(self.is_NaN() || self.is_infinite())
     }
 
     /// Returns `true` if the number is neither zero, infinite, subnormal or NaN
-    #[inline(always)]
+    #[inline]
     fn is_normal(&self) -> bool {
         self.classify() == FPNormal
     }
@@ -712,29 +712,29 @@ impl Float for f64 {
         }
     }
 
-    #[inline(always)]
+    #[inline]
     fn mantissa_digits() -> uint { 53 }
 
-    #[inline(always)]
+    #[inline]
     fn digits() -> uint { 15 }
 
-    #[inline(always)]
+    #[inline]
     fn epsilon() -> f64 { 2.2204460492503131e-16 }
 
-    #[inline(always)]
+    #[inline]
     fn min_exp() -> int { -1021 }
 
-    #[inline(always)]
+    #[inline]
     fn max_exp() -> int { 1024 }
 
-    #[inline(always)]
+    #[inline]
     fn min_10_exp() -> int { -307 }
 
-    #[inline(always)]
+    #[inline]
     fn max_10_exp() -> int { 308 }
 
     /// Constructs a floating point number by multiplying `x` by 2 raised to the power of `exp`
-    #[inline(always)]
+    #[inline]
     fn ldexp(x: f64, exp: int) -> f64 {
         ldexp(x, exp as c_int)
     }
@@ -745,7 +745,7 @@ impl Float for f64 {
     /// - `self = x * pow(2, exp)`
     /// - `0.5 <= abs(x) < 1.0`
     ///
-    #[inline(always)]
+    #[inline]
     fn frexp(&self) -> (f64, int) {
         let mut exp = 0;
         let x = frexp(*self, &mut exp);
@@ -756,14 +756,14 @@ impl Float for f64 {
     /// Returns the exponential of the number, minus `1`, in a way that is accurate
     /// even if the number is close to zero
     ///
-    #[inline(always)]
+    #[inline]
     fn exp_m1(&self) -> f64 { exp_m1(*self) }
 
     ///
     /// Returns the natural logarithm of the number plus `1` (`ln(1+n)`) more accurately
     /// than if the operations were performed separately
     ///
-    #[inline(always)]
+    #[inline]
     fn ln_1p(&self) -> f64 { ln_1p(*self) }
 
     ///
@@ -771,13 +771,13 @@ impl Float for f64 {
     /// produces a more accurate result with better performance than a separate multiplication
     /// operation followed by an add.
     ///
-    #[inline(always)]
+    #[inline]
     fn mul_add(&self, a: f64, b: f64) -> f64 {
         mul_add(*self, a, b)
     }
 
     /// Returns the next representable floating-point value in the direction of `other`
-    #[inline(always)]
+    #[inline]
     fn next_after(&self, other: f64) -> f64 {
         next_after(*self, other)
     }
@@ -794,7 +794,7 @@ impl Float for f64 {
 ///
 /// * num - The float value
 ///
-#[inline(always)]
+#[inline]
 pub fn to_str(num: f64) -> ~str {
     let (r, _) = strconv::to_str_common(
         &num, 10u, true, strconv::SignNeg, strconv::DigAll);
@@ -808,7 +808,7 @@ pub fn to_str(num: f64) -> ~str {
 ///
 /// * num - The float value
 ///
-#[inline(always)]
+#[inline]
 pub fn to_str_hex(num: f64) -> ~str {
     let (r, _) = strconv::to_str_common(
         &num, 16u, true, strconv::SignNeg, strconv::DigAll);
@@ -829,7 +829,7 @@ pub fn to_str_hex(num: f64) -> ~str {
 /// possible misinterpretation of the result at higher bases. If those values
 /// are expected, use `to_str_radix_special()` instead.
 ///
-#[inline(always)]
+#[inline]
 pub fn to_str_radix(num: f64, rdx: uint) -> ~str {
     let (r, special) = strconv::to_str_common(
         &num, rdx, true, strconv::SignNeg, strconv::DigAll);
@@ -847,7 +847,7 @@ pub fn to_str_radix(num: f64, rdx: uint) -> ~str {
 /// * num - The float value
 /// * radix - The base to use
 ///
-#[inline(always)]
+#[inline]
 pub fn to_str_radix_special(num: f64, rdx: uint) -> (~str, bool) {
     strconv::to_str_common(&num, rdx, true,
                            strconv::SignNeg, strconv::DigAll)
@@ -862,7 +862,7 @@ pub fn to_str_radix_special(num: f64, rdx: uint) -> (~str, bool) {
 /// * num - The float value
 /// * digits - The number of significant digits
 ///
-#[inline(always)]
+#[inline]
 pub fn to_str_exact(num: f64, dig: uint) -> ~str {
     let (r, _) = strconv::to_str_common(
         &num, 10u, true, strconv::SignNeg, strconv::DigExact(dig));
@@ -878,7 +878,7 @@ pub fn to_str_exact(num: f64, dig: uint) -> ~str {
 /// * num - The float value
 /// * digits - The number of significant digits
 ///
-#[inline(always)]
+#[inline]
 pub fn to_str_digits(num: f64, dig: uint) -> ~str {
     let (r, _) = strconv::to_str_common(
         &num, 10u, true, strconv::SignNeg, strconv::DigMax(dig));
@@ -886,12 +886,12 @@ pub fn to_str_digits(num: f64, dig: uint) -> ~str {
 }
 
 impl to_str::ToStr for f64 {
-    #[inline(always)]
+    #[inline]
     fn to_str(&self) -> ~str { to_str_digits(*self, 8) }
 }
 
 impl num::ToStrRadix for f64 {
-    #[inline(always)]
+    #[inline]
     fn to_str_radix(&self, rdx: uint) -> ~str {
         to_str_radix(*self, rdx)
     }
@@ -924,7 +924,7 @@ impl num::ToStrRadix for f64 {
 /// `none` if the string did not represent a valid number.  Otherwise,
 /// `Some(n)` where `n` is the floating-point number represented by `num`.
 ///
-#[inline(always)]
+#[inline]
 pub fn from_str(num: &str) -> Option<f64> {
     strconv::from_str_common(num, 10u, true, true, true,
                              strconv::ExpDec, false, false)
@@ -957,7 +957,7 @@ pub fn from_str(num: &str) -> Option<f64> {
 /// `none` if the string did not represent a valid number.  Otherwise,
 /// `Some(n)` where `n` is the floating-point number represented by `[num]`.
 ///
-#[inline(always)]
+#[inline]
 pub fn from_str_hex(num: &str) -> Option<f64> {
     strconv::from_str_common(num, 16u, true, true, true,
                              strconv::ExpBin, false, false)
@@ -982,19 +982,19 @@ pub fn from_str_hex(num: &str) -> Option<f64> {
 /// `none` if the string did not represent a valid number. Otherwise,
 /// `Some(n)` where `n` is the floating-point number represented by `num`.
 ///
-#[inline(always)]
+#[inline]
 pub fn from_str_radix(num: &str, rdx: uint) -> Option<f64> {
     strconv::from_str_common(num, rdx, true, true, false,
                              strconv::ExpNone, false, false)
 }
 
 impl FromStr for f64 {
-    #[inline(always)]
+    #[inline]
     fn from_str(val: &str) -> Option<f64> { from_str(val) }
 }
 
 impl num::FromStrRadix for f64 {
-    #[inline(always)]
+    #[inline]
     fn from_str_radix(val: &str, rdx: uint) -> Option<f64> {
         from_str_radix(val, rdx)
     }
diff --git a/src/libstd/num/float.rs b/src/libstd/num/float.rs
index 267a8890e82..c583aeacf16 100644
--- a/src/libstd/num/float.rs
+++ b/src/libstd/num/float.rs
@@ -99,7 +99,7 @@ pub mod consts {
 ///
 /// * num - The float value
 ///
-#[inline(always)]
+#[inline]
 pub fn to_str(num: float) -> ~str {
     let (r, _) = strconv::to_str_common(
         &num, 10u, true, strconv::SignNeg, strconv::DigAll);
@@ -113,7 +113,7 @@ pub fn to_str(num: float) -> ~str {
 ///
 /// * num - The float value
 ///
-#[inline(always)]
+#[inline]
 pub fn to_str_hex(num: float) -> ~str {
     let (r, _) = strconv::to_str_common(
         &num, 16u, true, strconv::SignNeg, strconv::DigAll);
@@ -134,7 +134,7 @@ pub fn to_str_hex(num: float) -> ~str {
 /// possible misinterpretation of the result at higher bases. If those values
 /// are expected, use `to_str_radix_special()` instead.
 ///
-#[inline(always)]
+#[inline]
 pub fn to_str_radix(num: float, radix: uint) -> ~str {
     let (r, special) = strconv::to_str_common(
         &num, radix, true, strconv::SignNeg, strconv::DigAll);
@@ -152,7 +152,7 @@ pub fn to_str_radix(num: float, radix: uint) -> ~str {
 /// * num - The float value
 /// * radix - The base to use
 ///
-#[inline(always)]
+#[inline]
 pub fn to_str_radix_special(num: float, radix: uint) -> (~str, bool) {
     strconv::to_str_common(&num, radix, true,
                            strconv::SignNeg, strconv::DigAll)
@@ -167,7 +167,7 @@ pub fn to_str_radix_special(num: float, radix: uint) -> (~str, bool) {
 /// * num - The float value
 /// * digits - The number of significant digits
 ///
-#[inline(always)]
+#[inline]
 pub fn to_str_exact(num: float, digits: uint) -> ~str {
     let (r, _) = strconv::to_str_common(
         &num, 10u, true, strconv::SignNeg, strconv::DigExact(digits));
@@ -183,7 +183,7 @@ pub fn to_str_exact(num: float, digits: uint) -> ~str {
 /// * num - The float value
 /// * digits - The number of significant digits
 ///
-#[inline(always)]
+#[inline]
 pub fn to_str_digits(num: float, digits: uint) -> ~str {
     let (r, _) = strconv::to_str_common(
         &num, 10u, true, strconv::SignNeg, strconv::DigMax(digits));
@@ -191,12 +191,12 @@ pub fn to_str_digits(num: float, digits: uint) -> ~str {
 }
 
 impl to_str::ToStr for float {
-    #[inline(always)]
+    #[inline]
     fn to_str(&self) -> ~str { to_str_digits(*self, 8) }
 }
 
 impl num::ToStrRadix for float {
-    #[inline(always)]
+    #[inline]
     fn to_str_radix(&self, radix: uint) -> ~str {
         to_str_radix(*self, radix)
     }
@@ -229,7 +229,7 @@ impl num::ToStrRadix for float {
 /// `none` if the string did not represent a valid number.  Otherwise,
 /// `Some(n)` where `n` is the floating-point number represented by `num`.
 ///
-#[inline(always)]
+#[inline]
 pub fn from_str(num: &str) -> Option<float> {
     strconv::from_str_common(num, 10u, true, true, true,
                              strconv::ExpDec, false, false)
@@ -262,7 +262,7 @@ pub fn from_str(num: &str) -> Option<float> {
 /// `none` if the string did not represent a valid number.  Otherwise,
 /// `Some(n)` where `n` is the floating-point number represented by `[num]`.
 ///
-#[inline(always)]
+#[inline]
 pub fn from_str_hex(num: &str) -> Option<float> {
     strconv::from_str_common(num, 16u, true, true, true,
                              strconv::ExpBin, false, false)
@@ -287,19 +287,19 @@ pub fn from_str_hex(num: &str) -> Option<float> {
 /// `none` if the string did not represent a valid number. Otherwise,
 /// `Some(n)` where `n` is the floating-point number represented by `num`.
 ///
-#[inline(always)]
+#[inline]
 pub fn from_str_radix(num: &str, radix: uint) -> Option<float> {
     strconv::from_str_common(num, radix, true, true, false,
                              strconv::ExpNone, false, false)
 }
 
 impl FromStr for float {
-    #[inline(always)]
+    #[inline]
     fn from_str(val: &str) -> Option<float> { from_str(val) }
 }
 
 impl num::FromStrRadix for float {
-    #[inline(always)]
+    #[inline]
     fn from_str_radix(val: &str, radix: uint) -> Option<float> {
         from_str_radix(val, radix)
     }
@@ -341,27 +341,27 @@ pub fn pow_with_uint(base: uint, pow: uint) -> float {
     return total;
 }
 
-#[inline(always)]
+#[inline]
 pub fn abs(x: float) -> float {
     f64::abs(x as f64) as float
 }
-#[inline(always)]
+#[inline]
 pub fn sqrt(x: float) -> float {
     f64::sqrt(x as f64) as float
 }
-#[inline(always)]
+#[inline]
 pub fn atan(x: float) -> float {
     f64::atan(x as f64) as float
 }
-#[inline(always)]
+#[inline]
 pub fn sin(x: float) -> float {
     f64::sin(x as f64) as float
 }
-#[inline(always)]
+#[inline]
 pub fn cos(x: float) -> float {
     f64::cos(x as f64) as float
 }
-#[inline(always)]
+#[inline]
 pub fn tan(x: float) -> float {
     f64::tan(x as f64) as float
 }
@@ -370,23 +370,23 @@ impl Num for float {}
 
 #[cfg(not(test))]
 impl Eq for float {
-    #[inline(always)]
+    #[inline]
     fn eq(&self, other: &float) -> bool { (*self) == (*other) }
-    #[inline(always)]
+    #[inline]
     fn ne(&self, other: &float) -> bool { (*self) != (*other) }
 }
 
 #[cfg(not(test))]
 impl ApproxEq<float> for float {
-    #[inline(always)]
+    #[inline]
     fn approx_epsilon() -> float { 1.0e-6 }
 
-    #[inline(always)]
+    #[inline]
     fn approx_eq(&self, other: &float) -> bool {
         self.approx_eq_eps(other, &ApproxEq::approx_epsilon::<float, float>())
     }
 
-    #[inline(always)]
+    #[inline]
     fn approx_eq_eps(&self, other: &float, approx_epsilon: &float) -> bool {
         (*self - *other).abs() < *approx_epsilon
     }
@@ -394,66 +394,66 @@ impl ApproxEq<float> for float {
 
 #[cfg(not(test))]
 impl Ord for float {
-    #[inline(always)]
+    #[inline]
     fn lt(&self, other: &float) -> bool { (*self) < (*other) }
-    #[inline(always)]
+    #[inline]
     fn le(&self, other: &float) -> bool { (*self) <= (*other) }
-    #[inline(always)]
+    #[inline]
     fn ge(&self, other: &float) -> bool { (*self) >= (*other) }
-    #[inline(always)]
+    #[inline]
     fn gt(&self, other: &float) -> bool { (*self) > (*other) }
 }
 
 impl Orderable for float {
     /// Returns `NaN` if either of the numbers are `NaN`.
-    #[inline(always)]
+    #[inline]
     fn min(&self, other: &float) -> float {
         (*self as f64).min(&(*other as f64)) as float
     }
 
     /// Returns `NaN` if either of the numbers are `NaN`.
-    #[inline(always)]
+    #[inline]
     fn max(&self, other: &float) -> float {
         (*self as f64).max(&(*other as f64)) as float
     }
 
     /// Returns the number constrained within the range `mn <= self <= mx`.
     /// If any of the numbers are `NaN` then `NaN` is returned.
-    #[inline(always)]
+    #[inline]
     fn clamp(&self, mn: &float, mx: &float) -> float {
         (*self as f64).clamp(&(*mn as f64), &(*mx as f64)) as float
     }
 }
 
 impl Zero for float {
-    #[inline(always)]
+    #[inline]
     fn zero() -> float { 0.0 }
 
     /// Returns true if the number is equal to either `0.0` or `-0.0`
-    #[inline(always)]
+    #[inline]
     fn is_zero(&self) -> bool { *self == 0.0 || *self == -0.0 }
 }
 
 impl One for float {
-    #[inline(always)]
+    #[inline]
     fn one() -> float { 1.0 }
 }
 
 impl Round for float {
     /// Round half-way cases toward `neg_infinity`
-    #[inline(always)]
+    #[inline]
     fn floor(&self) -> float { floor(*self as f64) as float }
 
     /// Round half-way cases toward `infinity`
-    #[inline(always)]
+    #[inline]
     fn ceil(&self) -> float { ceil(*self as f64) as float }
 
     /// Round half-way cases away from `0.0`
-    #[inline(always)]
+    #[inline]
     fn round(&self) -> float { round(*self as f64) as float }
 
     /// The integer part of the number (rounds towards `0.0`)
-    #[inline(always)]
+    #[inline]
     fn trunc(&self) -> float { trunc(*self as f64) as float }
 
     ///
@@ -463,81 +463,81 @@ impl Round for float {
     /// assert!(x == trunc(x) + fract(x))
     /// ~~~
     ///
-    #[inline(always)]
+    #[inline]
     fn fract(&self) -> float { *self - self.trunc() }
 }
 
 impl Fractional for float {
     /// The reciprocal (multiplicative inverse) of the number
-    #[inline(always)]
+    #[inline]
     fn recip(&self) -> float { 1.0 / *self }
 }
 
 impl Algebraic for float {
-    #[inline(always)]
+    #[inline]
     fn pow(&self, n: &float) -> float {
         (*self as f64).pow(&(*n as f64)) as float
     }
 
-    #[inline(always)]
+    #[inline]
     fn sqrt(&self) -> float {
         (*self as f64).sqrt() as float
     }
 
-    #[inline(always)]
+    #[inline]
     fn rsqrt(&self) -> float {
         (*self as f64).rsqrt() as float
     }
 
-    #[inline(always)]
+    #[inline]
     fn cbrt(&self) -> float {
         (*self as f64).cbrt() as float
     }
 
-    #[inline(always)]
+    #[inline]
     fn hypot(&self, other: &float) -> float {
         (*self as f64).hypot(&(*other as f64)) as float
     }
 }
 
 impl Trigonometric for float {
-    #[inline(always)]
+    #[inline]
     fn sin(&self) -> float {
         (*self as f64).sin() as float
     }
 
-    #[inline(always)]
+    #[inline]
     fn cos(&self) -> float {
         (*self as f64).cos() as float
     }
 
-    #[inline(always)]
+    #[inline]
     fn tan(&self) -> float {
         (*self as f64).tan() as float
     }
 
-    #[inline(always)]
+    #[inline]
     fn asin(&self) -> float {
         (*self as f64).asin() as float
     }
 
-    #[inline(always)]
+    #[inline]
     fn acos(&self) -> float {
         (*self as f64).acos() as float
     }
 
-    #[inline(always)]
+    #[inline]
     fn atan(&self) -> float {
         (*self as f64).atan() as float
     }
 
-    #[inline(always)]
+    #[inline]
     fn atan2(&self, other: &float) -> float {
         (*self as f64).atan2(&(*other as f64)) as float
     }
 
     /// Simultaneously computes the sine and cosine of the number
-    #[inline(always)]
+    #[inline]
     fn sin_cos(&self) -> (float, float) {
         match (*self as f64).sin_cos() {
             (s, c) => (s as float, c as float)
@@ -547,54 +547,54 @@ impl Trigonometric for float {
 
 impl Exponential for float {
     /// Returns the exponential of the number
-    #[inline(always)]
+    #[inline]
     fn exp(&self) -> float {
         (*self as f64).exp() as float
     }
 
     /// Returns 2 raised to the power of the number
-    #[inline(always)]
+    #[inline]
     fn exp2(&self) -> float {
         (*self as f64).exp2() as float
     }
 
     /// Returns the natural logarithm of the number
-    #[inline(always)]
+    #[inline]
     fn ln(&self) -> float {
         (*self as f64).ln() as float
     }
 
     /// Returns the logarithm of the number with respect to an arbitrary base
-    #[inline(always)]
+    #[inline]
     fn log(&self, base: &float) -> float {
         (*self as f64).log(&(*base as f64)) as float
     }
 
     /// Returns the base 2 logarithm of the number
-    #[inline(always)]
+    #[inline]
     fn log2(&self) -> float {
         (*self as f64).log2() as float
     }
 
     /// Returns the base 10 logarithm of the number
-    #[inline(always)]
+    #[inline]
     fn log10(&self) -> float {
         (*self as f64).log10() as float
     }
 }
 
 impl Hyperbolic for float {
-    #[inline(always)]
+    #[inline]
     fn sinh(&self) -> float {
         (*self as f64).sinh() as float
     }
 
-    #[inline(always)]
+    #[inline]
     fn cosh(&self) -> float {
         (*self as f64).cosh() as float
     }
 
-    #[inline(always)]
+    #[inline]
     fn tanh(&self) -> float {
         (*self as f64).tanh() as float
     }
@@ -608,7 +608,7 @@ impl Hyperbolic for float {
     /// - `self` if `self` is `0.0`, `-0.0`, `infinity`, or `neg_infinity`
     /// - `NaN` if `self` is `NaN`
     ///
-    #[inline(always)]
+    #[inline]
     fn asinh(&self) -> float {
         (*self as f64).asinh() as float
     }
@@ -622,7 +622,7 @@ impl Hyperbolic for float {
     /// - `infinity` if `self` is `infinity`
     /// - `NaN` if `self` is `NaN` or `self < 1.0` (including `neg_infinity`)
     ///
-    #[inline(always)]
+    #[inline]
     fn acosh(&self) -> float {
         (*self as f64).acosh() as float
     }
@@ -639,7 +639,7 @@ impl Hyperbolic for float {
     /// - `NaN` if the `self` is `NaN` or outside the domain of `-1.0 <= self <= 1.0`
     ///   (including `infinity` and `neg_infinity`)
     ///
-    #[inline(always)]
+    #[inline]
     fn atanh(&self) -> float {
         (*self as f64).atanh() as float
     }
@@ -647,157 +647,157 @@ impl Hyperbolic for float {
 
 impl Real for float {
     /// Archimedes' constant
-    #[inline(always)]
+    #[inline]
     fn pi() -> float { 3.14159265358979323846264338327950288 }
 
     /// 2.0 * pi
-    #[inline(always)]
+    #[inline]
     fn two_pi() -> float { 6.28318530717958647692528676655900576 }
 
     /// pi / 2.0
-    #[inline(always)]
+    #[inline]
     fn frac_pi_2() -> float { 1.57079632679489661923132169163975144 }
 
     /// pi / 3.0
-    #[inline(always)]
+    #[inline]
     fn frac_pi_3() -> float { 1.04719755119659774615421446109316763 }
 
     /// pi / 4.0
-    #[inline(always)]
+    #[inline]
     fn frac_pi_4() -> float { 0.785398163397448309615660845819875721 }
 
     /// pi / 6.0
-    #[inline(always)]
+    #[inline]
     fn frac_pi_6() -> float { 0.52359877559829887307710723054658381 }
 
     /// pi / 8.0
-    #[inline(always)]
+    #[inline]
     fn frac_pi_8() -> float { 0.39269908169872415480783042290993786 }
 
     /// 1.0 / pi
-    #[inline(always)]
+    #[inline]
     fn frac_1_pi() -> float { 0.318309886183790671537767526745028724 }
 
     /// 2.0 / pi
-    #[inline(always)]
+    #[inline]
     fn frac_2_pi() -> float { 0.636619772367581343075535053490057448 }
 
     /// 2 .0/ sqrt(pi)
-    #[inline(always)]
+    #[inline]
     fn frac_2_sqrtpi() -> float { 1.12837916709551257389615890312154517 }
 
     /// sqrt(2.0)
-    #[inline(always)]
+    #[inline]
     fn sqrt2() -> float { 1.41421356237309504880168872420969808 }
 
     /// 1.0 / sqrt(2.0)
-    #[inline(always)]
+    #[inline]
     fn frac_1_sqrt2() -> float { 0.707106781186547524400844362104849039 }
 
     /// Euler's number
-    #[inline(always)]
+    #[inline]
     fn e() -> float { 2.71828182845904523536028747135266250 }
 
     /// log2(e)
-    #[inline(always)]
+    #[inline]
     fn log2_e() -> float { 1.44269504088896340735992468100189214 }
 
     /// log10(e)
-    #[inline(always)]
+    #[inline]
     fn log10_e() -> float { 0.434294481903251827651128918916605082 }
 
     /// ln(2.0)
-    #[inline(always)]
+    #[inline]
     fn ln_2() -> float { 0.693147180559945309417232121458176568 }
 
     /// ln(10.0)
-    #[inline(always)]
+    #[inline]
     fn ln_10() -> float { 2.30258509299404568401799145468436421 }
 
     /// Converts to degrees, assuming the number is in radians
-    #[inline(always)]
+    #[inline]
     fn to_degrees(&self) -> float { (*self as f64).to_degrees() as float }
 
     /// Converts to radians, assuming the number is in degrees
-    #[inline(always)]
+    #[inline]
     fn to_radians(&self) -> float { (*self as f64).to_radians() as float }
 }
 
 impl RealExt for float {
-    #[inline(always)]
+    #[inline]
     fn lgamma(&self) -> (int, float) {
         let mut sign = 0;
         let result = lgamma(*self as f64, &mut sign);
         (sign as int, result as float)
     }
 
-    #[inline(always)]
+    #[inline]
     fn tgamma(&self) -> float { tgamma(*self as f64) as float }
 
-    #[inline(always)]
+    #[inline]
     fn j0(&self) -> float { j0(*self as f64) as float }
 
-    #[inline(always)]
+    #[inline]
     fn j1(&self) -> float { j1(*self as f64) as float }
 
-    #[inline(always)]
+    #[inline]
     fn jn(&self, n: int) -> float { jn(n as c_int, *self as f64) as float }
 
-    #[inline(always)]
+    #[inline]
     fn y0(&self) -> float { y0(*self as f64) as float }
 
-    #[inline(always)]
+    #[inline]
     fn y1(&self) -> float { y1(*self as f64) as float }
 
-    #[inline(always)]
+    #[inline]
     fn yn(&self, n: int) -> float { yn(n as c_int, *self as f64) as float }
 }
 
 #[cfg(not(test))]
 impl Add<float,float> for float {
-    #[inline(always)]
+    #[inline]
     fn add(&self, other: &float) -> float { *self + *other }
 }
 
 #[cfg(not(test))]
 impl Sub<float,float> for float {
-    #[inline(always)]
+    #[inline]
     fn sub(&self, other: &float) -> float { *self - *other }
 }
 
 #[cfg(not(test))]
 impl Mul<float,float> for float {
-    #[inline(always)]
+    #[inline]
     fn mul(&self, other: &float) -> float { *self * *other }
 }
 
 #[cfg(not(test))]
 impl Div<float,float> for float {
-    #[inline(always)]
+    #[inline]
     fn div(&self, other: &float) -> float { *self / *other }
 }
 
 #[cfg(not(test))]
 impl Rem<float,float> for float {
-    #[inline(always)]
+    #[inline]
     fn rem(&self, other: &float) -> float { *self % *other }
 }
 #[cfg(not(test))]
 impl Neg<float> for float {
-    #[inline(always)]
+    #[inline]
     fn neg(&self) -> float { -*self }
 }
 
 impl Signed for float {
     /// Computes the absolute value. Returns `NaN` if the number is `NaN`.
-    #[inline(always)]
+    #[inline]
     fn abs(&self) -> float { abs(*self) }
 
     ///
     /// The positive difference of two numbers. Returns `0.0` if the number is less than or
     /// equal to `other`, otherwise the difference between`self` and `other` is returned.
     ///
-    #[inline(always)]
+    #[inline]
     fn abs_sub(&self, other: &float) -> float {
         (*self as f64).abs_sub(&(*other as f64)) as float
     }
@@ -809,93 +809,93 @@ impl Signed for float {
     /// - `-1.0` if the number is negative, `-0.0` or `neg_infinity`
     /// - `NaN` if the number is NaN
     ///
-    #[inline(always)]
+    #[inline]
     fn signum(&self) -> float {
         if self.is_NaN() { NaN } else { f64::copysign(1.0, *self as f64) as float }
     }
 
     /// Returns `true` if the number is positive, including `+0.0` and `infinity`
-    #[inline(always)]
+    #[inline]
     fn is_positive(&self) -> bool { *self > 0.0 || (1.0 / *self) == infinity }
 
     /// Returns `true` if the number is negative, including `-0.0` and `neg_infinity`
-    #[inline(always)]
+    #[inline]
     fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == neg_infinity }
 }
 
 impl Bounded for float {
-    #[inline(always)]
+    #[inline]
     fn min_value() -> float { Bounded::min_value::<f64>() as float }
 
-    #[inline(always)]
+    #[inline]
     fn max_value() -> float { Bounded::max_value::<f64>() as float }
 }
 
 impl Primitive for float {
-    #[inline(always)]
+    #[inline]
     fn bits() -> uint { Primitive::bits::<f64>() }
 
-    #[inline(always)]
+    #[inline]
     fn bytes() -> uint { Primitive::bytes::<f64>() }
 }
 
 impl Float for float {
-    #[inline(always)]
+    #[inline]
     fn NaN() -> float { Float::NaN::<f64>() as float }
 
-    #[inline(always)]
+    #[inline]
     fn infinity() -> float { Float::infinity::<f64>() as float }
 
-    #[inline(always)]
+    #[inline]
     fn neg_infinity() -> float { Float::neg_infinity::<f64>() as float }
 
-    #[inline(always)]
+    #[inline]
     fn neg_zero() -> float { Float::neg_zero::<f64>() as float }
 
     /// Returns `true` if the number is NaN
-    #[inline(always)]
+    #[inline]
     fn is_NaN(&self) -> bool { (*self as f64).is_NaN() }
 
     /// Returns `true` if the number is infinite
-    #[inline(always)]
+    #[inline]
     fn is_infinite(&self) -> bool { (*self as f64).is_infinite() }
 
     /// Returns `true` if the number is neither infinite or NaN
-    #[inline(always)]
+    #[inline]
     fn is_finite(&self) -> bool { (*self as f64).is_finite() }
 
     /// Returns `true` if the number is neither zero, infinite, subnormal or NaN
-    #[inline(always)]
+    #[inline]
     fn is_normal(&self) -> bool { (*self as f64).is_normal() }
 
     /// Returns the floating point category of the number. If only one property is going to
     /// be tested, it is generally faster to use the specific predicate instead.
-    #[inline(always)]
+    #[inline]
     fn classify(&self) -> FPCategory { (*self as f64).classify() }
 
-    #[inline(always)]
+    #[inline]
     fn mantissa_digits() -> uint { Float::mantissa_digits::<f64>() }
 
-    #[inline(always)]
+    #[inline]
     fn digits() -> uint { Float::digits::<f64>() }
 
-    #[inline(always)]
+    #[inline]
     fn epsilon() -> float { Float::epsilon::<f64>() as float }
 
-    #[inline(always)]
+    #[inline]
     fn min_exp() -> int { Float::min_exp::<f64>() }
 
-    #[inline(always)]
+    #[inline]
     fn max_exp() -> int { Float::max_exp::<f64>() }
 
-    #[inline(always)]
+    #[inline]
     fn min_10_exp() -> int { Float::min_10_exp::<f64>() }
 
-    #[inline(always)]
+    #[inline]
     fn max_10_exp() -> int { Float::max_10_exp::<f64>() }
 
     /// Constructs a floating point number by multiplying `x` by 2 raised to the power of `exp`
-    #[inline(always)]
+    #[inline]
     fn ldexp(x: float, exp: int) -> float {
         Float::ldexp(x as f64, exp) as float
     }
@@ -906,7 +906,7 @@ impl Float for float {
     /// - `self = x * pow(2, exp)`
     /// - `0.5 <= abs(x) < 1.0`
     ///
-    #[inline(always)]
+    #[inline]
     fn frexp(&self) -> (float, int) {
         match (*self as f64).frexp() {
             (x, exp) => (x as float, exp)
@@ -917,7 +917,7 @@ impl Float for float {
     /// Returns the exponential of the number, minus `1`, in a way that is accurate
     /// even if the number is close to zero
     ///
-    #[inline(always)]
+    #[inline]
     fn exp_m1(&self) -> float {
         (*self as f64).exp_m1() as float
     }
@@ -926,7 +926,7 @@ impl Float for float {
     /// Returns the natural logarithm of the number plus `1` (`ln(1+n)`) more accurately
     /// than if the operations were performed separately
     ///
-    #[inline(always)]
+    #[inline]
     fn ln_1p(&self) -> float {
         (*self as f64).ln_1p() as float
     }
@@ -936,13 +936,13 @@ impl Float for float {
     /// produces a more accurate result with better performance than a separate multiplication
     /// operation followed by an add.
     ///
-    #[inline(always)]
+    #[inline]
     fn mul_add(&self, a: float, b: float) -> float {
         mul_add(*self as f64, a as f64, b as f64) as float
     }
 
     /// Returns the next representable floating-point value in the direction of `other`
-    #[inline(always)]
+    #[inline]
     fn next_after(&self, other: float) -> float {
         next_after(*self as f64, other as f64) as float
     }
diff --git a/src/libstd/num/i16.rs b/src/libstd/num/i16.rs
index 9977247b249..eec20297a53 100644
--- a/src/libstd/num/i16.rs
+++ b/src/libstd/num/i16.rs
@@ -19,14 +19,14 @@ int_module!(i16, 16)
 
 impl BitCount for i16 {
     /// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic.
-    #[inline(always)]
+    #[inline]
     fn population_count(&self) -> i16 { unsafe { intrinsics::ctpop16(*self) } }
 
     /// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic.
-    #[inline(always)]
+    #[inline]
     fn leading_zeros(&self) -> i16 { unsafe { intrinsics::ctlz16(*self) } }
 
     /// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic.
-    #[inline(always)]
+    #[inline]
     fn trailing_zeros(&self) -> i16 { unsafe { intrinsics::cttz16(*self) } }
 }
diff --git a/src/libstd/num/i32.rs b/src/libstd/num/i32.rs
index 0115f306e4e..769187cc66d 100644
--- a/src/libstd/num/i32.rs
+++ b/src/libstd/num/i32.rs
@@ -19,14 +19,14 @@ int_module!(i32, 32)
 
 impl BitCount for i32 {
     /// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic.
-    #[inline(always)]
+    #[inline]
     fn population_count(&self) -> i32 { unsafe { intrinsics::ctpop32(*self) } }
 
     /// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic.
-    #[inline(always)]
+    #[inline]
     fn leading_zeros(&self) -> i32 { unsafe { intrinsics::ctlz32(*self) } }
 
     /// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic.
-    #[inline(always)]
+    #[inline]
     fn trailing_zeros(&self) -> i32 { unsafe { intrinsics::cttz32(*self) } }
 }
diff --git a/src/libstd/num/i64.rs b/src/libstd/num/i64.rs
index 4e280f01f27..ae0e59d1661 100644
--- a/src/libstd/num/i64.rs
+++ b/src/libstd/num/i64.rs
@@ -19,14 +19,14 @@ int_module!(i64, 64)
 
 impl BitCount for i64 {
     /// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic.
-    #[inline(always)]
+    #[inline]
     fn population_count(&self) -> i64 { unsafe { intrinsics::ctpop64(*self) } }
 
     /// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic.
-    #[inline(always)]
+    #[inline]
     fn leading_zeros(&self) -> i64 { unsafe { intrinsics::ctlz64(*self) } }
 
     /// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic.
-    #[inline(always)]
+    #[inline]
     fn trailing_zeros(&self) -> i64 { unsafe { intrinsics::cttz64(*self) } }
 }
diff --git a/src/libstd/num/i8.rs b/src/libstd/num/i8.rs
index 939965b9691..31a1f4241f5 100644
--- a/src/libstd/num/i8.rs
+++ b/src/libstd/num/i8.rs
@@ -19,14 +19,14 @@ int_module!(i8, 8)
 
 impl BitCount for i8 {
     /// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic.
-    #[inline(always)]
+    #[inline]
     fn population_count(&self) -> i8 { unsafe { intrinsics::ctpop8(*self) } }
 
     /// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic.
-    #[inline(always)]
+    #[inline]
     fn leading_zeros(&self) -> i8 { unsafe { intrinsics::ctlz8(*self) } }
 
     /// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic.
-    #[inline(always)]
+    #[inline]
     fn trailing_zeros(&self) -> i8 { unsafe { intrinsics::cttz8(*self) } }
 }
diff --git a/src/libstd/num/int.rs b/src/libstd/num/int.rs
index 96ef7e9e341..d3c2733b47d 100644
--- a/src/libstd/num/int.rs
+++ b/src/libstd/num/int.rs
@@ -22,30 +22,30 @@ int_module!(int, super::bits)
 #[cfg(target_word_size = "32")]
 impl BitCount for int {
     /// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic.
-    #[inline(always)]
+    #[inline]
     fn population_count(&self) -> int { (*self as i32).population_count() as int }
 
     /// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic.
-    #[inline(always)]
+    #[inline]
     fn leading_zeros(&self) -> int { (*self as i32).leading_zeros() as int }
 
     /// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic.
-    #[inline(always)]
+    #[inline]
     fn trailing_zeros(&self) -> int { (*self as i32).trailing_zeros() as int }
 }
 
 #[cfg(target_word_size = "64")]
 impl BitCount for int {
     /// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic.
-    #[inline(always)]
+    #[inline]
     fn population_count(&self) -> int { (*self as i64).population_count() as int }
 
     /// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic.
-    #[inline(always)]
+    #[inline]
     fn leading_zeros(&self) -> int { (*self as i64).leading_zeros() as int }
 
     /// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic.
-    #[inline(always)]
+    #[inline]
     fn trailing_zeros(&self) -> int { (*self as i64).trailing_zeros() as int }
 }
 
diff --git a/src/libstd/num/int_macros.rs b/src/libstd/num/int_macros.rs
index 74f74d11b73..74ec46ccfcd 100644
--- a/src/libstd/num/int_macros.rs
+++ b/src/libstd/num/int_macros.rs
@@ -27,17 +27,17 @@ pub static min_value: $T = (-1 as $T) << (bits - 1);
 pub static max_value: $T = min_value - 1 as $T;
 
 /// Calculates the sum of two numbers
-#[inline(always)]
+#[inline]
 pub fn add(x: $T, y: $T) -> $T { x + y }
 /// Subtracts the second number from the first
-#[inline(always)]
+#[inline]
 pub fn sub(x: $T, y: $T) -> $T { x - y }
 /// Multiplies two numbers together
-#[inline(always)]
+#[inline]
 pub fn mul(x: $T, y: $T) -> $T { x * y }
 /// Divides the first argument by the second argument (using integer division)
 /// Divides the first argument by the second argument (using integer division)
-#[inline(always)]
+#[inline]
 pub fn div(x: $T, y: $T) -> $T { x / y }
 
 ///
@@ -60,26 +60,26 @@ pub fn div(x: $T, y: $T) -> $T { x / y }
 /// ~~~
 ///
 ///
-#[inline(always)]
+#[inline]
 pub fn rem(x: $T, y: $T) -> $T { x % y }
 
 /// Returns true iff `x < y`
-#[inline(always)]
+#[inline]
 pub fn lt(x: $T, y: $T) -> bool { x < y }
 /// Returns true iff `x <= y`
-#[inline(always)]
+#[inline]
 pub fn le(x: $T, y: $T) -> bool { x <= y }
 /// Returns true iff `x == y`
-#[inline(always)]
+#[inline]
 pub fn eq(x: $T, y: $T) -> bool { x == y }
 /// Returns true iff `x != y`
-#[inline(always)]
+#[inline]
 pub fn ne(x: $T, y: $T) -> bool { x != y }
 /// Returns true iff `x >= y`
-#[inline(always)]
+#[inline]
 pub fn ge(x: $T, y: $T) -> bool { x >= y }
 /// Returns true iff `x > y`
-#[inline(always)]
+#[inline]
 pub fn gt(x: $T, y: $T) -> bool { x > y }
 
 ///
@@ -99,7 +99,7 @@ pub fn gt(x: $T, y: $T) -> bool { x > y }
 /// assert!(sum == 10);
 /// ~~~
 ///
-#[inline(always)]
+#[inline]
 pub fn range_step(start: $T, stop: $T, step: $T, it: &fn($T) -> bool) -> bool {
     let mut i = start;
     if step == 0 {
@@ -122,62 +122,62 @@ pub fn range_step(start: $T, stop: $T, step: $T, it: &fn($T) -> bool) -> bool {
     return true;
 }
 
-#[inline(always)]
+#[inline]
 /// Iterate over the range [`lo`..`hi`)
 pub fn range(lo: $T, hi: $T, it: &fn($T) -> bool) -> bool {
     range_step(lo, hi, 1 as $T, it)
 }
 
-#[inline(always)]
+#[inline]
 /// Iterate over the range [`hi`..`lo`)
 pub fn range_rev(hi: $T, lo: $T, it: &fn($T) -> bool) -> bool {
     range_step(hi, lo, -1 as $T, it)
 }
 
 /// Computes the bitwise complement
-#[inline(always)]
+#[inline]
 pub fn compl(i: $T) -> $T {
     -1 as $T ^ i
 }
 
 /// Computes the absolute value
-#[inline(always)]
+#[inline]
 pub fn abs(i: $T) -> $T { i.abs() }
 
 impl Num for $T {}
 
 #[cfg(not(test))]
 impl Ord for $T {
-    #[inline(always)]
+    #[inline]
     fn lt(&self, other: &$T) -> bool { return (*self) < (*other); }
-    #[inline(always)]
+    #[inline]
     fn le(&self, other: &$T) -> bool { return (*self) <= (*other); }
-    #[inline(always)]
+    #[inline]
     fn ge(&self, other: &$T) -> bool { return (*self) >= (*other); }
-    #[inline(always)]
+    #[inline]
     fn gt(&self, other: &$T) -> bool { return (*self) > (*other); }
 }
 
 #[cfg(not(test))]
 impl Eq for $T {
-    #[inline(always)]
+    #[inline]
     fn eq(&self, other: &$T) -> bool { return (*self) == (*other); }
-    #[inline(always)]
+    #[inline]
     fn ne(&self, other: &$T) -> bool { return (*self) != (*other); }
 }
 
 impl Orderable for $T {
-    #[inline(always)]
+    #[inline]
     fn min(&self, other: &$T) -> $T {
         if *self < *other { *self } else { *other }
     }
 
-    #[inline(always)]
+    #[inline]
     fn max(&self, other: &$T) -> $T {
         if *self > *other { *self } else { *other }
     }
 
-    #[inline(always)]
+    #[inline]
     fn clamp(&self, mn: &$T, mx: &$T) -> $T {
         if *self > *mx { *mx } else
         if *self < *mn { *mn } else { *self }
@@ -185,33 +185,33 @@ impl Orderable for $T {
 }
 
 impl Zero for $T {
-    #[inline(always)]
+    #[inline]
     fn zero() -> $T { 0 }
 
-    #[inline(always)]
+    #[inline]
     fn is_zero(&self) -> bool { *self == 0 }
 }
 
 impl One for $T {
-    #[inline(always)]
+    #[inline]
     fn one() -> $T { 1 }
 }
 
 #[cfg(not(test))]
 impl Add<$T,$T> for $T {
-    #[inline(always)]
+    #[inline]
     fn add(&self, other: &$T) -> $T { *self + *other }
 }
 
 #[cfg(not(test))]
 impl Sub<$T,$T> for $T {
-    #[inline(always)]
+    #[inline]
     fn sub(&self, other: &$T) -> $T { *self - *other }
 }
 
 #[cfg(not(test))]
 impl Mul<$T,$T> for $T {
-    #[inline(always)]
+    #[inline]
     fn mul(&self, other: &$T) -> $T { *self * *other }
 }
 
@@ -235,7 +235,7 @@ impl Div<$T,$T> for $T {
     /// assert!(-1 / -2 ==  0);
     /// ~~~
     ///
-    #[inline(always)]
+    #[inline]
     fn div(&self, other: &$T) -> $T { *self / *other }
 }
 
@@ -262,19 +262,19 @@ impl Rem<$T,$T> for $T {
     /// assert!(-1 % -2 == -1);
     /// ~~~
     ///
-    #[inline(always)]
+    #[inline]
     fn rem(&self, other: &$T) -> $T { *self % *other }
 }
 
 #[cfg(not(test))]
 impl Neg<$T> for $T {
-    #[inline(always)]
+    #[inline]
     fn neg(&self) -> $T { -*self }
 }
 
 impl Signed for $T {
     /// Computes the absolute value
-    #[inline(always)]
+    #[inline]
     fn abs(&self) -> $T {
         if self.is_negative() { -*self } else { *self }
     }
@@ -283,7 +283,7 @@ impl Signed for $T {
     /// The positive difference of two numbers. Returns `0` if the number is less than or
     /// equal to `other`, otherwise the difference between`self` and `other` is returned.
     ///
-    #[inline(always)]
+    #[inline]
     fn abs_sub(&self, other: &$T) -> $T {
         if *self <= *other { 0 } else { *self - *other }
     }
@@ -295,7 +295,7 @@ impl Signed for $T {
     /// - `1` if the number is positive
     /// - `-1` if the number is negative
     ///
-    #[inline(always)]
+    #[inline]
     fn signum(&self) -> $T {
         match *self {
             n if n > 0 =>  1,
@@ -305,11 +305,11 @@ impl Signed for $T {
     }
 
     /// Returns true if the number is positive
-    #[inline(always)]
+    #[inline]
     fn is_positive(&self) -> bool { *self > 0 }
 
     /// Returns true if the number is negative
-    #[inline(always)]
+    #[inline]
     fn is_negative(&self) -> bool { *self < 0 }
 }
 
@@ -331,7 +331,7 @@ impl Integer for $T {
     /// assert!((-1).div_floor(-2) ==  0);
     /// ~~~
     ///
-    #[inline(always)]
+    #[inline]
     fn div_floor(&self, other: &$T) -> $T {
         // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
         // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
@@ -363,7 +363,7 @@ impl Integer for $T {
     /// assert!((-1).mod_floor(-2) == -1);
     /// ~~~
     ///
-    #[inline(always)]
+    #[inline]
     fn mod_floor(&self, other: &$T) -> $T {
         // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
         // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
@@ -375,7 +375,7 @@ impl Integer for $T {
     }
 
     /// Calculates `div_floor` and `mod_floor` simultaneously
-    #[inline(always)]
+    #[inline]
     fn div_mod_floor(&self, other: &$T) -> ($T,$T) {
         // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
         // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
@@ -387,7 +387,7 @@ impl Integer for $T {
     }
 
     /// Calculates `div` (`\`) and `rem` (`%`) simultaneously
-    #[inline(always)]
+    #[inline]
     fn div_rem(&self, other: &$T) -> ($T,$T) {
         (*self / *other, *self % *other)
     }
@@ -397,7 +397,7 @@ impl Integer for $T {
     ///
     /// The result is always positive
     ///
-    #[inline(always)]
+    #[inline]
     fn gcd(&self, other: &$T) -> $T {
         // Use Euclid's algorithm
         let mut (m, n) = (*self, *other);
@@ -412,21 +412,21 @@ impl Integer for $T {
     ///
     /// Calculates the Lowest Common Multiple (LCM) of the number and `other`
     ///
-    #[inline(always)]
+    #[inline]
     fn lcm(&self, other: &$T) -> $T {
         ((*self * *other) / self.gcd(other)).abs() // should not have to recaluculate abs
     }
 
     /// Returns `true` if the number can be divided by `other` without leaving a remainder
-    #[inline(always)]
+    #[inline]
     fn is_multiple_of(&self, other: &$T) -> bool { *self % *other == 0 }
 
     /// Returns `true` if the number is divisible by `2`
-    #[inline(always)]
+    #[inline]
     fn is_even(&self) -> bool { self.is_multiple_of(&2) }
 
     /// Returns `true` if the number is not divisible by `2`
-    #[inline(always)]
+    #[inline]
     fn is_odd(&self) -> bool { !self.is_even() }
 }
 
@@ -434,90 +434,90 @@ impl Bitwise for $T {}
 
 #[cfg(not(test))]
 impl BitOr<$T,$T> for $T {
-    #[inline(always)]
+    #[inline]
     fn bitor(&self, other: &$T) -> $T { *self | *other }
 }
 
 #[cfg(not(test))]
 impl BitAnd<$T,$T> for $T {
-    #[inline(always)]
+    #[inline]
     fn bitand(&self, other: &$T) -> $T { *self & *other }
 }
 
 #[cfg(not(test))]
 impl BitXor<$T,$T> for $T {
-    #[inline(always)]
+    #[inline]
     fn bitxor(&self, other: &$T) -> $T { *self ^ *other }
 }
 
 #[cfg(not(test))]
 impl Shl<$T,$T> for $T {
-    #[inline(always)]
+    #[inline]
     fn shl(&self, other: &$T) -> $T { *self << *other }
 }
 
 #[cfg(not(test))]
 impl Shr<$T,$T> for $T {
-    #[inline(always)]
+    #[inline]
     fn shr(&self, other: &$T) -> $T { *self >> *other }
 }
 
 #[cfg(not(test))]
 impl Not<$T> for $T {
-    #[inline(always)]
+    #[inline]
     fn not(&self) -> $T { !*self }
 }
 
 impl Bounded for $T {
-    #[inline(always)]
+    #[inline]
     fn min_value() -> $T { min_value }
 
-    #[inline(always)]
+    #[inline]
     fn max_value() -> $T { max_value }
 }
 
 impl Int for $T {}
 
 impl Primitive for $T {
-    #[inline(always)]
+    #[inline]
     fn bits() -> uint { bits }
 
-    #[inline(always)]
+    #[inline]
     fn bytes() -> uint { bits / 8 }
 }
 
 // String conversion functions and impl str -> num
 
 /// Parse a string as a number in base 10.
-#[inline(always)]
+#[inline]
 pub fn from_str(s: &str) -> Option<$T> {
     strconv::from_str_common(s, 10u, true, false, false,
                          strconv::ExpNone, false, false)
 }
 
 /// Parse a string as a number in the given base.
-#[inline(always)]
+#[inline]
 pub fn from_str_radix(s: &str, radix: uint) -> Option<$T> {
     strconv::from_str_common(s, radix, true, false, false,
                          strconv::ExpNone, false, false)
 }
 
 /// Parse a byte slice as a number in the given base.
-#[inline(always)]
+#[inline]
 pub fn parse_bytes(buf: &[u8], radix: uint) -> Option<$T> {
     strconv::from_str_bytes_common(buf, radix, true, false, false,
                                strconv::ExpNone, false, false)
 }
 
 impl FromStr for $T {
-    #[inline(always)]
+    #[inline]
     fn from_str(s: &str) -> Option<$T> {
         from_str(s)
     }
 }
 
 impl FromStrRadix for $T {
-    #[inline(always)]
+    #[inline]
     fn from_str_radix(s: &str, radix: uint) -> Option<$T> {
         from_str_radix(s, radix)
     }
@@ -526,7 +526,7 @@ impl FromStrRadix for $T {
 // String conversion functions and impl num -> str
 
 /// Convert to a string as a byte slice in a given base.
-#[inline(always)]
+#[inline]
 pub fn to_str_bytes<U>(n: $T, radix: uint, f: &fn(v: &[u8]) -> U) -> U {
     let (buf, _) = strconv::to_str_bytes_common(&n, radix, false,
                             strconv::SignNeg, strconv::DigAll);
@@ -534,7 +534,7 @@ pub fn to_str_bytes<U>(n: $T, radix: uint, f: &fn(v: &[u8]) -> U) -> U {
 }
 
 /// Convert to a string in base 10.
-#[inline(always)]
+#[inline]
 pub fn to_str(num: $T) -> ~str {
     let (buf, _) = strconv::to_str_common(&num, 10u, false,
                                       strconv::SignNeg, strconv::DigAll);
@@ -542,7 +542,7 @@ pub fn to_str(num: $T) -> ~str {
 }
 
 /// Convert to a string in a given base.
-#[inline(always)]
+#[inline]
 pub fn to_str_radix(num: $T, radix: uint) -> ~str {
     let (buf, _) = strconv::to_str_common(&num, radix, false,
                                       strconv::SignNeg, strconv::DigAll);
@@ -550,14 +550,14 @@ pub fn to_str_radix(num: $T, radix: uint) -> ~str {
 }
 
 impl ToStr for $T {
-    #[inline(always)]
+    #[inline]
     fn to_str(&self) -> ~str {
         to_str(*self)
     }
 }
 
 impl ToStrRadix for $T {
-    #[inline(always)]
+    #[inline]
     fn to_str_radix(&self, radix: uint) -> ~str {
         to_str_radix(*self, radix)
     }
diff --git a/src/libstd/num/num.rs b/src/libstd/num/num.rs
index a9893579721..30a18a0587b 100644
--- a/src/libstd/num/num.rs
+++ b/src/libstd/num/num.rs
@@ -307,7 +307,7 @@ pub trait Float: Real
 /// assert_eq!(twenty, 20f32);
 /// ~~~
 ///
-#[inline(always)]
+#[inline]
 pub fn cast<T:NumCast,U:NumCast>(n: T) -> U {
     NumCast::from(n)
 }
@@ -338,28 +338,28 @@ pub trait NumCast {
 macro_rules! impl_num_cast(
     ($T:ty, $conv:ident) => (
         impl NumCast for $T {
-            #[inline(always)]
+            #[inline]
             fn from<N:NumCast>(n: N) -> $T {
                 // `$conv` could be generated using `concat_idents!`, but that
                 // macro seems to be broken at the moment
                 n.$conv()
             }
 
-            #[inline(always)] fn to_u8(&self)    -> u8    { *self as u8    }
-            #[inline(always)] fn to_u16(&self)   -> u16   { *self as u16   }
-            #[inline(always)] fn to_u32(&self)   -> u32   { *self as u32   }
-            #[inline(always)] fn to_u64(&self)   -> u64   { *self as u64   }
-            #[inline(always)] fn to_uint(&self)  -> uint  { *self as uint  }
-
-            #[inline(always)] fn to_i8(&self)    -> i8    { *self as i8    }
-            #[inline(always)] fn to_i16(&self)   -> i16   { *self as i16   }
-            #[inline(always)] fn to_i32(&self)   -> i32   { *self as i32   }
-            #[inline(always)] fn to_i64(&self)   -> i64   { *self as i64   }
-            #[inline(always)] fn to_int(&self)   -> int   { *self as int   }
-
-            #[inline(always)] fn to_f32(&self)   -> f32   { *self as f32   }
-            #[inline(always)] fn to_f64(&self)   -> f64   { *self as f64   }
-            #[inline(always)] fn to_float(&self) -> float { *self as float }
+            #[inline] fn to_u8(&self)    -> u8    { *self as u8    }
+            #[inline] fn to_u16(&self)   -> u16   { *self as u16   }
+            #[inline] fn to_u32(&self)   -> u32   { *self as u32   }
+            #[inline] fn to_u64(&self)   -> u64   { *self as u64   }
+            #[inline] fn to_uint(&self)  -> uint  { *self as uint  }
+
+            #[inline] fn to_i8(&self)    -> i8    { *self as i8    }
+            #[inline] fn to_i16(&self)   -> i16   { *self as i16   }
+            #[inline] fn to_i32(&self)   -> i32   { *self as i32   }
+            #[inline] fn to_i64(&self)   -> i64   { *self as i64   }
+            #[inline] fn to_int(&self)   -> int   { *self as int   }
+
+            #[inline] fn to_f32(&self)   -> f32   { *self as f32   }
+            #[inline] fn to_f64(&self)   -> f64   { *self as f64   }
+            #[inline] fn to_float(&self) -> float { *self as float }
         }
     )
 )
@@ -410,14 +410,29 @@ pub fn pow_with_uint<T:NumCast+One+Zero+Copy+Div<T,T>+Mul<T,T>>(radix: uint, pow
     let mut multiplier = cast(radix);
     while (my_pow > 0u) {
         if my_pow % 2u == 1u {
-            total *= multiplier;
+            total = total * multiplier;
         }
-        my_pow     /= 2u;
-        multiplier *= multiplier;
+        my_pow     = my_pow / 2u;
+        multiplier = multiplier * multiplier;
     }
     total
 }
 
+impl<T: Zero> Zero for @mut T {
+    fn zero() -> @mut T { @mut Zero::zero() }
+    fn is_zero(&self) -> bool { (**self).is_zero() }
+}
+
+impl<T: Zero> Zero for @T {
+    fn zero() -> @T { @Zero::zero() }
+    fn is_zero(&self) -> bool { (**self).is_zero() }
+}
+
+impl<T: Zero> Zero for ~T {
+    fn zero() -> ~T { ~Zero::zero() }
+    fn is_zero(&self) -> bool { (**self).is_zero() }
+}
+
 /// Helper function for testing numeric operations
 #[cfg(test)]
 pub fn test_num<T:Num + NumCast>(ten: T, two: T) {
diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs
index 3905d82cd0f..a062838aacf 100644
--- a/src/libstd/num/strconv.rs
+++ b/src/libstd/num/strconv.rs
@@ -42,12 +42,12 @@ pub enum SignFormat {
     SignAll
 }
 
-#[inline(always)]
+#[inline]
 fn is_NaN<T:Eq>(num: &T) -> bool {
     *num != *num
 }
 
-#[inline(always)]
+#[inline]
 fn is_inf<T:Eq+NumStrConv>(num: &T) -> bool {
     match NumStrConv::inf() {
         None    => false,
@@ -55,7 +55,7 @@ fn is_inf<T:Eq+NumStrConv>(num: &T) -> bool {
     }
 }
 
-#[inline(always)]
+#[inline]
 fn is_neg_inf<T:Eq+NumStrConv>(num: &T) -> bool {
     match NumStrConv::neg_inf() {
         None    => false,
@@ -63,7 +63,7 @@ fn is_neg_inf<T:Eq+NumStrConv>(num: &T) -> bool {
     }
 }
 
-#[inline(always)]
+#[inline]
 fn is_neg_zero<T:Eq+One+Zero+NumStrConv+Div<T,T>>(num: &T) -> bool {
     let _0: T = Zero::zero();
     let _1: T = One::one();
@@ -83,23 +83,23 @@ pub trait NumStrConv {
 
 macro_rules! impl_NumStrConv_Floating (($t:ty) => (
     impl NumStrConv for $t {
-        #[inline(always)]
+        #[inline]
         fn NaN()      -> Option<$t> { Some( 0.0 / 0.0) }
-        #[inline(always)]
+        #[inline]
         fn inf()      -> Option<$t> { Some( 1.0 / 0.0) }
-        #[inline(always)]
+        #[inline]
         fn neg_inf()  -> Option<$t> { Some(-1.0 / 0.0) }
-        #[inline(always)]
+        #[inline]
         fn neg_zero() -> Option<$t> { Some(-0.0      ) }
 
-        #[inline(always)]
+        #[inline]
         fn round_to_zero(&self) -> $t {
             ( if *self < 0.0 { f64::ceil(*self as f64)  }
               else           { f64::floor(*self as f64) }
             ) as $t
         }
 
-        #[inline(always)]
+        #[inline]
         fn fractional_part(&self) -> $t {
             *self - self.round_to_zero()
         }
@@ -108,13 +108,13 @@ macro_rules! impl_NumStrConv_Floating (($t:ty) => (
 
 macro_rules! impl_NumStrConv_Integer (($t:ty) => (
     impl NumStrConv for $t {
-        #[inline(always)] fn NaN()      -> Option<$t> { None }
-        #[inline(always)] fn inf()      -> Option<$t> { None }
-        #[inline(always)] fn neg_inf()  -> Option<$t> { None }
-        #[inline(always)] fn neg_zero() -> Option<$t> { None }
+        #[inline] fn NaN()      -> Option<$t> { None }
+        #[inline] fn inf()      -> Option<$t> { None }
+        #[inline] fn neg_inf()  -> Option<$t> { None }
+        #[inline] fn neg_zero() -> Option<$t> { None }
 
-        #[inline(always)] fn round_to_zero(&self)   -> $t { *self }
-        #[inline(always)] fn fractional_part(&self) -> $t {     0 }
+        #[inline] fn round_to_zero(&self)   -> $t { *self }
+        #[inline] fn fractional_part(&self) -> $t {     0 }
     }
 ))
 
@@ -229,7 +229,7 @@ pub fn to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+NumStrConv+Copy+
         };
 
         // Decrease the deccumulator one digit at a time
-        deccum /= radix_gen;
+        deccum = deccum / radix_gen;
         deccum = deccum.round_to_zero();
 
         buf.push(char::from_digit(current_digit.to_int() as uint, radix)
@@ -282,7 +282,7 @@ pub fn to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+NumStrConv+Copy+
               )
         ) {
             // Shift first fractional digit into the integer part
-            deccum *= radix_gen;
+            deccum = deccum * radix_gen;
 
             // Calculate the absolute value of each digit.
             // See note in first loop.
@@ -381,7 +381,7 @@ pub fn to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+NumStrConv+Copy+
  * Converts a number to its string representation. This is a wrapper for
  * `to_str_bytes_common()`, for details see there.
  */
-#[inline(always)]
+#[inline]
 pub fn to_str_common<T:NumCast+Zero+One+Eq+Ord+NumStrConv+Copy+
                             Div<T,T>+Neg<T>+Rem<T,T>+Mul<T,T>>(
         num: &T, radix: uint, negative_zero: bool,
@@ -499,8 +499,8 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+
 
     // Initialize accumulator with signed zero for floating point parsing to
     // work
-    let mut accum      = if accum_positive { _0 } else { -_1 * _0};
-    let mut last_accum = accum; // Necessary to detect overflow
+    let mut accum      = if accum_positive { copy _0 } else { -_1 * _0};
+    let mut last_accum = copy accum; // Necessary to detect overflow
     let mut i          = start;
     let mut exp_found  = false;
 
@@ -511,13 +511,13 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+
         match char::to_digit(c, radix) {
             Some(digit) => {
                 // shift accum one digit left
-                accum *= radix_gen;
+                accum = accum * copy radix_gen;
 
                 // add/subtract current digit depending on sign
                 if accum_positive {
-                    accum += cast(digit as int);
+                    accum = accum + cast(digit as int);
                 } else {
-                    accum -= cast(digit as int);
+                    accum = accum - cast(digit as int);
                 }
 
                 // Detect overflow by comparing to last value, except
@@ -526,7 +526,7 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+
                     if accum_positive && accum <= last_accum { return None; }
                     if !accum_positive && accum >= last_accum { return None; }
                 }
-                last_accum = accum;
+                last_accum = copy accum;
             }
             None => match c {
                 '_' if ignore_underscores => {}
@@ -548,7 +548,7 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+
     // Parse fractional part of number
     // Skip if already reached start of exponent
     if !exp_found {
-        let mut power = _1;
+        let mut power = copy _1;
 
         while i < len {
             let c = buf[i] as char;
@@ -556,21 +556,21 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+
             match char::to_digit(c, radix) {
                 Some(digit) => {
                     // Decrease power one order of magnitude
-                    power /= radix_gen;
+                    power = power / radix_gen;
 
                     let digit_t: T = cast(digit);
 
                     // add/subtract current digit depending on sign
                     if accum_positive {
-                        accum += digit_t * power;
+                        accum = accum + digit_t * power;
                     } else {
-                        accum -= digit_t * power;
+                        accum = accum - digit_t * power;
                     }
 
                     // Detect overflow by comparing to last value
                     if accum_positive && accum < last_accum { return None; }
                     if !accum_positive && accum > last_accum { return None; }
-                    last_accum = accum;
+                    last_accum = copy accum;
                 }
                 None => match c {
                     '_' if ignore_underscores => {}
@@ -596,7 +596,7 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+
         }
     }
 
-    let mut multiplier = _1;
+    let mut multiplier = copy _1;
 
     if exp_found {
         let c = buf[i] as char;
@@ -632,7 +632,7 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+
  * Parses a string as a number. This is a wrapper for
  * `from_str_bytes_common()`, for details see there.
  */
-#[inline(always)]
+#[inline]
 pub fn from_str_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+Mul<T,T>+
                               Sub<T,T>+Neg<T>+Add<T,T>+NumStrConv>(
         buf: &str, radix: uint, negative: bool, fractional: bool,
diff --git a/src/libstd/num/uint.rs b/src/libstd/num/uint.rs
index bcb97ff5a07..126150c0f1b 100644
--- a/src/libstd/num/uint.rs
+++ b/src/libstd/num/uint.rs
@@ -95,7 +95,7 @@ pub fn iterate(lo: uint, hi: uint, it: &fn(uint) -> bool) -> bool {
 }
 
 impl iter::Times for uint {
-    #[inline(always)]
+    #[inline]
     ///
     /// A convenience form for basic iteration. Given a uint `x`,
     /// `for x.times { ... }` executes the given block x times.
@@ -117,7 +117,7 @@ impl iter::Times for uint {
 }
 
 /// Returns the smallest power of 2 greater than or equal to `n`
-#[inline(always)]
+#[inline]
 pub fn next_power_of_two(n: uint) -> uint {
     let halfbits: uint = sys::size_of::<uint>() * 4u;
     let mut tmp: uint = n - 1u;
diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs
index 2bc1ca9c673..52f620f97ce 100644
--- a/src/libstd/num/uint_macros.rs
+++ b/src/libstd/num/uint_macros.rs
@@ -28,42 +28,42 @@ pub static min_value: $T = 0 as $T;
 pub static max_value: $T = 0 as $T - 1 as $T;
 
 /// Calculates the sum of two numbers
-#[inline(always)]
+#[inline]
 pub fn add(x: $T, y: $T) -> $T { x + y }
 /// Subtracts the second number from the first
-#[inline(always)]
+#[inline]
 pub fn sub(x: $T, y: $T) -> $T { x - y }
 /// Multiplies two numbers together
-#[inline(always)]
+#[inline]
 pub fn mul(x: $T, y: $T) -> $T { x * y }
 /// Divides the first argument by the second argument (using integer division)
-#[inline(always)]
+#[inline]
 pub fn div(x: $T, y: $T) -> $T { x / y }
 /// Calculates the integer remainder when x is divided by y (equivalent to the
 /// '%' operator)
-#[inline(always)]
+#[inline]
 pub fn rem(x: $T, y: $T) -> $T { x % y }
 
 /// Returns true iff `x < y`
-#[inline(always)]
+#[inline]
 pub fn lt(x: $T, y: $T) -> bool { x < y }
 /// Returns true iff `x <= y`
-#[inline(always)]
+#[inline]
 pub fn le(x: $T, y: $T) -> bool { x <= y }
 /// Returns true iff `x == y`
-#[inline(always)]
+#[inline]
 pub fn eq(x: $T, y: $T) -> bool { x == y }
 /// Returns true iff `x != y`
-#[inline(always)]
+#[inline]
 pub fn ne(x: $T, y: $T) -> bool { x != y }
 /// Returns true iff `x >= y`
-#[inline(always)]
+#[inline]
 pub fn ge(x: $T, y: $T) -> bool { x >= y }
 /// Returns true iff `x > y`
-#[inline(always)]
+#[inline]
 pub fn gt(x: $T, y: $T) -> bool { x > y }
 
-#[inline(always)]
+#[inline]
 /**
  * Iterate through a range with a given step value.
  *
@@ -99,20 +99,20 @@ pub fn range_step(start: $T, stop: $T, step: $T_SIGNED, it: &fn($T) -> bool) ->
     return true;
 }
 
-#[inline(always)]
+#[inline]
 /// Iterate over the range [`lo`..`hi`)
 pub fn range(lo: $T, hi: $T, it: &fn($T) -> bool) -> bool {
     range_step(lo, hi, 1 as $T_SIGNED, it)
 }
 
-#[inline(always)]
+#[inline]
 /// Iterate over the range [`hi`..`lo`)
 pub fn range_rev(hi: $T, lo: $T, it: &fn($T) -> bool) -> bool {
     range_step(hi, lo, -1 as $T_SIGNED, it)
 }
 
 /// Computes the bitwise complement
-#[inline(always)]
+#[inline]
 pub fn compl(i: $T) -> $T {
     max_value ^ i
 }
@@ -121,37 +121,37 @@ impl Num for $T {}
 
 #[cfg(not(test))]
 impl Ord for $T {
-    #[inline(always)]
+    #[inline]
     fn lt(&self, other: &$T) -> bool { (*self) < (*other) }
-    #[inline(always)]
+    #[inline]
     fn le(&self, other: &$T) -> bool { (*self) <= (*other) }
-    #[inline(always)]
+    #[inline]
     fn ge(&self, other: &$T) -> bool { (*self) >= (*other) }
-    #[inline(always)]
+    #[inline]
     fn gt(&self, other: &$T) -> bool { (*self) > (*other) }
 }
 
 #[cfg(not(test))]
 impl Eq for $T {
-    #[inline(always)]
+    #[inline]
     fn eq(&self, other: &$T) -> bool { return (*self) == (*other); }
-    #[inline(always)]
+    #[inline]
     fn ne(&self, other: &$T) -> bool { return (*self) != (*other); }
 }
 
 impl Orderable for $T {
-    #[inline(always)]
+    #[inline]
     fn min(&self, other: &$T) -> $T {
         if *self < *other { *self } else { *other }
     }
 
-    #[inline(always)]
+    #[inline]
     fn max(&self, other: &$T) -> $T {
         if *self > *other { *self } else { *other }
     }
 
     /// Returns the number constrained within the range `mn <= self <= mx`.
-    #[inline(always)]
+    #[inline]
     fn clamp(&self, mn: &$T, mx: &$T) -> $T {
         cond!(
             (*self > *mx) { *mx   }
@@ -162,51 +162,51 @@ impl Orderable for $T {
 }
 
 impl Zero for $T {
-    #[inline(always)]
+    #[inline]
     fn zero() -> $T { 0 }
 
-    #[inline(always)]
+    #[inline]
     fn is_zero(&self) -> bool { *self == 0 }
 }
 
 impl One for $T {
-    #[inline(always)]
+    #[inline]
     fn one() -> $T { 1 }
 }
 
 #[cfg(not(test))]
 impl Add<$T,$T> for $T {
-    #[inline(always)]
+    #[inline]
     fn add(&self, other: &$T) -> $T { *self + *other }
 }
 
 #[cfg(not(test))]
 impl Sub<$T,$T> for $T {
-    #[inline(always)]
+    #[inline]
     fn sub(&self, other: &$T) -> $T { *self - *other }
 }
 
 #[cfg(not(test))]
 impl Mul<$T,$T> for $T {
-    #[inline(always)]
+    #[inline]
     fn mul(&self, other: &$T) -> $T { *self * *other }
 }
 
 #[cfg(not(test))]
 impl Div<$T,$T> for $T {
-    #[inline(always)]
+    #[inline]
     fn div(&self, other: &$T) -> $T { *self / *other }
 }
 
 #[cfg(not(test))]
 impl Rem<$T,$T> for $T {
-    #[inline(always)]
+    #[inline]
     fn rem(&self, other: &$T) -> $T { *self % *other }
 }
 
 #[cfg(not(test))]
 impl Neg<$T> for $T {
-    #[inline(always)]
+    #[inline]
     fn neg(&self) -> $T { -*self }
 }
 
@@ -214,27 +214,27 @@ impl Unsigned for $T {}
 
 impl Integer for $T {
     /// Calculates `div` (`\`) and `rem` (`%`) simultaneously
-    #[inline(always)]
+    #[inline]
     fn div_rem(&self, other: &$T) -> ($T,$T) {
         (*self / *other, *self % *other)
     }
 
     /// Unsigned integer division. Returns the same result as `div` (`/`).
-    #[inline(always)]
+    #[inline]
     fn div_floor(&self, other: &$T) -> $T { *self / *other }
 
     /// Unsigned integer modulo operation. Returns the same result as `rem` (`%`).
-    #[inline(always)]
+    #[inline]
     fn mod_floor(&self, other: &$T) -> $T { *self / *other }
 
     /// Calculates `div_floor` and `modulo_floor` simultaneously
-    #[inline(always)]
+    #[inline]
     fn div_mod_floor(&self, other: &$T) -> ($T,$T) {
         (*self / *other, *self % *other)
     }
 
     /// Calculates the Greatest Common Divisor (GCD) of the number and `other`
-    #[inline(always)]
+    #[inline]
     fn gcd(&self, other: &$T) -> $T {
         // Use Euclid's algorithm
         let mut (m, n) = (*self, *other);
@@ -247,21 +247,21 @@ impl Integer for $T {
     }
 
     /// Calculates the Lowest Common Multiple (LCM) of the number and `other`
-    #[inline(always)]
+    #[inline]
     fn lcm(&self, other: &$T) -> $T {
         (*self * *other) / self.gcd(other)
     }
 
     /// Returns `true` if the number can be divided by `other` without leaving a remainder
-    #[inline(always)]
+    #[inline]
     fn is_multiple_of(&self, other: &$T) -> bool { *self % *other == 0 }
 
     /// Returns `true` if the number is divisible by `2`
-    #[inline(always)]
+    #[inline]
     fn is_even(&self) -> bool { self.is_multiple_of(&2) }
 
     /// Returns `true` if the number is not divisible by `2`
-    #[inline(always)]
+    #[inline]
     fn is_odd(&self) -> bool { !self.is_even() }
 }
 
@@ -269,45 +269,45 @@ impl Bitwise for $T {}
 
 #[cfg(not(test))]
 impl BitOr<$T,$T> for $T {
-    #[inline(always)]
+    #[inline]
     fn bitor(&self, other: &$T) -> $T { *self | *other }
 }
 
 #[cfg(not(test))]
 impl BitAnd<$T,$T> for $T {
-    #[inline(always)]
+    #[inline]
     fn bitand(&self, other: &$T) -> $T { *self & *other }
 }
 
 #[cfg(not(test))]
 impl BitXor<$T,$T> for $T {
-    #[inline(always)]
+    #[inline]
     fn bitxor(&self, other: &$T) -> $T { *self ^ *other }
 }
 
 #[cfg(not(test))]
 impl Shl<$T,$T> for $T {
-    #[inline(always)]
+    #[inline]
     fn shl(&self, other: &$T) -> $T { *self << *other }
 }
 
 #[cfg(not(test))]
 impl Shr<$T,$T> for $T {
-    #[inline(always)]
+    #[inline]
     fn shr(&self, other: &$T) -> $T { *self >> *other }
 }
 
 #[cfg(not(test))]
 impl Not<$T> for $T {
-    #[inline(always)]
+    #[inline]
     fn not(&self) -> $T { !*self }
 }
 
 impl Bounded for $T {
-    #[inline(always)]
+    #[inline]
     fn min_value() -> $T { min_value }
 
-    #[inline(always)]
+    #[inline]
     fn max_value() -> $T { max_value }
 }
 
@@ -316,35 +316,35 @@ impl Int for $T {}
 // String conversion functions and impl str -> num
 
 /// Parse a string as a number in base 10.
-#[inline(always)]
+#[inline]
 pub fn from_str(s: &str) -> Option<$T> {
     strconv::from_str_common(s, 10u, false, false, false,
                              strconv::ExpNone, false, false)
 }
 
 /// Parse a string as a number in the given base.
-#[inline(always)]
+#[inline]
 pub fn from_str_radix(s: &str, radix: uint) -> Option<$T> {
     strconv::from_str_common(s, radix, false, false, false,
                              strconv::ExpNone, false, false)
 }
 
 /// Parse a byte slice as a number in the given base.
-#[inline(always)]
+#[inline]
 pub fn parse_bytes(buf: &[u8], radix: uint) -> Option<$T> {
     strconv::from_str_bytes_common(buf, radix, false, false, false,
                                    strconv::ExpNone, false, false)
 }
 
 impl FromStr for $T {
-    #[inline(always)]
+    #[inline]
     fn from_str(s: &str) -> Option<$T> {
         from_str(s)
     }
 }
 
 impl FromStrRadix for $T {
-    #[inline(always)]
+    #[inline]
     fn from_str_radix(s: &str, radix: uint) -> Option<$T> {
         from_str_radix(s, radix)
     }
@@ -353,7 +353,7 @@ impl FromStrRadix for $T {
 // String conversion functions and impl num -> str
 
 /// Convert to a string as a byte slice in a given base.
-#[inline(always)]
+#[inline]
 pub fn to_str_bytes<U>(n: $T, radix: uint, f: &fn(v: &[u8]) -> U) -> U {
     let (buf, _) = strconv::to_str_bytes_common(&n, radix, false,
                             strconv::SignNeg, strconv::DigAll);
@@ -361,7 +361,7 @@ pub fn to_str_bytes<U>(n: $T, radix: uint, f: &fn(v: &[u8]) -> U) -> U {
 }
 
 /// Convert to a string in base 10.
-#[inline(always)]
+#[inline]
 pub fn to_str(num: $T) -> ~str {
     let (buf, _) = strconv::to_str_common(&num, 10u, false,
                             strconv::SignNeg, strconv::DigAll);
@@ -369,7 +369,7 @@ pub fn to_str(num: $T) -> ~str {
 }
 
 /// Convert to a string in a given base.
-#[inline(always)]
+#[inline]
 pub fn to_str_radix(num: $T, radix: uint) -> ~str {
     let (buf, _) = strconv::to_str_common(&num, radix, false,
                             strconv::SignNeg, strconv::DigAll);
@@ -377,42 +377,42 @@ pub fn to_str_radix(num: $T, radix: uint) -> ~str {
 }
 
 impl ToStr for $T {
-    #[inline(always)]
+    #[inline]
     fn to_str(&self) -> ~str {
         to_str(*self)
     }
 }
 
 impl ToStrRadix for $T {
-    #[inline(always)]
+    #[inline]
     fn to_str_radix(&self, radix: uint) -> ~str {
         to_str_radix(*self, radix)
     }
 }
 
 impl Primitive for $T {
-    #[inline(always)]
+    #[inline]
     fn bits() -> uint { bits }
 
-    #[inline(always)]
+    #[inline]
     fn bytes() -> uint { bits / 8 }
 }
 
 impl BitCount for $T {
     /// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic.
-    #[inline(always)]
+    #[inline]
     fn population_count(&self) -> $T {
         (*self as $T_SIGNED).population_count() as $T
     }
 
     /// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic.
-    #[inline(always)]
+    #[inline]
     fn leading_zeros(&self) -> $T {
         (*self as $T_SIGNED).leading_zeros() as $T
     }
 
     /// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic.
-    #[inline(always)]
+    #[inline]
     fn trailing_zeros(&self) -> $T {
         (*self as $T_SIGNED).trailing_zeros() as $T
     }
diff --git a/src/libstd/old_iter.rs b/src/libstd/old_iter.rs
index 9fea4376816..83bb9eb0908 100644
--- a/src/libstd/old_iter.rs
+++ b/src/libstd/old_iter.rs
@@ -16,7 +16,7 @@
 
 #[allow(missing_doc)];
 
-use cmp::{Eq, Ord};
+use cmp::{Eq};
 use kinds::Copy;
 use option::{None, Option, Some};
 use vec;
@@ -54,11 +54,6 @@ pub trait CopyableIter<A:Copy> {
     fn find(&self, p: &fn(&A) -> bool) -> Option<A>;
 }
 
-pub trait CopyableOrderedIter<A:Copy + Ord> {
-    fn min(&self) -> A;
-    fn max(&self) -> A;
-}
-
 // A trait for sequences that can be built by imperatively pushing elements
 // onto them.
 pub trait Buildable<A> {
@@ -78,7 +73,7 @@ pub trait Buildable<A> {
      fn build_sized(size: uint, builder: &fn(push: &fn(A))) -> Self;
 }
 
-#[inline(always)]
+#[inline]
 pub fn _eachi<A,IA:BaseIter<A>>(this: &IA, blk: &fn(uint, &A) -> bool) -> bool {
     let mut i = 0;
     for this.each |a| {
@@ -94,7 +89,7 @@ pub fn eachi<A,IA:BaseIter<A>>(this: &IA, blk: &fn(uint, &A) -> bool) -> bool {
     _eachi(this, blk)
 }
 
-#[inline(always)]
+#[inline]
 pub fn all<A,IA:BaseIter<A>>(this: &IA, blk: &fn(&A) -> bool) -> bool {
     for this.each |a| {
         if !blk(a) {
@@ -104,7 +99,7 @@ pub fn all<A,IA:BaseIter<A>>(this: &IA, blk: &fn(&A) -> bool) -> bool {
     return true;
 }
 
-#[inline(always)]
+#[inline]
 pub fn any<A,IA:BaseIter<A>>(this: &IA, blk: &fn(&A) -> bool) -> bool {
     for this.each |a| {
         if blk(a) {
@@ -114,18 +109,18 @@ pub fn any<A,IA:BaseIter<A>>(this: &IA, blk: &fn(&A) -> bool) -> bool {
     return false;
 }
 
-#[inline(always)]
+#[inline]
 pub fn filter_to_vec<A:Copy,IA:BaseIter<A>>(this: &IA,
                                             prd: &fn(&A) -> bool)
                                          -> ~[A] {
     do vec::build_sized_opt(this.size_hint()) |push| {
         for this.each |a| {
-            if prd(a) { push(*a); }
+            if prd(a) { push(copy *a); }
         }
     }
 }
 
-#[inline(always)]
+#[inline]
 pub fn map_to_vec<A,B,IA:BaseIter<A>>(this: &IA, op: &fn(&A) -> B) -> ~[B] {
     do vec::build_sized_opt(this.size_hint()) |push| {
         for this.each |a| {
@@ -134,7 +129,7 @@ pub fn map_to_vec<A,B,IA:BaseIter<A>>(this: &IA, op: &fn(&A) -> B) -> ~[B] {
     }
 }
 
-#[inline(always)]
+#[inline]
 pub fn flat_map_to_vec<A,B,IA:BaseIter<A>,IB:BaseIter<B>>(this: &IA,
                                                           op: &fn(&A) -> IB)
                                                        -> ~[B] {
@@ -147,7 +142,7 @@ pub fn flat_map_to_vec<A,B,IA:BaseIter<A>,IB:BaseIter<B>>(this: &IA,
     }
 }
 
-#[inline(always)]
+#[inline]
 pub fn foldl<A,B,IA:BaseIter<A>>(this: &IA, b0: B, blk: &fn(&B, &A) -> B)
                               -> B {
     let mut b = b0;
@@ -157,12 +152,12 @@ pub fn foldl<A,B,IA:BaseIter<A>>(this: &IA, b0: B, blk: &fn(&B, &A) -> B)
     b
 }
 
-#[inline(always)]
+#[inline]
 pub fn to_vec<A:Copy,IA:BaseIter<A>>(this: &IA) -> ~[A] {
     map_to_vec(this, |&x| x)
 }
 
-#[inline(always)]
+#[inline]
 pub fn contains<A:Eq,IA:BaseIter<A>>(this: &IA, x: &A) -> bool {
     for this.each |a| {
         if *a == *x { return true; }
@@ -170,7 +165,7 @@ pub fn contains<A:Eq,IA:BaseIter<A>>(this: &IA, x: &A) -> bool {
     return false;
 }
 
-#[inline(always)]
+#[inline]
 pub fn count<A:Eq,IA:BaseIter<A>>(this: &IA, x: &A) -> uint {
     do foldl(this, 0) |count, value| {
         if *value == *x {
@@ -181,7 +176,7 @@ pub fn count<A:Eq,IA:BaseIter<A>>(this: &IA, x: &A) -> uint {
     }
 }
 
-#[inline(always)]
+#[inline]
 pub fn position<A,IA:BaseIter<A>>(this: &IA, f: &fn(&A) -> bool)
                                -> Option<uint> {
     let mut i = 0;
@@ -192,45 +187,11 @@ pub fn position<A,IA:BaseIter<A>>(this: &IA, f: &fn(&A) -> bool)
     return None;
 }
 
-// note: 'rposition' would only make sense to provide with a bidirectional
-// iter interface, such as would provide "reach" in addition to "each". As is,
-// it would have to be implemented with foldr, which is too inefficient.
-
-#[inline(always)]
-pub fn min<A:Copy + Ord,IA:BaseIter<A>>(this: &IA) -> A {
-    match do foldl::<A,Option<A>,IA>(this, None) |a, b| {
-        match a {
-          &Some(ref a_) if *a_ < *b => {
-             *(a)
-          }
-          _ => Some(*b)
-        }
-    } {
-        Some(val) => val,
-        None => fail!("min called on empty iterator")
-    }
-}
-
-#[inline(always)]
-pub fn max<A:Copy + Ord,IA:BaseIter<A>>(this: &IA) -> A {
-    match do foldl::<A,Option<A>,IA>(this, None) |a, b| {
-        match a {
-          &Some(ref a_) if *a_ > *b => {
-              *(a)
-          }
-          _ => Some(*b)
-        }
-    } {
-        Some(val) => val,
-        None => fail!("max called on empty iterator")
-    }
-}
-
-#[inline(always)]
+#[inline]
 pub fn find<A:Copy,IA:BaseIter<A>>(this: &IA, f: &fn(&A) -> bool)
                                 -> Option<A> {
     for this.each |i| {
-        if f(i) { return Some(*i) }
+        if f(i) { return Some(copy *i) }
     }
     return None;
 }
@@ -247,7 +208,7 @@ pub fn find<A:Copy,IA:BaseIter<A>>(this: &IA, f: &fn(&A) -> bool)
  *             as an argument a function that will push an element
  *             onto the sequence being constructed.
  */
-#[inline(always)]
+#[inline]
 pub fn build<A,B: Buildable<A>>(builder: &fn(push: &fn(A))) -> B {
     Buildable::build_sized(4, builder)
 }
@@ -265,7 +226,7 @@ pub fn build<A,B: Buildable<A>>(builder: &fn(push: &fn(A))) -> B {
  *             as an argument a function that will push an element
  *             onto the sequence being constructed.
  */
-#[inline(always)]
+#[inline]
 pub fn build_sized_opt<A,B: Buildable<A>>(size: Option<uint>,
                                           builder: &fn(push: &fn(A))) -> B {
     Buildable::build_sized(size.get_or_default(4), builder)
@@ -275,7 +236,7 @@ pub fn build_sized_opt<A,B: Buildable<A>>(size: Option<uint>,
 
 /// Applies a function to each element of an iterable and returns the results
 /// in a sequence built via `BU`.  See also `map_to_vec`.
-#[inline(always)]
+#[inline]
 pub fn map<T,IT: BaseIter<T>,U,BU: Buildable<U>>(v: &IT, f: &fn(&T) -> U)
     -> BU {
     do build_sized_opt(v.size_hint()) |push| {
@@ -291,7 +252,7 @@ pub fn map<T,IT: BaseIter<T>,U,BU: Buildable<U>>(v: &IT, f: &fn(&T) -> U)
  * Creates a generic sequence of size `n_elts` and initializes the elements
  * to the value returned by the function `op`.
  */
-#[inline(always)]
+#[inline]
 pub fn from_fn<T,BT: Buildable<T>>(n_elts: uint, op: InitOp<T>) -> BT {
     do Buildable::build_sized(n_elts) |push| {
         let mut i: uint = 0u;
@@ -305,31 +266,31 @@ pub fn from_fn<T,BT: Buildable<T>>(n_elts: uint, op: InitOp<T>) -> BT {
  * Creates an immutable vector of size `n_elts` and initializes the elements
  * to the value `t`.
  */
-#[inline(always)]
+#[inline]
 pub fn from_elem<T:Copy,BT:Buildable<T>>(n_elts: uint, t: T) -> BT {
     do Buildable::build_sized(n_elts) |push| {
         let mut i: uint = 0;
-        while i < n_elts { push(t); i += 1; }
+        while i < n_elts { push(copy t); i += 1; }
     }
 }
 
 /// Appends two generic sequences.
-#[inline(always)]
+#[inline]
 pub fn append<T:Copy,IT:BaseIter<T>,BT:Buildable<T>>(lhs: &IT, rhs: &IT)
                                                   -> BT {
     let size_opt = lhs.size_hint().chain_ref(
         |sz1| rhs.size_hint().map(|sz2| *sz1+*sz2));
     do build_sized_opt(size_opt) |push| {
-        for lhs.each |x| { push(*x); }
-        for rhs.each |x| { push(*x); }
+        for lhs.each |x| { push(copy *x); }
+        for rhs.each |x| { push(copy *x); }
     }
 }
 
 /// Copies a generic sequence, possibly converting it to a different
 /// type of sequence.
-#[inline(always)]
+#[inline]
 pub fn copy_seq<T:Copy,IT:BaseIter<T>,BT:Buildable<T>>(v: &IT) -> BT {
     do build_sized_opt(v.size_hint()) |push| {
-        for v.each |x| { push(*x); }
+        for v.each |x| { push(copy *x); }
     }
 }
diff --git a/src/libstd/option.rs b/src/libstd/option.rs
index 80f4fb7643c..7dc6b7fe4b1 100644
--- a/src/libstd/option.rs
+++ b/src/libstd/option.rs
@@ -88,14 +88,14 @@ impl<T:Ord> Ord for Option<T> {
     }
 }
 
-impl<T: Copy + Add<T,T>> Add<Option<T>, Option<T>> for Option<T> {
-    #[inline(always)]
+impl<T: Copy+Add<T,T>> Add<Option<T>, Option<T>> for Option<T> {
+    #[inline]
     fn add(&self, other: &Option<T>) -> Option<T> {
-        match (*self, *other) {
-            (None, None) => None,
-            (_, None) => *self,
-            (None, _) => *other,
-            (Some(ref lhs), Some(ref rhs)) => Some(*lhs + *rhs)
+        match (&*self, &*other) {
+            (&None, &None) => None,
+            (_, &None) => copy *self,
+            (&None, _) => copy *other,
+            (&Some(ref lhs), &Some(ref rhs)) => Some(*lhs + *rhs)
         }
     }
 }
@@ -126,12 +126,12 @@ impl<T> Option<T> {
     }
 
     /// Returns true if the option contains some value
-    #[inline(always)]
+    #[inline]
     pub fn is_some(&const self) -> bool { !self.is_none() }
 
     /// Update an optional value by optionally running its content through a
     /// function that returns an option.
-    #[inline(always)]
+    #[inline]
     pub fn chain<U>(self, f: &fn(t: T) -> Option<U>) -> Option<U> {
         match self {
             Some(t) => f(t),
@@ -140,7 +140,7 @@ impl<T> Option<T> {
     }
 
     /// Returns the leftmost Some() value, or None if both are None.
-    #[inline(always)]
+    #[inline]
     pub fn or(self, optb: Option<T>) -> Option<T> {
         match self {
             Some(opta) => Some(opta),
@@ -150,7 +150,7 @@ impl<T> Option<T> {
 
     /// Update an optional value by optionally running its content by reference
     /// through a function that returns an option.
-    #[inline(always)]
+    #[inline]
     pub fn chain_ref<'a, U>(&'a self, f: &fn(x: &'a T) -> Option<U>)
                             -> Option<U> {
         match *self {
@@ -160,27 +160,27 @@ impl<T> Option<T> {
     }
 
     /// Maps a `some` value from one type to another by reference
-    #[inline(always)]
+    #[inline]
     pub fn map<'a, U>(&self, f: &fn(&'a T) -> U) -> Option<U> {
         match *self { Some(ref x) => Some(f(x)), None => None }
     }
 
     /// As `map`, but consumes the option and gives `f` ownership to avoid
     /// copying.
-    #[inline(always)]
+    #[inline]
     pub fn map_consume<U>(self, f: &fn(v: T) -> U) -> Option<U> {
         match self { None => None, Some(v) => Some(f(v)) }
     }
 
     /// Applies a function to the contained value or returns a default
-    #[inline(always)]
+    #[inline]
     pub fn map_default<'a, U>(&'a self, def: U, f: &fn(&'a T) -> U) -> U {
         match *self { None => def, Some(ref t) => f(t) }
     }
 
     /// As `map_default`, but consumes the option and gives `f`
     /// ownership to avoid copying.
-    #[inline(always)]
+    #[inline]
     pub fn map_consume_default<U>(self, def: U, f: &fn(v: T) -> U) -> U {
         match self { None => def, Some(v) => f(v) }
     }
@@ -215,7 +215,7 @@ impl<T> Option<T> {
     Instead, prefer to use pattern matching and handle the `None`
     case explicitly.
      */
-    #[inline(always)]
+    #[inline]
     pub fn get_ref<'a>(&'a self) -> &'a T {
         match *self {
           Some(ref x) => x,
@@ -237,7 +237,7 @@ impl<T> Option<T> {
     Instead, prefer to use pattern matching and handle the `None`
     case explicitly.
      */
-    #[inline(always)]
+    #[inline]
     pub fn get_mut_ref<'a>(&'a mut self) -> &'a mut T {
         match *self {
           Some(ref mut x) => x,
@@ -245,7 +245,7 @@ impl<T> Option<T> {
         }
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn unwrap(self) -> T {
         /*!
         Moves a value out of an option type and returns it.
@@ -277,7 +277,7 @@ impl<T> Option<T> {
      *
      * Fails if the value equals `None`.
      */
-    #[inline(always)]
+    #[inline]
     pub fn swap_unwrap(&mut self) -> T {
         if self.is_none() { fail!("option::swap_unwrap none") }
         util::replace(self, None).unwrap()
@@ -291,7 +291,7 @@ impl<T> Option<T> {
      *
      * Fails if the value equals `none`
      */
-    #[inline(always)]
+    #[inline]
     pub fn expect(self, reason: &str) -> T {
         match self {
           Some(val) => val,
@@ -315,7 +315,7 @@ impl<T:Copy> Option<T> {
     Instead, prefer to use pattern matching and handle the `None`
     case explicitly.
     */
-    #[inline(always)]
+    #[inline]
     pub fn get(self) -> T {
         match self {
           Some(x) => return x,
@@ -324,13 +324,13 @@ impl<T:Copy> Option<T> {
     }
 
     /// Returns the contained value or a default
-    #[inline(always)]
+    #[inline]
     pub fn get_or_default(self, def: T) -> T {
         match self { Some(x) => x, None => def }
     }
 
     /// Applies a function zero or more times until the result is none.
-    #[inline(always)]
+    #[inline]
     pub fn while_some(self, blk: &fn(v: T) -> Option<T>) {
         let mut opt = self;
         while opt.is_some() {
@@ -341,7 +341,7 @@ impl<T:Copy> Option<T> {
 
 impl<T:Copy + Zero> Option<T> {
     /// Returns the contained value or zero (for this type)
-    #[inline(always)]
+    #[inline]
     pub fn get_or_zero(self) -> T {
         match self {
             Some(x) => x,
@@ -350,6 +350,11 @@ impl<T:Copy + Zero> Option<T> {
     }
 }
 
+impl<T> Zero for Option<T> {
+    fn zero() -> Option<T> { None }
+    fn is_zero(&self) -> bool { self.is_none() }
+}
+
 /// Immutable iterator over an `Option<A>`
 pub struct OptionIterator<'self, A> {
     priv opt: Option<&'self A>
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index 044b305a0dd..765dd30febc 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -40,6 +40,8 @@ use option::{Some, None};
 use os;
 use prelude::*;
 use ptr;
+use rt;
+use rt::TaskContext;
 use str;
 use uint;
 use unstable::finally::Finally;
@@ -144,7 +146,7 @@ pub mod win32 {
     }
 
     pub fn as_utf16_p<T>(s: &str, f: &fn(*u16) -> T) -> T {
-        let mut t = str::to_utf16(s);
+        let mut t = s.to_utf16();
         // Null terminate before passing on.
         t += [0u16];
         vec::as_imm_buf(t, |buf, _len| f(buf))
@@ -959,12 +961,10 @@ pub fn copy_file(from: &Path, to: &Path) -> bool {
             fclose(ostream);
 
             // Give the new file the old file's permissions
-            unsafe {
-                if do str::as_c_str(to.to_str()) |to_buf| {
-                    libc::chmod(to_buf, from_mode as mode_t)
-                } != 0 {
-                    return false; // should be a condition...
-                }
+            if do str::as_c_str(to.to_str()) |to_buf| {
+                libc::chmod(to_buf, from_mode as mode_t)
+            } != 0 {
+                return false; // should be a condition...
             }
             return ok;
         }
@@ -1169,10 +1169,17 @@ pub fn real_args() -> ~[~str] {
 #[cfg(target_os = "android")]
 #[cfg(target_os = "freebsd")]
 pub fn real_args() -> ~[~str] {
-    unsafe {
-        let argc = rustrt::rust_get_argc();
-        let argv = rustrt::rust_get_argv();
-        load_argc_and_argv(argc, argv)
+    if rt::context() == TaskContext {
+        match rt::args::clone() {
+            Some(args) => args,
+            None => fail!("process arguments not initialized")
+        }
+    } else {
+        unsafe {
+            let argc = rustrt::rust_get_argc();
+            let argv = rustrt::rust_get_argv();
+            load_argc_and_argv(argc, argv)
+        }
     }
 }
 
@@ -1685,10 +1692,11 @@ mod tests {
           assert!((ostream as uint != 0u));
           let s = ~"hello";
           let mut buf = s.as_bytes_with_null().to_owned();
+          let len = buf.len();
           do vec::as_mut_buf(buf) |b, _len| {
-              assert!((libc::fwrite(b as *c_void, 1u as size_t,
-                                   (s.len() + 1u) as size_t, ostream)
-                      == buf.len() as size_t))
+              assert_eq!(libc::fwrite(b as *c_void, 1u as size_t,
+                                      (s.len() + 1u) as size_t, ostream),
+                         len as size_t)
           }
           assert_eq!(libc::fclose(ostream), (0u as c_int));
           let in_mode = in.get_mode();
diff --git a/src/libstd/owned.rs b/src/libstd/owned.rs
index 3262fb4afdc..e7a6e38fdb0 100644
--- a/src/libstd/owned.rs
+++ b/src/libstd/owned.rs
@@ -14,20 +14,20 @@
 
 #[cfg(not(test))]
 impl<T:Eq> Eq for ~T {
-    #[inline(always)]
+    #[inline]
     fn eq(&self, other: &~T) -> bool { *(*self) == *(*other) }
-    #[inline(always)]
+    #[inline]
     fn ne(&self, other: &~T) -> bool { *(*self) != *(*other) }
 }
 
 #[cfg(not(test))]
 impl<T:Ord> Ord for ~T {
-    #[inline(always)]
+    #[inline]
     fn lt(&self, other: &~T) -> bool { *(*self) < *(*other) }
-    #[inline(always)]
+    #[inline]
     fn le(&self, other: &~T) -> bool { *(*self) <= *(*other) }
-    #[inline(always)]
+    #[inline]
     fn ge(&self, other: &~T) -> bool { *(*self) >= *(*other) }
-    #[inline(always)]
+    #[inline]
     fn gt(&self, other: &~T) -> bool { *(*self) > *(*other) }
 }
diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index 400657d0c25..9c51526aa7f 100644
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -515,7 +515,7 @@ impl GenericPath for PosixPath {
     fn with_filestem(&self, s: &str) -> PosixPath {
         match self.filetype() {
             None => self.with_filename(s),
-            Some(ref t) => self.with_filename(str::to_owned(s) + *t),
+            Some(ref t) => self.with_filename(s.to_owned() + *t),
         }
     }
 
@@ -657,7 +657,7 @@ impl GenericPath for WindowsPath {
             (None, None) => {
                 host = None;
                 device = None;
-                rest = str::to_owned(s);
+                rest = s.to_owned();
             }
         }
 
@@ -729,7 +729,7 @@ impl GenericPath for WindowsPath {
     fn with_filestem(&self, s: &str) -> WindowsPath {
         match self.filetype() {
             None => self.with_filename(s),
-            Some(ref t) => self.with_filename(str::to_owned(s) + *t),
+            Some(ref t) => self.with_filename(s.to_owned() + *t),
         }
     }
 
@@ -904,7 +904,7 @@ pub mod windows {
     use libc;
     use option::{None, Option, Some};
 
-    #[inline(always)]
+    #[inline]
     pub fn is_sep(u: char) -> bool {
         u == '/' || u == '\\'
     }
@@ -947,7 +947,6 @@ pub mod windows {
 mod tests {
     use option::{None, Some};
     use path::{PosixPath, WindowsPath, windows};
-    use str;
 
     #[test]
     fn test_double_slash_collapsing() {
@@ -984,7 +983,7 @@ mod tests {
     fn test_posix_paths() {
         fn t(wp: &PosixPath, s: &str) {
             let ss = wp.to_str();
-            let sss = str::to_owned(s);
+            let sss = s.to_owned();
             if (ss != sss) {
                 debug!("got %s", ss);
                 debug!("expected %s", sss);
@@ -1042,7 +1041,7 @@ mod tests {
     fn test_normalize() {
         fn t(wp: &PosixPath, s: &str) {
             let ss = wp.to_str();
-            let sss = str::to_owned(s);
+            let sss = s.to_owned();
             if (ss != sss) {
                 debug!("got %s", ss);
                 debug!("expected %s", sss);
@@ -1105,7 +1104,7 @@ mod tests {
     fn test_windows_paths() {
         fn t(wp: &WindowsPath, s: &str) {
             let ss = wp.to_str();
-            let sss = str::to_owned(s);
+            let sss = s.to_owned();
             if (ss != sss) {
                 debug!("got %s", ss);
                 debug!("expected %s", sss);
diff --git a/src/libstd/pipes.rs b/src/libstd/pipes.rs
index 012ad0ed80d..26dd4af45d6 100644
--- a/src/libstd/pipes.rs
+++ b/src/libstd/pipes.rs
@@ -85,7 +85,7 @@ bounded and unbounded protocols allows for less code duplication.
 #[allow(missing_doc)];
 
 use container::Container;
-use cast::{forget, transmute, transmute_copy};
+use cast::{forget, transmute, transmute_copy, transmute_mut};
 use either::{Either, Left, Right};
 use iterator::IteratorUtil;
 use kinds::Owned;
@@ -102,10 +102,6 @@ use util::replace;
 
 static SPIN_COUNT: uint = 0;
 
-macro_rules! move_it (
-    { $x:expr } => ( unsafe { let y = *ptr::to_unsafe_ptr(&($x)); y } )
-)
-
 #[deriving(Eq)]
 enum State {
     Empty,
@@ -316,9 +312,11 @@ impl<T> Drop for BufferResource<T> {
     fn finalize(&self) {
         unsafe {
             // FIXME(#4330) Need self by value to get mutability.
-            let this: &mut BufferResource<T> = transmute(self);
+            let this: &mut BufferResource<T> = transmute_mut(self);
+
+            let null_buffer: ~Buffer<T> = transmute(ptr::null::<Buffer<T>>());
+            let mut b = replace(&mut this.buffer, null_buffer);
 
-            let mut b = move_it!(this.buffer);
             //let p = ptr::to_unsafe_ptr(*b);
             //error!("drop %?", p);
             let old_count = intrinsics::atomic_xsub_rel(
diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs
index 61b8d36266e..309df27e151 100644
--- a/src/libstd/prelude.rs
+++ b/src/libstd/prelude.rs
@@ -47,9 +47,9 @@ pub use char::Char;
 pub use container::{Container, Mutable, Map, Set};
 pub use hash::Hash;
 pub use old_iter::{BaseIter, ReverseIter, ExtendedIter, EqIter};
-pub use old_iter::{CopyableIter, CopyableOrderedIter};
+pub use old_iter::CopyableIter;
 pub use iter::{Times, FromIter};
-pub use iterator::{Iterator, IteratorUtil};
+pub use iterator::{Iterator, IteratorUtil, OrdIterator};
 pub use num::{Num, NumCast};
 pub use num::{Orderable, Signed, Unsigned, Round};
 pub use num::{Algebraic, Trigonometric, Exponential, Hyperbolic};
@@ -61,7 +61,7 @@ pub use path::Path;
 pub use path::PosixPath;
 pub use path::WindowsPath;
 pub use ptr::RawPtr;
-pub use ascii::{Ascii, AsciiCast, OwnedAsciiCast, AsciiStr};
+pub use ascii::{Ascii, AsciiCast, OwnedAsciiCast, AsciiStr, ToBytesConsume};
 pub use str::{Str, StrVector, StrSlice, OwnedStr, StrUtil, NullTerminatedStr};
 pub use from_str::{FromStr};
 pub use to_bytes::IterBytes;
diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs
index cd5a3182f6b..7f89d454be1 100644
--- a/src/libstd/ptr.rs
+++ b/src/libstd/ptr.rs
@@ -19,31 +19,31 @@ use unstable::intrinsics;
 use uint;
 
 /// Calculate the offset from a pointer
-#[inline(always)]
+#[inline]
 pub fn offset<T>(ptr: *T, count: uint) -> *T {
     (ptr as uint + count * sys::size_of::<T>()) as *T
 }
 
 /// Calculate the offset from a const pointer
-#[inline(always)]
+#[inline]
 pub fn const_offset<T>(ptr: *const T, count: uint) -> *const T {
     (ptr as uint + count * sys::size_of::<T>()) as *T
 }
 
 /// Calculate the offset from a mut pointer
-#[inline(always)]
+#[inline]
 pub fn mut_offset<T>(ptr: *mut T, count: uint) -> *mut T {
     (ptr as uint + count * sys::size_of::<T>()) as *mut T
 }
 
 /// Return the offset of the first null pointer in `buf`.
-#[inline(always)]
+#[inline]
 pub unsafe fn buf_len<T>(buf: **T) -> uint {
     position(buf, |i| *i == null())
 }
 
 /// Return the first offset `i` such that `f(buf[i]) == true`.
-#[inline(always)]
+#[inline]
 pub unsafe fn position<T>(buf: *T, f: &fn(&T) -> bool) -> uint {
     let mut i = 0;
     loop {
@@ -53,19 +53,19 @@ pub unsafe fn position<T>(buf: *T, f: &fn(&T) -> bool) -> uint {
 }
 
 /// Create an unsafe null pointer
-#[inline(always)]
+#[inline]
 pub fn null<T>() -> *T { 0 as *T }
 
 /// Create an unsafe mutable null pointer
-#[inline(always)]
+#[inline]
 pub fn mut_null<T>() -> *mut T { 0 as *mut T }
 
 /// Returns true if the pointer is equal to the null pointer.
-#[inline(always)]
+#[inline]
 pub fn is_null<T>(ptr: *const T) -> bool { ptr == null() }
 
 /// Returns true if the pointer is not equal to the null pointer.
-#[inline(always)]
+#[inline]
 pub fn is_not_null<T>(ptr: *const T) -> bool { !is_null(ptr) }
 
 /**
@@ -74,22 +74,8 @@ pub fn is_not_null<T>(ptr: *const T) -> bool { !is_null(ptr) }
  * Copies `count` elements (not bytes) from `src` to `dst`. The source
  * and destination may overlap.
  */
-#[inline(always)]
-#[cfg(target_word_size = "32", stage0)]
-pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) {
-    use unstable::intrinsics::memmove32;
-    let n = count * sys::size_of::<T>();
-    memmove32(dst as *mut u8, src as *u8, n as u32);
-}
-
-/**
- * Copies data from one location to another.
- *
- * Copies `count` elements (not bytes) from `src` to `dst`. The source
- * and destination may overlap.
- */
-#[inline(always)]
-#[cfg(target_word_size = "32", not(stage0))]
+#[inline]
+#[cfg(target_word_size = "32")]
 pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) {
     use unstable::intrinsics::memmove32;
     memmove32(dst, src as *T, count as u32);
@@ -101,22 +87,8 @@ pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) {
  * Copies `count` elements (not bytes) from `src` to `dst`. The source
  * and destination may overlap.
  */
-#[inline(always)]
-#[cfg(target_word_size = "64", stage0)]
-pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) {
-    use unstable::intrinsics::memmove64;
-    let n = count * sys::size_of::<T>();
-    memmove64(dst as *mut u8, src as *u8, n as u64);
-}
-
-/**
- * Copies data from one location to another.
- *
- * Copies `count` elements (not bytes) from `src` to `dst`. The source
- * and destination may overlap.
- */
-#[inline(always)]
-#[cfg(target_word_size = "64", not(stage0))]
+#[inline]
+#[cfg(target_word_size = "64")]
 pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) {
     use unstable::intrinsics::memmove64;
     memmove64(dst, src as *T, count as u64);
@@ -128,22 +100,8 @@ pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) {
  * Copies `count` elements (not bytes) from `src` to `dst`. The source
  * and destination may *not* overlap.
  */
-#[inline(always)]
-#[cfg(target_word_size = "32", stage0)]
-pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: uint) {
-    use unstable::intrinsics::memmove32;
-    let n = count * sys::size_of::<T>();
-    memmove32(dst as *mut u8, src as *u8, n as u32);
-}
-
-/**
- * Copies data from one location to another.
- *
- * Copies `count` elements (not bytes) from `src` to `dst`. The source
- * and destination may *not* overlap.
- */
-#[inline(always)]
-#[cfg(target_word_size = "32", not(stage0))]
+#[inline]
+#[cfg(target_word_size = "32")]
 pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: uint) {
     use unstable::intrinsics::memcpy32;
     memcpy32(dst, src as *T, count as u32);
@@ -155,22 +113,8 @@ pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: u
  * Copies `count` elements (not bytes) from `src` to `dst`. The source
  * and destination may *not* overlap.
  */
-#[inline(always)]
-#[cfg(target_word_size = "64", stage0)]
-pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: uint) {
-    use unstable::intrinsics::memmove64;
-    let n = count * sys::size_of::<T>();
-    memmove64(dst as *mut u8, src as *u8, n as u64);
-}
-
-/**
- * Copies data from one location to another.
- *
- * Copies `count` elements (not bytes) from `src` to `dst`. The source
- * and destination may *not* overlap.
- */
-#[inline(always)]
-#[cfg(target_word_size = "64", not(stage0))]
+#[inline]
+#[cfg(target_word_size = "64")]
 pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: uint) {
     use unstable::intrinsics::memcpy64;
     memcpy64(dst, src as *T, count as u64);
@@ -180,8 +124,8 @@ pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: u
  * Invokes memset on the specified pointer, setting `count * size_of::<T>()`
  * bytes of memory starting at `dst` to `c`.
  */
-#[inline(always)]
-#[cfg(target_word_size = "32", not(stage0))]
+#[inline]
+#[cfg(target_word_size = "32")]
 pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) {
     use unstable::intrinsics::memset32;
     memset32(dst, c, count as u32);
@@ -191,8 +135,8 @@ pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) {
  * Invokes memset on the specified pointer, setting `count * size_of::<T>()`
  * bytes of memory starting at `dst` to `c`.
  */
-#[inline(always)]
-#[cfg(target_word_size = "64", not(stage0))]
+#[inline]
+#[cfg(target_word_size = "64")]
 pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) {
     use unstable::intrinsics::memset64;
     memset64(dst, c, count as u64);
@@ -222,26 +166,26 @@ pub unsafe fn swap_ptr<T>(x: *mut T, y: *mut T) {
  * Replace the value at a mutable location with a new one, returning the old
  * value, without deinitialising or copying either one.
  */
-#[inline(always)]
+#[inline]
 pub unsafe fn replace_ptr<T>(dest: *mut T, mut src: T) -> T {
     swap_ptr(dest, &mut src);
     src
 }
 
 /// Transform a region pointer - &T - to an unsafe pointer - *T.
-#[inline(always)]
+#[inline]
 pub fn to_unsafe_ptr<T>(thing: &T) -> *T {
     thing as *T
 }
 
 /// Transform a const region pointer - &const T - to a const unsafe pointer - *const T.
-#[inline(always)]
+#[inline]
 pub fn to_const_unsafe_ptr<T>(thing: &const T) -> *const T {
     thing as *const T
 }
 
 /// Transform a mutable region pointer - &mut T - to a mutable unsafe pointer - *mut T.
-#[inline(always)]
+#[inline]
 pub fn to_mut_unsafe_ptr<T>(thing: &mut T) -> *mut T {
     thing as *mut T
 }
@@ -297,11 +241,11 @@ pub trait RawPtr<T> {
 /// Extension methods for immutable pointers
 impl<T> RawPtr<T> for *T {
     /// Returns true if the pointer is equal to the null pointer.
-    #[inline(always)]
+    #[inline]
     fn is_null(&const self) -> bool { is_null(*self) }
 
     /// Returns true if the pointer is not equal to the null pointer.
-    #[inline(always)]
+    #[inline]
     fn is_not_null(&const self) -> bool { is_not_null(*self) }
 
     ///
@@ -314,7 +258,7 @@ impl<T> RawPtr<T> for *T {
     /// that this is still an unsafe operation because the returned value could
     /// be pointing to invalid memory.
     ///
-    #[inline(always)]
+    #[inline]
     unsafe fn to_option(&const self) -> Option<&T> {
         if self.is_null() { None } else {
             Some(cast::transmute(*self))
@@ -322,18 +266,18 @@ impl<T> RawPtr<T> for *T {
     }
 
     /// Calculates the offset from a pointer.
-    #[inline(always)]
+    #[inline]
     fn offset(&self, count: uint) -> *T { offset(*self, count) }
 }
 
 /// Extension methods for mutable pointers
 impl<T> RawPtr<T> for *mut T {
     /// Returns true if the pointer is equal to the null pointer.
-    #[inline(always)]
+    #[inline]
     fn is_null(&const self) -> bool { is_null(*self) }
 
     /// Returns true if the pointer is not equal to the null pointer.
-    #[inline(always)]
+    #[inline]
     fn is_not_null(&const self) -> bool { is_not_null(*self) }
 
     ///
@@ -346,7 +290,7 @@ impl<T> RawPtr<T> for *mut T {
     /// that this is still an unsafe operation because the returned value could
     /// be pointing to invalid memory.
     ///
-    #[inline(always)]
+    #[inline]
     unsafe fn to_option(&const self) -> Option<&T> {
         if self.is_null() { None } else {
             Some(cast::transmute(*self))
@@ -354,37 +298,37 @@ impl<T> RawPtr<T> for *mut T {
     }
 
     /// Calculates the offset from a mutable pointer.
-    #[inline(always)]
+    #[inline]
     fn offset(&self, count: uint) -> *mut T { mut_offset(*self, count) }
 }
 
 // Equality for pointers
 #[cfg(not(test))]
 impl<T> Eq for *const T {
-    #[inline(always)]
+    #[inline]
     fn eq(&self, other: &*const T) -> bool {
         (*self as uint) == (*other as uint)
     }
-    #[inline(always)]
+    #[inline]
     fn ne(&self, other: &*const T) -> bool { !self.eq(other) }
 }
 
 // Comparison for pointers
 #[cfg(not(test))]
 impl<T> Ord for *const T {
-    #[inline(always)]
+    #[inline]
     fn lt(&self, other: &*const T) -> bool {
         (*self as uint) < (*other as uint)
     }
-    #[inline(always)]
+    #[inline]
     fn le(&self, other: &*const T) -> bool {
         (*self as uint) <= (*other as uint)
     }
-    #[inline(always)]
+    #[inline]
     fn ge(&self, other: &*const T) -> bool {
         (*self as uint) >= (*other as uint)
     }
-    #[inline(always)]
+    #[inline]
     fn gt(&self, other: &*const T) -> bool {
         (*self as uint) > (*other as uint)
     }
@@ -592,7 +536,6 @@ pub mod ptr_tests {
     }
 
     #[test]
-    #[cfg(not(stage0))]
     fn test_set_memory() {
         let mut xs = [0u8, ..20];
         let ptr = vec::raw::to_mut_ptr(xs);
diff --git a/src/libstd/rand.rs b/src/libstd/rand.rs
index 7946f7e4f13..739e3dfedc7 100644
--- a/src/libstd/rand.rs
+++ b/src/libstd/rand.rs
@@ -451,7 +451,7 @@ pub trait RngUtil {
 /// Extension methods for random number generators
 impl<R: Rng> RngUtil for R {
     /// Return a random value for a Rand type
-    #[inline(always)]
+    #[inline]
     fn gen<T: Rand>(&mut self) -> T {
         Rand::rand(self)
     }
@@ -526,7 +526,7 @@ impl<R: Rng> RngUtil for R {
         if values.is_empty() {
             None
         } else {
-            Some(values[self.gen_uint_range(0u, values.len())])
+            Some(copy values[self.gen_uint_range(0u, values.len())])
         }
     }
     /**
@@ -555,7 +555,7 @@ impl<R: Rng> RngUtil for R {
         for v.each |item| {
             so_far += item.weight;
             if so_far > chosen {
-                return Some(item.item);
+                return Some(copy item.item);
             }
         }
         util::unreachable();
@@ -569,7 +569,7 @@ impl<R: Rng> RngUtil for R {
         let mut r = ~[];
         for v.each |item| {
             for uint::range(0u, item.weight) |_i| {
-                r.push(item.item);
+                r.push(copy item.item);
             }
         }
         r
@@ -762,7 +762,7 @@ impl IsaacRng {
 }
 
 impl Rng for IsaacRng {
-    #[inline(always)]
+    #[inline]
     fn next(&mut self) -> u32 {
         if self.cnt == 0 {
             // make some more numbers
@@ -862,7 +862,7 @@ pub fn task_rng() -> @@mut IsaacRng {
 
 // Allow direct chaining with `task_rng`
 impl<R: Rng> Rng for @@mut R {
-    #[inline(always)]
+    #[inline]
     fn next(&mut self) -> u32 {
         match *self {
             @@ref mut r => r.next()
diff --git a/src/libstd/rand/distributions.rs b/src/libstd/rand/distributions.rs
index f08d967cbe0..6f4f1a34977 100644
--- a/src/libstd/rand/distributions.rs
+++ b/src/libstd/rand/distributions.rs
@@ -26,7 +26,7 @@ use rand::{Rng,Rand};
 mod ziggurat_tables;
 
 // inlining should mean there is no performance penalty for this
-#[inline(always)]
+#[inline]
 fn ziggurat<R:Rng>(rng: &mut R,
                    center_u: bool,
                    X: ziggurat_tables::ZigTable,
@@ -77,11 +77,11 @@ pub struct StandardNormal(f64);
 
 impl Rand for StandardNormal {
     fn rand<R:Rng>(rng: &mut R) -> StandardNormal {
-        #[inline(always)]
+        #[inline]
         fn pdf(x: f64) -> f64 {
             f64::exp((-x*x/2.0) as f64) as f64
         }
-        #[inline(always)]
+        #[inline]
         fn zero_case<R:Rng>(rng: &mut R, u: f64) -> f64 {
             // compute a random number in the tail by hand
 
@@ -131,11 +131,11 @@ pub struct Exp1(f64);
 impl Rand for Exp1 {
     #[inline]
     fn rand<R:Rng>(rng: &mut R) -> Exp1 {
-        #[inline(always)]
+        #[inline]
         fn pdf(x: f64) -> f64 {
             f64::exp(-x)
         }
-        #[inline(always)]
+        #[inline]
         fn zero_case<R:Rng>(rng: &mut R, _u: f64) -> f64 {
             ziggurat_tables::ZIG_EXP_R - f64::ln(rng.gen())
         }
diff --git a/src/libstd/reflect.rs b/src/libstd/reflect.rs
index 1eb3d3a0daa..d276abf0c8b 100644
--- a/src/libstd/reflect.rs
+++ b/src/libstd/reflect.rs
@@ -35,7 +35,7 @@ pub trait MovePtr {
 }
 
 /// Helper function for alignment calculation.
-#[inline(always)]
+#[inline]
 pub fn align(size: uint, align: uint) -> uint {
     ((size + align) - 1u) & !(align - 1u)
 }
@@ -49,26 +49,26 @@ pub fn MovePtrAdaptor<V:TyVisitor + MovePtr>(v: V) -> MovePtrAdaptor<V> {
 }
 
 impl<V:TyVisitor + MovePtr> MovePtrAdaptor<V> {
-    #[inline(always)]
+    #[inline]
     pub fn bump(&self, sz: uint) {
         do self.inner.move_ptr() |p| {
             ((p as uint) + sz) as *c_void
         };
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn align(&self, a: uint) {
         do self.inner.move_ptr() |p| {
             align(p as uint, a) as *c_void
         };
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn align_to<T>(&self) {
         self.align(sys::min_align_of::<T>());
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn bump_past<T>(&self) {
         self.bump(sys::size_of::<T>());
     }
diff --git a/src/libstd/repr.rs b/src/libstd/repr.rs
index 46f69d020d1..ab3f83d34d5 100644
--- a/src/libstd/repr.rs
+++ b/src/libstd/repr.rs
@@ -18,6 +18,7 @@ More runtime type reflection
 
 use cast::transmute;
 use char;
+use container::Container;
 use intrinsic;
 use intrinsic::{TyDesc, TyVisitor, visit_tydesc};
 use intrinsic::Opaque;
@@ -163,7 +164,7 @@ pub fn ReprVisitor(ptr: *c_void, writer: @Writer) -> ReprVisitor {
 }
 
 impl MovePtr for ReprVisitor {
-    #[inline(always)]
+    #[inline]
     fn move_ptr(&self, adjustment: &fn(*c_void) -> *c_void) {
         *self.ptr = adjustment(*self.ptr);
     }
@@ -178,7 +179,7 @@ impl MovePtr for ReprVisitor {
 impl ReprVisitor {
     // Various helpers for the TyVisitor impl
 
-    #[inline(always)]
+    #[inline]
     pub fn get<T>(&self, f: &fn(&T)) -> bool {
         unsafe {
             f(transmute::<*c_void,&T>(*self.ptr));
@@ -186,12 +187,12 @@ impl ReprVisitor {
         true
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn visit_inner(&self, inner: *TyDesc) -> bool {
         self.visit_ptr_inner(*self.ptr, inner)
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn visit_ptr_inner(&self, ptr: *c_void, inner: *TyDesc) -> bool {
         unsafe {
             let u = ReprVisitor(ptr, self.writer);
@@ -201,7 +202,7 @@ impl ReprVisitor {
         }
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn write<T:Repr>(&self) -> bool {
         do self.get |v:&T| {
             v.write_repr(self.writer);
@@ -502,7 +503,7 @@ impl TyVisitor for ReprVisitor {
                                 _offset: uint,
                                 inner: *TyDesc)
                                 -> bool {
-        match self.var_stk[vec::uniq_len(&const *self.var_stk) - 1] {
+        match self.var_stk[self.var_stk.len() - 1] {
             Matched => {
                 if i != 0 {
                     self.writer.write_str(", ");
@@ -520,7 +521,7 @@ impl TyVisitor for ReprVisitor {
                                 _disr_val: int,
                                 n_fields: uint,
                                 _name: &str) -> bool {
-        match self.var_stk[vec::uniq_len(&const *self.var_stk) - 1] {
+        match self.var_stk[self.var_stk.len() - 1] {
             Matched => {
                 if n_fields > 0 {
                     self.writer.write_char(')');
diff --git a/src/libstd/result.rs b/src/libstd/result.rs
index 24751b66925..6cef5c33de0 100644
--- a/src/libstd/result.rs
+++ b/src/libstd/result.rs
@@ -38,7 +38,7 @@ pub enum Result<T, U> {
  *
  * If the result is an error
  */
-#[inline(always)]
+#[inline]
 pub fn get<T:Copy,U>(res: &Result<T, U>) -> T {
     match *res {
       Ok(ref t) => copy *t,
@@ -54,7 +54,7 @@ pub fn get<T:Copy,U>(res: &Result<T, U>) -> T {
  *
  * If the result is an error
  */
-#[inline(always)]
+#[inline]
 pub fn get_ref<'a, T, U>(res: &'a Result<T, U>) -> &'a T {
     match *res {
         Ok(ref t) => t,
@@ -70,7 +70,7 @@ pub fn get_ref<'a, T, U>(res: &'a Result<T, U>) -> &'a T {
  *
  * If the result is not an error
  */
-#[inline(always)]
+#[inline]
 pub fn get_err<T, U: Copy>(res: &Result<T, U>) -> U {
     match *res {
       Err(ref u) => copy *u,
@@ -79,7 +79,7 @@ pub fn get_err<T, U: Copy>(res: &Result<T, U>) -> U {
 }
 
 /// Returns true if the result is `ok`
-#[inline(always)]
+#[inline]
 pub fn is_ok<T, U>(res: &Result<T, U>) -> bool {
     match *res {
       Ok(_) => true,
@@ -88,7 +88,7 @@ pub fn is_ok<T, U>(res: &Result<T, U>) -> bool {
 }
 
 /// Returns true if the result is `err`
-#[inline(always)]
+#[inline]
 pub fn is_err<T, U>(res: &Result<T, U>) -> bool {
     !is_ok(res)
 }
@@ -99,7 +99,7 @@ pub fn is_err<T, U>(res: &Result<T, U>) -> bool {
  * `ok` result variants are converted to `either::right` variants, `err`
  * result variants are converted to `either::left`.
  */
-#[inline(always)]
+#[inline]
 pub fn to_either<T:Copy,U:Copy>(res: &Result<U, T>)
     -> Either<T, U> {
     match *res {
@@ -122,7 +122,7 @@ pub fn to_either<T:Copy,U:Copy>(res: &Result<U, T>)
  *         ok(parse_bytes(buf))
  *     }
  */
-#[inline(always)]
+#[inline]
 pub fn chain<T, U, V>(res: Result<T, V>, op: &fn(T)
     -> Result<U, V>) -> Result<U, V> {
     match res {
@@ -139,7 +139,7 @@ pub fn chain<T, U, V>(res: Result<T, V>, op: &fn(T)
  * immediately returned.  This function can be used to pass through a
  * successful result while handling an error.
  */
-#[inline(always)]
+#[inline]
 pub fn chain_err<T, U, V>(
     res: Result<T, V>,
     op: &fn(t: V) -> Result<T, U>)
@@ -164,7 +164,7 @@ pub fn chain_err<T, U, V>(
  *         print_buf(buf)
  *     }
  */
-#[inline(always)]
+#[inline]
 pub fn iter<T, E>(res: &Result<T, E>, f: &fn(&T)) {
     match *res {
       Ok(ref t) => f(t),
@@ -180,7 +180,7 @@ pub fn iter<T, E>(res: &Result<T, E>, f: &fn(&T)) {
  * This function can be used to pass through a successful result while
  * handling an error.
  */
-#[inline(always)]
+#[inline]
 pub fn iter_err<T, E>(res: &Result<T, E>, f: &fn(&E)) {
     match *res {
       Ok(_) => (),
@@ -202,7 +202,7 @@ pub fn iter_err<T, E>(res: &Result<T, E>, f: &fn(&E)) {
  *         parse_bytes(buf)
  *     }
  */
-#[inline(always)]
+#[inline]
 pub fn map<T, E: Copy, U: Copy>(res: &Result<T, E>, op: &fn(&T) -> U)
   -> Result<U, E> {
     match *res {
@@ -219,7 +219,7 @@ pub fn map<T, E: Copy, U: Copy>(res: &Result<T, E>, op: &fn(&T) -> U)
  * is immediately returned.  This function can be used to pass through a
  * successful result while handling an error.
  */
-#[inline(always)]
+#[inline]
 pub fn map_err<T:Copy,E,F:Copy>(res: &Result<T, E>, op: &fn(&E) -> F)
   -> Result<T, F> {
     match *res {
@@ -229,53 +229,53 @@ pub fn map_err<T:Copy,E,F:Copy>(res: &Result<T, E>, op: &fn(&E) -> F)
 }
 
 impl<T, E> Result<T, E> {
-    #[inline(always)]
+    #[inline]
     pub fn get_ref<'a>(&'a self) -> &'a T { get_ref(self) }
 
-    #[inline(always)]
+    #[inline]
     pub fn is_ok(&self) -> bool { is_ok(self) }
 
-    #[inline(always)]
+    #[inline]
     pub fn is_err(&self) -> bool { is_err(self) }
 
-    #[inline(always)]
+    #[inline]
     pub fn iter(&self, f: &fn(&T)) { iter(self, f) }
 
-    #[inline(always)]
+    #[inline]
     pub fn iter_err(&self, f: &fn(&E)) { iter_err(self, f) }
 
-    #[inline(always)]
+    #[inline]
     pub fn unwrap(self) -> T { unwrap(self) }
 
-    #[inline(always)]
+    #[inline]
     pub fn unwrap_err(self) -> E { unwrap_err(self) }
 
-    #[inline(always)]
+    #[inline]
     pub fn chain<U>(self, op: &fn(T) -> Result<U,E>) -> Result<U,E> {
         chain(self, op)
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn chain_err<F>(self, op: &fn(E) -> Result<T,F>) -> Result<T,F> {
         chain_err(self, op)
     }
 }
 
 impl<T:Copy,E> Result<T, E> {
-    #[inline(always)]
+    #[inline]
     pub fn get(&self) -> T { get(self) }
 
-    #[inline(always)]
+    #[inline]
     pub fn map_err<F:Copy>(&self, op: &fn(&E) -> F) -> Result<T,F> {
         map_err(self, op)
     }
 }
 
 impl<T, E: Copy> Result<T, E> {
-    #[inline(always)]
+    #[inline]
     pub fn get_err(&self) -> E { get_err(self) }
 
-    #[inline(always)]
+    #[inline]
     pub fn map<U:Copy>(&self, op: &fn(&T) -> U) -> Result<U,E> {
         map(self, op)
     }
@@ -298,7 +298,7 @@ impl<T, E: Copy> Result<T, E> {
  *         assert!(incd == ~[2u, 3u, 4u]);
  *     }
  */
-#[inline(always)]
+#[inline]
 pub fn map_vec<T,U:Copy,V:Copy>(
     ts: &[T], op: &fn(&T) -> Result<V,U>) -> Result<~[V],U> {
 
@@ -312,7 +312,7 @@ pub fn map_vec<T,U:Copy,V:Copy>(
     return Ok(vs);
 }
 
-#[inline(always)]
+#[inline]
 #[allow(missing_doc)]
 pub fn map_opt<T,U:Copy,V:Copy>(
     o_t: &Option<T>, op: &fn(&T) -> Result<V,U>) -> Result<Option<V>,U> {
@@ -335,7 +335,7 @@ pub fn map_opt<T,U:Copy,V:Copy>(
  * used in 'careful' code contexts where it is both appropriate and easy
  * to accommodate an error like the vectors being of different lengths.
  */
-#[inline(always)]
+#[inline]
 pub fn map_vec2<S,T,U:Copy,V:Copy>(ss: &[S], ts: &[T],
                 op: &fn(&S,&T) -> Result<V,U>) -> Result<~[V],U> {
 
@@ -358,7 +358,7 @@ pub fn map_vec2<S,T,U:Copy,V:Copy>(ss: &[S], ts: &[T],
  * error.  This could be implemented using `map_zip()` but it is more efficient
  * on its own as no result vector is built.
  */
-#[inline(always)]
+#[inline]
 pub fn iter_vec2<S,T,U:Copy>(ss: &[S], ts: &[T],
                          op: &fn(&S,&T) -> Result<(),U>) -> Result<(),U> {
 
@@ -376,7 +376,7 @@ pub fn iter_vec2<S,T,U:Copy>(ss: &[S], ts: &[T],
 }
 
 /// Unwraps a result, assuming it is an `ok(T)`
-#[inline(always)]
+#[inline]
 pub fn unwrap<T, U>(res: Result<T, U>) -> T {
     match res {
       Ok(t) => t,
@@ -385,7 +385,7 @@ pub fn unwrap<T, U>(res: Result<T, U>) -> T {
 }
 
 /// Unwraps a result, assuming it is an `err(U)`
-#[inline(always)]
+#[inline]
 pub fn unwrap_err<T, U>(res: Result<T, U>) -> U {
     match res {
       Err(u) => u,
diff --git a/src/libstd/rt/args.rs b/src/libstd/rt/args.rs
new file mode 100644
index 00000000000..75ee4f381f6
--- /dev/null
+++ b/src/libstd/rt/args.rs
@@ -0,0 +1,125 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Global storage for command line arguments
+//!
+//! The current incarnation of the Rust runtime expects for
+//! the processes `argc` and `argv` arguments to be stored
+//! in a globally-accessible location for use by the `os` module.
+//!
+//! XXX: Would be nice for this to not exist.
+//! XXX: This has a lot of C glue for lack of globals.
+
+use libc;
+use option::{Option, Some, None};
+use str;
+use uint;
+use unstable::finally::Finally;
+use util;
+
+/// One-time global initialization.
+pub unsafe fn init(argc: int, argv: **u8) {
+    let args = load_argc_and_argv(argc, argv);
+    put(args);
+}
+
+/// One-time global cleanup.
+pub fn cleanup() {
+    rtassert!(take().is_some());
+}
+
+/// Take the global arguments from global storage.
+pub fn take() -> Option<~[~str]> {
+    with_lock(|| unsafe {
+        let ptr = get_global_ptr();
+        let val = util::replace(&mut *ptr, None);
+        val.map(|s: &~~[~str]| (**s).clone())
+    })
+}
+
+/// Give the global arguments to global storage.
+///
+/// It is an error if the arguments already exist.
+pub fn put(args: ~[~str]) {
+    with_lock(|| unsafe {
+        let ptr = get_global_ptr();
+        rtassert!((*ptr).is_none());
+        (*ptr) = Some(~args.clone());
+    })
+}
+
+/// Make a clone of the global arguments.
+pub fn clone() -> Option<~[~str]> {
+    with_lock(|| unsafe {
+        let ptr = get_global_ptr();
+        (*ptr).map(|s: &~~[~str]| (**s).clone())
+    })
+}
+
+fn with_lock<T>(f: &fn() -> T) -> T {
+    do (|| {
+        unsafe {
+            rust_take_global_args_lock();
+            f()
+        }
+    }).finally {
+        unsafe {
+            rust_drop_global_args_lock();
+        }
+    }
+}
+
+fn get_global_ptr() -> *mut Option<~~[~str]> {
+    unsafe { rust_get_global_args_ptr() }
+}
+
+// Copied from `os`.
+unsafe fn load_argc_and_argv(argc: int, argv: **u8) -> ~[~str] {
+    let mut args = ~[];
+    for uint::range(0, argc as uint) |i| {
+        args.push(str::raw::from_c_str(*(argv as **libc::c_char).offset(i)));
+    }
+    return args;
+}
+
+extern {
+    fn rust_take_global_args_lock();
+    fn rust_drop_global_args_lock();
+    fn rust_get_global_args_ptr() -> *mut Option<~~[~str]>;
+}
+
+#[cfg(test)]
+mod tests {
+    use option::{Some, None};
+    use super::*;
+    use unstable::finally::Finally;
+
+    #[test]
+    fn smoke_test() {
+        // Preserve the actual global state.
+        let saved_value = take();
+
+        let expected = ~[~"happy", ~"today?"];
+
+        put(expected.clone());
+        assert!(clone() == Some(expected.clone()));
+        assert!(take() == Some(expected.clone()));
+        assert!(take() == None);
+
+        do (|| {
+        }).finally {
+            // Restore the actual global state.
+            match saved_value {
+                Some(ref args) => put(args.clone()),
+                None => ()
+            }
+        }
+    }
+}
diff --git a/src/libstd/rt/borrowck.rs b/src/libstd/rt/borrowck.rs
new file mode 100644
index 00000000000..e057f6e9637
--- /dev/null
+++ b/src/libstd/rt/borrowck.rs
@@ -0,0 +1,283 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use cast::transmute;
+use libc::{c_char, c_void, size_t, STDERR_FILENO};
+use io;
+use io::{Writer, WriterUtil};
+use managed::raw::BoxRepr;
+use option::{Option, None, Some};
+use uint;
+use str;
+use str::OwnedStr;
+use sys;
+use vec::ImmutableVector;
+
+#[allow(non_camel_case_types)]
+type rust_task = c_void;
+
+pub static FROZEN_BIT: uint = 1 << (uint::bits - 1);
+pub static MUT_BIT: uint = 1 << (uint::bits - 2);
+static ALL_BITS: uint = FROZEN_BIT | MUT_BIT;
+
+#[deriving(Eq)]
+struct BorrowRecord {
+    box: *mut BoxRepr,
+    file: *c_char,
+    line: size_t
+}
+
+fn try_take_task_borrow_list() -> Option<~[BorrowRecord]> {
+    unsafe {
+        let cur_task: *rust_task = rust_try_get_task();
+        if cur_task.is_not_null() {
+            let ptr = rust_take_task_borrow_list(cur_task);
+            if ptr.is_null() {
+                None
+            } else {
+                let v: ~[BorrowRecord] = transmute(ptr);
+                Some(v)
+            }
+        } else {
+            None
+        }
+    }
+}
+
+fn swap_task_borrow_list(f: &fn(~[BorrowRecord]) -> ~[BorrowRecord]) {
+    unsafe {
+        let cur_task: *rust_task = rust_try_get_task();
+        if cur_task.is_not_null() {
+            let mut borrow_list: ~[BorrowRecord] = {
+                let ptr = rust_take_task_borrow_list(cur_task);
+                if ptr.is_null() { ~[] } else { transmute(ptr) }
+            };
+            borrow_list = f(borrow_list);
+            rust_set_task_borrow_list(cur_task, transmute(borrow_list));
+        }
+    }
+}
+
+pub unsafe fn clear_task_borrow_list() {
+    // pub because it is used by the box annihilator.
+    let _ = try_take_task_borrow_list();
+}
+
+unsafe fn fail_borrowed(box: *mut BoxRepr, file: *c_char, line: size_t) {
+    debug_borrow("fail_borrowed: ", box, 0, 0, file, line);
+
+    match try_take_task_borrow_list() {
+        None => { // not recording borrows
+            let msg = "borrowed";
+            do str::as_buf(msg) |msg_p, _| {
+                sys::begin_unwind_(msg_p as *c_char, file, line);
+            }
+        }
+        Some(borrow_list) => { // recording borrows
+            let mut msg = ~"borrowed";
+            let mut sep = " at ";
+            for borrow_list.rev_iter().advance |entry| {
+                if entry.box == box {
+                    msg.push_str(sep);
+                    let filename = str::raw::from_c_str(entry.file);
+                    msg.push_str(filename);
+                    msg.push_str(fmt!(":%u", entry.line as uint));
+                    sep = " and at ";
+                }
+            }
+            do str::as_buf(msg) |msg_p, _| {
+                sys::begin_unwind_(msg_p as *c_char, file, line)
+            }
+        }
+    }
+}
+
+/// Because this code is so perf. sensitive, use a static constant so that
+/// debug printouts are compiled out most of the time.
+static ENABLE_DEBUG: bool = false;
+
+#[inline]
+unsafe fn debug_borrow<T>(tag: &'static str,
+                          p: *const T,
+                          old_bits: uint,
+                          new_bits: uint,
+                          filename: *c_char,
+                          line: size_t) {
+    //! A useful debugging function that prints a pointer + tag + newline
+    //! without allocating memory.
+
+    if ENABLE_DEBUG && ::rt::env::get().debug_borrow {
+        debug_borrow_slow(tag, p, old_bits, new_bits, filename, line);
+    }
+
+    unsafe fn debug_borrow_slow<T>(tag: &'static str,
+                                   p: *const T,
+                                   old_bits: uint,
+                                   new_bits: uint,
+                                   filename: *c_char,
+                                   line: size_t) {
+        let dbg = STDERR_FILENO as io::fd_t;
+        dbg.write_str(tag);
+        dbg.write_hex(p as uint);
+        dbg.write_str(" ");
+        dbg.write_hex(old_bits);
+        dbg.write_str(" ");
+        dbg.write_hex(new_bits);
+        dbg.write_str(" ");
+        dbg.write_cstr(filename);
+        dbg.write_str(":");
+        dbg.write_hex(line as uint);
+        dbg.write_str("\n");
+    }
+}
+
+trait DebugPrints {
+    fn write_hex(&self, val: uint);
+    unsafe fn write_cstr(&self, str: *c_char);
+}
+
+impl DebugPrints for io::fd_t {
+    fn write_hex(&self, mut i: uint) {
+        let letters = ['0', '1', '2', '3', '4', '5', '6', '7', '8',
+                       '9', 'a', 'b', 'c', 'd', 'e', 'f'];
+        static uint_nibbles: uint = ::uint::bytes << 1;
+        let mut buffer = [0_u8, ..uint_nibbles+1];
+        let mut c = uint_nibbles;
+        while c > 0 {
+            c -= 1;
+            buffer[c] = letters[i & 0xF] as u8;
+            i >>= 4;
+        }
+        self.write(buffer.slice(0, uint_nibbles));
+    }
+
+    unsafe fn write_cstr(&self, p: *c_char) {
+        use libc::strlen;
+        use vec;
+
+        let len = strlen(p);
+        let p: *u8 = transmute(p);
+        do vec::raw::buf_as_slice(p, len as uint) |s| {
+            self.write(s);
+        }
+    }
+}
+
+#[inline]
+pub unsafe fn borrow_as_imm(a: *u8, file: *c_char, line: size_t) -> uint {
+    let a: *mut BoxRepr = transmute(a);
+    let old_ref_count = (*a).header.ref_count;
+    let new_ref_count = old_ref_count | FROZEN_BIT;
+
+    debug_borrow("borrow_as_imm:", a, old_ref_count, new_ref_count, file, line);
+
+    if (old_ref_count & MUT_BIT) != 0 {
+        fail_borrowed(a, file, line);
+    }
+
+    (*a).header.ref_count = new_ref_count;
+
+    old_ref_count
+}
+
+#[inline]
+pub unsafe fn borrow_as_mut(a: *u8, file: *c_char, line: size_t) -> uint {
+    let a: *mut BoxRepr = transmute(a);
+    let old_ref_count = (*a).header.ref_count;
+    let new_ref_count = old_ref_count | MUT_BIT | FROZEN_BIT;
+
+    debug_borrow("borrow_as_mut:", a, old_ref_count, new_ref_count, file, line);
+
+    if (old_ref_count & (MUT_BIT|FROZEN_BIT)) != 0 {
+        fail_borrowed(a, file, line);
+    }
+
+    (*a).header.ref_count = new_ref_count;
+
+    old_ref_count
+}
+
+pub unsafe fn record_borrow(a: *u8, old_ref_count: uint,
+                            file: *c_char, line: size_t) {
+    if (old_ref_count & ALL_BITS) == 0 {
+        // was not borrowed before
+        let a: *mut BoxRepr = transmute(a);
+        debug_borrow("record_borrow:", a, old_ref_count, 0, file, line);
+        do swap_task_borrow_list |borrow_list| {
+            let mut borrow_list = borrow_list;
+            borrow_list.push(BorrowRecord {box: a, file: file, line: line});
+            borrow_list
+        }
+    }
+}
+
+pub unsafe fn unrecord_borrow(a: *u8, old_ref_count: uint,
+                              file: *c_char, line: size_t) {
+    if (old_ref_count & ALL_BITS) == 0 {
+        // was not borrowed before, so we should find the record at
+        // the end of the list
+        let a: *mut BoxRepr = transmute(a);
+        debug_borrow("unrecord_borrow:", a, old_ref_count, 0, file, line);
+        do swap_task_borrow_list |borrow_list| {
+            let mut borrow_list = borrow_list;
+            assert!(!borrow_list.is_empty());
+            let br = borrow_list.pop();
+            if br.box != a || br.file != file || br.line != line {
+                let err = fmt!("wrong borrow found, br=%?", br);
+                do str::as_buf(err) |msg_p, _| {
+                    sys::begin_unwind_(msg_p as *c_char, file, line)
+                }
+            }
+            borrow_list
+        }
+    }
+}
+
+#[inline]
+pub unsafe fn return_to_mut(a: *u8, orig_ref_count: uint,
+                            file: *c_char, line: size_t) {
+    // Sometimes the box is null, if it is conditionally frozen.
+    // See e.g. #4904.
+    if !a.is_null() {
+        let a: *mut BoxRepr = transmute(a);
+        let old_ref_count = (*a).header.ref_count;
+        let new_ref_count =
+            (old_ref_count & !ALL_BITS) | (orig_ref_count & ALL_BITS);
+
+        debug_borrow("return_to_mut:",
+                     a, old_ref_count, new_ref_count, file, line);
+
+        (*a).header.ref_count = new_ref_count;
+    }
+}
+
+#[inline]
+pub unsafe fn check_not_borrowed(a: *u8,
+                                 file: *c_char,
+                                 line: size_t) {
+    let a: *mut BoxRepr = transmute(a);
+    let ref_count = (*a).header.ref_count;
+    debug_borrow("check_not_borrowed:", a, ref_count, 0, file, line);
+    if (ref_count & FROZEN_BIT) != 0 {
+        fail_borrowed(a, file, line);
+    }
+}
+
+
+extern {
+    #[rust_stack]
+    pub fn rust_take_task_borrow_list(task: *rust_task) -> *c_void;
+
+    #[rust_stack]
+    pub fn rust_set_task_borrow_list(task: *rust_task, map: *c_void);
+
+    #[rust_stack]
+    pub fn rust_try_get_task() -> *rust_task;
+}
diff --git a/src/libstd/rt/comm.rs b/src/libstd/rt/comm.rs
index 82e6d44fe62..dd27c03ff51 100644
--- a/src/libstd/rt/comm.rs
+++ b/src/libstd/rt/comm.rs
@@ -399,12 +399,6 @@ impl<T: Owned> GenericChan<T> for SharedChan<T> {
 }
 
 impl<T: Owned> GenericSmartChan<T> for SharedChan<T> {
-    #[cfg(stage0)] // odd type checking errors
-    fn try_send(&self, _val: T) -> bool {
-        fail!()
-    }
-
-    #[cfg(not(stage0))]
     fn try_send(&self, val: T) -> bool {
         unsafe {
             let (next_pone, next_cone) = oneshot();
@@ -448,12 +442,6 @@ impl<T: Owned> GenericPort<T> for SharedPort<T> {
         }
     }
 
-    #[cfg(stage0)] // odd type checking errors
-    fn try_recv(&self) -> Option<T> {
-        fail!()
-    }
-
-    #[cfg(not(stage0))]
     fn try_recv(&self) -> Option<T> {
         unsafe {
             let (next_link_port, next_link_chan) = oneshot();
diff --git a/src/libstd/rt/context.rs b/src/libstd/rt/context.rs
index d5ca8473cee..09ba869549f 100644
--- a/src/libstd/rt/context.rs
+++ b/src/libstd/rt/context.rs
@@ -207,7 +207,7 @@ fn align_down(sp: *mut uint) -> *mut uint {
 }
 
 // XXX: ptr::offset is positive ints only
-#[inline(always)]
+#[inline]
 pub fn mut_offset<T>(ptr: *mut T, count: int) -> *mut T {
     use core::sys::size_of;
     (ptr as int + count * (size_of::<T>() as int)) as *mut T
diff --git a/src/libstd/rt/io/extensions.rs b/src/libstd/rt/io/extensions.rs
index c7c3eadbe21..55861f127bb 100644
--- a/src/libstd/rt/io/extensions.rs
+++ b/src/libstd/rt/io/extensions.rs
@@ -297,7 +297,8 @@ impl<T: Reader> ReaderUtil for T {
 
             do (|| {
                 while total_read < len {
-                    let slice = vec::mut_slice(*buf, start_len + total_read, buf.len());
+                    let len = buf.len();
+                    let slice = vec::mut_slice(*buf, start_len + total_read, len);
                     match self.read(slice) {
                         Some(nread) => {
                             total_read += nread;
diff --git a/src/libstd/rt/local_heap.rs b/src/libstd/rt/local_heap.rs
index 6bf228a1b22..f62c9fb2c66 100644
--- a/src/libstd/rt/local_heap.rs
+++ b/src/libstd/rt/local_heap.rs
@@ -10,11 +10,24 @@
 
 //! The local, garbage collected heap
 
+use libc;
 use libc::{c_void, uintptr_t, size_t};
 use ops::Drop;
+use repr::BoxRepr;
+use rt;
+use rt::OldTaskContext;
+use rt::local::Local;
+use rt::task::Task;
 
 type MemoryRegion = c_void;
-type BoxedRegion = c_void;
+
+struct Env { priv opaque: () }
+
+struct BoxedRegion {
+    env: *Env,
+    backing_region: *MemoryRegion,
+    live_allocs: *BoxRepr
+}
 
 pub type OpaqueBox = c_void;
 pub type TypeDesc = c_void;
@@ -49,6 +62,12 @@ impl LocalHeap {
         }
     }
 
+    pub fn realloc(&mut self, ptr: *OpaqueBox, size: uint) -> *OpaqueBox {
+        unsafe {
+            return rust_boxed_region_realloc(self.boxed_region, ptr, size as size_t);
+        }
+    }
+
     pub fn free(&mut self, box: *OpaqueBox) {
         unsafe {
             return rust_boxed_region_free(self.boxed_region, box);
@@ -65,6 +84,40 @@ impl Drop for LocalHeap {
     }
 }
 
+// A little compatibility function
+pub unsafe fn local_free(ptr: *libc::c_char) {
+    match rt::context() {
+        OldTaskContext => {
+            rust_upcall_free_noswitch(ptr);
+
+            extern {
+                #[fast_ffi]
+                unsafe fn rust_upcall_free_noswitch(ptr: *libc::c_char);
+            }
+        }
+        _ => {
+            do Local::borrow::<Task,()> |task| {
+                task.heap.free(ptr as *libc::c_void);
+            }
+        }
+    }
+}
+
+pub fn live_allocs() -> *BoxRepr {
+    let region = match rt::context() {
+        OldTaskContext => {
+            unsafe { rust_current_boxed_region() }
+        }
+        _ => {
+            do Local::borrow::<Task, *BoxedRegion> |task| {
+                task.heap.boxed_region
+            }
+        }
+    };
+
+    return unsafe { (*region).live_allocs };
+}
+
 extern {
     fn rust_new_memory_region(synchronized: uintptr_t,
                                detailed_leaks: uintptr_t,
@@ -76,5 +129,9 @@ extern {
     fn rust_boxed_region_malloc(region: *BoxedRegion,
                                 td: *TypeDesc,
                                 size: size_t) -> *OpaqueBox;
+    fn rust_boxed_region_realloc(region: *BoxedRegion,
+                                 ptr: *OpaqueBox,
+                                 size: size_t) -> *OpaqueBox;
     fn rust_boxed_region_free(region: *BoxedRegion, box: *OpaqueBox);
+    fn rust_current_boxed_region() -> *BoxedRegion;
 }
diff --git a/src/libstd/rt/logging.rs b/src/libstd/rt/logging.rs
index a0d05397689..84186180aa6 100644
--- a/src/libstd/rt/logging.rs
+++ b/src/libstd/rt/logging.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 use either::*;
+use libc;
 
 pub trait Logger {
     fn log(&mut self, msg: Either<~str, &'static str>);
@@ -20,6 +21,10 @@ impl Logger for StdErrLogger {
     fn log(&mut self, msg: Either<~str, &'static str>) {
         use io::{Writer, WriterUtil};
 
+        if !should_log_console() {
+            return;
+        }
+
         let s: &str = match msg {
             Left(ref s) => {
                 let s: &str = *s;
@@ -44,7 +49,6 @@ pub fn init(crate_map: *u8) {
     use str;
     use ptr;
     use option::{Some, None};
-    use libc::c_char;
 
     let log_spec = os::getenv("RUST_LOG");
     match log_spec {
@@ -61,8 +65,16 @@ pub fn init(crate_map: *u8) {
             }
         }
     }
+}
 
-    extern {
-        fn rust_update_log_settings(crate_map: *u8, settings: *c_char);
-    }
+pub fn console_on() { unsafe { rust_log_console_on() } }
+pub fn console_off() { unsafe { rust_log_console_off() } }
+fn should_log_console() -> bool { unsafe { rust_should_log_console() != 0 } }
+
+extern {
+    fn rust_update_log_settings(crate_map: *u8, settings: *libc::c_char);
+    fn rust_log_console_on();
+    fn rust_log_console_off();
+    fn rust_should_log_console() -> libc::uintptr_t;
 }
+
diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs
index 581e3addff0..bbf1cf0d9b7 100644
--- a/src/libstd/rt/mod.rs
+++ b/src/libstd/rt/mod.rs
@@ -58,22 +58,23 @@ Several modules in `core` are clients of `rt`:
 #[deny(unused_imports)];
 #[deny(unused_mut)];
 #[deny(unused_variable)];
+#[deny(unused_unsafe)];
 
 use cell::Cell;
 use clone::Clone;
 use container::Container;
-use from_str::FromStr;
+use iter::Times;
 use iterator::IteratorUtil;
-use option::{Some, None};
-use os;
+use option::Some;
 use ptr::RawPtr;
-use uint;
 use rt::sched::{Scheduler, Coroutine, Shutdown};
 use rt::sleeper_list::SleeperList;
 use rt::task::Task;
 use rt::thread::Thread;
 use rt::work_queue::WorkQueue;
 use rt::uv::uvio::UvEventLoop;
+use unstable::atomics::{AtomicInt, SeqCst};
+use unstable::sync::UnsafeAtomicRcBox;
 use vec::{OwnedVector, MutableVector};
 
 /// The global (exchange) heap.
@@ -122,7 +123,7 @@ mod thread;
 pub mod env;
 
 /// The local, managed heap
-mod local_heap;
+pub mod local_heap;
 
 /// The Logger trait and implementations
 pub mod logging;
@@ -148,7 +149,7 @@ pub mod local_ptr;
 /// Bindings to pthread/windows thread-local storage.
 pub mod thread_local_storage;
 
-/// A concurrent data structure with which parent tasks wait on child tasks.
+/// For waiting on child tasks.
 pub mod join_latch;
 
 pub mod metrics;
@@ -157,6 +158,12 @@ pub mod metrics;
 /// Just stuff
 pub mod util;
 
+// Global command line argument storage
+pub mod args;
+
+// Support for dynamic borrowck
+pub mod borrowck;
+
 /// Set up a default runtime configuration, given compiler-supplied arguments.
 ///
 /// This is invoked by the `start` _language item_ (unstable::lang) to
@@ -171,71 +178,104 @@ pub mod util;
 /// # Return value
 ///
 /// The return value is used as the process return code. 0 on success, 101 on error.
-pub fn start(_argc: int, _argv: **u8, crate_map: *u8, main: ~fn()) -> int {
+pub fn start(argc: int, argv: **u8, crate_map: *u8, main: ~fn()) -> int {
 
-    init(crate_map);
-    run(main);
+    init(argc, argv, crate_map);
+    let exit_code = run(main);
     cleanup();
 
-    return 0;
+    return exit_code;
 }
 
-/// One-time runtime initialization. Currently all this does is set up logging
-/// based on the RUST_LOG environment variable.
-pub fn init(crate_map: *u8) {
-    logging::init(crate_map);
+/// One-time runtime initialization.
+///
+/// Initializes global state, including frobbing
+/// the crate's logging flags, registering GC
+/// metadata, and storing the process arguments.
+pub fn init(argc: int, argv: **u8, crate_map: *u8) {
+    // XXX: Derefing these pointers is not safe.
+    // Need to propagate the unsafety to `start`.
+    unsafe {
+        args::init(argc, argv);
+        logging::init(crate_map);
+        rust_update_gc_metadata(crate_map);
+    }
+
+    extern {
+        fn rust_update_gc_metadata(crate_map: *u8);
+    }
 }
 
+/// One-time runtime cleanup.
 pub fn cleanup() {
+    args::cleanup();
     global_heap::cleanup();
 }
 
-pub fn run(main: ~fn()) {
-    let nthreads = match os::getenv("RUST_THREADS") {
-        Some(nstr) => FromStr::from_str(nstr).get(),
-        None => unsafe {
-            // Using more threads than cores in test code
-            // to force the OS to preempt them frequently.
-            // Assuming that this help stress test concurrent types.
-            util::num_cpus() * 2
-        }
-    };
+/// Execute the main function in a scheduler.
+///
+/// Configures the runtime according to the environment, by default
+/// using a task scheduler with the same number of threads as cores.
+/// Returns a process exit code.
+pub fn run(main: ~fn()) -> int {
+
+    static DEFAULT_ERROR_CODE: int = 101;
 
+    let nthreads = util::default_sched_threads();
+
+    // The shared list of sleeping schedulers. Schedulers wake each other
+    // occassionally to do new work.
     let sleepers = SleeperList::new();
+    // The shared work queue. Temporary until work stealing is implemented.
     let work_queue = WorkQueue::new();
 
-    let mut handles = ~[];
+    // The schedulers.
     let mut scheds = ~[];
+    // Handles to the schedulers. When the main task ends these will be
+    // sent the Shutdown message to terminate the schedulers.
+    let mut handles = ~[];
 
-    for uint::range(0, nthreads) |_| {
+    for nthreads.times {
+        // Every scheduler is driven by an I/O event loop.
         let loop_ = ~UvEventLoop::new();
         let mut sched = ~Scheduler::new(loop_, work_queue.clone(), sleepers.clone());
         let handle = sched.make_handle();
 
-        handles.push(handle);
         scheds.push(sched);
+        handles.push(handle);
     }
 
-    let main_cell = Cell::new(main);
+    // Create a shared cell for transmitting the process exit
+    // code from the main task to this function.
+    let exit_code = UnsafeAtomicRcBox::new(AtomicInt::new(0));
+    let exit_code_clone = exit_code.clone();
+
+    // When the main task exits, after all the tasks in the main
+    // task tree, shut down the schedulers and set the exit code.
     let handles = Cell::new(handles);
-    let mut new_task = ~Task::new_root();
-    let on_exit: ~fn(bool) = |exit_status| {
+    let on_exit: ~fn(bool) = |exit_success| {
 
         let mut handles = handles.take();
-        // Tell schedulers to exit
         for handles.mut_iter().advance |handle| {
             handle.send(Shutdown);
         }
 
-        rtassert!(exit_status);
+        unsafe {
+            let exit_code = if exit_success { 0 } else { DEFAULT_ERROR_CODE };
+            (*exit_code_clone.get()).store(exit_code, SeqCst);
+        }
     };
+
+    // Create and enqueue the main task.
+    let main_cell = Cell::new(main);
+    let mut new_task = ~Task::new_root();
     new_task.on_exit = Some(on_exit);
     let main_task = ~Coroutine::with_task(&mut scheds[0].stack_pool,
                                           new_task, main_cell.take());
     scheds[0].enqueue_task(main_task);
 
+    // Run each scheduler in a thread.
     let mut threads = ~[];
-
     while !scheds.is_empty() {
         let sched = scheds.pop();
         let sched_cell = Cell::new(sched);
@@ -248,7 +288,12 @@ pub fn run(main: ~fn()) {
     }
 
     // Wait for schedulers
-    let _threads = threads;
+    { let _threads = threads; }
+
+    // Return the exit code
+    unsafe {
+        (*exit_code.get()).load(SeqCst)
+    }
 }
 
 /// Possible contexts in which Rust code may be executing.
diff --git a/src/libstd/rt/sched.rs b/src/libstd/rt/sched.rs
index 453d3303db6..bbe4aa25e29 100644
--- a/src/libstd/rt/sched.rs
+++ b/src/libstd/rt/sched.rs
@@ -646,12 +646,12 @@ impl Scheduler {
     }
 }
 
-// The cases for the below function.                                              
+// The cases for the below function.
 enum ResumeAction {
     SendHome,
     Requeue,
     ResumeNow,
-    Homeless                                                                      
+    Homeless
 }
 
 impl SchedHandle {
diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs
index e7f87906fe5..97c3b6a749b 100644
--- a/src/libstd/rt/task.rs
+++ b/src/libstd/rt/task.rs
@@ -15,6 +15,7 @@
 
 use borrow;
 use cast::transmute;
+use cleanup;
 use libc::{c_void, uintptr_t};
 use ptr;
 use prelude::*;
@@ -118,6 +119,10 @@ impl Task {
             }
             _ => ()
         }
+
+        // Destroy remaining boxes
+        unsafe { cleanup::annihilate(); }
+
         self.destroyed = true;
     }
 }
@@ -249,6 +254,18 @@ mod test {
     }
 
     #[test]
+    fn comm_shared_chan() {
+        use comm::*;
+
+        do run_in_newsched_task() {
+            let (port, chan) = stream();
+            let chan = SharedChan::new(chan);
+            chan.send(10);
+            assert!(port.recv() == 10);
+        }
+    }
+
+    #[test]
     fn linked_failure() {
         do run_in_newsched_task() {
             let res = do spawntask_try {
@@ -257,4 +274,45 @@ mod test {
             assert!(res.is_err());
         }
     }
+
+    #[test]
+    fn heap_cycles() {
+        use option::{Option, Some, None};
+
+        do run_in_newsched_task {
+            struct List {
+                next: Option<@mut List>,
+            }
+
+            let a = @mut List { next: None };
+            let b = @mut List { next: Some(a) };
+
+            a.next = Some(b);
+        }
+    }
+
+    // XXX: This is a copy of test_future_result in std::task.
+    // It can be removed once the scheduler is turned on by default.
+    #[test]
+    fn future_result() {
+        do run_in_newsched_task {
+            use option::{Some, None};
+            use task::*;
+
+            let mut result = None;
+            let mut builder = task();
+            builder.future_result(|r| result = Some(r));
+            do builder.spawn {}
+            assert_eq!(result.unwrap().recv(), Success);
+
+            result = None;
+            let mut builder = task();
+            builder.future_result(|r| result = Some(r));
+            builder.unlinked();
+            do builder.spawn {
+                fail!();
+            }
+            assert_eq!(result.unwrap().recv(), Failure);
+        }
+    }
 }
diff --git a/src/libstd/rt/test.rs b/src/libstd/rt/test.rs
index 36efcd91834..b0e49684014 100644
--- a/src/libstd/rt/test.rs
+++ b/src/libstd/rt/test.rs
@@ -74,7 +74,7 @@ pub fn run_in_mt_newsched_task(f: ~fn()) {
     do run_in_bare_thread {
         let nthreads = match os::getenv("RUST_TEST_THREADS") {
             Some(nstr) => FromStr::from_str(nstr).get(),
-            None => unsafe {
+            None => {
                 // Using more threads than cores in test code
                 // to force the OS to preempt them frequently.
                 // Assuming that this help stress test concurrent types.
diff --git a/src/libstd/rt/util.rs b/src/libstd/rt/util.rs
index 904b2f8bbb9..5219ae1d540 100644
--- a/src/libstd/rt/util.rs
+++ b/src/libstd/rt/util.rs
@@ -9,8 +9,11 @@
 // except according to those terms.
 
 use container::Container;
+use from_str::FromStr;
 use iterator::IteratorUtil;
 use libc;
+use option::{Some, None};
+use os;
 use str::StrSlice;
 
 /// Get the number of cores available
@@ -24,6 +27,15 @@ pub fn num_cpus() -> uint {
     }
 }
 
+/// Get's the number of scheduler threads requested by the environment
+/// either `RUST_THREADS` or `num_cpus`.
+pub fn default_sched_threads() -> uint {
+    match os::getenv("RUST_THREADS") {
+        Some(nstr) => FromStr::from_str(nstr).get(),
+        None => num_cpus()
+    }
+}
+
 pub fn dumb_println(s: &str) {
     use io::WriterUtil;
     let dbg = ::libc::STDERR_FILENO as ::io::fd_t;
diff --git a/src/libstd/rt/uv/timer.rs b/src/libstd/rt/uv/timer.rs
index 5557a580987..14465eb7dfd 100644
--- a/src/libstd/rt/uv/timer.rs
+++ b/src/libstd/rt/uv/timer.rs
@@ -143,7 +143,7 @@ mod test {
             let count_ptr: *mut int = &mut count;
             let mut loop_ = Loop::new();
             let mut timer = TimerWatcher::new(&mut loop_);
-            do timer.start(10, 20) |timer, status| {
+            do timer.start(1, 2) |timer, status| {
                 assert!(status.is_none());
                 unsafe {
                     *count_ptr += 1;
@@ -160,14 +160,14 @@ mod test {
                         let mut timer2 = TimerWatcher::new(&mut loop_);
                         do timer2.start(10, 0) |timer2, _| {
 
-                            unsafe { *count_ptr += 1; }
+                            *count_ptr += 1;
 
                             timer2.close(||());
 
                             // Restart the original timer
                             let mut timer = timer;
-                            do timer.start(10, 0) |timer, _| {
-                                unsafe { *count_ptr += 1; }
+                            do timer.start(1, 0) |timer, _| {
+                                *count_ptr += 1;
                                 timer.close(||());
                             }
                         }
diff --git a/src/libstd/run.rs b/src/libstd/run.rs
index b204cf6cfb0..060de3f4d5d 100644
--- a/src/libstd/run.rs
+++ b/src/libstd/run.rs
@@ -915,7 +915,7 @@ priv fn waitpid(pid: pid_t) -> int {
 #[cfg(test)]
 mod tests {
     use io;
-    use libc::{c_int};
+    use libc::{c_int, uintptr_t};
     use option::{Option, None, Some};
     use os;
     use path::Path;
@@ -958,7 +958,10 @@ mod tests {
 
         assert_eq!(status, 0);
         assert_eq!(output_str.trim().to_owned(), ~"hello");
-        assert_eq!(error, ~[]);
+        // FIXME #7224
+        if !running_on_valgrind() {
+            assert_eq!(error, ~[]);
+        }
     }
 
     #[test]
@@ -1043,7 +1046,10 @@ mod tests {
 
         assert_eq!(status, 0);
         assert_eq!(output_str.trim().to_owned(), ~"hello");
-        assert_eq!(error, ~[]);
+        // FIXME #7224
+        if !running_on_valgrind() {
+            assert_eq!(error, ~[]);
+        }
     }
 
     #[test]
@@ -1057,14 +1063,20 @@ mod tests {
 
         assert_eq!(status, 0);
         assert_eq!(output_str.trim().to_owned(), ~"hello");
-        assert_eq!(error, ~[]);
+        // FIXME #7224
+        if !running_on_valgrind() {
+            assert_eq!(error, ~[]);
+        }
 
         let run::ProcessOutput {status, output, error}
             = prog.finish_with_output();
 
         assert_eq!(status, 0);
         assert_eq!(output, ~[]);
-        assert_eq!(error, ~[]);
+        // FIXME #7224
+        if !running_on_valgrind() {
+            assert_eq!(error, ~[]);
+        }
     }
 
     #[test]
@@ -1148,6 +1160,7 @@ mod tests {
 
     #[test]
     fn test_inherit_env() {
+        if running_on_valgrind() { return; }
 
         let mut prog = run_env(None);
         let output = str::from_bytes(prog.finish_with_output().output);
@@ -1169,4 +1182,12 @@ mod tests {
 
         assert!(output.contains("RUN_TEST_NEW_ENV=123"));
     }
+
+    fn running_on_valgrind() -> bool {
+        unsafe { rust_running_on_valgrind() != 0 }
+    }
+
+    extern {
+        fn rust_running_on_valgrind() -> uintptr_t;
+    }
 }
diff --git a/src/libstd/str.rs b/src/libstd/str.rs
index 1086fcaa75c..04f5247782b 100644
--- a/src/libstd/str.rs
+++ b/src/libstd/str.rs
@@ -23,11 +23,11 @@ use cast;
 use char;
 use char::Char;
 use clone::Clone;
-use cmp::{TotalOrd, Ordering, Less, Equal, Greater};
 use container::Container;
 use iter::Times;
-use iterator::{Iterator, IteratorUtil, FilterIterator, AdditiveIterator};
+use iterator::{Iterator, IteratorUtil, FilterIterator, AdditiveIterator, MapIterator};
 use libc;
+use num::Zero;
 use option::{None, Option, Some};
 use old_iter::{BaseIter, EqIter};
 use ptr;
@@ -37,8 +37,6 @@ use uint;
 use vec;
 use vec::{OwnedVector, OwnedCopyableVector, ImmutableVector};
 
-#[cfg(not(test))] use cmp::{Eq, Ord, Equiv, TotalEq};
-
 /*
 Section: Conditions
 */
@@ -108,21 +106,21 @@ pub fn from_bytes_slice<'a>(vector: &'a [u8]) -> &'a str {
 }
 
 /// Copy a slice into a new unique str
-#[inline(always)]
+#[inline]
 pub fn to_owned(s: &str) -> ~str {
     unsafe { raw::slice_bytes_owned(s, 0, s.len()) }
 }
 
 impl ToStr for ~str {
-    #[inline(always)]
+    #[inline]
     fn to_str(&self) -> ~str { to_owned(*self) }
 }
 impl<'self> ToStr for &'self str {
-    #[inline(always)]
+    #[inline]
     fn to_str(&self) -> ~str { to_owned(*self) }
 }
 impl ToStr for @str {
-    #[inline(always)]
+    #[inline]
     fn to_str(&self) -> ~str { to_owned(*self) }
 }
 
@@ -243,26 +241,26 @@ pub trait CharEq {
     fn only_ascii(&self) -> bool;
 }
 impl CharEq for char {
-    #[inline(always)]
+    #[inline]
     fn matches(&self, c: char) -> bool { *self == c }
 
     fn only_ascii(&self) -> bool { (*self as uint) < 128 }
 }
 impl<'self> CharEq for &'self fn(char) -> bool {
-    #[inline(always)]
+    #[inline]
     fn matches(&self, c: char) -> bool { (*self)(c) }
 
     fn only_ascii(&self) -> bool { false }
 }
 impl CharEq for extern "Rust" fn(char) -> bool {
-    #[inline(always)]
+    #[inline]
     fn matches(&self, c: char) -> bool { (*self)(c) }
 
     fn only_ascii(&self) -> bool { false }
 }
 
 impl<'self, C: CharEq> CharEq for &'self [C] {
-    #[inline(always)]
+    #[inline]
     fn matches(&self, c: char) -> bool {
         self.iter().any_(|m| m.matches(c))
     }
@@ -291,6 +289,10 @@ pub type WordIterator<'self> =
     FilterIterator<'self, &'self str,
              StrCharSplitIterator<'self, extern "Rust" fn(char) -> bool>>;
 
+/// An iterator over the lines of a string, separated by either `\n` or (`\r\n`).
+pub type AnyLineIterator<'self> =
+    MapIterator<'self, &'self str, &'self str, StrCharSplitIterator<'self, char>>;
+
 impl<'self, Sep: CharEq> Iterator<&'self str> for StrCharSplitIterator<'self, Sep> {
     #[inline]
     fn next(&mut self) -> Option<&'self str> {
@@ -400,56 +402,6 @@ impl<'self> Iterator<&'self str> for StrStrSplitIterator<'self> {
     }
 }
 
-/// Levenshtein Distance between two strings
-pub fn levdistance(s: &str, t: &str) -> uint {
-
-    let slen = s.len();
-    let tlen = t.len();
-
-    if slen == 0 { return tlen; }
-    if tlen == 0 { return slen; }
-
-    let mut dcol = vec::from_fn(tlen + 1, |x| x);
-
-    for s.iter().enumerate().advance |(i, sc)| {
-
-        let mut current = i;
-        dcol[0] = current + 1;
-
-        for t.iter().enumerate().advance |(j, tc)| {
-
-            let next = dcol[j + 1];
-
-            if sc == tc {
-                dcol[j + 1] = current;
-            } else {
-                dcol[j + 1] = ::cmp::min(current, next);
-                dcol[j + 1] = ::cmp::min(dcol[j + 1], dcol[j]) + 1;
-            }
-
-            current = next;
-        }
-    }
-
-    return dcol[tlen];
-}
-
-/**
- * Splits a string into substrings separated by LF ('\n')
- * and/or CR LF ("\r\n")
- */
-pub fn each_line_any<'a>(s: &'a str, it: &fn(&'a str) -> bool) -> bool {
-    for s.line_iter().advance |s| {
-        let l = s.len();
-        if l > 0u && s[l - 1u] == '\r' as u8 {
-            if !it( unsafe { raw::slice_bytes(s, 0, l - 1) } ) { return false; }
-        } else {
-            if !it( s ) { return false; }
-        }
-    }
-    return true;
-}
-
 /** Splits a string into substrings with possibly internal whitespace,
  *  each of them at most `lim` bytes long. The substrings have leading and trailing
  *  whitespace removed, and are only cut at whitespace boundaries.
@@ -576,196 +528,6 @@ pub fn eq(a: &~str, b: &~str) -> bool {
     eq_slice(*a, *b)
 }
 
-#[inline]
-fn cmp(a: &str, b: &str) -> Ordering {
-    let low = uint::min(a.len(), b.len());
-
-    for uint::range(0, low) |idx| {
-        match a[idx].cmp(&b[idx]) {
-          Greater => return Greater,
-          Less => return Less,
-          Equal => ()
-        }
-    }
-
-    a.len().cmp(&b.len())
-}
-
-#[cfg(not(test))]
-impl<'self> TotalOrd for &'self str {
-    #[inline]
-    fn cmp(&self, other: & &'self str) -> Ordering { cmp(*self, *other) }
-}
-
-#[cfg(not(test))]
-impl TotalOrd for ~str {
-    #[inline]
-    fn cmp(&self, other: &~str) -> Ordering { cmp(*self, *other) }
-}
-
-#[cfg(not(test))]
-impl TotalOrd for @str {
-    #[inline]
-    fn cmp(&self, other: &@str) -> Ordering { cmp(*self, *other) }
-}
-
-/// Bytewise slice less than
-#[inline]
-fn lt(a: &str, b: &str) -> bool {
-    let (a_len, b_len) = (a.len(), b.len());
-    let end = uint::min(a_len, b_len);
-
-    let mut i = 0;
-    while i < end {
-        let (c_a, c_b) = (a[i], b[i]);
-        if c_a < c_b { return true; }
-        if c_a > c_b { return false; }
-        i += 1;
-    }
-
-    return a_len < b_len;
-}
-
-/// Bytewise less than or equal
-#[inline]
-pub fn le(a: &str, b: &str) -> bool {
-    !lt(b, a)
-}
-
-/// Bytewise greater than or equal
-#[inline]
-fn ge(a: &str, b: &str) -> bool {
-    !lt(a, b)
-}
-
-/// Bytewise greater than
-#[inline]
-fn gt(a: &str, b: &str) -> bool {
-    !le(a, b)
-}
-
-#[cfg(not(test))]
-impl<'self> Eq for &'self str {
-    #[inline(always)]
-    fn eq(&self, other: & &'self str) -> bool {
-        eq_slice((*self), (*other))
-    }
-    #[inline(always)]
-    fn ne(&self, other: & &'self str) -> bool { !(*self).eq(other) }
-}
-
-#[cfg(not(test))]
-impl Eq for ~str {
-    #[inline(always)]
-    fn eq(&self, other: &~str) -> bool {
-        eq_slice((*self), (*other))
-    }
-    #[inline(always)]
-    fn ne(&self, other: &~str) -> bool { !(*self).eq(other) }
-}
-
-#[cfg(not(test))]
-impl Eq for @str {
-    #[inline(always)]
-    fn eq(&self, other: &@str) -> bool {
-        eq_slice((*self), (*other))
-    }
-    #[inline(always)]
-    fn ne(&self, other: &@str) -> bool { !(*self).eq(other) }
-}
-
-#[cfg(not(test))]
-impl<'self> TotalEq for &'self str {
-    #[inline(always)]
-    fn equals(&self, other: & &'self str) -> bool {
-        eq_slice((*self), (*other))
-    }
-}
-
-#[cfg(not(test))]
-impl TotalEq for ~str {
-    #[inline(always)]
-    fn equals(&self, other: &~str) -> bool {
-        eq_slice((*self), (*other))
-    }
-}
-
-#[cfg(not(test))]
-impl TotalEq for @str {
-    #[inline(always)]
-    fn equals(&self, other: &@str) -> bool {
-        eq_slice((*self), (*other))
-    }
-}
-
-#[cfg(not(test))]
-impl Ord for ~str {
-    #[inline(always)]
-    fn lt(&self, other: &~str) -> bool { lt((*self), (*other)) }
-    #[inline(always)]
-    fn le(&self, other: &~str) -> bool { le((*self), (*other)) }
-    #[inline(always)]
-    fn ge(&self, other: &~str) -> bool { ge((*self), (*other)) }
-    #[inline(always)]
-    fn gt(&self, other: &~str) -> bool { gt((*self), (*other)) }
-}
-
-#[cfg(not(test))]
-impl<'self> Ord for &'self str {
-    #[inline(always)]
-    fn lt(&self, other: & &'self str) -> bool { lt((*self), (*other)) }
-    #[inline(always)]
-    fn le(&self, other: & &'self str) -> bool { le((*self), (*other)) }
-    #[inline(always)]
-    fn ge(&self, other: & &'self str) -> bool { ge((*self), (*other)) }
-    #[inline(always)]
-    fn gt(&self, other: & &'self str) -> bool { gt((*self), (*other)) }
-}
-
-#[cfg(not(test))]
-impl Ord for @str {
-    #[inline(always)]
-    fn lt(&self, other: &@str) -> bool { lt((*self), (*other)) }
-    #[inline(always)]
-    fn le(&self, other: &@str) -> bool { le((*self), (*other)) }
-    #[inline(always)]
-    fn ge(&self, other: &@str) -> bool { ge((*self), (*other)) }
-    #[inline(always)]
-    fn gt(&self, other: &@str) -> bool { gt((*self), (*other)) }
-}
-
-#[cfg(not(test))]
-impl<'self, S: Str> Equiv<S> for &'self str {
-    #[inline(always)]
-    fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) }
-}
-#[cfg(not(test))]
-impl<'self, S: Str> Equiv<S> for @str {
-    #[inline(always)]
-    fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) }
-}
-
-#[cfg(not(test))]
-impl<'self, S: Str> Equiv<S> for ~str {
-    #[inline(always)]
-    fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) }
-}
-
-
-/*
-Section: Iterating through strings
-*/
-
-/// Apply a function to each character
-pub fn map(ss: &str, ff: &fn(char) -> char) -> ~str {
-    let mut result = ~"";
-    result.reserve(ss.len());
-    for ss.iter().advance |cc| {
-        result.push_char(ff(cc));
-    }
-    result
-}
-
 /*
 Section: Searching
 */
@@ -820,30 +582,6 @@ pub fn is_utf16(v: &[u16]) -> bool {
     return true;
 }
 
-/// Converts to a vector of `u16` encoded as UTF-16
-pub fn to_utf16(s: &str) -> ~[u16] {
-    let mut u = ~[];
-    for s.iter().advance |ch| {
-        // Arithmetic with u32 literals is easier on the eyes than chars.
-        let mut ch = ch as u32;
-
-        if (ch & 0xFFFF_u32) == ch {
-            // The BMP falls through (assuming non-surrogate, as it
-            // should)
-            assert!(ch <= 0xD7FF_u32 || ch >= 0xE000_u32);
-            u.push(ch as u16)
-        } else {
-            // Supplementary planes break into surrogates.
-            assert!(ch >= 0x1_0000_u32 && ch <= 0x10_FFFF_u32);
-            ch -= 0x1_0000_u32;
-            let w1 = 0xD800_u16 | ((ch >> 10) as u16);
-            let w2 = 0xDC00_u16 | ((ch as u16) & 0x3FF_u16);
-            u.push_all([w1, w2])
-        }
-    }
-    u
-}
-
 /// Iterates over the utf-16 characters in the specified slice, yielding each
 /// decoded unicode character to the function provided.
 ///
@@ -967,7 +705,7 @@ impl<'self> StrUtil for &'self str {
 /**
  * Deprecated. Use the `as_c_str` method on strings instead.
  */
-#[inline(always)]
+#[inline]
 pub fn as_c_str<T>(s: &str, f: &fn(*libc::c_char) -> T) -> T {
     s.as_c_str(f)
 }
@@ -980,7 +718,7 @@ pub fn as_c_str<T>(s: &str, f: &fn(*libc::c_char) -> T) -> T {
  * indexable area for a null byte, as is the case in slices pointing
  * to full strings, or suffixes of them.
  */
-#[inline(always)]
+#[inline]
 pub fn as_buf<T>(s: &str, f: &fn(*u8, uint) -> T) -> T {
     unsafe {
         let v : *(*u8,uint) = transmute(&s);
@@ -989,40 +727,6 @@ pub fn as_buf<T>(s: &str, f: &fn(*u8, uint) -> T) -> T {
     }
 }
 
-/**
- * Returns the byte offset of an inner slice relative to an enclosing outer slice
- *
- * # Example
- *
- * ~~~ {.rust}
- * let string = "a\nb\nc";
- * let mut lines = ~[];
- * for string.line_iter().advance |line| { lines.push(line) }
- *
- * assert!(subslice_offset(string, lines[0]) == 0); // &"a"
- * assert!(subslice_offset(string, lines[1]) == 2); // &"b"
- * assert!(subslice_offset(string, lines[2]) == 4); // &"c"
- * ~~~
- */
-#[inline(always)]
-pub fn subslice_offset(outer: &str, inner: &str) -> uint {
-    do as_buf(outer) |a, a_len| {
-        do as_buf(inner) |b, b_len| {
-            let a_start: uint;
-            let a_end: uint;
-            let b_start: uint;
-            let b_end: uint;
-            unsafe {
-                a_start = cast::transmute(a); a_end = a_len + cast::transmute(a);
-                b_start = cast::transmute(b); b_end = b_len + cast::transmute(b);
-            }
-            assert!(a_start <= b_start);
-            assert!(b_end <= a_end);
-            b_start - a_start
-        }
-    }
-}
-
 /// Unsafe operations
 pub mod raw {
     use cast;
@@ -1207,12 +911,138 @@ pub mod raw {
 #[cfg(not(test))]
 pub mod traits {
     use ops::Add;
-    impl<'self> Add<&'self str,~str> for ~str {
-        #[inline(always)]
+    use cmp::{TotalOrd, Ordering, Less, Equal, Greater, Eq, Ord, Equiv, TotalEq};
+    use super::{Str, eq_slice};
+
+    impl<'self> Add<&'self str,~str> for &'self str {
+        #[inline]
         fn add(&self, rhs: & &'self str) -> ~str {
-            self.append((*rhs))
+            let mut ret = self.to_owned();
+            ret.push_str(*rhs);
+            ret
+        }
+    }
+
+    impl<'self> TotalOrd for &'self str {
+        #[inline]
+        fn cmp(&self, other: & &'self str) -> Ordering {
+            for self.bytes_iter().zip(other.bytes_iter()).advance |(s_b, o_b)| {
+                match s_b.cmp(&o_b) {
+                    Greater => return Greater,
+                    Less => return Less,
+                    Equal => ()
+                }
+            }
+
+            self.len().cmp(&other.len())
+        }
+    }
+
+    impl TotalOrd for ~str {
+        #[inline]
+        fn cmp(&self, other: &~str) -> Ordering { self.as_slice().cmp(&other.as_slice()) }
+    }
+
+    impl TotalOrd for @str {
+        #[inline]
+        fn cmp(&self, other: &@str) -> Ordering { self.as_slice().cmp(&other.as_slice()) }
+    }
+
+    impl<'self> Eq for &'self str {
+        #[inline]
+        fn eq(&self, other: & &'self str) -> bool {
+            eq_slice((*self), (*other))
+        }
+        #[inline]
+        fn ne(&self, other: & &'self str) -> bool { !(*self).eq(other) }
+    }
+
+    impl Eq for ~str {
+        #[inline]
+        fn eq(&self, other: &~str) -> bool {
+            eq_slice((*self), (*other))
+        }
+        #[inline]
+        fn ne(&self, other: &~str) -> bool { !(*self).eq(other) }
+    }
+
+    impl Eq for @str {
+        #[inline]
+        fn eq(&self, other: &@str) -> bool {
+            eq_slice((*self), (*other))
+        }
+        #[inline]
+        fn ne(&self, other: &@str) -> bool { !(*self).eq(other) }
+    }
+
+    impl<'self> TotalEq for &'self str {
+        #[inline]
+        fn equals(&self, other: & &'self str) -> bool {
+            eq_slice((*self), (*other))
+        }
+    }
+
+    impl TotalEq for ~str {
+        #[inline]
+        fn equals(&self, other: &~str) -> bool {
+            eq_slice((*self), (*other))
+        }
+    }
+
+    impl TotalEq for @str {
+        #[inline]
+        fn equals(&self, other: &@str) -> bool {
+            eq_slice((*self), (*other))
         }
     }
+
+    impl<'self> Ord for &'self str {
+        #[inline]
+        fn lt(&self, other: & &'self str) -> bool { self.cmp(other) == Less }
+        #[inline]
+        fn le(&self, other: & &'self str) -> bool { self.cmp(other) != Greater }
+        #[inline]
+        fn ge(&self, other: & &'self str) -> bool { self.cmp(other) != Less }
+        #[inline]
+        fn gt(&self, other: & &'self str) -> bool { self.cmp(other) == Greater }
+    }
+
+    impl Ord for ~str {
+        #[inline]
+        fn lt(&self, other: &~str) -> bool { self.cmp(other) == Less }
+        #[inline]
+        fn le(&self, other: &~str) -> bool { self.cmp(other) != Greater }
+        #[inline]
+        fn ge(&self, other: &~str) -> bool { self.cmp(other) != Less }
+        #[inline]
+        fn gt(&self, other: &~str) -> bool { self.cmp(other) == Greater }
+    }
+
+    impl Ord for @str {
+        #[inline]
+        fn lt(&self, other: &@str) -> bool { self.cmp(other) == Less }
+        #[inline]
+        fn le(&self, other: &@str) -> bool { self.cmp(other) != Greater }
+        #[inline]
+        fn ge(&self, other: &@str) -> bool { self.cmp(other) != Less }
+        #[inline]
+        fn gt(&self, other: &@str) -> bool { self.cmp(other) == Greater }
+    }
+
+    impl<'self, S: Str> Equiv<S> for &'self str {
+        #[inline]
+        fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) }
+    }
+
+    impl<'self, S: Str> Equiv<S> for @str {
+        #[inline]
+        fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) }
+    }
+
+    impl<'self, S: Str> Equiv<S> for ~str {
+        #[inline]
+        fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) }
+    }
 }
 
 #[cfg(test)]
@@ -1225,17 +1055,17 @@ pub trait Str {
 }
 
 impl<'self> Str for &'self str {
-    #[inline(always)]
+    #[inline]
     fn as_slice<'a>(&'a self) -> &'a str { *self }
 }
 impl<'self> Str for ~str {
-    #[inline(always)]
+    #[inline]
     fn as_slice<'a>(&'a self) -> &'a str {
         let s: &'a str = *self; s
     }
 }
 impl<'self> Str for @str {
-    #[inline(always)]
+    #[inline]
     fn as_slice<'a>(&'a self) -> &'a str {
         let s: &'a str = *self; s
     }
@@ -1256,6 +1086,7 @@ pub trait StrSlice<'self> {
     fn matches_index_iter(&self, sep: &'self str) -> StrMatchesIndexIterator<'self>;
     fn split_str_iter(&self, &'self str) -> StrStrSplitIterator<'self>;
     fn line_iter(&self) -> StrCharSplitIterator<'self, char>;
+    fn any_line_iter(&self) -> AnyLineIterator<'self>;
     fn word_iter(&self) -> WordIterator<'self>;
     fn ends_with(&self, needle: &str) -> bool;
     fn is_empty(&self) -> bool;
@@ -1282,6 +1113,7 @@ pub trait StrSlice<'self> {
     fn replace(&self, from: &str, to: &str) -> ~str;
     fn to_owned(&self) -> ~str;
     fn to_managed(&self) -> @str;
+    fn to_utf16(&self) -> ~[u16];
     fn is_char_boundary(&self, index: uint) -> bool;
     fn char_range_at(&self, start: uint) -> CharRange;
     fn char_at(&self, i: uint) -> char;
@@ -1296,6 +1128,12 @@ pub trait StrSlice<'self> {
     fn repeat(&self, nn: uint) -> ~str;
 
     fn slice_shift_char(&self) -> (char, &'self str);
+
+    fn map_chars(&self, ff: &fn(char) -> char) -> ~str;
+
+    fn lev_distance(&self, t: &str) -> uint;
+
+    fn subslice_offset(&self, inner: &str) -> uint;
 }
 
 /// Extension methods for strings
@@ -1437,6 +1275,17 @@ impl<'self> StrSlice<'self> for &'self str {
     fn line_iter(&self) -> StrCharSplitIterator<'self, char> {
         self.split_options_iter('\n', self.len(), false)
     }
+
+    /// An iterator over the lines of a string, separated by either
+    /// `\n` or (`\r\n`).
+    fn any_line_iter(&self) -> AnyLineIterator<'self> {
+        do self.line_iter().transform |line| {
+            let l = line.len();
+            if l > 0 && line[l - 1] == '\r' as u8 { line.slice(0, l - 1) }
+            else { line }
+        }
+    }
+
     /// An iterator over the words of a string (subsequences separated
     /// by any sequence of whitespace).
     #[inline]
@@ -1462,7 +1311,7 @@ impl<'self> StrSlice<'self> for &'self str {
     #[inline]
     fn is_alphanumeric(&self) -> bool { self.iter().all(char::is_alphanumeric) }
     /// Returns the size in bytes not counting the null terminator
-    #[inline(always)]
+    #[inline]
     fn len(&self) -> uint {
         do as_buf(*self) |_p, n| { n - 1u }
     }
@@ -1586,7 +1435,7 @@ impl<'self> StrSlice<'self> for &'self str {
      *
      * # Example
      *
-     * ~~~
+     * ~~~ {.rust}
      * assert_eq!("11foo1bar11".trim_chars(&'1'), "foo1bar")
      * assert_eq!("12foo1bar12".trim_chars(& &['1', '2']), "foo1bar")
      * assert_eq!("123foo1bar123".trim_chars(&|c: char| c.is_digit()), "foo1bar")
@@ -1605,7 +1454,7 @@ impl<'self> StrSlice<'self> for &'self str {
      *
      * # Example
      *
-     * ~~~
+     * ~~~ {.rust}
      * assert_eq!("11foo1bar11".trim_left_chars(&'1'), "foo1bar11")
      * assert_eq!("12foo1bar12".trim_left_chars(& &['1', '2']), "foo1bar12")
      * assert_eq!("123foo1bar123".trim_left_chars(&|c: char| c.is_digit()), "foo1bar123")
@@ -1627,7 +1476,7 @@ impl<'self> StrSlice<'self> for &'self str {
      *
      * # Example
      *
-     * ~~~
+     * ~~~ {.rust}
      * assert_eq!("11foo1bar11".trim_right_chars(&'1'), "11foo1bar")
      * assert_eq!("12foo1bar12".trim_right_chars(& &['1', '2']), "12foo1bar")
      * assert_eq!("123foo1bar123".trim_right_chars(&|c: char| c.is_digit()), "123foo1bar")
@@ -1679,6 +1528,30 @@ impl<'self> StrSlice<'self> for &'self str {
         unsafe { ::cast::transmute(v) }
     }
 
+    /// Converts to a vector of `u16` encoded as UTF-16.
+    fn to_utf16(&self) -> ~[u16] {
+        let mut u = ~[];
+        for self.iter().advance |ch| {
+            // Arithmetic with u32 literals is easier on the eyes than chars.
+            let mut ch = ch as u32;
+
+            if (ch & 0xFFFF_u32) == ch {
+                // The BMP falls through (assuming non-surrogate, as it
+                // should)
+                assert!(ch <= 0xD7FF_u32 || ch >= 0xE000_u32);
+                u.push(ch as u16)
+            } else {
+                // Supplementary planes break into surrogates.
+                assert!(ch >= 0x1_0000_u32 && ch <= 0x10_FFFF_u32);
+                ch -= 0x1_0000_u32;
+                let w1 = 0xD800_u16 | ((ch >> 10) as u16);
+                let w2 = 0xDC00_u16 | ((ch as u16) & 0x3FF_u16);
+                u.push_all([w1, w2])
+            }
+        }
+        u
+    }
+
     /**
      * Returns false if the index points into the middle of a multi-byte
      * character sequence.
@@ -1921,6 +1794,85 @@ impl<'self> StrSlice<'self> for &'self str {
     }
 
 
+    /// Apply a function to each character.
+    fn map_chars(&self, ff: &fn(char) -> char) -> ~str {
+        let mut result = with_capacity(self.len());
+        for self.iter().advance |cc| {
+            result.push_char(ff(cc));
+        }
+        result
+    }
+
+    /// Levenshtein Distance between two strings.
+    fn lev_distance(&self, t: &str) -> uint {
+        let slen = self.len();
+        let tlen = t.len();
+
+        if slen == 0 { return tlen; }
+        if tlen == 0 { return slen; }
+
+        let mut dcol = vec::from_fn(tlen + 1, |x| x);
+
+        for self.iter().enumerate().advance |(i, sc)| {
+
+            let mut current = i;
+            dcol[0] = current + 1;
+
+            for t.iter().enumerate().advance |(j, tc)| {
+
+                let next = dcol[j + 1];
+
+                if sc == tc {
+                    dcol[j + 1] = current;
+                } else {
+                    dcol[j + 1] = ::cmp::min(current, next);
+                    dcol[j + 1] = ::cmp::min(dcol[j + 1], dcol[j]) + 1;
+                }
+
+                current = next;
+            }
+        }
+
+        return dcol[tlen];
+    }
+
+
+    /**
+     * Returns the byte offset of an inner slice relative to an enclosing outer slice.
+     *
+     * Fails if `inner` is not a direct slice contained within self.
+     *
+     * # Example
+     *
+     * ~~~ {.rust}
+     * let string = "a\nb\nc";
+     * let mut lines = ~[];
+     * for string.line_iter().advance |line| { lines.push(line) }
+     *
+     * assert!(string.subslice_offset(lines[0]) == 0); // &"a"
+     * assert!(string.subslice_offset(lines[1]) == 2); // &"b"
+     * assert!(string.subslice_offset(lines[2]) == 4); // &"c"
+     * ~~~
+     */
+    #[inline]
+    fn subslice_offset(&self, inner: &str) -> uint {
+        do as_buf(*self) |a, a_len| {
+            do as_buf(inner) |b, b_len| {
+                let a_start: uint;
+                let a_end: uint;
+                let b_start: uint;
+                let b_end: uint;
+                unsafe {
+                    a_start = cast::transmute(a); a_end = a_len + cast::transmute(a);
+                    b_start = cast::transmute(b); b_end = b_len + cast::transmute(b);
+                }
+                assert!(a_start <= b_start);
+                assert!(b_end <= a_end);
+                b_start - a_start
+            }
+        }
+    }
+
 }
 
 #[allow(missing_doc)]
@@ -1973,7 +1925,7 @@ pub trait OwnedStr {
 
 impl OwnedStr for ~str {
     /// Appends a string slice to the back of a string, without overallocating
-    #[inline(always)]
+    #[inline]
     fn push_str_no_overallocate(&mut self, rhs: &str) {
         unsafe {
             let llen = self.len();
@@ -2126,7 +2078,7 @@ impl OwnedStr for ~str {
      * * s - A string
      * * n - The number of bytes to reserve space for
      */
-    #[inline(always)]
+    #[inline]
     pub fn reserve(&mut self, n: uint) {
         unsafe {
             let v: *mut ~[u8] = cast::transmute(self);
@@ -2154,7 +2106,7 @@ impl OwnedStr for ~str {
      * * s - A string
      * * n - The number of bytes to reserve space for
      */
-    #[inline(always)]
+    #[inline]
     fn reserve_at_least(&mut self, n: uint) {
         self.reserve(uint::next_power_of_two(n + 1u) - 1u)
     }
@@ -2179,7 +2131,7 @@ impl OwnedStr for ~str {
 }
 
 impl Clone for ~str {
-    #[inline(always)]
+    #[inline]
     fn clone(&self) -> ~str {
         to_owned(*self)
     }
@@ -2250,6 +2202,22 @@ impl<'self> Iterator<u8> for StrBytesRevIterator<'self> {
     }
 }
 
+// This works because every lifetime is a sub-lifetime of 'static
+impl<'self> Zero for &'self str {
+    fn zero() -> &'self str { "" }
+    fn is_zero(&self) -> bool { self.is_empty() }
+}
+
+impl Zero for ~str {
+    fn zero() -> ~str { ~"" }
+    fn is_zero(&self) -> bool { self.len() == 0 }
+}
+
+impl Zero for @str {
+    fn zero() -> @str { @"" }
+    fn is_zero(&self) -> bool { self.len() == 0 }
+}
+
 #[cfg(test)]
 mod tests {
     use iterator::IteratorUtil;
@@ -2280,10 +2248,10 @@ mod tests {
 
     #[test]
     fn test_le() {
-        assert!((le(&"", &"")));
-        assert!((le(&"", &"foo")));
-        assert!((le(&"foo", &"foo")));
-        assert!((!eq(&~"foo", &~"bar")));
+        assert!("" <= "");
+        assert!("" <= "foo");
+        assert!("foo" <= "foo");
+        assert!("foo" != ~"bar");
     }
 
     #[test]
@@ -3003,15 +2971,15 @@ mod tests {
         let a = "kernelsprite";
         let b = a.slice(7, a.len());
         let c = a.slice(0, a.len() - 6);
-        assert_eq!(subslice_offset(a, b), 7);
-        assert_eq!(subslice_offset(a, c), 0);
+        assert_eq!(a.subslice_offset(b), 7);
+        assert_eq!(a.subslice_offset(c), 0);
 
         let string = "a\nb\nc";
         let mut lines = ~[];
         for string.line_iter().advance |line| { lines.push(line) }
-        assert_eq!(subslice_offset(string, lines[0]), 0);
-        assert_eq!(subslice_offset(string, lines[1]), 2);
-        assert_eq!(subslice_offset(string, lines[2]), 4);
+        assert_eq!(string.subslice_offset(lines[0]), 0);
+        assert_eq!(string.subslice_offset(lines[1]), 2);
+        assert_eq!(string.subslice_offset(lines[2]), 4);
     }
 
     #[test]
@@ -3019,7 +2987,7 @@ mod tests {
     fn test_subslice_offset_2() {
         let a = "alchemiter";
         let b = "cruxtruder";
-        subslice_offset(a, b);
+        a.subslice_offset(b);
     }
 
     #[test]
@@ -3069,8 +3037,8 @@ mod tests {
 
     #[test]
     fn test_map() {
-        assert_eq!(~"", map("", |c| unsafe {libc::toupper(c as c_char)} as char));
-        assert_eq!(~"YMCA", map("ymca", |c| unsafe {libc::toupper(c as c_char)} as char));
+        assert_eq!(~"", "".map_chars(|c| unsafe {libc::toupper(c as c_char)} as char));
+        assert_eq!(~"YMCA", "ymca".map_chars(|c| unsafe {libc::toupper(c as c_char)} as char));
     }
 
     #[test]
@@ -3114,10 +3082,10 @@ mod tests {
 
         for pairs.each |p| {
             let (s, u) = copy *p;
-            assert!(to_utf16(s) == u);
+            assert!(s.to_utf16() == u);
             assert!(from_utf16(u) == s);
-            assert!(from_utf16(to_utf16(s)) == s);
-            assert!(to_utf16(from_utf16(u)) == u);
+            assert!(from_utf16(s.to_utf16()) == s);
+            assert!(from_utf16(u).to_utf16() == u);
         }
     }
 
@@ -3189,6 +3157,24 @@ mod tests {
     }
 
     #[test]
+    fn test_add() {
+        macro_rules! t (
+            ($s1:expr, $s2:expr, $e:expr) => {
+                assert_eq!($s1 + $s2, $e);
+                assert_eq!($s1.to_owned() + $s2, $e);
+                assert_eq!($s1.to_managed() + $s2, $e);
+            }
+        );
+
+        t!("foo",  "bar", ~"foobar");
+        t!("foo", @"bar", ~"foobar");
+        t!("foo", ~"bar", ~"foobar");
+        t!("ศไทย中",  "华Việt Nam", ~"ศไทย中华Việt Nam");
+        t!("ศไทย中", @"华Việt Nam", ~"ศไทย中华Việt Nam");
+        t!("ศไทย中", ~"华Việt Nam", ~"ศไทย中华Việt Nam");
+    }
+
+    #[test]
     fn test_iterator() {
         use iterator::*;
         let s = ~"ศไทย中华Việt Nam";
@@ -3337,4 +3323,18 @@ mod tests {
         t("zzz", "zz", ~["","z"]);
         t("zzzzz", "zz", ~["","","z"]);
     }
+
+    #[test]
+    fn test_str_zero() {
+        use num::Zero;
+        fn t<S: Zero + Str>() {
+            let s: S = Zero::zero();
+            assert_eq!(s.as_slice(), "");
+            assert!(s.is_zero());
+        }
+
+        t::<&str>();
+        t::<@str>();
+        t::<~str>();
+    }
 }
diff --git a/src/libstd/str/ascii.rs b/src/libstd/str/ascii.rs
index 618d5095777..c71765f911a 100644
--- a/src/libstd/str/ascii.rs
+++ b/src/libstd/str/ascii.rs
@@ -17,26 +17,27 @@ use cast;
 use old_iter::BaseIter;
 use iterator::IteratorUtil;
 use vec::{CopyableVector, ImmutableVector, OwnedVector};
+use to_bytes::IterBytes;
 
-/// Datatype to hold one ascii character. It is 8 bit long.
+/// Datatype to hold one ascii character. It wraps a `u8`, with the highest bit always zero.
 #[deriving(Clone, Eq)]
 pub struct Ascii { priv chr: u8 }
 
 impl Ascii {
     /// Converts a ascii character into a `u8`.
-    #[inline(always)]
+    #[inline]
     pub fn to_byte(self) -> u8 {
         self.chr
     }
 
     /// Converts a ascii character into a `char`.
-    #[inline(always)]
+    #[inline]
     pub fn to_char(self) -> char {
         self.chr as char
     }
 
     /// Convert to lowercase.
-    #[inline(always)]
+    #[inline]
     pub fn to_lower(self) -> Ascii {
         if self.chr >= 65 && self.chr <= 90 {
             Ascii{chr: self.chr | 0x20 }
@@ -46,7 +47,7 @@ impl Ascii {
     }
 
     /// Convert to uppercase.
-    #[inline(always)]
+    #[inline]
     pub fn to_upper(self) -> Ascii {
         if self.chr >= 97 && self.chr <= 122 {
             Ascii{chr: self.chr & !0x20 }
@@ -56,14 +57,14 @@ impl Ascii {
     }
 
     /// Compares two ascii characters of equality, ignoring case.
-    #[inline(always)]
+    #[inline]
     pub fn eq_ignore_case(self, other: Ascii) -> bool {
         self.to_lower().chr == other.to_lower().chr
     }
 }
 
 impl ToStr for Ascii {
-    #[inline(always)]
+    #[inline]
     fn to_str(&self) -> ~str { str::from_bytes(['\'' as u8, self.chr, '\'' as u8]) }
 }
 
@@ -72,18 +73,26 @@ pub trait AsciiCast<T> {
     /// Convert to an ascii type
     fn to_ascii(&self) -> T;
 
+    /// Convert to an ascii type, not doing any range asserts
+    unsafe fn to_ascii_nocheck(&self) -> T;
+
     /// Check if convertible to ascii
     fn is_ascii(&self) -> bool;
 }
 
 impl<'self> AsciiCast<&'self[Ascii]> for &'self [u8] {
-    #[inline(always)]
+    #[inline]
     fn to_ascii(&self) -> &'self[Ascii] {
         assert!(self.is_ascii());
-        unsafe{ cast::transmute(*self) }
+        unsafe {self.to_ascii_nocheck()}
+    }
+
+    #[inline]
+    unsafe fn to_ascii_nocheck(&self) -> &'self[Ascii] {
+        cast::transmute(*self)
     }
 
-    #[inline(always)]
+    #[inline]
     fn is_ascii(&self) -> bool {
         for self.each |b| {
             if !b.is_ascii() { return false; }
@@ -93,40 +102,55 @@ impl<'self> AsciiCast<&'self[Ascii]> for &'self [u8] {
 }
 
 impl<'self> AsciiCast<&'self[Ascii]> for &'self str {
-    #[inline(always)]
+    #[inline]
     fn to_ascii(&self) -> &'self[Ascii] {
         assert!(self.is_ascii());
-        let (p,len): (*u8, uint) = unsafe{ cast::transmute(*self) };
-        unsafe{ cast::transmute((p, len - 1))}
+        unsafe {self.to_ascii_nocheck()}
+    }
+
+    #[inline]
+    unsafe fn to_ascii_nocheck(&self) -> &'self[Ascii] {
+        let (p,len): (*u8, uint) = cast::transmute(*self);
+        cast::transmute((p, len - 1))
     }
 
-    #[inline(always)]
+    #[inline]
     fn is_ascii(&self) -> bool {
         self.bytes_iter().all(|b| b.is_ascii())
     }
 }
 
 impl AsciiCast<Ascii> for u8 {
-    #[inline(always)]
+    #[inline]
     fn to_ascii(&self) -> Ascii {
         assert!(self.is_ascii());
+        unsafe {self.to_ascii_nocheck()}
+    }
+
+    #[inline]
+    unsafe fn to_ascii_nocheck(&self) -> Ascii {
         Ascii{ chr: *self }
     }
 
-    #[inline(always)]
+    #[inline]
     fn is_ascii(&self) -> bool {
         *self & 128 == 0u8
     }
 }
 
 impl AsciiCast<Ascii> for char {
-    #[inline(always)]
+    #[inline]
     fn to_ascii(&self) -> Ascii {
         assert!(self.is_ascii());
+        unsafe {self.to_ascii_nocheck()}
+    }
+
+    #[inline]
+    unsafe fn to_ascii_nocheck(&self) -> Ascii {
         Ascii{ chr: *self as u8 }
     }
 
-    #[inline(always)]
+    #[inline]
     fn is_ascii(&self) -> bool {
         *self - ('\x7F' & *self) == '\x00'
     }
@@ -135,26 +159,38 @@ impl AsciiCast<Ascii> for char {
 /// Trait for copyless casting to an ascii vector.
 pub trait OwnedAsciiCast {
     /// Take ownership and cast to an ascii vector without trailing zero element.
-    fn to_ascii_consume(self) -> ~[Ascii];
+    fn into_ascii(self) -> ~[Ascii];
+
+    /// Take ownership and cast to an ascii vector without trailing zero element.
+    /// Does not perform validation checks.
+    unsafe fn into_ascii_nocheck(self) -> ~[Ascii];
 }
 
 impl OwnedAsciiCast for ~[u8] {
-    #[inline(always)]
-    fn to_ascii_consume(self) -> ~[Ascii] {
+    #[inline]
+    fn into_ascii(self) -> ~[Ascii] {
         assert!(self.is_ascii());
-        unsafe {cast::transmute(self)}
+        unsafe {self.into_ascii_nocheck()}
+    }
+
+    #[inline]
+    unsafe fn into_ascii_nocheck(self) -> ~[Ascii] {
+        cast::transmute(self)
     }
 }
 
 impl OwnedAsciiCast for ~str {
-    #[inline(always)]
-    fn to_ascii_consume(self) -> ~[Ascii] {
+    #[inline]
+    fn into_ascii(self) -> ~[Ascii] {
         assert!(self.is_ascii());
-        let mut s = self;
-        unsafe {
-            str::raw::pop_byte(&mut s);
-            cast::transmute(s)
-        }
+        unsafe {self.into_ascii_nocheck()}
+    }
+
+    #[inline]
+    unsafe fn into_ascii_nocheck(self) -> ~[Ascii] {
+        let mut r: ~[Ascii] = cast::transmute(self);
+        r.pop();
+        r
     }
 }
 
@@ -169,39 +205,66 @@ pub trait AsciiStr {
     /// Convert to vector representing a upper cased ascii string.
     fn to_upper(&self) -> ~[Ascii];
 
+    /// Compares two Ascii strings ignoring case
+    fn eq_ignore_case(self, other: &[Ascii]) -> bool;
 }
 
 impl<'self> AsciiStr for &'self [Ascii] {
-    #[inline(always)]
+    #[inline]
     fn to_str_ascii(&self) -> ~str {
         let mut cpy = self.to_owned();
         cpy.push(0u8.to_ascii());
         unsafe {cast::transmute(cpy)}
     }
 
-    #[inline(always)]
+    #[inline]
     fn to_lower(&self) -> ~[Ascii] {
         self.map(|a| a.to_lower())
     }
 
-    #[inline(always)]
+    #[inline]
     fn to_upper(&self) -> ~[Ascii] {
         self.map(|a| a.to_upper())
     }
+
+    #[inline]
+    fn eq_ignore_case(self, other: &[Ascii]) -> bool {
+        do self.iter().zip(other.iter()).all |(&a, &b)| { a.eq_ignore_case(b) }
+    }
 }
 
 impl ToStrConsume for ~[Ascii] {
-    #[inline(always)]
-    fn to_str_consume(self) -> ~str {
+    #[inline]
+    fn into_str(self) -> ~str {
         let mut cpy = self;
         cpy.push(0u8.to_ascii());
         unsafe {cast::transmute(cpy)}
     }
 }
 
+impl IterBytes for Ascii {
+    #[inline]
+    fn iter_bytes(&self, _lsb0: bool, f: &fn(buf: &[u8]) -> bool) -> bool {
+        f([self.to_byte()])
+    }
+}
+
+/// Trait to convert to a owned byte array by consuming self
+pub trait ToBytesConsume {
+    /// Converts to a owned byte array by consuming self
+    fn into_bytes(self) -> ~[u8];
+}
+
+impl ToBytesConsume for ~[Ascii] {
+    fn into_bytes(self) -> ~[u8] {
+        unsafe {cast::transmute(self)}
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
+    use to_bytes::ToBytes;
 
     macro_rules! v2ascii (
         ( [$($e:expr),*]) => ( [$(Ascii{chr:$e}),*]);
@@ -245,6 +308,8 @@ mod tests {
         assert_eq!("YMCA".to_ascii().to_lower().to_str_ascii(), ~"ymca");
         assert_eq!("abcDEFxyz:.;".to_ascii().to_upper().to_str_ascii(), ~"ABCDEFXYZ:.;");
 
+        assert!("aBcDeF&?#".to_ascii().eq_ignore_case("AbCdEf&?#".to_ascii()));
+
         assert!("".is_ascii());
         assert!("a".is_ascii());
         assert!(!"\u2009".is_ascii());
@@ -253,21 +318,22 @@ mod tests {
 
     #[test]
     fn test_owned_ascii_vec() {
-        // FIXME: #4318 Compiler crashes on moving self
-        //assert_eq!(~"( ;".to_ascii_consume(), v2ascii!(~[40, 32, 59]));
-        //assert_eq!(~[40u8, 32u8, 59u8].to_ascii_consume(), v2ascii!(~[40, 32, 59]));
-        //assert_eq!(~"( ;".to_ascii_consume_with_null(), v2ascii!(~[40, 32, 59, 0]));
-        //assert_eq!(~[40u8, 32u8, 59u8].to_ascii_consume_with_null(),
-        //           v2ascii!(~[40, 32, 59, 0]));
+        assert_eq!((~"( ;").into_ascii(), v2ascii!(~[40, 32, 59]));
+        assert_eq!((~[40u8, 32u8, 59u8]).into_ascii(), v2ascii!(~[40, 32, 59]));
     }
 
     #[test]
     fn test_ascii_to_str() { assert_eq!(v2ascii!([40, 32, 59]).to_str_ascii(), ~"( ;"); }
 
     #[test]
-    fn test_ascii_to_str_consume() {
-        // FIXME: #4318 Compiler crashes on moving self
-        //assert_eq!(v2ascii!(~[40, 32, 59]).to_str_consume(), ~"( ;");
+    fn test_ascii_into_str() {
+        assert_eq!(v2ascii!(~[40, 32, 59]).into_str(), ~"( ;");
+    }
+
+    #[test]
+    fn test_ascii_to_bytes() {
+        assert_eq!(v2ascii!(~[40, 32, 59]).to_bytes(false), ~[40u8, 32u8, 59u8]);
+        assert_eq!(v2ascii!(~[40, 32, 59]).into_bytes(), ~[40u8, 32u8, 59u8]);
     }
 
     #[test] #[should_fail]
diff --git a/src/libstd/sys.rs b/src/libstd/sys.rs
index e49ad348542..523c5d633cf 100644
--- a/src/libstd/sys.rs
+++ b/src/libstd/sys.rs
@@ -57,25 +57,25 @@ pub mod rustrt {
  * Useful for calling certain function in the Rust runtime or otherwise
  * performing dark magick.
  */
-#[inline(always)]
+#[inline]
 pub fn get_type_desc<T>() -> *TypeDesc {
     unsafe { intrinsics::get_tydesc::<T>() as *TypeDesc }
 }
 
 /// Returns a pointer to a type descriptor.
-#[inline(always)]
+#[inline]
 pub fn get_type_desc_val<T>(_val: &T) -> *TypeDesc {
     get_type_desc::<T>()
 }
 
 /// Returns the size of a type
-#[inline(always)]
+#[inline]
 pub fn size_of<T>() -> uint {
     unsafe { intrinsics::size_of::<T>() }
 }
 
 /// Returns the size of the type that `_val` points to
-#[inline(always)]
+#[inline]
 pub fn size_of_val<T>(_val: &T) -> uint {
     size_of::<T>()
 }
@@ -85,14 +85,14 @@ pub fn size_of_val<T>(_val: &T) -> uint {
  *
  * Useful for building structures containing variable-length arrays.
  */
-#[inline(always)]
+#[inline]
 pub fn nonzero_size_of<T>() -> uint {
     let s = size_of::<T>();
     if s == 0 { 1 } else { s }
 }
 
 /// Returns the size of the type of the value that `_val` points to
-#[inline(always)]
+#[inline]
 pub fn nonzero_size_of_val<T>(_val: &T) -> uint {
     nonzero_size_of::<T>()
 }
@@ -104,33 +104,33 @@ pub fn nonzero_size_of_val<T>(_val: &T) -> uint {
  * This is the alignment used for struct fields. It may be smaller
  * than the preferred alignment.
  */
-#[inline(always)]
+#[inline]
 pub fn min_align_of<T>() -> uint {
     unsafe { intrinsics::min_align_of::<T>() }
 }
 
 /// Returns the ABI-required minimum alignment of the type of the value that
 /// `_val` points to
-#[inline(always)]
+#[inline]
 pub fn min_align_of_val<T>(_val: &T) -> uint {
     min_align_of::<T>()
 }
 
 /// Returns the preferred alignment of a type
-#[inline(always)]
+#[inline]
 pub fn pref_align_of<T>() -> uint {
     unsafe { intrinsics::pref_align_of::<T>() }
 }
 
 /// Returns the preferred alignment of the type of the value that
 /// `_val` points to
-#[inline(always)]
+#[inline]
 pub fn pref_align_of_val<T>(_val: &T) -> uint {
     pref_align_of::<T>()
 }
 
 /// Returns the refcount of a shared box (as just before calling this)
-#[inline(always)]
+#[inline]
 pub fn refcount<T>(t: @T) -> uint {
     unsafe {
         let ref_ptr: *uint = cast::transmute_copy(&t);
@@ -180,10 +180,13 @@ impl FailWithCause for &'static str {
 
 // FIXME #4427: Temporary until rt::rt_fail_ goes away
 pub fn begin_unwind_(msg: *c_char, file: *c_char, line: size_t) -> ! {
+    use cell::Cell;
     use option::Option;
+    use either::Left;
     use rt::{context, OldTaskContext, TaskContext};
     use rt::task::{Task, Unwinder};
     use rt::local::Local;
+    use rt::logging::Logger;
 
     let context = context();
     match context {
@@ -200,19 +203,28 @@ pub fn begin_unwind_(msg: *c_char, file: *c_char, line: size_t) -> ! {
                 let msg = str::raw::from_c_str(msg);
                 let file = str::raw::from_c_str(file);
 
-                let outmsg = fmt!("%s at line %i of file %s", msg, line as int, file);
+                let outmsg = fmt!("task failed: '%s' at line %i of file %s",
+                                  msg, line as int, file);
 
                 // XXX: Logging doesn't work correctly in non-task context because it
                 // invokes the local heap
                 if context == TaskContext {
-                    error!(outmsg);
+                    // XXX: Logging doesn't work here - the check to call the log
+                    // function never passes - so calling the log function directly.
+                    let outmsg = Cell::new(outmsg);
+                    do Local::borrow::<Task, ()> |task| {
+                        task.logger.log(Left(outmsg.take()));
+                    }
                 } else {
-                    rtdebug!("%s", outmsg);
+                    rterrln!("%s", outmsg);
                 }
 
                 gc::cleanup_stack_for_failure();
 
                 let task = Local::unsafe_borrow::<Task>();
+                if (*task).unwinder.unwinding {
+                    rtabort!("unwinding again");
+                }
                 (*task).unwinder.begin_unwind();
             }
         }
diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs
index 9df93d19d21..63eb768d1c9 100644
--- a/src/libstd/task/spawn.rs
+++ b/src/libstd/task/spawn.rs
@@ -79,7 +79,6 @@ use cast;
 use cell::Cell;
 use container::Map;
 use comm::{Chan, GenericChan};
-use ptr;
 use hashmap::HashSet;
 use task::local_data_priv::{local_get, local_set, OldHandle};
 use task::rt::rust_task;
@@ -99,10 +98,6 @@ use rt::task::Task;
 #[cfg(test)] use comm;
 #[cfg(test)] use task;
 
-macro_rules! move_it (
-    { $x:expr } => ( unsafe { let y = *ptr::to_unsafe_ptr(&($x)); y } )
-)
-
 type TaskSet = HashSet<*rust_task>;
 
 fn new_taskset() -> TaskSet {
@@ -162,14 +157,14 @@ struct AncestorNode {
 struct AncestorList(Option<Exclusive<AncestorNode>>);
 
 // Accessors for taskgroup arcs and ancestor arcs that wrap the unsafety.
-#[inline(always)]
+#[inline]
 fn access_group<U>(x: &TaskGroupArc, blk: &fn(TaskGroupInner) -> U) -> U {
     unsafe {
         x.with(blk)
     }
 }
 
-#[inline(always)]
+#[inline]
 fn access_ancestors<U>(x: &Exclusive<AncestorNode>,
                        blk: &fn(x: &mut AncestorNode) -> U) -> U {
     unsafe {
@@ -583,13 +578,29 @@ pub fn spawn_raw(opts: TaskOpts, f: ~fn()) {
     }
 }
 
-fn spawn_raw_newsched(_opts: TaskOpts, f: ~fn()) {
+fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) {
     use rt::sched::*;
 
-    let task = do Local::borrow::<Task, ~Task>() |running_task| {
-        ~running_task.new_child()
+    let mut task = if opts.linked {
+        do Local::borrow::<Task, ~Task>() |running_task| {
+            ~running_task.new_child()
+        }
+    } else {
+        // An unlinked task is a new root in the task tree
+        ~Task::new_root()
     };
 
+    if opts.notify_chan.is_some() {
+        let notify_chan = opts.notify_chan.swap_unwrap();
+        let notify_chan = Cell::new(notify_chan);
+        let on_exit: ~fn(bool) = |success| {
+            notify_chan.take().send(
+                if success { Success } else { Failure }
+            )
+        };
+        task.on_exit = Some(on_exit);
+    }
+
     let mut sched = Local::take::<Scheduler>();
     let task = ~Coroutine::with_task(&mut sched.stack_pool,
                                      task, f);
@@ -644,23 +655,16 @@ fn spawn_raw_oldsched(mut opts: TaskOpts, f: ~fn()) {
                           notify_chan: Option<Chan<TaskResult>>,
                           f: ~fn())
                        -> ~fn() {
-        let child_data = Cell::new((child_arc, ancestors));
+        let child_data = Cell::new((notify_chan, child_arc, ancestors));
         let result: ~fn() = || {
             // Agh. Get move-mode items into the closure. FIXME (#2829)
-            let mut (child_arc, ancestors) = child_data.take();
+            let mut (notify_chan, child_arc, ancestors) = child_data.take();
             // Child task runs this code.
 
             // Even if the below code fails to kick the child off, we must
             // send Something on the notify channel.
 
-            //let mut notifier = None;//notify_chan.map(|c| AutoNotify(c));
-            let notifier = match notify_chan {
-                Some(ref notify_chan_value) => {
-                    let moved_ncv = move_it!(*notify_chan_value);
-                    Some(AutoNotify(moved_ncv))
-                }
-                _ => None
-            };
+            let notifier = notify_chan.map_consume(|c| AutoNotify(c));
 
             if enlist_many(child, &child_arc, &mut ancestors) {
                 let group = @@mut TCB(child,
diff --git a/src/libstd/to_bytes.rs b/src/libstd/to_bytes.rs
index c0c8b729f9e..822aab0a027 100644
--- a/src/libstd/to_bytes.rs
+++ b/src/libstd/to_bytes.rs
@@ -14,6 +14,7 @@ The `ToBytes` and `IterBytes` traits
 
 */
 
+use cast;
 use io;
 use io::Writer;
 use option::{None, Option, Some};
@@ -48,7 +49,7 @@ pub trait IterBytes {
 }
 
 impl IterBytes for bool {
-    #[inline(always)]
+    #[inline]
     fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool {
         f([
             *self as u8
@@ -57,7 +58,7 @@ impl IterBytes for bool {
 }
 
 impl IterBytes for u8 {
-    #[inline(always)]
+    #[inline]
     fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool {
         f([
             *self
@@ -66,7 +67,7 @@ impl IterBytes for u8 {
 }
 
 impl IterBytes for u16 {
-    #[inline(always)]
+    #[inline]
     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
         if lsb0 {
             f([
@@ -83,7 +84,7 @@ impl IterBytes for u16 {
 }
 
 impl IterBytes for u32 {
-    #[inline(always)]
+    #[inline]
     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
         if lsb0 {
             f([
@@ -104,7 +105,7 @@ impl IterBytes for u32 {
 }
 
 impl IterBytes for u64 {
-    #[inline(always)]
+    #[inline]
     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
         if lsb0 {
             f([
@@ -133,35 +134,35 @@ impl IterBytes for u64 {
 }
 
 impl IterBytes for i8 {
-    #[inline(always)]
+    #[inline]
     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
         (*self as u8).iter_bytes(lsb0, f)
     }
 }
 
 impl IterBytes for i16 {
-    #[inline(always)]
+    #[inline]
     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
         (*self as u16).iter_bytes(lsb0, f)
     }
 }
 
 impl IterBytes for i32 {
-    #[inline(always)]
+    #[inline]
     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
         (*self as u32).iter_bytes(lsb0, f)
     }
 }
 
 impl IterBytes for i64 {
-    #[inline(always)]
+    #[inline]
     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
         (*self as u64).iter_bytes(lsb0, f)
     }
 }
 
 impl IterBytes for char {
-    #[inline(always)]
+    #[inline]
     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
         (*self as u32).iter_bytes(lsb0, f)
     }
@@ -169,7 +170,7 @@ impl IterBytes for char {
 
 #[cfg(target_word_size = "32")]
 impl IterBytes for uint {
-    #[inline(always)]
+    #[inline]
     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
         (*self as u32).iter_bytes(lsb0, f)
     }
@@ -177,28 +178,57 @@ impl IterBytes for uint {
 
 #[cfg(target_word_size = "64")]
 impl IterBytes for uint {
-    #[inline(always)]
+    #[inline]
     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
         (*self as u64).iter_bytes(lsb0, f)
     }
 }
 
 impl IterBytes for int {
-    #[inline(always)]
+    #[inline]
     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
         (*self as uint).iter_bytes(lsb0, f)
     }
 }
 
+impl IterBytes for float {
+    #[inline]
+    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
+        (*self as f64).iter_bytes(lsb0, f)
+    }
+}
+
+impl IterBytes for f32 {
+    #[inline]
+    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
+        let i: u32 = unsafe {
+            // 0.0 == -0.0 so they should also have the same hashcode
+            cast::transmute(if *self == -0.0 { 0.0 } else { *self })
+        };
+        i.iter_bytes(lsb0, f)
+    }
+}
+
+impl IterBytes for f64 {
+    #[inline]
+    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
+        let i: u64 = unsafe {
+            // 0.0 == -0.0 so they should also have the same hashcode
+            cast::transmute(if *self == -0.0 { 0.0 } else { *self })
+        };
+        i.iter_bytes(lsb0, f)
+    }
+}
+
 impl<'self,A:IterBytes> IterBytes for &'self [A] {
-    #[inline(always)]
+    #[inline]
     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
         self.each(|elt| elt.iter_bytes(lsb0, |b| f(b)))
     }
 }
 
 impl<A:IterBytes,B:IterBytes> IterBytes for (A,B) {
-  #[inline(always)]
+  #[inline]
   fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
     match *self {
       (ref a, ref b) => { a.iter_bytes(lsb0, f) && b.iter_bytes(lsb0, f) }
@@ -207,7 +237,7 @@ impl<A:IterBytes,B:IterBytes> IterBytes for (A,B) {
 }
 
 impl<A:IterBytes,B:IterBytes,C:IterBytes> IterBytes for (A,B,C) {
-  #[inline(always)]
+  #[inline]
   fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
     match *self {
       (ref a, ref b, ref c) => {
@@ -223,28 +253,28 @@ fn borrow<'x,A>(a: &'x [A]) -> &'x [A] {
 }
 
 impl<A:IterBytes> IterBytes for ~[A] {
-    #[inline(always)]
+    #[inline]
     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
         borrow(*self).iter_bytes(lsb0, f)
     }
 }
 
 impl<A:IterBytes> IterBytes for @[A] {
-    #[inline(always)]
+    #[inline]
     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
         borrow(*self).iter_bytes(lsb0, f)
     }
 }
 
 impl<'self> IterBytes for &'self str {
-    #[inline(always)]
+    #[inline]
     fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool {
         f(self.as_bytes())
     }
 }
 
 impl IterBytes for ~str {
-    #[inline(always)]
+    #[inline]
     fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool {
         // this should possibly include the null terminator, but that
         // breaks .find_equiv on hashmaps.
@@ -253,7 +283,7 @@ impl IterBytes for ~str {
 }
 
 impl IterBytes for @str {
-    #[inline(always)]
+    #[inline]
     fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool {
         // this should possibly include the null terminator, but that
         // breaks .find_equiv on hashmaps.
@@ -262,7 +292,7 @@ impl IterBytes for @str {
 }
 
 impl<A:IterBytes> IterBytes for Option<A> {
-    #[inline(always)]
+    #[inline]
     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
         match *self {
           Some(ref a) => 0u8.iter_bytes(lsb0, f) && a.iter_bytes(lsb0, f),
@@ -272,21 +302,21 @@ impl<A:IterBytes> IterBytes for Option<A> {
 }
 
 impl<'self,A:IterBytes> IterBytes for &'self A {
-    #[inline(always)]
+    #[inline]
     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
         (**self).iter_bytes(lsb0, f)
     }
 }
 
 impl<A:IterBytes> IterBytes for @A {
-    #[inline(always)]
+    #[inline]
     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
         (**self).iter_bytes(lsb0, f)
     }
 }
 
 impl<A:IterBytes> IterBytes for ~A {
-    #[inline(always)]
+    #[inline]
     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
         (**self).iter_bytes(lsb0, f)
     }
@@ -295,7 +325,7 @@ impl<A:IterBytes> IterBytes for ~A {
 // NB: raw-pointer IterBytes does _not_ dereference
 // to the target; it just gives you the pointer-bytes.
 impl<A> IterBytes for *const A {
-    #[inline(always)]
+    #[inline]
     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
         (*self as uint).iter_bytes(lsb0, f)
     }
diff --git a/src/libstd/to_str.rs b/src/libstd/to_str.rs
index bfda92d46a2..3e782e728fe 100644
--- a/src/libstd/to_str.rs
+++ b/src/libstd/to_str.rs
@@ -31,16 +31,16 @@ pub trait ToStr {
 /// Trait for converting a type to a string, consuming it in the process.
 pub trait ToStrConsume {
     /// Cosume and convert to a string.
-    fn to_str_consume(self) -> ~str;
+    fn into_str(self) -> ~str;
 }
 
 impl ToStr for () {
-    #[inline(always)]
+    #[inline]
     fn to_str(&self) -> ~str { ~"()" }
 }
 
 impl<A:ToStr> ToStr for (A,) {
-    #[inline(always)]
+    #[inline]
     fn to_str(&self) -> ~str {
         match *self {
             (ref a,) => {
@@ -51,7 +51,7 @@ impl<A:ToStr> ToStr for (A,) {
 }
 
 impl<A:ToStr+Hash+Eq, B:ToStr+Hash+Eq> ToStr for HashMap<A, B> {
-    #[inline(always)]
+    #[inline]
     fn to_str(&self) -> ~str {
         let mut (acc, first) = (~"{", true);
         for self.each |key, value| {
@@ -71,7 +71,7 @@ impl<A:ToStr+Hash+Eq, B:ToStr+Hash+Eq> ToStr for HashMap<A, B> {
 }
 
 impl<A:ToStr+Hash+Eq> ToStr for HashSet<A> {
-    #[inline(always)]
+    #[inline]
     fn to_str(&self) -> ~str {
         let mut (acc, first) = (~"{", true);
         for self.each |element| {
@@ -89,7 +89,7 @@ impl<A:ToStr+Hash+Eq> ToStr for HashSet<A> {
 }
 
 impl<A:ToStr,B:ToStr> ToStr for (A, B) {
-    #[inline(always)]
+    #[inline]
     fn to_str(&self) -> ~str {
         // FIXME(#4653): this causes an llvm assertion
         //let &(ref a, ref b) = self;
@@ -102,7 +102,7 @@ impl<A:ToStr,B:ToStr> ToStr for (A, B) {
 }
 
 impl<A:ToStr,B:ToStr,C:ToStr> ToStr for (A, B, C) {
-    #[inline(always)]
+    #[inline]
     fn to_str(&self) -> ~str {
         // FIXME(#4653): this causes an llvm assertion
         //let &(ref a, ref b, ref c) = self;
@@ -119,7 +119,7 @@ impl<A:ToStr,B:ToStr,C:ToStr> ToStr for (A, B, C) {
 }
 
 impl<'self,A:ToStr> ToStr for &'self [A] {
-    #[inline(always)]
+    #[inline]
     fn to_str(&self) -> ~str {
         let mut (acc, first) = (~"[", true);
         for self.each |elt| {
@@ -137,7 +137,7 @@ impl<'self,A:ToStr> ToStr for &'self [A] {
 }
 
 impl<A:ToStr> ToStr for ~[A] {
-    #[inline(always)]
+    #[inline]
     fn to_str(&self) -> ~str {
         let mut (acc, first) = (~"[", true);
         for self.each |elt| {
@@ -155,7 +155,7 @@ impl<A:ToStr> ToStr for ~[A] {
 }
 
 impl<A:ToStr> ToStr for @[A] {
-    #[inline(always)]
+    #[inline]
     fn to_str(&self) -> ~str {
         let mut (acc, first) = (~"[", true);
         for self.each |elt| {
diff --git a/src/libstd/trie.rs b/src/libstd/trie.rs
index 4bd3946f885..aaeaa489834 100644
--- a/src/libstd/trie.rs
+++ b/src/libstd/trie.rs
@@ -34,17 +34,17 @@ pub struct TrieMap<T> {
 
 impl<T> Container for TrieMap<T> {
     /// Return the number of elements in the map
-    #[inline(always)]
+    #[inline]
     fn len(&const self) -> uint { self.length }
 
     /// Return true if the map contains no elements
-    #[inline(always)]
+    #[inline]
     fn is_empty(&const self) -> bool { self.len() == 0 }
 }
 
 impl<T> Mutable for TrieMap<T> {
     /// Clear the map, removing all values.
-    #[inline(always)]
+    #[inline]
     fn clear(&mut self) {
         self.root = TrieNode::new();
         self.length = 0;
@@ -53,37 +53,37 @@ impl<T> Mutable for TrieMap<T> {
 
 impl<T> Map<uint, T> for TrieMap<T> {
     /// Return true if the map contains a value for the specified key
-    #[inline(always)]
+    #[inline]
     fn contains_key(&self, key: &uint) -> bool {
         self.find(key).is_some()
     }
 
     /// Visit all key-value pairs in order
-    #[inline(always)]
+    #[inline]
     fn each<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) -> bool {
         self.root.each(f)
     }
 
     /// Visit all keys in order
-    #[inline(always)]
+    #[inline]
     fn each_key(&self, f: &fn(&uint) -> bool) -> bool {
         self.each(|k, _| f(k))
     }
 
     /// Visit all values in order
-    #[inline(always)]
+    #[inline]
     fn each_value<'a>(&'a self, f: &fn(&'a T) -> bool) -> bool {
         self.each(|_, v| f(v))
     }
 
     /// Iterate over the map and mutate the contained values
-    #[inline(always)]
+    #[inline]
     fn mutate_values(&mut self, f: &fn(&uint, &mut T) -> bool) -> bool {
         self.root.mutate_values(f)
     }
 
     /// Return a reference to the value corresponding to the key
-    #[inline(hint)]
+    #[inline]
     fn find<'a>(&'a self, key: &uint) -> Option<&'a T> {
         let mut node: &'a TrieNode<T> = &self.root;
         let mut idx = 0;
@@ -104,7 +104,7 @@ impl<T> Map<uint, T> for TrieMap<T> {
     }
 
     /// Return a mutable reference to the value corresponding to the key
-    #[inline(always)]
+    #[inline]
     fn find_mut<'a>(&'a mut self, key: &uint) -> Option<&'a mut T> {
         find_mut(&mut self.root.children[chunk(*key, 0)], *key, 1)
     }
@@ -112,14 +112,14 @@ impl<T> Map<uint, T> for TrieMap<T> {
     /// Insert a key-value pair into the map. An existing value for a
     /// key is replaced by the new value. Return true if the key did
     /// not already exist in the map.
-    #[inline(always)]
+    #[inline]
     fn insert(&mut self, key: uint, value: T) -> bool {
         self.swap(key, value).is_none()
     }
 
     /// Remove a key-value pair from the map. Return true if the key
     /// was present in the map, otherwise false.
-    #[inline(always)]
+    #[inline]
     fn remove(&mut self, key: &uint) -> bool {
         self.pop(key).is_some()
     }
@@ -147,25 +147,25 @@ impl<T> Map<uint, T> for TrieMap<T> {
 
 impl<T> TrieMap<T> {
     /// Create an empty TrieMap
-    #[inline(always)]
+    #[inline]
     pub fn new() -> TrieMap<T> {
         TrieMap{root: TrieNode::new(), length: 0}
     }
 
     /// Visit all key-value pairs in reverse order
-    #[inline(always)]
+    #[inline]
     pub fn each_reverse<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) -> bool {
         self.root.each_reverse(f)
     }
 
     /// Visit all keys in reverse order
-    #[inline(always)]
+    #[inline]
     pub fn each_key_reverse(&self, f: &fn(&uint) -> bool) -> bool {
         self.each_reverse(|k, _| f(k))
     }
 
     /// Visit all values in reverse order
-    #[inline(always)]
+    #[inline]
     pub fn each_value_reverse(&self, f: &fn(&T) -> bool) -> bool {
         self.each_reverse(|_, v| f(v))
     }
@@ -178,15 +178,15 @@ pub struct TrieSet {
 
 impl BaseIter<uint> for TrieSet {
     /// Visit all values in order
-    #[inline(always)]
+    #[inline]
     fn each(&self, f: &fn(&uint) -> bool) -> bool { self.map.each_key(f) }
-    #[inline(always)]
+    #[inline]
     fn size_hint(&self) -> Option<uint> { Some(self.len()) }
 }
 
 impl ReverseIter<uint> for TrieSet {
     /// Visit all values in reverse order
-    #[inline(always)]
+    #[inline]
     fn each_reverse(&self, f: &fn(&uint) -> bool) -> bool {
         self.map.each_key_reverse(f)
     }
@@ -194,43 +194,43 @@ impl ReverseIter<uint> for TrieSet {
 
 impl Container for TrieSet {
     /// Return the number of elements in the set
-    #[inline(always)]
+    #[inline]
     fn len(&const self) -> uint { self.map.len() }
 
     /// Return true if the set contains no elements
-    #[inline(always)]
+    #[inline]
     fn is_empty(&const self) -> bool { self.map.is_empty() }
 }
 
 impl Mutable for TrieSet {
     /// Clear the set, removing all values.
-    #[inline(always)]
+    #[inline]
     fn clear(&mut self) { self.map.clear() }
 }
 
 impl TrieSet {
     /// Create an empty TrieSet
-    #[inline(always)]
+    #[inline]
     pub fn new() -> TrieSet {
         TrieSet{map: TrieMap::new()}
     }
 
     /// Return true if the set contains a value
-    #[inline(always)]
+    #[inline]
     pub fn contains(&self, value: &uint) -> bool {
         self.map.contains_key(value)
     }
 
     /// Add a value to the set. Return true if the value was not already
     /// present in the set.
-    #[inline(always)]
+    #[inline]
     pub fn insert(&mut self, value: uint) -> bool {
         self.map.insert(value, ())
     }
 
     /// Remove a value from the set. Return true if the value was
     /// present in the set.
-    #[inline(always)]
+    #[inline]
     pub fn remove(&mut self, value: &uint) -> bool {
         self.map.remove(value)
     }
@@ -242,7 +242,7 @@ struct TrieNode<T> {
 }
 
 impl<T> TrieNode<T> {
-    #[inline(always)]
+    #[inline]
     fn new() -> TrieNode<T> {
         // FIXME: #5244: [Nothing, ..SIZE] should be possible without Copy
         TrieNode{count: 0,
@@ -291,7 +291,7 @@ impl<T> TrieNode<T> {
 }
 
 // if this was done via a trait, the key could be generic
-#[inline(always)]
+#[inline]
 fn chunk(n: uint, idx: uint) -> uint {
     let sh = uint::bits - (SHIFT * (idx + 1));
     (n >> sh) & MASK
diff --git a/src/libstd/tuple.rs b/src/libstd/tuple.rs
index 589c18de0ab..fefd55c3541 100644
--- a/src/libstd/tuple.rs
+++ b/src/libstd/tuple.rs
@@ -29,25 +29,25 @@ pub trait CopyableTuple<T, U> {
 
 impl<T:Copy,U:Copy> CopyableTuple<T, U> for (T, U) {
     /// Return the first element of self
-    #[inline(always)]
+    #[inline]
     fn first(&self) -> T {
         match *self {
-            (t, _) => t,
+            (ref t, _) => copy *t,
         }
     }
 
     /// Return the second element of self
-    #[inline(always)]
+    #[inline]
     fn second(&self) -> U {
         match *self {
-            (_, u) => u,
+            (_, ref u) => copy *u,
         }
     }
 
     /// Return the results of swapping the two elements of self
-    #[inline(always)]
+    #[inline]
     fn swap(&self) -> (U, T) {
-        match *self {
+        match copy *self {
             (t, u) => (u, t),
         }
     }
@@ -63,13 +63,13 @@ pub trait ImmutableTuple<T, U> {
 }
 
 impl<T, U> ImmutableTuple<T, U> for (T, U) {
-    #[inline(always)]
+    #[inline]
     fn first_ref<'a>(&'a self) -> &'a T {
         match *self {
             (ref t, _) => t,
         }
     }
-    #[inline(always)]
+    #[inline]
     fn second_ref<'a>(&'a self) -> &'a U {
         match *self {
             (_, ref u) => u,
@@ -83,7 +83,7 @@ pub trait ExtendedTupleOps<A,B> {
 }
 
 impl<'self,A:Copy,B:Copy> ExtendedTupleOps<A,B> for (&'self [A], &'self [B]) {
-    #[inline(always)]
+    #[inline]
     fn zip(&self) -> ~[(A, B)] {
         match *self {
             (ref a, ref b) => {
@@ -92,7 +92,7 @@ impl<'self,A:Copy,B:Copy> ExtendedTupleOps<A,B> for (&'self [A], &'self [B]) {
         }
     }
 
-    #[inline(always)]
+    #[inline]
     fn map<C>(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C] {
         match *self {
             (ref a, ref b) => {
@@ -103,7 +103,7 @@ impl<'self,A:Copy,B:Copy> ExtendedTupleOps<A,B> for (&'self [A], &'self [B]) {
 }
 
 impl<A:Copy,B:Copy> ExtendedTupleOps<A,B> for (~[A], ~[B]) {
-    #[inline(always)]
+    #[inline]
     fn zip(&self) -> ~[(A, B)] {
         match *self {
             (ref a, ref b) => {
@@ -112,7 +112,7 @@ impl<A:Copy,B:Copy> ExtendedTupleOps<A,B> for (~[A], ~[B]) {
         }
     }
 
-    #[inline(always)]
+    #[inline]
     fn map<C>(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C] {
         match *self {
             (ref a, ref b) => {
@@ -135,6 +135,7 @@ macro_rules! tuple_impls {
         pub mod inner {
             use clone::Clone;
             #[cfg(not(test))] use cmp::*;
+            #[cfg(not(test))] use num::Zero;
 
             $(
                 pub trait $cloneable_trait<$($T),+> {
@@ -143,7 +144,7 @@ macro_rules! tuple_impls {
 
                 impl<$($T:Clone),+> $cloneable_trait<$($T),+> for ($($T),+) {
                     $(
-                        #[inline(always)]
+                        #[inline]
                         fn $get_fn(&self) -> $T {
                             self.$get_ref_fn().clone()
                         }
@@ -156,7 +157,7 @@ macro_rules! tuple_impls {
 
                 impl<$($T),+> $immutable_trait<$($T),+> for ($($T),+) {
                     $(
-                        #[inline(always)]
+                        #[inline]
                         fn $get_ref_fn<'a>(&'a self) -> &'a $T {
                             match *self { $get_pattern => $ret }
                         }
@@ -171,11 +172,11 @@ macro_rules! tuple_impls {
 
                 #[cfg(not(test))]
                 impl<$($T:Eq),+> Eq for ($($T),+) {
-                    #[inline(always)]
+                    #[inline]
                     fn eq(&self, other: &($($T),+)) -> bool {
                         $(*self.$get_ref_fn() == *other.$get_ref_fn())&&+
                     }
-                    #[inline(always)]
+                    #[inline]
                     fn ne(&self, other: &($($T),+)) -> bool {
                         !(*self == *other)
                     }
@@ -183,7 +184,7 @@ macro_rules! tuple_impls {
 
                 #[cfg(not(test))]
                 impl<$($T:TotalEq),+> TotalEq for ($($T),+) {
-                    #[inline(always)]
+                    #[inline]
                     fn equals(&self, other: &($($T),+)) -> bool {
                         $(self.$get_ref_fn().equals(other.$get_ref_fn()))&&+
                     }
@@ -191,15 +192,15 @@ macro_rules! tuple_impls {
 
                 #[cfg(not(test))]
                 impl<$($T:Ord),+> Ord for ($($T),+) {
-                    #[inline(always)]
+                    #[inline]
                     fn lt(&self, other: &($($T),+)) -> bool {
                         lexical_lt!($(self.$get_ref_fn(), other.$get_ref_fn()),+)
                     }
-                    #[inline(always)]
+                    #[inline]
                     fn le(&self, other: &($($T),+)) -> bool { !(*other).lt(&(*self)) }
-                    #[inline(always)]
+                    #[inline]
                     fn ge(&self, other: &($($T),+)) -> bool { !(*self).lt(other) }
-                    #[inline(always)]
+                    #[inline]
                     fn gt(&self, other: &($($T),+)) -> bool { (*other).lt(&(*self)) }
                 }
 
@@ -210,6 +211,18 @@ macro_rules! tuple_impls {
                         lexical_cmp!($(self.$get_ref_fn(), other.$get_ref_fn()),+)
                     }
                 }
+
+                #[cfg(not(test))]
+                impl<$($T:Zero),+> Zero for ($($T),+) {
+                    #[inline]
+                    fn zero() -> ($($T),+) {
+                        ($(Zero::zero::<$T>()),+)
+                    }
+                    #[inline]
+                    fn is_zero(&self) -> bool {
+                        $(self.$get_ref_fn().is_zero())&&+
+                    }
+                }
             )+
         }
     }
diff --git a/src/libstd/unstable/atomics.rs b/src/libstd/unstable/atomics.rs
index aa70897ad48..6e7a7e2b129 100644
--- a/src/libstd/unstable/atomics.rs
+++ b/src/libstd/unstable/atomics.rs
@@ -82,7 +82,7 @@ impl AtomicFlag {
     /**
      * Clears the atomic flag
      */
-    #[inline(always)]
+    #[inline]
     pub fn clear(&mut self, order: Ordering) {
         unsafe {atomic_store(&mut self.v, 0, order)}
     }
@@ -91,7 +91,7 @@ impl AtomicFlag {
      * Sets the flag if it was previously unset, returns the previous value of the
      * flag.
      */
-    #[inline(always)]
+    #[inline]
     pub fn test_and_set(&mut self, order: Ordering) -> bool {
         unsafe {atomic_compare_and_swap(&mut self.v, 0, 1, order) > 0}
     }
@@ -102,26 +102,26 @@ impl AtomicBool {
         AtomicBool { v: if v { 1 } else { 0 } }
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn load(&self, order: Ordering) -> bool {
         unsafe { atomic_load(&self.v, order) > 0 }
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn store(&mut self, val: bool, order: Ordering) {
         let val = if val { 1 } else { 0 };
 
         unsafe { atomic_store(&mut self.v, val, order); }
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn swap(&mut self, val: bool, order: Ordering) -> bool {
         let val = if val { 1 } else { 0 };
 
         unsafe { atomic_swap(&mut self.v, val, order) > 0}
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn compare_and_swap(&mut self, old: bool, new: bool, order: Ordering) -> bool {
         let old = if old { 1 } else { 0 };
         let new = if new { 1 } else { 0 };
@@ -135,34 +135,34 @@ impl AtomicInt {
         AtomicInt { v:v }
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn load(&self, order: Ordering) -> int {
         unsafe { atomic_load(&self.v, order) }
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn store(&mut self, val: int, order: Ordering) {
         unsafe { atomic_store(&mut self.v, val, order); }
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn swap(&mut self, val: int, order: Ordering) -> int {
         unsafe { atomic_swap(&mut self.v, val, order) }
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn compare_and_swap(&mut self, old: int, new: int, order: Ordering) -> int {
         unsafe { atomic_compare_and_swap(&mut self.v, old, new, order) }
     }
 
     /// Returns the old value (like __sync_fetch_and_add).
-    #[inline(always)]
+    #[inline]
     pub fn fetch_add(&mut self, val: int, order: Ordering) -> int {
         unsafe { atomic_add(&mut self.v, val, order) }
     }
 
     /// Returns the old value (like __sync_fetch_and_sub).
-    #[inline(always)]
+    #[inline]
     pub fn fetch_sub(&mut self, val: int, order: Ordering) -> int {
         unsafe { atomic_sub(&mut self.v, val, order) }
     }
@@ -173,34 +173,34 @@ impl AtomicUint {
         AtomicUint { v:v }
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn load(&self, order: Ordering) -> uint {
         unsafe { atomic_load(&self.v, order) }
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn store(&mut self, val: uint, order: Ordering) {
         unsafe { atomic_store(&mut self.v, val, order); }
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn swap(&mut self, val: uint, order: Ordering) -> uint {
         unsafe { atomic_swap(&mut self.v, val, order) }
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn compare_and_swap(&mut self, old: uint, new: uint, order: Ordering) -> uint {
         unsafe { atomic_compare_and_swap(&mut self.v, old, new, order) }
     }
 
     /// Returns the old value (like __sync_fetch_and_add).
-    #[inline(always)]
+    #[inline]
     pub fn fetch_add(&mut self, val: uint, order: Ordering) -> uint {
         unsafe { atomic_add(&mut self.v, val, order) }
     }
 
     /// Returns the old value (like __sync_fetch_and_sub)..
-    #[inline(always)]
+    #[inline]
     pub fn fetch_sub(&mut self, val: uint, order: Ordering) -> uint {
         unsafe { atomic_sub(&mut self.v, val, order) }
     }
@@ -211,22 +211,22 @@ impl<T> AtomicPtr<T> {
         AtomicPtr { p:p }
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn load(&self, order: Ordering) -> *mut T {
         unsafe { atomic_load(&self.p, order) }
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn store(&mut self, ptr: *mut T, order: Ordering) {
         unsafe { atomic_store(&mut self.p, ptr, order); }
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn swap(&mut self, ptr: *mut T, order: Ordering) -> *mut T {
         unsafe { atomic_swap(&mut self.p, ptr, order) }
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn compare_and_swap(&mut self, old: *mut T, new: *mut T, order: Ordering) -> *mut T {
         unsafe { atomic_compare_and_swap(&mut self.p, old, new, order) }
     }
@@ -249,7 +249,7 @@ impl<T> AtomicOption<T> {
         }
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn swap(&mut self, val: ~T, order: Ordering) -> Option<~T> {
         unsafe {
             let val = cast::transmute(val);
@@ -265,7 +265,7 @@ impl<T> AtomicOption<T> {
         }
     }
 
-    #[inline(always)]
+    #[inline]
     pub fn take(&mut self, order: Ordering) -> Option<~T> {
         unsafe {
             self.swap(cast::transmute(0), order)
@@ -286,7 +286,7 @@ impl<T> Drop for AtomicOption<T> {
     }
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe fn atomic_store<T>(dst: &mut T, val: T, order:Ordering) {
     let dst = cast::transmute(dst);
     let val = cast::transmute(val);
@@ -297,7 +297,7 @@ pub unsafe fn atomic_store<T>(dst: &mut T, val: T, order:Ordering) {
     }
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe fn atomic_load<T>(dst: &T, order:Ordering) -> T {
     let dst = cast::transmute(dst);
 
@@ -307,7 +307,7 @@ pub unsafe fn atomic_load<T>(dst: &T, order:Ordering) -> T {
     })
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe fn atomic_swap<T>(dst: &mut T, val: T, order: Ordering) -> T {
     let dst = cast::transmute(dst);
     let val = cast::transmute(val);
@@ -320,7 +320,7 @@ pub unsafe fn atomic_swap<T>(dst: &mut T, val: T, order: Ordering) -> T {
 }
 
 /// Returns the old value (like __sync_fetch_and_add).
-#[inline(always)]
+#[inline]
 pub unsafe fn atomic_add<T>(dst: &mut T, val: T, order: Ordering) -> T {
     let dst = cast::transmute(dst);
     let val = cast::transmute(val);
@@ -333,7 +333,7 @@ pub unsafe fn atomic_add<T>(dst: &mut T, val: T, order: Ordering) -> T {
 }
 
 /// Returns the old value (like __sync_fetch_and_sub).
-#[inline(always)]
+#[inline]
 pub unsafe fn atomic_sub<T>(dst: &mut T, val: T, order: Ordering) -> T {
     let dst = cast::transmute(dst);
     let val = cast::transmute(val);
@@ -345,7 +345,7 @@ pub unsafe fn atomic_sub<T>(dst: &mut T, val: T, order: Ordering) -> T {
     })
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe fn atomic_compare_and_swap<T>(dst:&mut T, old:T, new:T, order: Ordering) -> T {
     let dst = cast::transmute(dst);
     let old = cast::transmute(old);
diff --git a/src/libstd/unstable/dynamic_lib.rs b/src/libstd/unstable/dynamic_lib.rs
index 96aba1d2971..64dd5bba6bc 100644
--- a/src/libstd/unstable/dynamic_lib.rs
+++ b/src/libstd/unstable/dynamic_lib.rs
@@ -15,7 +15,6 @@ Dynamic library facilities.
 A simple wrapper over the platforms dynamic library facilities
 
 */
-use ptr;
 use cast;
 use path;
 use libc;
@@ -42,19 +41,15 @@ impl DynamicLibrary {
     /// Lazily open a dynamic library. When passed None it gives a
     /// handle to the calling process
     pub fn open(filename: Option<&path::Path>) -> Result<DynamicLibrary, ~str> {
-        let open_wrapper = |raw_ptr| {
-            do dl::check_for_errors_in {
-                unsafe {
-                    DynamicLibrary { handle: dl::open(raw_ptr) }
+        do dl::check_for_errors_in {
+            unsafe {
+                DynamicLibrary { handle:
+                    match filename {
+                        Some(name) => dl::open_external(name),
+                        None => dl::open_internal()
+                    }
                 }
             }
-        };
-
-        match filename {
-            Some(name) => do name.to_str().as_c_str |raw_name| {
-                open_wrapper(raw_name)
-            },
-            None => open_wrapper(ptr::null())
         }
     }
 
@@ -74,6 +69,7 @@ impl DynamicLibrary {
 }
 
 #[test]
+#[ignore(cfg(windows))]
 priv fn test_loading_cosine () {
     // The math library does not need to be loaded since it is already
     // statically linked in
@@ -106,13 +102,20 @@ priv fn test_loading_cosine () {
 #[cfg(target_os = "freebsd")]
 mod dl {
     use libc;
+    use path;
     use ptr;
     use str;
     use task;
     use result::*;
 
-    pub unsafe fn open(filename: *libc::c_char) -> *libc::c_void {
-        dlopen(filename, Lazy as libc::c_int)
+    pub unsafe fn open_external(filename: &path::Path) -> *libc::c_void {
+        do filename.to_str().as_c_str |raw_name| {
+            dlopen(raw_name, Lazy as libc::c_int)
+        }
+    }
+
+    pub unsafe fn open_internal() -> *libc::c_void {
+        dlopen(ptr::null(), Lazy as libc::c_int)
     }
 
     pub fn check_for_errors_in<T>(f: &fn()->T) -> Result<T, ~str> {
@@ -159,11 +162,22 @@ mod dl {
 mod dl {
     use os;
     use libc;
+    use path;
+    use ptr;
+    use str;
     use task;
     use result::*;
 
-    pub unsafe fn open(filename: *libc::c_char) -> *libc::c_void {
-        LoadLibrary(filename)
+    pub unsafe fn open_external(filename: &path::Path) -> *libc::c_void {
+        do os::win32::as_utf16_p(filename.to_str()) |raw_name| {
+            LoadLibraryW(raw_name)
+        }
+    }
+
+    pub unsafe fn open_internal() -> *libc::c_void {
+        let mut handle = ptr::null();
+        GetModuleHandleExW(0 as libc::DWORD, ptr::null(), &handle as **libc::c_void);
+        handle
     }
 
     pub fn check_for_errors_in<T>(f: &fn()->T) -> Result<T, ~str> {
@@ -192,7 +206,9 @@ mod dl {
     #[link_name = "kernel32"]
     extern "stdcall" {
         fn SetLastError(error: u32);
-        fn LoadLibrary(name: *libc::c_char) -> *libc::c_void;
+        fn LoadLibraryW(name: *u16) -> *libc::c_void;
+        fn GetModuleHandleExW(dwFlags: libc::DWORD, name: *u16,
+                              handle: **libc::c_void) -> *libc::c_void;
         fn GetProcAddress(handle: *libc::c_void, name: *libc::c_char) -> *libc::c_void;
         fn FreeLibrary(handle: *libc::c_void);
     }
diff --git a/src/libstd/unstable/extfmt.rs b/src/libstd/unstable/extfmt.rs
index 7d9ce585d7c..d466488ce5e 100644
--- a/src/libstd/unstable/extfmt.rs
+++ b/src/libstd/unstable/extfmt.rs
@@ -673,7 +673,7 @@ pub mod rt {
         }
         buf.push_str(s);
     }
-    #[inline(always)]
+    #[inline]
     pub fn have_flag(flags: u32, f: u32) -> bool {
         flags & f != 0
     }
diff --git a/src/libstd/unstable/global.rs b/src/libstd/unstable/global.rs
index 96549a83a8c..f81252274c4 100644
--- a/src/libstd/unstable/global.rs
+++ b/src/libstd/unstable/global.rs
@@ -105,7 +105,7 @@ unsafe fn global_data_modify_<T:Owned>(
                 let dtor: ~fn() = match maybe_dtor {
                     Some(dtor) => dtor,
                     None => {
-                        let dtor: ~fn() = || unsafe {
+                        let dtor: ~fn() = || {
                             let _destroy_value: ~T = transmute(data);
                         };
                         dtor
diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs
index 908c5e23ab0..13425007785 100644
--- a/src/libstd/unstable/intrinsics.rs
+++ b/src/libstd/unstable/intrinsics.rs
@@ -130,36 +130,23 @@ pub extern "rust-intrinsic" {
 
     /// Equivalent to the `llvm.memcpy.p0i8.0i8.i32` intrinsic, with a size of
     /// `count` * `size_of::<T>()` and an alignment of `min_align_of::<T>()`
-    #[cfg(not(stage0))]
     pub fn memcpy32<T>(dst: *mut T, src: *T, count: u32);
     /// Equivalent to the `llvm.memcpy.p0i8.0i8.i64` intrinsic, with a size of
     /// `count` * `size_of::<T>()` and an alignment of `min_align_of::<T>()`
-    #[cfg(not(stage0))]
     pub fn memcpy64<T>(dst: *mut T, src: *T, count: u64);
 
-    /// Equivalent to the `llvm.memmove.p0i8.0i8.i32` intrinsic.
-    #[cfg(stage0)]
-    pub fn memmove32(dst: *mut u8, src: *u8, size: u32);
-    /// Equivalent to the `llvm.memmove.p0i8.0i8.i64` intrinsic.
-    #[cfg(stage0)]
-    pub fn memmove64(dst: *mut u8, src: *u8, size: u64);
-
     /// Equivalent to the `llvm.memmove.p0i8.0i8.i32` intrinsic, with a size of
     /// `count` * `size_of::<T>()` and an alignment of `min_align_of::<T>()`
-    #[cfg(not(stage0))]
     pub fn memmove32<T>(dst: *mut T, src: *T, count: u32);
     /// Equivalent to the `llvm.memmove.p0i8.0i8.i64` intrinsic, with a size of
     /// `count` * `size_of::<T>()` and an alignment of `min_align_of::<T>()`
-    #[cfg(not(stage0))]
     pub fn memmove64<T>(dst: *mut T, src: *T, count: u64);
 
     /// Equivalent to the `llvm.memset.p0i8.i32` intrinsic, with a size of
     /// `count` * `size_of::<T>()` and an alignment of `min_align_of::<T>()`
-    #[cfg(not(stage0))]
     pub fn memset32<T>(dst: *mut T, val: u8, count: u32);
     /// Equivalent to the `llvm.memset.p0i8.i64` intrinsic, with a size of
     /// `count` * `size_of::<T>()` and an alignment of `min_align_of::<T>()`
-    #[cfg(not(stage0))]
     pub fn memset64<T>(dst: *mut T, val: u8, count: u64);
 
     pub fn sqrtf32(x: f32) -> f32;
diff --git a/src/libstd/unstable/lang.rs b/src/libstd/unstable/lang.rs
index 3d61c1fe144..f750b31a466 100644
--- a/src/libstd/unstable/lang.rs
+++ b/src/libstd/unstable/lang.rs
@@ -14,7 +14,6 @@ use iterator::IteratorUtil;
 use uint;
 use cast::transmute;
 use libc::{c_char, c_uchar, c_void, size_t, uintptr_t, c_int, STDERR_FILENO};
-use managed::raw::BoxRepr;
 use str;
 use sys;
 use rt::{context, OldTaskContext};
@@ -23,14 +22,11 @@ use rt::local::Local;
 use option::{Option, Some, None};
 use io;
 use rt::global_heap;
+use rt::borrowck;
 
 #[allow(non_camel_case_types)]
 pub type rust_task = c_void;
 
-pub static FROZEN_BIT: uint = 1 << (uint::bits - 1);
-pub static MUT_BIT: uint = 1 << (uint::bits - 2);
-static ALL_BITS: uint = FROZEN_BIT | MUT_BIT;
-
 pub mod rustrt {
     use unstable::lang::rust_task;
     use libc::{c_void, c_char, uintptr_t};
@@ -47,15 +43,6 @@ pub mod rustrt {
                                               size: uintptr_t)
                                            -> *c_char;
 
-        #[fast_ffi]
-        unsafe fn rust_upcall_free_noswitch(ptr: *c_char);
-
-        #[rust_stack]
-        fn rust_take_task_borrow_list(task: *rust_task) -> *c_void;
-
-        #[rust_stack]
-        fn rust_set_task_borrow_list(task: *rust_task, map: *c_void);
-
         #[rust_stack]
         fn rust_try_get_task() -> *rust_task;
 
@@ -78,161 +65,18 @@ pub fn fail_bounds_check(file: *c_char, line: size_t,
     }
 }
 
-#[deriving(Eq)]
-struct BorrowRecord {
-    box: *mut BoxRepr,
-    file: *c_char,
-    line: size_t
-}
-
-fn try_take_task_borrow_list() -> Option<~[BorrowRecord]> {
-    unsafe {
-        let cur_task: *rust_task = rustrt::rust_try_get_task();
-        if cur_task.is_not_null() {
-            let ptr = rustrt::rust_take_task_borrow_list(cur_task);
-            if ptr.is_null() {
-                None
-            } else {
-                let v: ~[BorrowRecord] = transmute(ptr);
-                Some(v)
-            }
-        } else {
-            None
-        }
-    }
-}
-
-fn swap_task_borrow_list(f: &fn(~[BorrowRecord]) -> ~[BorrowRecord]) {
-    unsafe {
-        let cur_task: *rust_task = rustrt::rust_try_get_task();
-        if cur_task.is_not_null() {
-            let mut borrow_list: ~[BorrowRecord] = {
-                let ptr = rustrt::rust_take_task_borrow_list(cur_task);
-                if ptr.is_null() { ~[] } else { transmute(ptr) }
-            };
-            borrow_list = f(borrow_list);
-            rustrt::rust_set_task_borrow_list(cur_task, transmute(borrow_list));
-        }
-    }
-}
-
-pub unsafe fn clear_task_borrow_list() {
-    // pub because it is used by the box annihilator.
-    let _ = try_take_task_borrow_list();
-}
-
-unsafe fn fail_borrowed(box: *mut BoxRepr, file: *c_char, line: size_t) {
-    debug_borrow("fail_borrowed: ", box, 0, 0, file, line);
-
-    match try_take_task_borrow_list() {
-        None => { // not recording borrows
-            let msg = "borrowed";
-            do str::as_buf(msg) |msg_p, _| {
-                fail_(msg_p as *c_char, file, line);
-            }
-        }
-        Some(borrow_list) => { // recording borrows
-            let mut msg = ~"borrowed";
-            let mut sep = " at ";
-            for borrow_list.rev_iter().advance |entry| {
-                if entry.box == box {
-                    msg.push_str(sep);
-                    let filename = str::raw::from_c_str(entry.file);
-                    msg.push_str(filename);
-                    msg.push_str(fmt!(":%u", entry.line as uint));
-                    sep = " and at ";
-                }
-            }
-            do str::as_buf(msg) |msg_p, _| {
-                fail_(msg_p as *c_char, file, line)
-            }
-        }
-    }
-}
-
 // FIXME #4942: Make these signatures agree with exchange_alloc's signatures
 #[lang="exchange_malloc"]
-#[inline(always)]
+#[inline]
 pub unsafe fn exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
     transmute(global_heap::malloc(transmute(td), transmute(size)))
 }
 
-/// Because this code is so perf. sensitive, use a static constant so that
-/// debug printouts are compiled out most of the time.
-static ENABLE_DEBUG: bool = false;
-
-#[inline]
-unsafe fn debug_borrow<T>(tag: &'static str,
-                          p: *const T,
-                          old_bits: uint,
-                          new_bits: uint,
-                          filename: *c_char,
-                          line: size_t) {
-    //! A useful debugging function that prints a pointer + tag + newline
-    //! without allocating memory.
-
-    if ENABLE_DEBUG && ::rt::env::get().debug_borrow {
-        debug_borrow_slow(tag, p, old_bits, new_bits, filename, line);
-    }
-
-    unsafe fn debug_borrow_slow<T>(tag: &'static str,
-                                   p: *const T,
-                                   old_bits: uint,
-                                   new_bits: uint,
-                                   filename: *c_char,
-                                   line: size_t) {
-        let dbg = STDERR_FILENO as io::fd_t;
-        dbg.write_str(tag);
-        dbg.write_hex(p as uint);
-        dbg.write_str(" ");
-        dbg.write_hex(old_bits);
-        dbg.write_str(" ");
-        dbg.write_hex(new_bits);
-        dbg.write_str(" ");
-        dbg.write_cstr(filename);
-        dbg.write_str(":");
-        dbg.write_hex(line as uint);
-        dbg.write_str("\n");
-    }
-}
-
-trait DebugPrints {
-    fn write_hex(&self, val: uint);
-    unsafe fn write_cstr(&self, str: *c_char);
-}
-
-impl DebugPrints for io::fd_t {
-    fn write_hex(&self, mut i: uint) {
-        let letters = ['0', '1', '2', '3', '4', '5', '6', '7', '8',
-                       '9', 'a', 'b', 'c', 'd', 'e', 'f'];
-        static uint_nibbles: uint = ::uint::bytes << 1;
-        let mut buffer = [0_u8, ..uint_nibbles+1];
-        let mut c = uint_nibbles;
-        while c > 0 {
-            c -= 1;
-            buffer[c] = letters[i & 0xF] as u8;
-            i >>= 4;
-        }
-        self.write(buffer.slice(0, uint_nibbles));
-    }
-
-    unsafe fn write_cstr(&self, p: *c_char) {
-        use libc::strlen;
-        use vec;
-
-        let len = strlen(p);
-        let p: *u8 = transmute(p);
-        do vec::raw::buf_as_slice(p, len as uint) |s| {
-            self.write(s);
-        }
-    }
-}
-
 // NB: Calls to free CANNOT be allowed to fail, as throwing an exception from
 // inside a landing pad may corrupt the state of the exception handler. If a
 // problem occurs, call exit instead.
 #[lang="exchange_free"]
-#[inline(always)]
+#[inline]
 pub unsafe fn exchange_free(ptr: *c_char) {
     global_heap::free(transmute(ptr))
 }
@@ -258,138 +102,63 @@ pub unsafe fn local_malloc(td: *c_char, size: uintptr_t) -> *c_char {
 // problem occurs, call exit instead.
 #[lang="free"]
 pub unsafe fn local_free(ptr: *c_char) {
-    match context() {
-        OldTaskContext => {
-            rustrt::rust_upcall_free_noswitch(ptr);
-        }
-        _ => {
-            do Local::borrow::<Task,()> |task| {
-                task.heap.free(ptr as *c_void);
-            }
-        }
-    }
+    ::rt::local_heap::local_free(ptr);
 }
 
 #[lang="borrow_as_imm"]
-#[inline(always)]
+#[inline]
 pub unsafe fn borrow_as_imm(a: *u8, file: *c_char, line: size_t) -> uint {
-    let a: *mut BoxRepr = transmute(a);
-    let old_ref_count = (*a).header.ref_count;
-    let new_ref_count = old_ref_count | FROZEN_BIT;
-
-    debug_borrow("borrow_as_imm:", a, old_ref_count, new_ref_count, file, line);
-
-    if (old_ref_count & MUT_BIT) != 0 {
-        fail_borrowed(a, file, line);
-    }
-
-    (*a).header.ref_count = new_ref_count;
-
-    old_ref_count
+    borrowck::borrow_as_imm(a, file, line)
 }
 
 #[lang="borrow_as_mut"]
-#[inline(always)]
+#[inline]
 pub unsafe fn borrow_as_mut(a: *u8, file: *c_char, line: size_t) -> uint {
-    let a: *mut BoxRepr = transmute(a);
-    let old_ref_count = (*a).header.ref_count;
-    let new_ref_count = old_ref_count | MUT_BIT | FROZEN_BIT;
-
-    debug_borrow("borrow_as_mut:", a, old_ref_count, new_ref_count, file, line);
-
-    if (old_ref_count & (MUT_BIT|FROZEN_BIT)) != 0 {
-        fail_borrowed(a, file, line);
-    }
-
-    (*a).header.ref_count = new_ref_count;
-
-    old_ref_count
+    borrowck::borrow_as_mut(a, file, line)
 }
 
-
 #[lang="record_borrow"]
 pub unsafe fn record_borrow(a: *u8, old_ref_count: uint,
                             file: *c_char, line: size_t) {
-    if (old_ref_count & ALL_BITS) == 0 {
-        // was not borrowed before
-        let a: *mut BoxRepr = transmute(a);
-        debug_borrow("record_borrow:", a, old_ref_count, 0, file, line);
-        do swap_task_borrow_list |borrow_list| {
-            let mut borrow_list = borrow_list;
-            borrow_list.push(BorrowRecord {box: a, file: file, line: line});
-            borrow_list
-        }
-    }
+    borrowck::record_borrow(a, old_ref_count, file, line)
 }
 
 #[lang="unrecord_borrow"]
 pub unsafe fn unrecord_borrow(a: *u8, old_ref_count: uint,
                               file: *c_char, line: size_t) {
-    if (old_ref_count & ALL_BITS) == 0 {
-        // was not borrowed before, so we should find the record at
-        // the end of the list
-        let a: *mut BoxRepr = transmute(a);
-        debug_borrow("unrecord_borrow:", a, old_ref_count, 0, file, line);
-        do swap_task_borrow_list |borrow_list| {
-            let mut borrow_list = borrow_list;
-            assert!(!borrow_list.is_empty());
-            let br = borrow_list.pop();
-            if br.box != a || br.file != file || br.line != line {
-                let err = fmt!("wrong borrow found, br=%?", br);
-                do str::as_buf(err) |msg_p, _| {
-                    fail_(msg_p as *c_char, file, line)
-                }
-            }
-            borrow_list
-        }
-    }
+    borrowck::unrecord_borrow(a, old_ref_count, file, line)
 }
 
 #[lang="return_to_mut"]
-#[inline(always)]
+#[inline]
 pub unsafe fn return_to_mut(a: *u8, orig_ref_count: uint,
                             file: *c_char, line: size_t) {
-    // Sometimes the box is null, if it is conditionally frozen.
-    // See e.g. #4904.
-    if !a.is_null() {
-        let a: *mut BoxRepr = transmute(a);
-        let old_ref_count = (*a).header.ref_count;
-        let new_ref_count =
-            (old_ref_count & !ALL_BITS) | (orig_ref_count & ALL_BITS);
-
-        debug_borrow("return_to_mut:",
-                     a, old_ref_count, new_ref_count, file, line);
-
-        (*a).header.ref_count = new_ref_count;
-    }
+    borrowck::return_to_mut(a, orig_ref_count, file, line)
 }
 
 #[lang="check_not_borrowed"]
-#[inline(always)]
+#[inline]
 pub unsafe fn check_not_borrowed(a: *u8,
                                  file: *c_char,
                                  line: size_t) {
-    let a: *mut BoxRepr = transmute(a);
-    let ref_count = (*a).header.ref_count;
-    debug_borrow("check_not_borrowed:", a, ref_count, 0, file, line);
-    if (ref_count & FROZEN_BIT) != 0 {
-        fail_borrowed(a, file, line);
-    }
+    borrowck::check_not_borrowed(a, file, line)
 }
 
 #[lang="strdup_uniq"]
-#[inline(always)]
+#[inline]
 pub unsafe fn strdup_uniq(ptr: *c_uchar, len: uint) -> ~str {
     str::raw::from_buf_len(ptr, len)
 }
 
+#[lang="annihilate"]
+pub unsafe fn annihilate() {
+    ::cleanup::annihilate()
+}
+
 #[lang="start"]
 pub fn start(main: *u8, argc: int, argv: **c_char,
              crate_map: *u8) -> int {
     use rt;
-    use sys::Closure;
-    use ptr;
-    use cast;
     use os;
 
     unsafe {
@@ -399,17 +168,8 @@ pub fn start(main: *u8, argc: int, argv: **c_char,
                               crate_map as *c_void) as int;
         } else {
             return do rt::start(argc, argv as **u8, crate_map) {
-                unsafe {
-                    // `main` is an `fn() -> ()` that doesn't take an environment
-                    // XXX: Could also call this as an `extern "Rust" fn` once they work
-                    let main = Closure {
-                        code: main as *(),
-                        env: ptr::null(),
-                    };
-                    let mainfn: &fn() = cast::transmute(main);
-
-                    mainfn();
-                }
+                let main: extern "Rust" fn() = transmute(main);
+                main();
             };
         }
     }
diff --git a/src/libstd/unstable/mod.rs b/src/libstd/unstable/mod.rs
index ae878050142..0a46ef619af 100644
--- a/src/libstd/unstable/mod.rs
+++ b/src/libstd/unstable/mod.rs
@@ -18,11 +18,6 @@ use task;
 
 pub mod at_exit;
 
-// Currently only works for *NIXes
-#[cfg(target_os = "linux")]
-#[cfg(target_os = "android")]
-#[cfg(target_os = "macos")]
-#[cfg(target_os = "freebsd")]
 pub mod dynamic_lib;
 
 pub mod global;
diff --git a/src/libstd/unstable/sync.rs b/src/libstd/unstable/sync.rs
index 3cf46bec41a..162891124f6 100644
--- a/src/libstd/unstable/sync.rs
+++ b/src/libstd/unstable/sync.rs
@@ -40,7 +40,7 @@ impl<T: Owned> UnsafeAtomicRcBox<T> {
         }
     }
 
-    #[inline(always)]
+    #[inline]
     pub unsafe fn get(&self) -> *mut T
     {
         let mut data: ~AtomicRcBoxData<T> = cast::transmute(self.data);
@@ -50,7 +50,7 @@ impl<T: Owned> UnsafeAtomicRcBox<T> {
         return r;
     }
 
-    #[inline(always)]
+    #[inline]
     pub unsafe fn get_immut(&self) -> *T
     {
         let mut data: ~AtomicRcBoxData<T> = cast::transmute(self.data);
@@ -118,7 +118,7 @@ fn LittleLock() -> LittleLock {
 }
 
 impl LittleLock {
-    #[inline(always)]
+    #[inline]
     pub unsafe fn lock<T>(&self, f: &fn() -> T) -> T {
         do atomically {
             rust_lock_little_lock(self.l);
@@ -169,7 +169,7 @@ impl<T:Owned> Exclusive<T> {
     // Currently, scheduling operations (i.e., yielding, receiving on a pipe,
     // accessing the provided condition variable) are prohibited while inside
     // the exclusive. Supporting that is a work in progress.
-    #[inline(always)]
+    #[inline]
     pub unsafe fn with<U>(&self, f: &fn(x: &mut T) -> U) -> U {
         let rec = self.x.get();
         do (*rec).lock.lock {
@@ -183,7 +183,7 @@ impl<T:Owned> Exclusive<T> {
         }
     }
 
-    #[inline(always)]
+    #[inline]
     pub unsafe fn with_imm<U>(&self, f: &fn(x: &T) -> U) -> U {
         do self.with |x| {
             f(cast::transmute_immut(x))
diff --git a/src/libstd/util.rs b/src/libstd/util.rs
index 61c284f580c..2a5d44c9ce2 100644
--- a/src/libstd/util.rs
+++ b/src/libstd/util.rs
@@ -16,11 +16,11 @@ use prelude::*;
 use unstable::intrinsics;
 
 /// The identity function.
-#[inline(always)]
+#[inline]
 pub fn id<T>(x: T) -> T { x }
 
 /// Ignores a value.
-#[inline(always)]
+#[inline]
 pub fn ignore<T>(_x: T) { }
 
 /// Sets `*ptr` to `new_value`, invokes `op()`, and then restores the
@@ -30,7 +30,7 @@ pub fn ignore<T>(_x: T) { }
 /// an obvious borrowck hazard. Typically passing in `&mut T` will
 /// cause borrow check errors because it freezes whatever location
 /// that `&mut T` is stored in (either statically or dynamically).
-#[inline(always)]
+#[inline]
 pub fn with<T,R>(
     ptr: @mut T,
     value: T,
@@ -46,7 +46,7 @@ pub fn with<T,R>(
  * Swap the values at two mutable locations of the same type, without
  * deinitialising or copying either one.
  */
-#[inline(always)]
+#[inline]
 pub fn swap<T>(x: &mut T, y: &mut T) {
     unsafe {
         // Give ourselves some scratch space to work with
@@ -68,7 +68,7 @@ pub fn swap<T>(x: &mut T, y: &mut T) {
  * Replace the value at a mutable location with a new one, returning the old
  * value, without deinitialising or copying either one.
  */
-#[inline(always)]
+#[inline]
 pub fn replace<T>(dest: &mut T, mut src: T) -> T {
     swap(dest, &mut src);
     src
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
index 211ee12c291..4339153c43e 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -19,10 +19,11 @@ use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater};
 use clone::Clone;
 use old_iter::BaseIter;
 use old_iter;
-use iterator::{Iterator, IteratorUtil};
+use iterator::{Iterator};
 use iter::FromIter;
 use kinds::Copy;
 use libc;
+use num::Zero;
 use old_iter::CopyableIter;
 use option::{None, Option, Some};
 use ptr::to_unsafe_ptr;
@@ -47,12 +48,8 @@ pub mod rustrt {
         // to ~[] and reserve_shared_actual applies to @[].
         #[fast_ffi]
         unsafe fn vec_reserve_shared(t: *sys::TypeDesc,
-                                     v: **raw::VecRepr,
+                                     v: *mut *mut raw::VecRepr,
                                      n: libc::size_t);
-        #[fast_ffi]
-        unsafe fn vec_reserve_shared_actual(t: *sys::TypeDesc,
-                                            v: **raw::VecRepr,
-                                            n: libc::size_t);
     }
 }
 
@@ -78,11 +75,11 @@ pub fn reserve<T>(v: &mut ~[T], n: uint) {
     use managed;
     if capacity(v) < n {
         unsafe {
-            let ptr: **raw::VecRepr = cast::transmute(v);
+            let ptr: *mut *mut raw::VecRepr = cast::transmute(v);
             let td = sys::get_type_desc::<T>();
             if ((**ptr).box_header.ref_count ==
                 managed::raw::RC_MANAGED_UNIQUE) {
-                rustrt::vec_reserve_shared_actual(td, ptr, n as libc::size_t);
+                ::at_vec::raw::reserve_raw(td, ptr, n);
             } else {
                 rustrt::vec_reserve_shared(td, ptr, n as libc::size_t);
             }
@@ -110,7 +107,7 @@ pub fn reserve_at_least<T>(v: &mut ~[T], n: uint) {
 }
 
 /// Returns the number of elements the vector can hold without reallocating
-#[inline(always)]
+#[inline]
 pub fn capacity<T>(v: &const ~[T]) -> uint {
     unsafe {
         let repr: **raw::VecRepr = transmute(v);
@@ -118,15 +115,6 @@ pub fn capacity<T>(v: &const ~[T]) -> uint {
     }
 }
 
-// A botch to tide us over until core and std are fully demuted.
-#[allow(missing_doc)]
-pub fn uniq_len<T>(v: &const ~[T]) -> uint {
-    unsafe {
-        let v: &~[T] = transmute(v);
-        as_const_buf(*v, |_p, len| len)
-    }
-}
-
 /**
  * Creates and initializes an owned vector.
  *
@@ -155,8 +143,10 @@ pub fn from_fn<T>(n_elts: uint, op: old_iter::InitOp<T>) -> ~[T] {
  * to the value `t`.
  */
 pub fn from_elem<T:Copy>(n_elts: uint, t: T) -> ~[T] {
-    // hack: manually inline from_fn for 2x plus speedup (sadly very important, from_elem is a
-    // bottleneck in borrowck!)
+    // FIXME (#7136): manually inline from_fn for 2x plus speedup (sadly very
+    // important, from_elem is a bottleneck in borrowck!). Unfortunately it
+    // still is substantially slower than using the unsafe
+    // vec::with_capacity/ptr::set_memory for primitive types.
     unsafe {
         let mut v = with_capacity(n_elts);
         do as_mut_buf(v) |p, _len| {
@@ -173,7 +163,7 @@ pub fn from_elem<T:Copy>(n_elts: uint, t: T) -> ~[T] {
 
 /// Creates a new unique vector with the same contents as the slice
 pub fn to_owned<T:Copy>(t: &[T]) -> ~[T] {
-    from_fn(t.len(), |i| t[i])
+    from_fn(t.len(), |i| copy t[i])
 }
 
 /// Creates a new vector with a capacity of `capacity`
@@ -195,7 +185,7 @@ pub fn with_capacity<T>(capacity: uint) -> ~[T] {
  *             as an argument a function that will push an element
  *             onto the vector being constructed.
  */
-#[inline(always)]
+#[inline]
 pub fn build_sized<A>(size: uint, builder: &fn(push: &fn(v: A))) -> ~[A] {
     let mut vec = with_capacity(size);
     builder(|x| vec.push(x));
@@ -212,7 +202,7 @@ pub fn build_sized<A>(size: uint, builder: &fn(push: &fn(v: A))) -> ~[A] {
  *             as an argument a function that will push an element
  *             onto the vector being constructed.
  */
-#[inline(always)]
+#[inline]
 pub fn build<A>(builder: &fn(push: &fn(v: A))) -> ~[A] {
     build_sized(4, builder)
 }
@@ -229,7 +219,7 @@ pub fn build<A>(builder: &fn(push: &fn(v: A))) -> ~[A] {
  *             as an argument a function that will push an element
  *             onto the vector being constructed.
  */
-#[inline(always)]
+#[inline]
 pub fn build_sized_opt<A>(size: Option<uint>,
                           builder: &fn(push: &fn(v: A)))
                        -> ~[A] {
@@ -277,7 +267,7 @@ pub fn last_opt<'r,T>(v: &'r [T]) -> Option<&'r T> {
 }
 
 /// Return a slice that points into another slice.
-#[inline(always)]
+#[inline]
 pub fn slice<'r,T>(v: &'r [T], start: uint, end: uint) -> &'r [T] {
     assert!(start <= end);
     assert!(end <= v.len());
@@ -290,7 +280,7 @@ pub fn slice<'r,T>(v: &'r [T], start: uint, end: uint) -> &'r [T] {
 }
 
 /// Return a slice that points into another slice.
-#[inline(always)]
+#[inline]
 pub fn mut_slice<'r,T>(v: &'r mut [T], start: uint, end: uint)
                     -> &'r mut [T] {
     assert!(start <= end);
@@ -304,7 +294,7 @@ pub fn mut_slice<'r,T>(v: &'r mut [T], start: uint, end: uint)
 }
 
 /// Return a slice that points into another slice.
-#[inline(always)]
+#[inline]
 pub fn const_slice<'r,T>(v: &'r const [T], start: uint, end: uint)
                       -> &'r const [T] {
     assert!(start <= end);
@@ -447,9 +437,9 @@ pub fn partitioned<T:Copy>(v: &[T], f: &fn(&T) -> bool) -> (~[T], ~[T]) {
 
     for each(v) |elt| {
         if f(elt) {
-            lefts.push(*elt);
+            lefts.push(copy *elt);
         } else {
-            rights.push(*elt);
+            rights.push(copy *elt);
         }
     }
 
@@ -639,7 +629,7 @@ pub fn swap_remove<T>(v: &mut ~[T], index: uint) -> T {
 }
 
 /// Append an element to a vector
-#[inline(always)]
+#[inline]
 pub fn push<T>(v: &mut ~[T], initval: T) {
     unsafe {
         let repr: **raw::VecRepr = transmute(&mut *v);
@@ -654,7 +644,7 @@ pub fn push<T>(v: &mut ~[T], initval: T) {
 }
 
 // This doesn't bother to make sure we have space.
-#[inline(always)] // really pretty please
+#[inline] // really pretty please
 unsafe fn push_fast<T>(v: &mut ~[T], initval: T) {
     let repr: **mut raw::VecRepr = transmute(v);
     let fill = (**repr).unboxed.fill;
@@ -681,7 +671,7 @@ fn push_slow<T>(v: &mut ~[T], initval: T) {
 /// vec::push_all(&mut a, [2, 3, 4]);
 /// assert!(a == ~[1, 2, 3, 4]);
 /// ~~~
-#[inline(always)]
+#[inline]
 pub fn push_all<T:Copy>(v: &mut ~[T], rhs: &const [T]) {
     let new_len = v.len() + rhs.len();
     reserve(&mut *v, new_len);
@@ -702,7 +692,7 @@ pub fn push_all<T:Copy>(v: &mut ~[T], rhs: &const [T]) {
 /// vec::push_all_move(&mut a, ~[~2, ~3, ~4]);
 /// assert!(a == ~[~1, ~2, ~3, ~4]);
 /// ~~~
-#[inline(always)]
+#[inline]
 pub fn push_all_move<T>(v: &mut ~[T], mut rhs: ~[T]) {
     let new_len = v.len() + rhs.len();
     reserve(&mut *v, new_len);
@@ -773,7 +763,7 @@ pub fn dedup<T:Eq>(v: &mut ~[T]) {
 
 /// Iterates over the `rhs` vector, copying each element and appending it to the
 /// `lhs`. Afterwards, the `lhs` is then returned for use again.
-#[inline(always)]
+#[inline]
 pub fn append<T:Copy>(lhs: ~[T], rhs: &const [T]) -> ~[T] {
     let mut v = lhs;
     v.push_all(rhs);
@@ -782,7 +772,7 @@ pub fn append<T:Copy>(lhs: ~[T], rhs: &const [T]) -> ~[T] {
 
 /// Appends one element to the vector provided. The vector itself is then
 /// returned for use again.
-#[inline(always)]
+#[inline]
 pub fn append_one<T>(lhs: ~[T], x: T) -> ~[T] {
     let mut v = lhs;
     v.push(x);
@@ -804,7 +794,7 @@ pub fn grow<T:Copy>(v: &mut ~[T], n: uint, initval: &T) {
     let mut i: uint = 0u;
 
     while i < n {
-        v.push(*initval);
+        v.push(copy *initval);
         i += 1u;
     }
 }
@@ -976,7 +966,7 @@ pub fn filter<T>(v: ~[T], f: &fn(t: &T) -> bool) -> ~[T] {
 pub fn filtered<T:Copy>(v: &[T], f: &fn(t: &T) -> bool) -> ~[T] {
     let mut result = ~[];
     for each(v) |elem| {
-        if f(elem) { result.push(*elem); }
+        if f(elem) { result.push(copy *elem); }
     }
     result
 }
@@ -1032,7 +1022,7 @@ impl<'self, T:Copy> VectorVector<T> for &'self [~[T]] {
         let mut r = ~[];
         let mut first = true;
         for self.each |&inner| {
-            if first { first = false; } else { r.push(*sep); }
+            if first { first = false; } else { r.push(copy *sep); }
             r.push_all(inner);
         }
         r
@@ -1050,7 +1040,7 @@ impl<'self, T:Copy> VectorVector<T> for &'self [&'self [T]] {
         let mut r = ~[];
         let mut first = true;
         for self.each |&inner| {
-            if first { first = false; } else { r.push(*sep); }
+            if first { first = false; } else { r.push(copy *sep); }
             r.push_all(inner);
         }
         r
@@ -1083,7 +1073,7 @@ pub fn find<T:Copy>(v: &[T], f: &fn(t: &T) -> bool) -> Option<T> {
  */
 pub fn find_between<T:Copy>(v: &[T], start: uint, end: uint,
                       f: &fn(t: &T) -> bool) -> Option<T> {
-    position_between(v, start, end, f).map(|i| v[*i])
+    position_between(v, start, end, f).map(|i| copy v[*i])
 }
 
 /**
@@ -1109,7 +1099,7 @@ pub fn rfind_between<T:Copy>(v: &[T],
                              end: uint,
                              f: &fn(t: &T) -> bool)
                           -> Option<T> {
-    rposition_between(v, start, end, f).map(|i| v[*i])
+    rposition_between(v, start, end, f).map(|i| copy v[*i])
 }
 
 /// Find the first index containing a matching value
@@ -1233,7 +1223,7 @@ pub fn bsearch_elem<T:TotalOrd>(v: &[T], x: &T) -> Option<uint> {
 pub fn unzip_slice<T:Copy,U:Copy>(v: &[(T, U)]) -> (~[T], ~[U]) {
     let mut (ts, us) = (~[], ~[]);
     for each(v) |p| {
-        let (t, u) = *p;
+        let (t, u) = copy *p;
         ts.push(t);
         us.push(u);
     }
@@ -1268,7 +1258,7 @@ pub fn zip_slice<T:Copy,U:Copy>(v: &const [T], u: &const [U])
     let mut i = 0u;
     assert_eq!(sz, u.len());
     while i < sz {
-        zipped.push((v[i], u[i]));
+        zipped.push((copy v[i], copy u[i]));
         i += 1u;
     }
     zipped
@@ -1301,7 +1291,7 @@ pub fn zip<T, U>(mut v: ~[T], mut u: ~[U]) -> ~[(T, U)] {
  * * a - The index of the first element
  * * b - The index of the second element
  */
-#[inline(always)]
+#[inline]
 pub fn swap<T>(v: &mut [T], a: uint, b: uint) {
     unsafe {
         // Can't take two mutable loans from one vector, so instead just cast
@@ -1365,8 +1355,8 @@ pub fn reversed<T:Copy>(v: &const [T]) -> ~[T] {
     let mut rs: ~[T] = ~[];
     let mut i = v.len();
     if i == 0 { return (rs); } else { i -= 1; }
-    while i != 0 { rs.push(v[i]); i -= 1; }
-    rs.push(v[0]);
+    while i != 0 { rs.push(copy v[i]); i -= 1; }
+    rs.push(copy v[0]);
     rs
 }
 
@@ -1409,7 +1399,7 @@ pub fn reversed<T:Copy>(v: &const [T]) -> ~[T] {
  * }
  * ~~~
  */
-#[inline(always)]
+#[inline]
 pub fn each<'r,T>(v: &'r [T], f: &fn(&'r T) -> bool) -> bool {
     //            ^^^^
     // NB---this CANNOT be &const [T]!  The reason
@@ -1435,7 +1425,7 @@ pub fn each<'r,T>(v: &'r [T], f: &fn(&'r T) -> bool) -> bool {
 
 /// Like `each()`, but for the case where you have a vector that *may or may
 /// not* have mutable contents.
-#[inline(always)]
+#[inline]
 pub fn each_const<T>(v: &const [T], f: &fn(elem: &const T) -> bool) -> bool {
     let mut i = 0;
     let n = v.len();
@@ -1453,7 +1443,7 @@ pub fn each_const<T>(v: &const [T], f: &fn(elem: &const T) -> bool) -> bool {
  *
  * Return true to continue, false to break.
  */
-#[inline(always)]
+#[inline]
 pub fn eachi<'r,T>(v: &'r [T], f: &fn(uint, v: &'r T) -> bool) -> bool {
     let mut i = 0;
     for each(v) |p| {
@@ -1485,7 +1475,7 @@ pub fn eachi<'r,T>(v: &'r [T], f: &fn(uint, v: &'r T) -> bool) -> bool {
  */
 pub fn each_permutation<T:Copy>(values: &[T], fun: &fn(perm : &[T]) -> bool) -> bool {
     let length = values.len();
-    let mut permutation = vec::from_fn(length, |i| values[i]);
+    let mut permutation = vec::from_fn(length, |i| copy values[i]);
     if length <= 1 {
         fun(permutation);
         return true;
@@ -1512,7 +1502,7 @@ pub fn each_permutation<T:Copy>(values: &[T], fun: &fn(perm : &[T]) -> bool) ->
         reverse_part(indices, k+1, length);
         // fixup permutation based on indices
         for uint::range(k, length) |i| {
-            permutation[i] = values[indices[i]];
+            permutation[i] = copy values[indices[i]];
         }
     }
 }
@@ -1546,7 +1536,7 @@ pub fn windowed<'r, T>(n: uint, v: &'r [T], it: &fn(&'r [T]) -> bool) -> bool {
  * Allows for unsafe manipulation of vector contents, which is useful for
  * foreign interop.
  */
-#[inline(always)]
+#[inline]
 pub fn as_imm_buf<T,U>(s: &[T],
                        /* NB---this CANNOT be const, see below */
                        f: &fn(*T, uint) -> U) -> U {
@@ -1565,7 +1555,7 @@ pub fn as_imm_buf<T,U>(s: &[T],
 }
 
 /// Similar to `as_imm_buf` but passing a `*const T`
-#[inline(always)]
+#[inline]
 pub fn as_const_buf<T,U>(s: &const [T], f: &fn(*const T, uint) -> U) -> U {
     unsafe {
         let v : *(*const T,uint) = transmute(&s);
@@ -1575,7 +1565,7 @@ pub fn as_const_buf<T,U>(s: &const [T], f: &fn(*const T, uint) -> U) -> U {
 }
 
 /// Similar to `as_imm_buf` but passing a `*mut T`
-#[inline(always)]
+#[inline]
 pub fn as_mut_buf<T,U>(s: &mut [T], f: &fn(*mut T, uint) -> U) -> U {
     unsafe {
         let v : *(*mut T,uint) = transmute(&s);
@@ -1618,49 +1608,49 @@ fn equals<T: TotalEq>(a: &[T], b: &[T]) -> bool {
 
 #[cfg(not(test))]
 impl<'self,T:Eq> Eq for &'self [T] {
-    #[inline(always)]
+    #[inline]
     fn eq(&self, other: & &'self [T]) -> bool { eq(*self, *other) }
-    #[inline(always)]
+    #[inline]
     fn ne(&self, other: & &'self [T]) -> bool { !self.eq(other) }
 }
 
 #[cfg(not(test))]
 impl<T:Eq> Eq for ~[T] {
-    #[inline(always)]
+    #[inline]
     fn eq(&self, other: &~[T]) -> bool { eq(*self, *other) }
-    #[inline(always)]
+    #[inline]
     fn ne(&self, other: &~[T]) -> bool { !self.eq(other) }
 }
 
 #[cfg(not(test))]
 impl<T:Eq> Eq for @[T] {
-    #[inline(always)]
+    #[inline]
     fn eq(&self, other: &@[T]) -> bool { eq(*self, *other) }
-    #[inline(always)]
+    #[inline]
     fn ne(&self, other: &@[T]) -> bool { !self.eq(other) }
 }
 
 #[cfg(not(test))]
 impl<'self,T:TotalEq> TotalEq for &'self [T] {
-    #[inline(always)]
+    #[inline]
     fn equals(&self, other: & &'self [T]) -> bool { equals(*self, *other) }
 }
 
 #[cfg(not(test))]
 impl<T:TotalEq> TotalEq for ~[T] {
-    #[inline(always)]
+    #[inline]
     fn equals(&self, other: &~[T]) -> bool { equals(*self, *other) }
 }
 
 #[cfg(not(test))]
 impl<T:TotalEq> TotalEq for @[T] {
-    #[inline(always)]
+    #[inline]
     fn equals(&self, other: &@[T]) -> bool { equals(*self, *other) }
 }
 
 #[cfg(not(test))]
 impl<'self,T:Eq> Equiv<~[T]> for &'self [T] {
-    #[inline(always)]
+    #[inline]
     fn equiv(&self, other: &~[T]) -> bool { eq(*self, *other) }
 }
 
@@ -1682,19 +1672,19 @@ fn cmp<T: TotalOrd>(a: &[T], b: &[T]) -> Ordering {
 
 #[cfg(not(test))]
 impl<'self,T:TotalOrd> TotalOrd for &'self [T] {
-    #[inline(always)]
+    #[inline]
     fn cmp(&self, other: & &'self [T]) -> Ordering { cmp(*self, *other) }
 }
 
 #[cfg(not(test))]
 impl<T: TotalOrd> TotalOrd for ~[T] {
-    #[inline(always)]
+    #[inline]
     fn cmp(&self, other: &~[T]) -> Ordering { cmp(*self, *other) }
 }
 
 #[cfg(not(test))]
 impl<T: TotalOrd> TotalOrd for @[T] {
-    #[inline(always)]
+    #[inline]
     fn cmp(&self, other: &@[T]) -> Ordering { cmp(*self, *other) }
 }
 
@@ -1719,37 +1709,37 @@ fn gt<T:Ord>(a: &[T], b: &[T]) -> bool { lt(b, a)  }
 
 #[cfg(not(test))]
 impl<'self,T:Ord> Ord for &'self [T] {
-    #[inline(always)]
+    #[inline]
     fn lt(&self, other: & &'self [T]) -> bool { lt((*self), (*other)) }
-    #[inline(always)]
+    #[inline]
     fn le(&self, other: & &'self [T]) -> bool { le((*self), (*other)) }
-    #[inline(always)]
+    #[inline]
     fn ge(&self, other: & &'self [T]) -> bool { ge((*self), (*other)) }
-    #[inline(always)]
+    #[inline]
     fn gt(&self, other: & &'self [T]) -> bool { gt((*self), (*other)) }
 }
 
 #[cfg(not(test))]
 impl<T:Ord> Ord for ~[T] {
-    #[inline(always)]
+    #[inline]
     fn lt(&self, other: &~[T]) -> bool { lt((*self), (*other)) }
-    #[inline(always)]
+    #[inline]
     fn le(&self, other: &~[T]) -> bool { le((*self), (*other)) }
-    #[inline(always)]
+    #[inline]
     fn ge(&self, other: &~[T]) -> bool { ge((*self), (*other)) }
-    #[inline(always)]
+    #[inline]
     fn gt(&self, other: &~[T]) -> bool { gt((*self), (*other)) }
 }
 
 #[cfg(not(test))]
 impl<T:Ord> Ord for @[T] {
-    #[inline(always)]
+    #[inline]
     fn lt(&self, other: &@[T]) -> bool { lt((*self), (*other)) }
-    #[inline(always)]
+    #[inline]
     fn le(&self, other: &@[T]) -> bool { le((*self), (*other)) }
-    #[inline(always)]
+    #[inline]
     fn ge(&self, other: &@[T]) -> bool { ge((*self), (*other)) }
-    #[inline(always)]
+    #[inline]
     fn gt(&self, other: &@[T]) -> bool { gt((*self), (*other)) }
 }
 
@@ -1760,26 +1750,39 @@ pub mod traits {
     use vec::append;
 
     impl<'self,T:Copy> Add<&'self const [T],~[T]> for ~[T] {
-        #[inline(always)]
+        #[inline]
         fn add(&self, rhs: & &'self const [T]) -> ~[T] {
             append(copy *self, (*rhs))
         }
     }
 }
 
-impl<'self,T> Container for &'self const [T] {
+impl<'self, T> Container for &'self const [T] {
     /// Returns true if a vector contains no elements
     #[inline]
-    fn is_empty(&const self) -> bool {
+    fn is_empty(&self) -> bool {
         as_const_buf(*self, |_p, len| len == 0u)
     }
 
     /// Returns the length of a vector
     #[inline]
-    fn len(&const self) -> uint {
+    fn len(&self) -> uint {
         as_const_buf(*self, |_p, len| len)
     }
+}
 
+impl<T> Container for ~[T] {
+    /// Returns true if a vector contains no elements
+    #[inline]
+    fn is_empty(&self) -> bool {
+        as_const_buf(*self, |_p, len| len == 0u)
+    }
+
+    /// Returns the length of a vector
+    #[inline]
+    fn len(&self) -> uint {
+        as_const_buf(*self, |_p, len| len)
+    }
 }
 
 #[allow(missing_doc)]
@@ -1951,7 +1954,7 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
 
     /// Returns a pointer to the element at the given index, without doing
     /// bounds checking.
-    #[inline(always)]
+    #[inline]
     unsafe fn unsafe_ref(&self, index: uint) -> *T {
         let (ptr, _): (*T, uint) = transmute(*self);
         ptr.offset(index)
@@ -2022,9 +2025,9 @@ impl<'self,T:Copy> ImmutableCopyableVector<T> for &'self [T] {
     }
 
     /// Returns the element at the given index, without doing bounds checking.
-    #[inline(always)]
+    #[inline]
     unsafe fn unsafe_get(&self, index: uint) -> T {
-        *self.unsafe_ref(index)
+        copy *self.unsafe_ref(index)
     }
 }
 
@@ -2203,14 +2206,14 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] {
         }
     }
 
-    #[inline(always)]
+    #[inline]
     unsafe fn unsafe_mut_ref(&self, index: uint) -> *mut T {
         let pair_ptr: &(*mut T, uint) = transmute(self);
         let (ptr, _) = *pair_ptr;
         ptr.offset(index)
     }
 
-    #[inline(always)]
+    #[inline]
     unsafe fn unsafe_set(&self, index: uint, val: T) {
         *self.unsafe_mut_ref(index) = val;
     }
@@ -2271,7 +2274,7 @@ pub mod raw {
      * modifing its buffers, so it is up to the caller to ensure that
      * the vector is actually the specified size.
      */
-    #[inline(always)]
+    #[inline]
     pub unsafe fn set_len<T>(v: &mut ~[T], new_len: uint) {
         let repr: **mut VecRepr = transmute(v);
         (**repr).unboxed.fill = new_len * sys::nonzero_size_of::<T>();
@@ -2286,7 +2289,7 @@ pub mod raw {
      * Modifying the vector may cause its buffer to be reallocated, which
      * would also make any pointers to it invalid.
      */
-    #[inline(always)]
+    #[inline]
     pub fn to_ptr<T>(v: &[T]) -> *T {
         unsafe {
             let repr: **SliceRepr = transmute(&v);
@@ -2295,7 +2298,7 @@ pub mod raw {
     }
 
     /** see `to_ptr()` */
-    #[inline(always)]
+    #[inline]
     pub fn to_const_ptr<T>(v: &const [T]) -> *const T {
         unsafe {
             let repr: **SliceRepr = transmute(&v);
@@ -2304,7 +2307,7 @@ pub mod raw {
     }
 
     /** see `to_ptr()` */
-    #[inline(always)]
+    #[inline]
     pub fn to_mut_ptr<T>(v: &mut [T]) -> *mut T {
         unsafe {
             let repr: **SliceRepr = transmute(&v);
@@ -2316,7 +2319,7 @@ pub mod raw {
      * Form a slice from a pointer and length (as a number of units,
      * not bytes).
      */
-    #[inline(always)]
+    #[inline]
     pub unsafe fn buf_as_slice<T,U>(p: *T,
                                     len: uint,
                                     f: &fn(v: &[T]) -> U) -> U {
@@ -2329,7 +2332,7 @@ pub mod raw {
      * Form a slice from a pointer and length (as a number of units,
      * not bytes).
      */
-    #[inline(always)]
+    #[inline]
     pub unsafe fn mut_buf_as_slice<T,U>(p: *mut T,
                                         len: uint,
                                         f: &fn(v: &mut [T]) -> U) -> U {
@@ -2341,9 +2344,9 @@ pub mod raw {
     /**
      * Unchecked vector indexing.
      */
-    #[inline(always)]
+    #[inline]
     pub unsafe fn get<T:Copy>(v: &const [T], i: uint) -> T {
-        as_const_buf(v, |p, _len| *ptr::const_offset(p, i))
+        as_const_buf(v, |p, _len| copy *ptr::const_offset(p, i))
     }
 
     /**
@@ -2351,7 +2354,7 @@ pub mod raw {
      * old value and hence is only suitable when the vector
      * is newly allocated.
      */
-    #[inline(always)]
+    #[inline]
     pub unsafe fn init_elem<T>(v: &mut [T], i: uint, val: T) {
         let mut box = Some(val);
         do as_mut_buf(v) |p, _len| {
@@ -2370,7 +2373,7 @@ pub mod raw {
     * * elts - The number of elements in the buffer
     */
     // Was in raw, but needs to be called by net_tcp::on_tcp_read_cb
-    #[inline(always)]
+    #[inline]
     pub unsafe fn from_buf_raw<T>(ptr: *T, elts: uint) -> ~[T] {
         let mut dst = with_capacity(elts);
         set_len(&mut dst, elts);
@@ -2384,7 +2387,7 @@ pub mod raw {
       * Copies `count` bytes from `src` to `dst`. The source and destination
       * may overlap.
       */
-    #[inline(always)]
+    #[inline]
     pub unsafe fn copy_memory<T>(dst: &mut [T], src: &const [T],
                                  count: uint) {
         assert!(dst.len() >= count);
@@ -2450,7 +2453,7 @@ pub mod bytes {
       * Copies `count` bytes from `src` to `dst`. The source and destination
       * may overlap.
       */
-    #[inline(always)]
+    #[inline]
     pub fn copy_memory(dst: &mut [u8], src: &const [u8], count: uint) {
         // Bound checks are done at vec::raw::copy_memory.
         unsafe { vec::raw::copy_memory(dst, src, count) }
@@ -2461,31 +2464,31 @@ pub mod bytes {
 // ITERATION TRAIT METHODS
 
 impl<'self,A> old_iter::BaseIter<A> for &'self [A] {
-    #[inline(always)]
+    #[inline]
     fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) -> bool {
         each(*self, blk)
     }
-    #[inline(always)]
+    #[inline]
     fn size_hint(&self) -> Option<uint> { Some(self.len()) }
 }
 
 // FIXME(#4148): This should be redundant
 impl<A> old_iter::BaseIter<A> for ~[A] {
-    #[inline(always)]
+    #[inline]
     fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) -> bool {
         each(*self, blk)
     }
-    #[inline(always)]
+    #[inline]
     fn size_hint(&self) -> Option<uint> { Some(self.len()) }
 }
 
 // FIXME(#4148): This should be redundant
 impl<A> old_iter::BaseIter<A> for @[A] {
-    #[inline(always)]
+    #[inline]
     fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) -> bool {
         each(*self, blk)
     }
-    #[inline(always)]
+    #[inline]
     fn size_hint(&self) -> Option<uint> { Some(self.len()) }
 }
 
@@ -2615,28 +2618,27 @@ impl<A:Copy> old_iter::CopyableIter<A> for @[A] {
     }
 }
 
-impl<'self,A:Copy + Ord> old_iter::CopyableOrderedIter<A> for &'self [A] {
-    fn min(&self) -> A { old_iter::min(self) }
-    fn max(&self) -> A { old_iter::max(self) }
+impl<A:Clone> Clone for ~[A] {
+    #[inline]
+    fn clone(&self) -> ~[A] {
+        self.map(|item| item.clone())
+    }
 }
 
-// FIXME(#4148): This should be redundant
-impl<A:Copy + Ord> old_iter::CopyableOrderedIter<A> for ~[A] {
-    fn min(&self) -> A { old_iter::min(self) }
-    fn max(&self) -> A { old_iter::max(self) }
+// This works because every lifetime is a sub-lifetime of 'static
+impl<'self, A> Zero for &'self [A] {
+    fn zero() -> &'self [A] { &'self [] }
+    fn is_zero(&self) -> bool { self.is_empty() }
 }
 
-// FIXME(#4148): This should be redundant
-impl<A:Copy + Ord> old_iter::CopyableOrderedIter<A> for @[A] {
-    fn min(&self) -> A { old_iter::min(self) }
-    fn max(&self) -> A { old_iter::max(self) }
+impl<A> Zero for ~[A] {
+    fn zero() -> ~[A] { ~[] }
+    fn is_zero(&self) -> bool { self.len() == 0 }
 }
 
-impl<A:Clone> Clone for ~[A] {
-    #[inline]
-    fn clone(&self) -> ~[A] {
-        self.map(|item| item.clone())
-    }
+impl<A> Zero for @[A] {
+    fn zero() -> @[A] { @[] }
+    fn is_zero(&self) -> bool { self.len() == 0 }
 }
 
 macro_rules! iterator {
@@ -2704,7 +2706,7 @@ pub struct VecMutRevIterator<'self, T> {
 iterator!{impl VecMutRevIterator -> &'self mut T, -1}
 
 impl<T> FromIter<T> for ~[T]{
-    #[inline(always)]
+    #[inline]
     pub fn from_iter(iter: &fn(f: &fn(T) -> bool) -> bool) -> ~[T] {
         let mut v = ~[];
         for iter |x| { v.push(x) }
@@ -4293,4 +4295,20 @@ mod tests {
         }
         assert_eq!(v, ~[~[1,2,3],~[1,3,2],~[2,1,3],~[2,3,1],~[3,1,2],~[3,2,1]]);
     }
+
+    #[test]
+    fn test_vec_zero() {
+        use num::Zero;
+        macro_rules! t (
+            ($ty:ty) => {
+                let v: $ty = Zero::zero();
+                assert!(v.is_empty());
+                assert!(v.is_zero());
+            }
+        );
+
+        t!(&[int]);
+        t!(@[int]);
+        t!(~[int]);
+    }
 }
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index e3182916723..1758433aa73 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -95,7 +95,7 @@ impl<D:Decoder> Decodable<D> for ident {
 }
 
 impl to_bytes::IterBytes for ident {
-    #[inline(always)]
+    #[inline]
     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool {
         self.name.iter_bytes(lsb0, f)
     }
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index cc89db6e189..a4ded8fea8c 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -198,7 +198,7 @@ pub fn is_call_expr(e: @expr) -> bool {
 
 // This makes def_id hashable
 impl to_bytes::IterBytes for def_id {
-    #[inline(always)]
+    #[inline]
     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool {
         self.crate.iter_bytes(lsb0, f) && self.node.iter_bytes(lsb0, f)
     }
@@ -395,30 +395,30 @@ impl id_range {
 pub fn id_visitor<T: Copy>(vfn: @fn(node_id, T)) -> visit::vt<T> {
     let visit_generics: @fn(&Generics, T) = |generics, t| {
         for generics.ty_params.each |p| {
-            vfn(p.id, t);
+            vfn(p.id, copy t);
         }
         for generics.lifetimes.each |p| {
-            vfn(p.id, t);
+            vfn(p.id, copy t);
         }
     };
     visit::mk_vt(@visit::Visitor {
         visit_mod: |m, sp, id, (t, vt)| {
-            vfn(id, t);
+            vfn(id, copy t);
             visit::visit_mod(m, sp, id, (t, vt));
         },
 
         visit_view_item: |vi, (t, vt)| {
             match vi.node {
-              view_item_extern_mod(_, _, id) => vfn(id, t),
+              view_item_extern_mod(_, _, id) => vfn(id, copy t),
               view_item_use(ref vps) => {
                   for vps.each |vp| {
                       match vp.node {
-                          view_path_simple(_, _, id) => vfn(id, t),
-                          view_path_glob(_, id) => vfn(id, t),
+                          view_path_simple(_, _, id) => vfn(id, copy t),
+                          view_path_glob(_, id) => vfn(id, copy t),
                           view_path_list(_, ref paths, id) => {
-                              vfn(id, t);
+                              vfn(id, copy t);
                               for paths.each |p| {
-                                  vfn(p.node.id, t);
+                                  vfn(p.node.id, copy t);
                               }
                           }
                       }
@@ -429,34 +429,34 @@ pub fn id_visitor<T: Copy>(vfn: @fn(node_id, T)) -> visit::vt<T> {
         },
 
         visit_foreign_item: |ni, (t, vt)| {
-            vfn(ni.id, t);
+            vfn(ni.id, copy t);
             visit::visit_foreign_item(ni, (t, vt));
         },
 
         visit_item: |i, (t, vt)| {
-            vfn(i.id, t);
+            vfn(i.id, copy t);
             match i.node {
               item_enum(ref enum_definition, _) =>
-                for (*enum_definition).variants.each |v| { vfn(v.node.id, t); },
+                for (*enum_definition).variants.each |v| { vfn(v.node.id, copy t); },
               _ => ()
             }
             visit::visit_item(i, (t, vt));
         },
 
         visit_local: |l, (t, vt)| {
-            vfn(l.node.id, t);
+            vfn(l.node.id, copy t);
             visit::visit_local(l, (t, vt));
         },
         visit_block: |b, (t, vt)| {
-            vfn(b.node.id, t);
+            vfn(b.node.id, copy t);
             visit::visit_block(b, (t, vt));
         },
         visit_stmt: |s, (t, vt)| {
-            vfn(ast_util::stmt_id(s), t);
+            vfn(ast_util::stmt_id(s), copy t);
             visit::visit_stmt(s, (t, vt));
         },
         visit_pat: |p, (t, vt)| {
-            vfn(p.id, t);
+            vfn(p.id, copy t);
             visit::visit_pat(p, (t, vt));
         },
 
@@ -464,36 +464,36 @@ pub fn id_visitor<T: Copy>(vfn: @fn(node_id, T)) -> visit::vt<T> {
             {
                 let r = e.get_callee_id();
                 for r.iter().advance |callee_id| {
-                    vfn(*callee_id, t);
+                    vfn(*callee_id, copy t);
                 }
             }
-            vfn(e.id, t);
+            vfn(e.id, copy t);
             visit::visit_expr(e, (t, vt));
         },
 
         visit_ty: |ty, (t, vt)| {
             match ty.node {
-              ty_path(_, id) => vfn(id, t),
+              ty_path(_, id) => vfn(id, copy t),
               _ => { /* fall through */ }
             }
             visit::visit_ty(ty, (t, vt));
         },
 
         visit_generics: |generics, (t, vt)| {
-            visit_generics(generics, t);
+            visit_generics(generics, copy t);
             visit::visit_generics(generics, (t, vt));
         },
 
         visit_fn: |fk, d, a, b, id, (t, vt)| {
-            vfn(id, t);
+            vfn(id, copy t);
 
             match *fk {
                 visit::fk_item_fn(_, generics, _, _) => {
-                    visit_generics(generics, t);
+                    visit_generics(generics, copy t);
                 }
                 visit::fk_method(_, generics, m) => {
-                    vfn(m.self_id, t);
-                    visit_generics(generics, t);
+                    vfn(m.self_id, copy t);
+                    visit_generics(generics, copy t);
                 }
                 visit::fk_anon(_) |
                 visit::fk_fn_block => {
@@ -501,13 +501,13 @@ pub fn id_visitor<T: Copy>(vfn: @fn(node_id, T)) -> visit::vt<T> {
             }
 
             for d.inputs.each |arg| {
-                vfn(arg.id, t)
+                vfn(arg.id, copy t)
             }
-            visit::visit_fn(fk, d, a, b, id, (t, vt));
+            visit::visit_fn(fk, d, a, b, id, (copy t, vt));
         },
 
         visit_struct_field: |f, (t, vt)| {
-            vfn(f.node.id, t);
+            vfn(f.node.id, copy t);
             visit::visit_struct_field(f, (t, vt));
         },
 
diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs
index a184d959390..e096711262f 100644
--- a/src/libsyntax/attr.rs
+++ b/src/libsyntax/attr.rs
@@ -312,7 +312,7 @@ pub enum inline_attr {
 
 /// True if something like #[inline] is found in the list of attrs.
 pub fn find_inline_attr(attrs: &[ast::attribute]) -> inline_attr {
-    // FIXME (#2809)---validate the usage of #[inline] and #[inline(always)]
+    // FIXME (#2809)---validate the usage of #[inline] and #[inline]
     do attrs.iter().fold(ia_none) |ia,attr| {
         match attr.node.value.node {
           ast::meta_word(s) if "inline" == s => ia_hint,
diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs
index 1704b4ef6c5..e67ca5260b8 100644
--- a/src/libsyntax/diagnostic.rs
+++ b/src/libsyntax/diagnostic.rs
@@ -318,7 +318,7 @@ pub fn expect<T:Copy>(diag: @span_handler,
                        opt: Option<T>,
                        msg: &fn() -> ~str) -> T {
     match opt {
-       Some(ref t) => (*t),
+       Some(ref t) => copy *t,
        None => diag.handler().bug(msg())
     }
 }
diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs
index 49b3d3ec861..22ce305b857 100644
--- a/src/libsyntax/ext/deriving/generic.rs
+++ b/src/libsyntax/ext/deriving/generic.rs
@@ -1052,7 +1052,7 @@ f(cx, span, ~[self_1.method(__arg_1_1, __arg_2_1),
               self_2.method(__arg_1_2, __arg_2_2)])
 ~~~
 */
-#[inline(always)]
+#[inline]
 pub fn cs_same_method(f: &fn(@ExtCtxt, span, ~[@expr]) -> @expr,
                       enum_nonmatch_f: EnumNonMatchFunc,
                       cx: @ExtCtxt, span: span,
@@ -1083,7 +1083,7 @@ Fold together the results of calling the derived method on all the
 fields. `use_foldl` controls whether this is done left-to-right
 (`true`) or right-to-left (`false`).
 */
-#[inline(always)]
+#[inline]
 pub fn cs_same_method_fold(use_foldl: bool,
                            f: &fn(@ExtCtxt, span, @expr, @expr) -> @expr,
                            base: @expr,
@@ -1111,7 +1111,7 @@ pub fn cs_same_method_fold(use_foldl: bool,
 Use a given binop to combine the result of calling the derived method
 on all the fields.
 */
-#[inline(always)]
+#[inline]
 pub fn cs_binop(binop: ast::binop, base: @expr,
                 enum_nonmatch_f: EnumNonMatchFunc,
                 cx: @ExtCtxt, span: span,
@@ -1130,7 +1130,7 @@ pub fn cs_binop(binop: ast::binop, base: @expr,
 }
 
 /// cs_binop with binop == or
-#[inline(always)]
+#[inline]
 pub fn cs_or(enum_nonmatch_f: EnumNonMatchFunc,
              cx: @ExtCtxt, span: span,
              substructure: &Substructure) -> @expr {
@@ -1139,7 +1139,7 @@ pub fn cs_or(enum_nonmatch_f: EnumNonMatchFunc,
              cx, span, substructure)
 }
 /// cs_binop with binop == and
-#[inline(always)]
+#[inline]
 pub fn cs_and(enum_nonmatch_f: EnumNonMatchFunc,
               cx: @ExtCtxt, span: span,
               substructure: &Substructure) -> @expr {
diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs
index 0198ca424d7..f5170d284c6 100644
--- a/src/libsyntax/ext/deriving/mod.rs
+++ b/src/libsyntax/ext/deriving/mod.rs
@@ -31,6 +31,7 @@ pub mod encodable;
 pub mod decodable;
 pub mod rand;
 pub mod to_str;
+pub mod zero;
 
 #[path="cmp/eq.rs"]
 pub mod eq;
@@ -98,6 +99,7 @@ pub fn expand_meta_deriving(cx: @ExtCtxt,
                             "Rand" => expand!(rand::expand_deriving_rand),
 
                             "ToStr" => expand!(to_str::expand_deriving_to_str),
+                            "Zero" => expand!(zero::expand_deriving_zero),
 
                             ref tname => {
                                 cx.span_err(titem.span, fmt!("unknown \
diff --git a/src/libsyntax/ext/deriving/zero.rs b/src/libsyntax/ext/deriving/zero.rs
new file mode 100644
index 00000000000..121d8351ee4
--- /dev/null
+++ b/src/libsyntax/ext/deriving/zero.rs
@@ -0,0 +1,96 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use core::prelude::*;
+
+use ast::{meta_item, item, expr};
+use codemap::span;
+use ext::base::ExtCtxt;
+use ext::build::AstBuilder;
+use ext::deriving::generic::*;
+
+use core::vec;
+
+pub fn expand_deriving_zero(cx: @ExtCtxt,
+                            span: span,
+                            mitem: @meta_item,
+                            in_items: ~[@item])
+    -> ~[@item] {
+    let trait_def = TraitDef {
+        path: Path::new(~["std", "num", "Zero"]),
+        additional_bounds: ~[],
+        generics: LifetimeBounds::empty(),
+        methods: ~[
+            MethodDef {
+                name: "zero",
+                generics: LifetimeBounds::empty(),
+                explicit_self: None,
+                args: ~[],
+                ret_ty: Self,
+                const_nonmatching: false,
+                combine_substructure: zero_substructure
+            },
+            MethodDef {
+                name: "is_zero",
+                generics: LifetimeBounds::empty(),
+                explicit_self: borrowed_explicit_self(),
+                args: ~[],
+                ret_ty: Literal(Path::new(~["bool"])),
+                const_nonmatching: false,
+                combine_substructure: |cx, span, substr| {
+                    cs_and(|cx, span, _, _| cx.span_bug(span,
+                                                        "Non-matching enum \
+                                                         variant in \
+                                                         deriving(Zero)"),
+                           cx, span, substr)
+                }
+            }
+        ]
+    };
+    trait_def.expand(cx, span, mitem, in_items)
+}
+
+fn zero_substructure(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr {
+    let zero_ident = ~[
+        cx.ident_of("std"),
+        cx.ident_of("num"),
+        cx.ident_of("Zero"),
+        cx.ident_of("zero")
+    ];
+    let zero_call = || {
+        cx.expr_call_global(span, copy zero_ident, ~[])
+    };
+
+    return match *substr.fields {
+        StaticStruct(_, ref summary) => {
+            match *summary {
+                Left(count) => {
+                    if count == 0 {
+                        cx.expr_ident(span, substr.type_ident)
+                    } else {
+                        let exprs = vec::from_fn(count, |_| zero_call());
+                        cx.expr_call_ident(span, substr.type_ident, exprs)
+                    }
+                }
+                Right(ref fields) => {
+                    let zero_fields = do fields.map |ident| {
+                        cx.field_imm(span, *ident, zero_call())
+                    };
+                    cx.expr_struct_ident(span, substr.type_ident, zero_fields)
+                }
+            }
+        }
+        StaticEnum(*) => {
+            cx.span_fatal(span, "`Zero` cannot be derived for enums, \
+                                 only structs")
+        }
+        _ => cx.bug("Non-static method in `deriving(Zero)`")
+    };
+}
diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs
index 25166eca7bb..44e480dc7df 100644
--- a/src/libsyntax/ext/quote.rs
+++ b/src/libsyntax/ext/quote.rs
@@ -39,8 +39,6 @@ pub mod rt {
     use parse;
     use print::pprust;
 
-    use core::str;
-
     pub use ast::*;
     pub use parse::token::*;
     pub use parse::new_parser_from_tts;
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 035675e523e..c1bf979cd31 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -969,7 +969,7 @@ mod test {
     // change every identifier to "zz"
     pub fn to_zz() -> @fn(ast::ident)->ast::ident {
         let zz_id = token::str_to_ident("zz");
-        |id| {zz_id}
+        |_id| {zz_id}
     }
 
     // maybe add to expand.rs...
diff --git a/src/libsyntax/opt_vec.rs b/src/libsyntax/opt_vec.rs
index 791f7444b62..81f540fd69f 100644
--- a/src/libsyntax/opt_vec.rs
+++ b/src/libsyntax/opt_vec.rs
@@ -103,7 +103,7 @@ impl<T:Copy> OptVec<T> {
         }
     }
 
-    #[inline(always)]
+    #[inline]
     fn mapi_to_vec<B>(&self, op: &fn(uint, &T) -> B) -> ~[B] {
         let mut index = 0;
         old_iter::map_to_vec(self, |a| {
@@ -145,31 +145,31 @@ impl<A> BaseIter<A> for OptVec<A> {
 }
 
 impl<A> old_iter::ExtendedIter<A> for OptVec<A> {
-    #[inline(always)]
+    #[inline]
     fn eachi(&self, blk: &fn(v: uint, v: &A) -> bool) -> bool {
         old_iter::eachi(self, blk)
     }
-    #[inline(always)]
+    #[inline]
     fn all(&self, blk: &fn(&A) -> bool) -> bool {
         old_iter::all(self, blk)
     }
-    #[inline(always)]
+    #[inline]
     fn any(&self, blk: &fn(&A) -> bool) -> bool {
         old_iter::any(self, blk)
     }
-    #[inline(always)]
+    #[inline]
     fn foldl<B>(&self, b0: B, blk: &fn(&B, &A) -> B) -> B {
         old_iter::foldl(self, b0, blk)
     }
-    #[inline(always)]
+    #[inline]
     fn position(&self, f: &fn(&A) -> bool) -> Option<uint> {
         old_iter::position(self, f)
     }
-    #[inline(always)]
+    #[inline]
     fn map_to_vec<B>(&self, op: &fn(&A) -> B) -> ~[B] {
         old_iter::map_to_vec(self, op)
     }
-    #[inline(always)]
+    #[inline]
     fn flat_map_to_vec<B,IB:BaseIter<B>>(&self, op: &fn(&A) -> IB)
         -> ~[B] {
         old_iter::flat_map_to_vec(self, op)
@@ -178,28 +178,21 @@ impl<A> old_iter::ExtendedIter<A> for OptVec<A> {
 }
 
 impl<A: Eq> old_iter::EqIter<A> for OptVec<A> {
-    #[inline(always)]
+    #[inline]
     fn contains(&self, x: &A) -> bool { old_iter::contains(self, x) }
-    #[inline(always)]
+    #[inline]
     fn count(&self, x: &A) -> uint { old_iter::count(self, x) }
 }
 
 impl<A: Copy> old_iter::CopyableIter<A> for OptVec<A> {
-    #[inline(always)]
+    #[inline]
     fn filter_to_vec(&self, pred: &fn(&A) -> bool) -> ~[A] {
         old_iter::filter_to_vec(self, pred)
     }
-    #[inline(always)]
+    #[inline]
     fn to_vec(&self) -> ~[A] { old_iter::to_vec(self) }
-    #[inline(always)]
+    #[inline]
     fn find(&self, f: &fn(&A) -> bool) -> Option<A> {
         old_iter::find(self, f)
     }
 }
-
-impl<A: Copy+Ord> old_iter::CopyableOrderedIter<A> for OptVec<A> {
-    #[inline(always)]
-    fn min(&self) -> A { old_iter::min(self) }
-    #[inline(always)]
-    fn max(&self) -> A { old_iter::max(self) }
-}
diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs
index b7bb1b3bc53..472f807cd8b 100644
--- a/src/libsyntax/parse/comments.rs
+++ b/src/libsyntax/parse/comments.rs
@@ -69,52 +69,59 @@ pub fn strip_doc_comment_decoration(comment: &str) -> ~str {
         return lines.slice(i, j).to_owned();
     }
 
-    // drop leftmost columns that contain only values in chars
-    fn block_trim(lines: ~[~str], chars: ~str, max: Option<uint>) -> ~[~str] {
-
-        let mut i = max.get_or_default(uint::max_value);
-        for lines.each |line| {
-            if line.trim().is_empty() {
-                loop;
-            }
+    /// remove a "[ \t]*\*" block from each line, if possible
+    fn horizontal_trim(lines: ~[~str]) -> ~[~str] {
+        let mut i = uint::max_value;
+        let mut can_trim = true;
+        let mut first = true;
+        for lines.iter().advance |line| {
             for line.iter().enumerate().advance |(j, c)| {
-                if j >= i {
+                if j > i || !"* \t".contains_char(c) {
+                    can_trim = false;
                     break;
                 }
-                if !chars.contains_char(c) {
-                    i = j;
+                if c == '*' {
+                    if first {
+                        i = j;
+                        first = false;
+                    } else if i != j {
+                        can_trim = false;
+                    }
                     break;
                 }
             }
+            if i > line.len() {
+                can_trim = false;
+            }
+            if !can_trim {
+                break;
+            }
         }
 
-        return do lines.map |line| {
-            let mut chars = ~[];
-            for line.iter().advance |c| { chars.push(c) }
-            if i > chars.len() {
-                ~""
-            } else {
-                str::from_chars(chars.slice(i, chars.len()).to_owned())
+        if can_trim {
+            do lines.map |line| {
+                line.slice(i + 1, line.len()).to_owned()
             }
-        };
+        } else {
+            lines
+        }
     }
 
     if comment.starts_with("//") {
         // FIXME #5475:
-        // return comment.slice(3u, comment.len()).trim().to_owned();
-        let r = comment.slice(3u, comment.len()); return r.trim().to_owned();
-
+        // return comment.slice(3u, comment.len()).to_owned();
+        let r = comment.slice(3u, comment.len()); return r.to_owned();
     }
 
     if comment.starts_with("/*") {
-        let mut lines = ~[];
-        for str::each_line_any(comment.slice(3u, comment.len() - 2u)) |line| {
-            lines.push(line.to_owned())
-        }
+        let lines = comment.slice(3u, comment.len() - 2u)
+            .any_line_iter()
+            .transform(|s| s.to_owned())
+            .collect::<~[~str]>();
+
         let lines = vertical_trim(lines);
-        let lines = block_trim(lines, ~"\t ", None);
-        let lines = block_trim(lines, ~"*", Some(1u));
-        let lines = block_trim(lines, ~"\t ", None);
+        let lines = horizontal_trim(lines);
+
         return lines.connect("\n");
     }
 
@@ -372,3 +379,36 @@ pub fn gather_comments_and_literals(span_diagnostic:
 
     (comments, literals)
 }
+
+#[cfg(test)]
+mod test {
+    use super::*;
+
+    #[test] fn test_block_doc_comment_1() {
+        let comment = "/**\n * Test \n **  Test\n *   Test\n*/";
+        let correct_stripped = " Test \n*  Test\n   Test";
+        let stripped = strip_doc_comment_decoration(comment);
+        assert_eq!(stripped.slice(0, stripped.len()), correct_stripped);
+    }
+
+    #[test] fn test_block_doc_comment_2() {
+        let comment = "/**\n * Test\n *  Test\n*/";
+        let correct_stripped = " Test\n  Test";
+        let stripped = strip_doc_comment_decoration(comment);
+        assert_eq!(stripped.slice(0, stripped.len()), correct_stripped);
+    }
+
+    #[test] fn test_block_doc_comment_3() {
+        let comment = "/**\n let a: *int;\n *a = 5;\n*/";
+        let correct_stripped = " let a: *int;\n *a = 5;";
+        let stripped = strip_doc_comment_decoration(comment);
+        assert_eq!(stripped.slice(0, stripped.len()), correct_stripped);
+    }
+
+    #[test] fn test_line_doc_comment() {
+        let comment = "/// Test";
+        let correct_stripped = " Test";
+        let stripped = strip_doc_comment_decoration(comment);
+        assert_eq!(stripped.slice(0, stripped.len()), correct_stripped);
+    }
+}
diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs
index cc7b7fab07e..bb315bf2933 100644
--- a/src/libsyntax/parse/obsolete.rs
+++ b/src/libsyntax/parse/obsolete.rs
@@ -68,7 +68,7 @@ pub enum ObsoleteSyntax {
 }
 
 impl to_bytes::IterBytes for ObsoleteSyntax {
-    #[inline(always)]
+    #[inline]
     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool {
         (*self as uint).iter_bytes(lsb0, f)
     }
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index e7bc67340f0..273a59f0a3d 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -400,6 +400,7 @@ impl ident_interner {
     }
 }
 
+
 // return a fresh interner, preloaded with special identifiers.
 fn mk_fresh_ident_interner() -> @ident_interner {
     // the indices here must correspond to the numbers in
@@ -446,39 +447,38 @@ fn mk_fresh_ident_interner() -> @ident_interner {
         "const",              // 37
         "copy",               // 38
         "do",                 // 39
-        "drop",               // 40
-        "else",               // 41
-        "enum",               // 42
-        "extern",             // 43
-        "false",              // 44
-        "fn",                 // 45
-        "for",                // 46
-        "if",                 // 47
-        "impl",               // 48
-        "let",                // 49
-        "__log",              // 50
-        "loop",               // 51
-        "match",              // 52
-        "mod",                // 53
-        "mut",                // 54
-        "once",               // 55
-        "priv",               // 56
-        "pub",                // 57
-        "pure",               // 58
-        "ref",                // 59
-        "return",             // 60
+        "else",               // 40
+        "enum",               // 41
+        "extern",             // 42
+        "false",              // 43
+        "fn",                 // 44
+        "for",                // 45
+        "if",                 // 46
+        "impl",               // 47
+        "let",                // 48
+        "__log",              // 49
+        "loop",               // 50
+        "match",              // 51
+        "mod",                // 52
+        "mut",                // 53
+        "once",               // 54
+        "priv",               // 55
+        "pub",                // 56
+        "pure",               // 57
+        "ref",                // 58
+        "return",             // 59
         "static",             // 29 -- also a special ident
         "self",               //  8 -- also a special ident
-        "struct",             // 61
-        "super",              // 62
-        "true",               // 63
-        "trait",              // 64
-        "type",               // 65
-        "unsafe",             // 66
-        "use",                // 67
-        "while",              // 68
-
-        "be",                 // 69
+        "struct",             // 60
+        "super",              // 61
+        "true",               // 62
+        "trait",              // 63
+        "type",               // 64
+        "unsafe",             // 65
+        "use",                // 66
+        "while",              // 67
+
+        "be",                 // 68
     ];
 
     @ident_interner {
@@ -498,9 +498,7 @@ pub fn get_ident_interner() -> @ident_interner {
             Some(interner) => *interner,
             None => {
                 let interner = mk_fresh_ident_interner();
-                unsafe {
-                    local_data::local_data_set(key, @interner);
-                }
+                local_data::local_data_set(key, @interner);
                 interner
             }
         }
@@ -615,41 +613,41 @@ pub mod keywords {
         pub fn to_ident(&self) -> ident {
             match *self {
                 As => ident { name: 35, ctxt: 0 },
-                   Break => ident { name: 36, ctxt: 0 },
-                   Const => ident { name: 37, ctxt: 0 },
-                   Copy => ident { name: 38, ctxt: 0 },
-                   Do => ident { name: 39, ctxt: 0 },
-                   Else => ident { name: 41, ctxt: 0 },
-                   Enum => ident { name: 42, ctxt: 0 },
-                   Extern => ident { name: 43, ctxt: 0 },
-                   False => ident { name: 44, ctxt: 0 },
-                   Fn => ident { name: 45, ctxt: 0 },
-                   For => ident { name: 46, ctxt: 0 },
-                   If => ident { name: 47, ctxt: 0 },
-                   Impl => ident { name: 48, ctxt: 0 },
-                   Let => ident { name: 49, ctxt: 0 },
-                   __Log => ident { name: 50, ctxt: 0 },
-                   Loop => ident { name: 51, ctxt: 0 },
-                   Match => ident { name: 52, ctxt: 0 },
-                   Mod => ident { name: 53, ctxt: 0 },
-                   Mut => ident { name: 54, ctxt: 0 },
-                   Once => ident { name: 55, ctxt: 0 },
-                   Priv => ident { name: 56, ctxt: 0 },
-                   Pub => ident { name: 57, ctxt: 0 },
-                   Pure => ident { name: 58, ctxt: 0 },
-                   Ref => ident { name: 59, ctxt: 0 },
-                   Return => ident { name: 60, ctxt: 0 },
-                   Static => ident { name: 29, ctxt: 0 },
-                   Self => ident { name: 8, ctxt: 0 },
-                   Struct => ident { name: 61, ctxt: 0 },
-                   Super => ident { name: 62, ctxt: 0 },
-                   True => ident { name: 63, ctxt: 0 },
-                   Trait => ident { name: 64, ctxt: 0 },
-                   Type => ident { name: 65, ctxt: 0 },
-                   Unsafe => ident { name: 66, ctxt: 0 },
-                   Use => ident { name: 67, ctxt: 0 },
-                   While => ident { name: 68, ctxt: 0 },
-                   Be => ident { name: 69, ctxt: 0 },
+                Break => ident { name: 36, ctxt: 0 },
+                Const => ident { name: 37, ctxt: 0 },
+                Copy => ident { name: 38, ctxt: 0 },
+                Do => ident { name: 39, ctxt: 0 },
+                Else => ident { name: 40, ctxt: 0 },
+                Enum => ident { name: 41, ctxt: 0 },
+                Extern => ident { name: 42, ctxt: 0 },
+                False => ident { name: 43, ctxt: 0 },
+                Fn => ident { name: 44, ctxt: 0 },
+                For => ident { name: 45, ctxt: 0 },
+                If => ident { name: 46, ctxt: 0 },
+                Impl => ident { name: 47, ctxt: 0 },
+                Let => ident { name: 48, ctxt: 0 },
+                __Log => ident { name: 49, ctxt: 0 },
+                Loop => ident { name: 50, ctxt: 0 },
+                Match => ident { name: 51, ctxt: 0 },
+                Mod => ident { name: 52, ctxt: 0 },
+                Mut => ident { name: 53, ctxt: 0 },
+                Once => ident { name: 54, ctxt: 0 },
+                Priv => ident { name: 55, ctxt: 0 },
+                Pub => ident { name: 56, ctxt: 0 },
+                Pure => ident { name: 57, ctxt: 0 },
+                Ref => ident { name: 58, ctxt: 0 },
+                Return => ident { name: 59, ctxt: 0 },
+                Static => ident { name: 29, ctxt: 0 },
+                Self => ident { name: 8, ctxt: 0 },
+                Struct => ident { name: 60, ctxt: 0 },
+                Super => ident { name: 61, ctxt: 0 },
+                True => ident { name: 62, ctxt: 0 },
+                Trait => ident { name: 63, ctxt: 0 },
+                Type => ident { name: 64, ctxt: 0 },
+                Unsafe => ident { name: 65, ctxt: 0 },
+                Use => ident { name: 66, ctxt: 0 },
+                While => ident { name: 67, ctxt: 0 },
+                Be => ident { name: 68, ctxt: 0 },
             }
         }
     }
@@ -665,7 +663,7 @@ pub fn is_keyword(kw: keywords::Keyword, tok: &Token) -> bool {
 pub fn is_any_keyword(tok: &Token) -> bool {
     match *tok {
         token::IDENT(sid, false) => match sid.name {
-            8 | 29 | 35 .. 69 => true,
+            8 | 29 | 35 .. 68 => true,
             _ => false,
         },
         _ => false
@@ -675,7 +673,7 @@ pub fn is_any_keyword(tok: &Token) -> bool {
 pub fn is_strict_keyword(tok: &Token) -> bool {
     match *tok {
         token::IDENT(sid, false) => match sid.name {
-            8 | 29 | 35 .. 68 => true,
+            8 | 29 | 35 .. 67 => true,
             _ => false,
         },
         _ => false,
@@ -685,13 +683,14 @@ pub fn is_strict_keyword(tok: &Token) -> bool {
 pub fn is_reserved_keyword(tok: &Token) -> bool {
     match *tok {
         token::IDENT(sid, false) => match sid.name {
-            69 => true,
+            68 => true,
             _ => false,
         },
         _ => false,
     }
 }
 
+
 #[cfg(test)]
 mod test {
     use super::*;
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 7eec9e2ee89..e72d9b502dc 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -322,7 +322,7 @@ pub fn commasep<IN: Copy>(s: @ps, b: breaks, elts: &[IN], op: &fn(@ps, IN)) {
     let mut first = true;
     for elts.each |elt| {
         if first { first = false; } else { word_space(s, ","); }
-        op(s, *elt);
+        op(s, copy *elt);
     }
     end(s);
 }
@@ -334,13 +334,13 @@ pub fn commasep_cmnt<IN: Copy>(s: @ps, b: breaks, elts: &[IN], op: &fn(@ps, IN),
     let len = elts.len();
     let mut i = 0u;
     for elts.each |elt| {
-        maybe_print_comment(s, get_span(*elt).hi);
-        op(s, *elt);
+        maybe_print_comment(s, get_span(copy *elt).hi);
+        op(s, copy *elt);
         i += 1u;
         if i < len {
             word(s.s, ",");
-            maybe_print_trailing_comment(s, get_span(*elt),
-                                         Some(get_span(elts[i]).hi));
+            maybe_print_trailing_comment(s, get_span(copy *elt),
+                                         Some(get_span(copy elts[i]).hi));
             space_if_not_bol(s);
         }
     }
@@ -2118,7 +2118,7 @@ pub fn print_string(s: @ps, st: &str) {
 pub fn to_str<T: Copy>(t: T, f: @fn(@ps, T), intr: @ident_interner) -> ~str {
     do io::with_str_writer |wr| {
         let s = rust_printer(wr, intr);
-        f(s, t);
+        f(s, copy t);
         eof(s.s);
     }
 }
diff --git a/src/libsyntax/syntax.rc b/src/libsyntax/syntax.rc
index 78fbcab213c..278600bc039 100644
--- a/src/libsyntax/syntax.rc
+++ b/src/libsyntax/syntax.rc
@@ -30,17 +30,8 @@ extern mod core(name = "std");
 extern mod extra(name = "extra");
 
 // For deriving(Encodable) purposes...
-#[cfg(stage0)]
-extern mod std(name = "extra");
-#[cfg(not(stage0))]
 extern mod std(name = "std");
 
-// For bootstrapping purposes.
-#[cfg(stage0)]
-pub use core::str;
-#[cfg(stage0)]
-pub use core::unstable;
-
 use core::prelude::*;
 
 pub mod util {
diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs
index d4f183ada7b..bd5c178e7fe 100644
--- a/src/libsyntax/util/interner.rs
+++ b/src/libsyntax/util/interner.rs
@@ -36,7 +36,7 @@ impl<T:Eq + IterBytes + Hash + Const + Copy> Interner<T> {
 
     pub fn prefill(init: &[T]) -> Interner<T> {
         let rv = Interner::new();
-        for init.each() |v| { rv.intern(*v); }
+        for init.each() |v| { rv.intern(copy *v); }
         rv
     }
 
@@ -48,7 +48,7 @@ impl<T:Eq + IterBytes + Hash + Const + Copy> Interner<T> {
 
         let vect = &mut *self.vect;
         let new_idx = vect.len();
-        self.map.insert(val, new_idx);
+        self.map.insert(copy val, new_idx);
         vect.push(val);
         new_idx
     }
@@ -63,7 +63,7 @@ impl<T:Eq + IterBytes + Hash + Const + Copy> Interner<T> {
         new_idx
     }
 
-    pub fn get(&self, idx: uint) -> T { self.vect[idx] }
+    pub fn get(&self, idx: uint) -> T { copy self.vect[idx] }
 
     pub fn len(&self) -> uint { let vect = &*self.vect; vect.len() }
 
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 6e753a8cc58..f24c393d7b4 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -127,15 +127,15 @@ pub fn visit_crate<E: Copy>(c: &crate, (e, v): (E, vt<E>)) {
 }
 
 pub fn visit_mod<E: Copy>(m: &_mod, _sp: span, _id: node_id, (e, v): (E, vt<E>)) {
-    for m.view_items.each |vi| { (v.visit_view_item)(*vi, (e, v)); }
-    for m.items.each |i| { (v.visit_item)(*i, (e, v)); }
+    for m.view_items.each |vi| { (v.visit_view_item)(*vi, (copy e, v)); }
+    for m.items.each |i| { (v.visit_item)(*i, (copy e, v)); }
 }
 
 pub fn visit_view_item<E>(_vi: @view_item, (_e, _v): (E, vt<E>)) { }
 
 pub fn visit_local<E: Copy>(loc: @local, (e, v): (E, vt<E>)) {
-    (v.visit_pat)(loc.node.pat, (e, v));
-    (v.visit_ty)(loc.node.ty, (e, v));
+    (v.visit_pat)(loc.node.pat, (copy e, v));
+    (v.visit_ty)(loc.node.ty, (copy e, v));
     match loc.node.init {
       None => (),
       Some(ex) => (v.visit_expr)(ex, (e, v))
@@ -149,8 +149,8 @@ fn visit_trait_ref<E: Copy>(tref: @ast::trait_ref, (e, v): (E, vt<E>)) {
 pub fn visit_item<E: Copy>(i: @item, (e, v): (E, vt<E>)) {
     match i.node {
         item_const(t, ex) => {
-            (v.visit_ty)(t, (e, v));
-            (v.visit_expr)(ex, (e, v));
+            (v.visit_ty)(t, (copy e, v));
+            (v.visit_expr)(ex, (copy e, v));
         }
         item_fn(ref decl, purity, abi, ref generics, ref body) => {
             (v.visit_fn)(
@@ -170,15 +170,15 @@ pub fn visit_item<E: Copy>(i: @item, (e, v): (E, vt<E>)) {
         }
         item_mod(ref m) => (v.visit_mod)(m, i.span, i.id, (e, v)),
         item_foreign_mod(ref nm) => {
-            for nm.view_items.each |vi| { (v.visit_view_item)(*vi, (e, v)); }
-            for nm.items.each |ni| { (v.visit_foreign_item)(*ni, (e, v)); }
+            for nm.view_items.each |vi| { (v.visit_view_item)(*vi, (copy e, v)); }
+            for nm.items.each |ni| { (v.visit_foreign_item)(*ni, (copy e, v)); }
         }
         item_ty(t, ref tps) => {
-            (v.visit_ty)(t, (e, v));
+            (v.visit_ty)(t, (copy e, v));
             (v.visit_generics)(tps, (e, v));
         }
         item_enum(ref enum_definition, ref tps) => {
-            (v.visit_generics)(tps, (e, v));
+            (v.visit_generics)(tps, (copy e, v));
             visit_enum_def(
                 enum_definition,
                 tps,
@@ -186,24 +186,24 @@ pub fn visit_item<E: Copy>(i: @item, (e, v): (E, vt<E>)) {
             );
         }
         item_impl(ref tps, ref traits, ty, ref methods) => {
-            (v.visit_generics)(tps, (e, v));
+            (v.visit_generics)(tps, (copy e, v));
             for traits.iter().advance |&p| {
-                visit_trait_ref(p, (e, v));
+                visit_trait_ref(p, (copy e, v));
             }
-            (v.visit_ty)(ty, (e, v));
+            (v.visit_ty)(ty, (copy e, v));
             for methods.each |m| {
-                visit_method_helper(*m, (e, v))
+                visit_method_helper(*m, (copy e, v))
             }
         }
         item_struct(struct_def, ref generics) => {
-            (v.visit_generics)(generics, (e, v));
+            (v.visit_generics)(generics, (copy e, v));
             (v.visit_struct_def)(struct_def, i.ident, generics, i.id, (e, v));
         }
         item_trait(ref generics, ref traits, ref methods) => {
-            (v.visit_generics)(generics, (e, v));
-            for traits.each |p| { visit_path(p.path, (e, v)); }
+            (v.visit_generics)(generics, (copy e, v));
+            for traits.each |p| { visit_path(p.path, (copy e, v)); }
             for methods.each |m| {
-                (v.visit_trait_method)(m, (e, v));
+                (v.visit_trait_method)(m, (copy e, v));
             }
         }
         item_mac(ref m) => visit_mac(m, (e, v))
@@ -216,15 +216,19 @@ pub fn visit_enum_def<E: Copy>(enum_definition: &ast::enum_def,
     for enum_definition.variants.each |vr| {
         match vr.node.kind {
             tuple_variant_kind(ref variant_args) => {
-                for variant_args.each |va| { (v.visit_ty)(va.ty, (e, v)); }
+                for variant_args.each |va| {
+                    (v.visit_ty)(va.ty, (copy e, v));
+                }
             }
             struct_variant_kind(struct_def) => {
                 (v.visit_struct_def)(struct_def, vr.node.name, tps,
-                                   vr.node.id, (e, v));
+                                     vr.node.id, (copy e, v));
             }
         }
         // Visit the disr expr if it exists
-        for vr.node.disr_expr.iter().advance |ex| { (v.visit_expr)(*ex, (e, v)) }
+        for vr.node.disr_expr.iter().advance |ex| {
+            (v.visit_expr)(*ex, (copy e, v))
+        }
     }
 }
 
@@ -238,71 +242,75 @@ pub fn visit_ty<E: Copy>(t: @Ty, (e, v): (E, vt<E>)) {
         },
         ty_tup(ref ts) => {
             for ts.each |tt| {
-                (v.visit_ty)(*tt, (e, v));
+                (v.visit_ty)(*tt, (copy e, v));
             }
         },
         ty_closure(ref f) => {
-            for f.decl.inputs.each |a| { (v.visit_ty)(a.ty, (e, v)); }
+            for f.decl.inputs.each |a| { (v.visit_ty)(a.ty, (copy e, v)); }
             (v.visit_ty)(f.decl.output, (e, v));
         },
         ty_bare_fn(ref f) => {
-            for f.decl.inputs.each |a| { (v.visit_ty)(a.ty, (e, v)); }
+            for f.decl.inputs.each |a| { (v.visit_ty)(a.ty, (copy e, v)); }
             (v.visit_ty)(f.decl.output, (e, v));
         },
         ty_path(p, _) => visit_path(p, (e, v)),
         ty_fixed_length_vec(ref mt, ex) => {
-            (v.visit_ty)(mt.ty, (e, v));
-            (v.visit_expr)(ex, (e, v));
+            (v.visit_ty)(mt.ty, (copy e, v));
+            (v.visit_expr)(ex, (copy e, v));
         },
         ty_nil | ty_bot | ty_mac(_) | ty_infer => ()
     }
 }
 
 pub fn visit_path<E: Copy>(p: @Path, (e, v): (E, vt<E>)) {
-    for p.types.each |tp| { (v.visit_ty)(*tp, (e, v)); }
+    for p.types.each |tp| { (v.visit_ty)(*tp, (copy e, v)); }
 }
 
 pub fn visit_pat<E: Copy>(p: @pat, (e, v): (E, vt<E>)) {
     match p.node {
         pat_enum(path, ref children) => {
-            visit_path(path, (e, v));
+            visit_path(path, (copy e, v));
             for children.iter().advance |children| {
-                for children.iter().advance |child| { (v.visit_pat)(*child, (e, v)); }
+                for children.iter().advance |child| {
+                    (v.visit_pat)(*child, (copy e, v));
+                }
             }
         }
         pat_struct(path, ref fields, _) => {
-            visit_path(path, (e, v));
+            visit_path(path, (copy e, v));
             for fields.each |f| {
-                (v.visit_pat)(f.pat, (e, v));
+                (v.visit_pat)(f.pat, (copy e, v));
             }
         }
         pat_tup(ref elts) => {
             for elts.each |elt| {
-                (v.visit_pat)(*elt, (e, v))
+                (v.visit_pat)(*elt, (copy e, v))
             }
         },
         pat_box(inner) | pat_uniq(inner) | pat_region(inner) => {
             (v.visit_pat)(inner, (e, v))
         },
         pat_ident(_, path, ref inner) => {
-            visit_path(path, (e, v));
-            for inner.iter().advance |subpat| { (v.visit_pat)(*subpat, (e, v)) }
+            visit_path(path, (copy e, v));
+            for inner.iter().advance |subpat| {
+                (v.visit_pat)(*subpat, (copy e, v))
+            }
         }
         pat_lit(ex) => (v.visit_expr)(ex, (e, v)),
         pat_range(e1, e2) => {
-            (v.visit_expr)(e1, (e, v));
+            (v.visit_expr)(e1, (copy e, v));
             (v.visit_expr)(e2, (e, v));
         }
         pat_wild => (),
         pat_vec(ref before, ref slice, ref after) => {
             for before.each |elt| {
-                (v.visit_pat)(*elt, (e, v));
+                (v.visit_pat)(*elt, (copy e, v));
             }
             for slice.iter().advance |elt| {
-                (v.visit_pat)(*elt, (e, v));
+                (v.visit_pat)(*elt, (copy e, v));
             }
             for after.each |tail| {
-                (v.visit_pat)(*tail, (e, v));
+                (v.visit_pat)(*tail, (copy e, v));
             }
         }
     }
@@ -311,7 +319,7 @@ pub fn visit_pat<E: Copy>(p: @pat, (e, v): (E, vt<E>)) {
 pub fn visit_foreign_item<E: Copy>(ni: @foreign_item, (e, v): (E, vt<E>)) {
     match ni.node {
         foreign_item_fn(ref fd, _, ref generics) => {
-            visit_fn_decl(fd, (e, v));
+            visit_fn_decl(fd, (copy e, v));
             (v.visit_generics)(generics, (e, v));
         }
         foreign_item_const(t) => {
@@ -324,7 +332,7 @@ pub fn visit_ty_param_bounds<E: Copy>(bounds: @OptVec<TyParamBound>,
                                       (e, v): (E, vt<E>)) {
     for bounds.each |bound| {
         match *bound {
-            TraitTyParamBound(ty) => visit_trait_ref(ty, (e, v)),
+            TraitTyParamBound(ty) => visit_trait_ref(ty, (copy e, v)),
             RegionTyParamBound => {}
         }
     }
@@ -332,14 +340,14 @@ pub fn visit_ty_param_bounds<E: Copy>(bounds: @OptVec<TyParamBound>,
 
 pub fn visit_generics<E: Copy>(generics: &Generics, (e, v): (E, vt<E>)) {
     for generics.ty_params.each |tp| {
-        visit_ty_param_bounds(tp.bounds, (e, v));
+        visit_ty_param_bounds(tp.bounds, (copy e, v));
     }
 }
 
 pub fn visit_fn_decl<E: Copy>(fd: &fn_decl, (e, v): (E, vt<E>)) {
     for fd.inputs.each |a| {
-        (v.visit_pat)(a.pat, (e, v));
-        (v.visit_ty)(a.ty, (e, v));
+        (v.visit_pat)(a.pat, (copy e, v));
+        (v.visit_ty)(a.ty, (copy e, v));
     }
     (v.visit_ty)(fd.output, (e, v));
 }
@@ -365,15 +373,15 @@ pub fn visit_method_helper<E: Copy>(m: &method, (e, v): (E, vt<E>)) {
 
 pub fn visit_fn<E: Copy>(fk: &fn_kind, decl: &fn_decl, body: &blk, _sp: span,
                          _id: node_id, (e, v): (E, vt<E>)) {
-    visit_fn_decl(decl, (e, v));
+    visit_fn_decl(decl, (copy e, v));
     let generics = generics_of_fn(fk);
-    (v.visit_generics)(&generics, (e, v));
+    (v.visit_generics)(&generics, (copy e, v));
     (v.visit_block)(body, (e, v));
 }
 
 pub fn visit_ty_method<E: Copy>(m: &ty_method, (e, v): (E, vt<E>)) {
-    for m.decl.inputs.each |a| { (v.visit_ty)(a.ty, (e, v)); }
-    (v.visit_generics)(&m.generics, (e, v));
+    for m.decl.inputs.each |a| { (v.visit_ty)(a.ty, (copy e, v)); }
+    (v.visit_generics)(&m.generics, (copy e, v));
     (v.visit_ty)(m.decl.output, (e, v));
 }
 
@@ -392,7 +400,7 @@ pub fn visit_struct_def<E: Copy>(
     (e, v): (E, vt<E>)
 ) {
     for sd.fields.each |f| {
-        (v.visit_struct_field)(*f, (e, v));
+        (v.visit_struct_field)(*f, (copy e, v));
     }
 }
 
@@ -406,10 +414,10 @@ pub fn visit_struct_method<E: Copy>(m: @method, (e, v): (E, vt<E>)) {
 
 pub fn visit_block<E: Copy>(b: &blk, (e, v): (E, vt<E>)) {
     for b.node.view_items.each |vi| {
-        (v.visit_view_item)(*vi, (e, v));
+        (v.visit_view_item)(*vi, (copy e, v));
     }
     for b.node.stmts.each |s| {
-        (v.visit_stmt)(*s, (e, v));
+        (v.visit_stmt)(*s, (copy e, v));
     }
     visit_expr_opt(b.node.expr, (e, v));
 }
@@ -435,7 +443,7 @@ pub fn visit_expr_opt<E>(eo: Option<@expr>, (e, v): (E, vt<E>)) {
 }
 
 pub fn visit_exprs<E: Copy>(exprs: &[@expr], (e, v): (E, vt<E>)) {
-    for exprs.each |ex| { (v.visit_expr)(*ex, (e, v)); }
+    for exprs.each |ex| { (v.visit_expr)(*ex, (copy e, v)); }
 }
 
 pub fn visit_mac<E>(_m: &mac, (_e, _v): (E, vt<E>)) {
@@ -444,53 +452,57 @@ pub fn visit_mac<E>(_m: &mac, (_e, _v): (E, vt<E>)) {
 
 pub fn visit_expr<E: Copy>(ex: @expr, (e, v): (E, vt<E>)) {
     match ex.node {
-        expr_vstore(x, _) => (v.visit_expr)(x, (e, v)),
-        expr_vec(ref es, _) => visit_exprs(*es, (e, v)),
+        expr_vstore(x, _) => (v.visit_expr)(x, (copy e, v)),
+        expr_vec(ref es, _) => visit_exprs(*es, (copy e, v)),
         expr_repeat(element, count, _) => {
-            (v.visit_expr)(element, (e, v));
-            (v.visit_expr)(count, (e, v));
+            (v.visit_expr)(element, (copy e, v));
+            (v.visit_expr)(count, (copy e, v));
         }
         expr_struct(p, ref flds, base) => {
-            visit_path(p, (e, v));
-            for flds.each |f| { (v.visit_expr)(f.node.expr, (e, v)); }
-            visit_expr_opt(base, (e, v));
+            visit_path(p, (copy e, v));
+            for flds.each |f| {
+                (v.visit_expr)(f.node.expr, (copy e, v));
+            }
+            visit_expr_opt(base, (copy e, v));
         }
         expr_tup(ref elts) => {
-            for elts.each |el| { (v.visit_expr)(*el, (e, v)) }
+            for elts.each |el| { (v.visit_expr)(*el, (copy e, v)) }
         }
         expr_call(callee, ref args, _) => {
-            visit_exprs(*args, (e, v));
-            (v.visit_expr)(callee, (e, v));
+            visit_exprs(*args, (copy e, v));
+            (v.visit_expr)(callee, (copy e, v));
         }
         expr_method_call(_, callee, _, ref tys, ref args, _) => {
-            visit_exprs(*args, (e, v));
-            for tys.each |tp| { (v.visit_ty)(*tp, (e, v)); }
-            (v.visit_expr)(callee, (e, v));
+            visit_exprs(*args, (copy e, v));
+            for tys.each |tp| {
+                (v.visit_ty)(*tp, (copy e, v));
+            }
+            (v.visit_expr)(callee, (copy e, v));
         }
         expr_binary(_, _, a, b) => {
-            (v.visit_expr)(a, (e, v));
-            (v.visit_expr)(b, (e, v));
+            (v.visit_expr)(a, (copy e, v));
+            (v.visit_expr)(b, (copy e, v));
         }
         expr_addr_of(_, x) | expr_unary(_, _, x) |
-        expr_loop_body(x) | expr_do_body(x) => (v.visit_expr)(x, (e, v)),
+        expr_loop_body(x) | expr_do_body(x) => (v.visit_expr)(x, (copy e, v)),
         expr_lit(_) => (),
         expr_cast(x, t) => {
-            (v.visit_expr)(x, (e, v));
-            (v.visit_ty)(t, (e, v));
+            (v.visit_expr)(x, (copy e, v));
+            (v.visit_ty)(t, (copy e, v));
         }
         expr_if(x, ref b, eo) => {
-            (v.visit_expr)(x, (e, v));
-            (v.visit_block)(b, (e, v));
-            visit_expr_opt(eo, (e, v));
+            (v.visit_expr)(x, (copy e, v));
+            (v.visit_block)(b, (copy e, v));
+            visit_expr_opt(eo, (copy e, v));
         }
         expr_while(x, ref b) => {
-            (v.visit_expr)(x, (e, v));
-            (v.visit_block)(b, (e, v));
+            (v.visit_expr)(x, (copy e, v));
+            (v.visit_block)(b, (copy e, v));
         }
-        expr_loop(ref b, _) => (v.visit_block)(b, (e, v)),
+        expr_loop(ref b, _) => (v.visit_block)(b, (copy e, v)),
         expr_match(x, ref arms) => {
-            (v.visit_expr)(x, (e, v));
-            for arms.each |a| { (v.visit_arm)(a, (e, v)); }
+            (v.visit_expr)(x, (copy e, v));
+            for arms.each |a| { (v.visit_arm)(a, (copy e, v)); }
         }
         expr_fn_block(ref decl, ref body) => {
             (v.visit_fn)(
@@ -499,44 +511,46 @@ pub fn visit_expr<E: Copy>(ex: @expr, (e, v): (E, vt<E>)) {
                 body,
                 ex.span,
                 ex.id,
-                (e, v)
+                (copy e, v)
             );
         }
-        expr_block(ref b) => (v.visit_block)(b, (e, v)),
+        expr_block(ref b) => (v.visit_block)(b, (copy e, v)),
         expr_assign(a, b) => {
-            (v.visit_expr)(b, (e, v));
-            (v.visit_expr)(a, (e, v));
+            (v.visit_expr)(b, (copy e, v));
+            (v.visit_expr)(a, (copy e, v));
         }
-        expr_copy(a) => (v.visit_expr)(a, (e, v)),
+        expr_copy(a) => (v.visit_expr)(a, (copy e, v)),
         expr_assign_op(_, _, a, b) => {
-            (v.visit_expr)(b, (e, v));
-            (v.visit_expr)(a, (e, v));
+            (v.visit_expr)(b, (copy e, v));
+            (v.visit_expr)(a, (copy e, v));
         }
         expr_field(x, _, ref tys) => {
-            (v.visit_expr)(x, (e, v));
-            for tys.each |tp| { (v.visit_ty)(*tp, (e, v)); }
+            (v.visit_expr)(x, (copy e, v));
+            for tys.each |tp| {
+                (v.visit_ty)(*tp, (copy e, v));
+            }
         }
         expr_index(_, a, b) => {
-            (v.visit_expr)(a, (e, v));
-            (v.visit_expr)(b, (e, v));
+            (v.visit_expr)(a, (copy e, v));
+            (v.visit_expr)(b, (copy e, v));
         }
-        expr_path(p) => visit_path(p, (e, v)),
+        expr_path(p) => visit_path(p, (copy e, v)),
         expr_self => (),
         expr_break(_) => (),
         expr_again(_) => (),
-        expr_ret(eo) => visit_expr_opt(eo, (e, v)),
+        expr_ret(eo) => visit_expr_opt(eo, (copy e, v)),
         expr_log(lv, x) => {
-            (v.visit_expr)(lv, (e, v));
-            (v.visit_expr)(x, (e, v));
+            (v.visit_expr)(lv, (copy e, v));
+            (v.visit_expr)(x, (copy e, v));
         }
-        expr_mac(ref mac) => visit_mac(mac, (e, v)),
-        expr_paren(x) => (v.visit_expr)(x, (e, v)),
+        expr_mac(ref mac) => visit_mac(mac, (copy e, v)),
+        expr_paren(x) => (v.visit_expr)(x, (copy e, v)),
         expr_inline_asm(ref a) => {
             for a.inputs.each |&(_, in)| {
-                (v.visit_expr)(in, (e, v));
+                (v.visit_expr)(in, (copy e, v));
             }
             for a.outputs.each |&(_, out)| {
-                (v.visit_expr)(out, (e, v));
+                (v.visit_expr)(out, (copy e, v));
             }
         }
     }
@@ -544,9 +558,9 @@ pub fn visit_expr<E: Copy>(ex: @expr, (e, v): (E, vt<E>)) {
 }
 
 pub fn visit_arm<E: Copy>(a: &arm, (e, v): (E, vt<E>)) {
-    for a.pats.iter().advance |p| { (v.visit_pat)(*p, (e, v)); }
-    visit_expr_opt(a.guard, (e, v));
-    (v.visit_block)(&a.body, (e, v));
+    for a.pats.iter().advance |p| { (v.visit_pat)(*p, (copy e, v)); }
+    visit_expr_opt(a.guard, (copy e, v));
+    (v.visit_block)(&a.body, (copy e, v));
 }
 
 // Simpler, non-context passing interface. Always walks the whole tree, simply
diff --git a/src/rt/arch/i386/morestack.S b/src/rt/arch/i386/morestack.S
index 1b276820805..a95e183a1d1 100644
--- a/src/rt/arch/i386/morestack.S
+++ b/src/rt/arch/i386/morestack.S
@@ -207,12 +207,14 @@ MORESTACK:
 	subl $12, %esp
 
 	// Save the return value of the function we allocated space for
+	movl %edx, 4(%esp)
 	movl %eax, (%esp)
 
 	call UPCALL_DEL_STACK
 
 	// And restore it
 	movl (%esp), %eax
+	movl 4(%esp), %edx
 
 	addl $12,%esp
 
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp
index fe4e75fb8d2..51e2849eb54 100644
--- a/src/rt/rust_builtin.cpp
+++ b/src/rt/rust_builtin.cpp
@@ -17,6 +17,7 @@
 #include "sync/timer.h"
 #include "sync/rust_thread.h"
 #include "rust_abi.h"
+#include "vg/valgrind.h"
 
 #include <time.h>
 
@@ -67,11 +68,10 @@ rust_env_pairs() {
 }
 #endif
 
-extern "C" CDECL void
-vec_reserve_shared_actual(type_desc* ty, rust_vec_box** vp,
-                          size_t n_elts) {
+extern "C" CDECL void *
+rust_local_realloc(rust_opaque_box *ptr, size_t size) {
     rust_task *task = rust_get_current_task();
-    reserve_vec_exact_shared(task, vp, n_elts * ty->size);
+    return task->boxed.realloc(ptr, size);
 }
 
 // This is completely misnamed.
@@ -590,12 +590,18 @@ rust_log_console_on() {
     log_console_on();
 }
 
-extern void log_console_off(rust_env *env);
+extern void log_console_off();
 
 extern "C" CDECL void
 rust_log_console_off() {
-    rust_task *task = rust_get_current_task();
-    log_console_off(task->kernel->env);
+    log_console_off();
+}
+
+extern bool should_log_console();
+
+extern "C" CDECL uintptr_t
+rust_should_log_console() {
+    return (uintptr_t)should_log_console();
 }
 
 extern "C" CDECL void
@@ -731,17 +737,10 @@ rust_task_deref(rust_task *task) {
 // Must call on rust stack.
 extern "C" CDECL void
 rust_call_tydesc_glue(void *root, size_t *tydesc, size_t glue_index) {
-#ifdef _RUST_STAGE0
-    void (*glue_fn)(void *, void *, void *, void *) =
-        (void (*)(void *, void *, void *, void *))tydesc[glue_index];
-    if (glue_fn)
-        glue_fn(0, 0, 0, root);
-#else
     void (*glue_fn)(void *, void *, void *) =
         (void (*)(void *, void *, void *))tydesc[glue_index];
     if (glue_fn)
         glue_fn(0, 0, root);
-#endif
 }
 
 // Don't run on the Rust stack!
@@ -761,11 +760,7 @@ public:
 
     virtual void run() {
         record_sp_limit(0);
-#ifdef _RUST_STAGE0
-        fn.f(NULL, fn.env, NULL);
-#else
         fn.f(fn.env, NULL);
-#endif
     }
 };
 
@@ -888,6 +883,12 @@ rust_delete_memory_region(memory_region *region) {
 }
 
 extern "C" CDECL boxed_region*
+rust_current_boxed_region() {
+    rust_task *task = rust_get_current_task();
+    return &task->boxed;
+}
+
+extern "C" CDECL boxed_region*
 rust_new_boxed_region(memory_region *region,
                       uintptr_t poison_on_free) {
     return new boxed_region(region, poison_on_free);
@@ -903,6 +904,11 @@ rust_boxed_region_malloc(boxed_region *region, type_desc *td, size_t size) {
     return region->malloc(td, size);
 }
 
+extern "C" CDECL rust_opaque_box*
+rust_boxed_region_realloc(boxed_region *region, rust_opaque_box *ptr, size_t size) {
+    return region->realloc(ptr, size);
+}
+
 extern "C" CDECL void
 rust_boxed_region_free(boxed_region *region, rust_opaque_box *box) {
     region->free(box);
@@ -930,6 +936,11 @@ rust_begin_unwind(uintptr_t token) {
 #endif
 }
 
+extern "C" CDECL uintptr_t
+rust_running_on_valgrind() {
+    return RUNNING_ON_VALGRIND;
+}
+
 extern int get_num_cpus();
 
 extern "C" CDECL uintptr_t
@@ -937,6 +948,24 @@ rust_get_num_cpus() {
     return get_num_cpus();
 }
 
+static lock_and_signal global_args_lock;
+static uintptr_t global_args_ptr = 0;
+
+extern "C" CDECL void
+rust_take_global_args_lock() {
+    global_args_lock.lock();
+}
+
+extern "C" CDECL void
+rust_drop_global_args_lock() {
+    global_args_lock.unlock();
+}
+
+extern "C" CDECL uintptr_t*
+rust_get_global_args_ptr() {
+    return &global_args_ptr;
+}
+
 //
 // Local Variables:
 // mode: C++
diff --git a/src/rt/rust_gc_metadata.cpp b/src/rt/rust_gc_metadata.cpp
index fbf0575b31d..e37856255a7 100644
--- a/src/rt/rust_gc_metadata.cpp
+++ b/src/rt/rust_gc_metadata.cpp
@@ -79,6 +79,11 @@ rust_gc_metadata() {
     return (void *)global_safe_points;
 }
 
+extern "C" CDECL void
+rust_update_gc_metadata(const void* map) {
+    update_gc_metadata(map);
+}
+
 //
 // Local Variables:
 // mode: C++
diff --git a/src/rt/rust_log.cpp b/src/rt/rust_log.cpp
index df24f569495..8179c53e96d 100644
--- a/src/rt/rust_log.cpp
+++ b/src/rt/rust_log.cpp
@@ -43,11 +43,15 @@ log_console_on() {
  * overridden by the environment.
  */
 void
-log_console_off(rust_env *env) {
+log_console_off() {
     scoped_lock with(_log_lock);
-    if (env->logspec == NULL) {
-        _log_to_console = false;
-    }
+    _log_to_console = false;
+}
+
+bool
+should_log_console() {
+    scoped_lock with(_log_lock);
+    return _log_to_console;
 }
 
 rust_log::rust_log(rust_sched_loop *sched_loop) :
diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp
index f9b588b7850..fe1b4622137 100644
--- a/src/rt/rust_task.cpp
+++ b/src/rt/rust_task.cpp
@@ -162,11 +162,7 @@ void task_start_wrapper(spawn_args *a)
 
     bool threw_exception = false;
     try {
-#ifdef _RUST_STAGE0
-        a->f(NULL, a->envptr, a->argptr);
-#else
         a->f(a->envptr, a->argptr);
-#endif
     } catch (rust_task *ex) {
         assert(ex == task && "Expected this task to be thrown for unwinding");
         threw_exception = true;
@@ -187,11 +183,7 @@ void task_start_wrapper(spawn_args *a)
     if(env) {
         // free the environment (which should be a unique closure).
         const type_desc *td = env->td;
-#ifdef _RUST_STAGE0
-        td->drop_glue(NULL, NULL, NULL, box_body(env));
-#else
         td->drop_glue(NULL, NULL, box_body(env));
-#endif
         task->kernel->region()->free(env);
     }
 
diff --git a/src/rt/rust_type.h b/src/rt/rust_type.h
index b50c08379de..6d36d2c960a 100644
--- a/src/rt/rust_type.h
+++ b/src/rt/rust_type.h
@@ -21,19 +21,11 @@ struct rust_opaque_box;
 // - the main function: has a NULL environment, but uses the void* arg
 // - unique closures of type fn~(): have a non-NULL environment, but
 //   no arguments (and hence the final void*) is harmless
-#ifdef _RUST_STAGE0
-typedef void (*CDECL spawn_fn)(void *, rust_opaque_box*, void *);
-#else
 typedef void (*CDECL spawn_fn)(rust_opaque_box*, void *);
-#endif
 
 struct type_desc;
 
-#ifdef _RUST_STAGE0
-typedef void CDECL (glue_fn)(void *, void *, const type_desc **, void *);
-#else
 typedef void CDECL (glue_fn)(void *, const type_desc **, void *);
-#endif
 
 // Corresponds to the boxed data in the @ region.  The body follows the
 // header; you can obtain a ptr via box_body() below.
diff --git a/src/rt/rust_util.h b/src/rt/rust_util.h
index 5b8378b0ad3..242c2ef0a81 100644
--- a/src/rt/rust_util.h
+++ b/src/rt/rust_util.h
@@ -57,16 +57,6 @@ vec_data(rust_vec *v) {
     return reinterpret_cast<T*>(v->data);
 }
 
-inline void reserve_vec_exact_shared(rust_task* task, rust_vec_box** vpp,
-                                     size_t size) {
-    rust_opaque_box** ovpp = (rust_opaque_box**)vpp;
-    if (size > (*vpp)->body.alloc) {
-        *vpp = (rust_vec_box*)task->boxed.realloc(
-            *ovpp, size + sizeof(rust_vec));
-        (*vpp)->body.alloc = size;
-    }
-}
-
 inline void reserve_vec_exact(rust_vec_box** vpp,
                               size_t size) {
     if (size > (*vpp)->body.alloc) {
diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in
index 4d7fa589f6f..b604f60cba6 100644
--- a/src/rt/rustrt.def.in
+++ b/src/rt/rustrt.def.in
@@ -37,6 +37,7 @@ rust_list_dir_wfd_size
 rust_list_dir_wfd_fp_buf
 rust_log_console_on
 rust_log_console_off
+rust_should_log_console
 rust_set_environ
 rust_unset_sigprocmask
 rust_sched_current_nonlazy_threads
@@ -52,7 +53,7 @@ rust_get_stack_segment
 rust_get_c_stack
 rust_log_str
 start_task
-vec_reserve_shared_actual
+rust_local_realloc
 vec_reserve_shared
 task_clear_event_reject
 task_wait_event
@@ -186,6 +187,7 @@ rust_call_tydesc_glue
 tdefl_compress_mem_to_heap
 tinfl_decompress_mem_to_heap
 rust_gc_metadata
+rust_update_gc_metadata
 rust_uv_ip4_port
 rust_uv_ip6_port
 rust_uv_tcp_getpeername
@@ -237,6 +239,7 @@ rust_delete_memory_region
 rust_new_boxed_region
 rust_delete_boxed_region
 rust_boxed_region_malloc
+rust_boxed_region_realloc
 rust_boxed_region_free
 rust_try
 rust_begin_unwind
@@ -247,4 +250,7 @@ rust_valgrind_stack_deregister
 rust_take_env_lock
 rust_drop_env_lock
 rust_update_log_settings
+rust_running_on_valgrind
 rust_get_num_cpus
+rust_get_global_args_ptr
+rust_current_boxed_region
diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp
index 53b291ff470..32b6df4e1dd 100644
--- a/src/rustllvm/PassWrapper.cpp
+++ b/src/rustllvm/PassWrapper.cpp
@@ -63,3 +63,8 @@ extern "C" LLVMPassRef LLVMCreatePass(const char * PassName) {
         return (LLVMPassRef)0;
     }
 }
+
+extern "C" void LLVMDestroyPass(LLVMPassRef PassRef) {
+    Pass *p = unwrap(PassRef);
+    delete p;
+}
diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp
index ba87624e2dd..614c1723c5f 100644
--- a/src/rustllvm/RustWrapper.cpp
+++ b/src/rustllvm/RustWrapper.cpp
@@ -560,3 +560,228 @@ extern "C" bool LLVMRustStartMultithreading() {
     assert(lock.release());
     return ret;
 }
+
+
+typedef DIBuilder* DIBuilderRef;
+
+template<typename DIT>
+DIT unwrapDI(LLVMValueRef ref) { 
+    return DIT(ref ? unwrap<MDNode>(ref) : NULL); 
+}
+
+extern "C" DIBuilderRef LLVMDIBuilderCreate(LLVMModuleRef M) {
+    return new DIBuilder(*unwrap(M));
+}
+
+extern "C" void LLVMDIBuilderDispose(DIBuilderRef Builder) {
+    delete Builder;
+}
+
+extern "C" void LLVMDIBuilderFinalize(DIBuilderRef Builder) {
+    Builder->finalize();
+}
+
+extern "C" void LLVMDIBuilderCreateCompileUnit(
+    DIBuilderRef Builder,
+    unsigned Lang,
+    const char* File,
+    const char* Dir,
+    const char* Producer,
+    bool isOptimized,
+    const char* Flags,
+    unsigned RuntimeVer,
+    const char* SplitName) {
+    Builder->createCompileUnit(Lang, File, Dir, Producer, isOptimized,
+        Flags, RuntimeVer, SplitName);
+}
+
+extern "C" LLVMValueRef LLVMDIBuilderCreateFile(
+    DIBuilderRef Builder,
+    const char* Filename,
+    const char* Directory) {
+    return wrap(Builder->createFile(Filename, Directory));
+}
+
+extern "C" LLVMValueRef LLVMDIBuilderCreateSubroutineType(
+    DIBuilderRef Builder,
+    LLVMValueRef File, 
+    LLVMValueRef ParameterTypes) {
+    return wrap(Builder->createSubroutineType(
+        unwrapDI<DIFile>(File), 
+        unwrapDI<DIArray>(ParameterTypes)));
+}
+
+extern "C" LLVMValueRef LLVMDIBuilderCreateFunction(
+    DIBuilderRef Builder,
+    LLVMValueRef Scope, 
+    const char* Name,
+    const char* LinkageName,
+    LLVMValueRef File,  
+    unsigned LineNo,
+    LLVMValueRef Ty, 
+    bool isLocalToUnit,
+    bool isDefinition,
+    unsigned ScopeLine,
+    unsigned Flags,
+    bool isOptimized,
+    LLVMValueRef Fn,
+    LLVMValueRef TParam,
+    LLVMValueRef Decl) {
+    return wrap(Builder->createFunction(
+        unwrapDI<DIScope>(Scope), Name, LinkageName, 
+        unwrapDI<DIFile>(File), LineNo, 
+        unwrapDI<DIType>(Ty), isLocalToUnit, isDefinition, ScopeLine, 
+        Flags, isOptimized,
+        unwrap<Function>(Fn), 
+        unwrapDI<MDNode*>(TParam),
+        unwrapDI<MDNode*>(Decl)));
+}
+
+extern "C" LLVMValueRef LLVMDIBuilderCreateBasicType(
+    DIBuilderRef Builder,
+    const char* Name,
+    uint64_t SizeInBits,
+    uint64_t AlignInBits,
+    unsigned Encoding) {
+    return wrap(Builder->createBasicType(
+        Name, SizeInBits, 
+        AlignInBits, Encoding));
+}
+    
+extern "C" LLVMValueRef LLVMDIBuilderCreatePointerType(
+    DIBuilderRef Builder,
+    LLVMValueRef PointeeTy,
+    uint64_t SizeInBits,
+    uint64_t AlignInBits,
+    const char* Name) {
+    return wrap(Builder->createPointerType(
+        unwrapDI<DIType>(PointeeTy), SizeInBits, AlignInBits, Name));
+}
+
+extern "C" LLVMValueRef LLVMDIBuilderCreateStructType(
+    DIBuilderRef Builder,
+    LLVMValueRef Scope,
+    const char* Name,
+    LLVMValueRef File,
+    unsigned LineNumber,
+    uint64_t SizeInBits,
+    uint64_t AlignInBits,
+    unsigned Flags,
+    LLVMValueRef DerivedFrom,
+    LLVMValueRef Elements,
+    unsigned RunTimeLang,
+    LLVMValueRef VTableHolder) {
+    return wrap(Builder->createStructType(
+        unwrapDI<DIDescriptor>(Scope), Name, 
+        unwrapDI<DIFile>(File), LineNumber, 
+        SizeInBits, AlignInBits, Flags, 
+        unwrapDI<DIType>(DerivedFrom), 
+        unwrapDI<DIArray>(Elements), RunTimeLang, 
+        unwrapDI<MDNode*>(VTableHolder)));
+}
+
+extern "C" LLVMValueRef LLVMDIBuilderCreateMemberType(
+    DIBuilderRef Builder,
+    LLVMValueRef Scope,
+    const char* Name,
+    LLVMValueRef File,
+    unsigned LineNo,
+    uint64_t SizeInBits,
+    uint64_t AlignInBits,
+    uint64_t OffsetInBits,
+    unsigned Flags,
+    LLVMValueRef Ty) {
+    return wrap(Builder->createMemberType(
+        unwrapDI<DIDescriptor>(Scope), Name, 
+        unwrapDI<DIFile>(File), LineNo,
+        SizeInBits, AlignInBits, OffsetInBits, Flags, 
+        unwrapDI<DIType>(Ty)));
+}
+    
+extern "C" LLVMValueRef LLVMDIBuilderCreateLexicalBlock(
+    DIBuilderRef Builder,
+    LLVMValueRef Scope,
+    LLVMValueRef File,
+    unsigned Line,
+    unsigned Col) {
+    return wrap(Builder->createLexicalBlock(
+        unwrapDI<DIDescriptor>(Scope), 
+        unwrapDI<DIFile>(File), Line, Col));
+}
+    
+extern "C" LLVMValueRef LLVMDIBuilderCreateLocalVariable(
+    DIBuilderRef Builder,
+    unsigned Tag,
+    LLVMValueRef Scope,
+    const char* Name,
+    LLVMValueRef File,
+    unsigned LineNo,
+    LLVMValueRef Ty,
+    bool AlwaysPreserve,
+    unsigned Flags,
+    unsigned ArgNo) {
+    return wrap(Builder->createLocalVariable(Tag, 
+        unwrapDI<DIDescriptor>(Scope), Name, 
+        unwrapDI<DIFile>(File), 
+        LineNo, 
+        unwrapDI<DIType>(Ty), AlwaysPreserve, Flags, ArgNo));
+}
+
+extern "C" LLVMValueRef LLVMDIBuilderCreateArrayType(
+    DIBuilderRef Builder,
+    uint64_t Size,  
+    uint64_t AlignInBits,  
+    LLVMValueRef Ty, 
+    LLVMValueRef Subscripts) {
+    return wrap(Builder->createArrayType(Size, AlignInBits,
+        unwrapDI<DIType>(Ty), 
+        unwrapDI<DIArray>(Subscripts)));
+}
+
+extern "C" LLVMValueRef LLVMDIBuilderCreateVectorType(
+    DIBuilderRef Builder,
+    uint64_t Size,  
+    uint64_t AlignInBits,  
+    LLVMValueRef Ty, 
+    LLVMValueRef Subscripts) {
+    return wrap(Builder->createVectorType(Size, AlignInBits,
+        unwrapDI<DIType>(Ty), 
+        unwrapDI<DIArray>(Subscripts)));
+}
+
+extern "C" LLVMValueRef LLVMDIBuilderGetOrCreateSubrange(
+    DIBuilderRef Builder, 
+    int64_t Lo, 
+    int64_t Count) {
+    return wrap(Builder->getOrCreateSubrange(Lo, Count));
+}
+
+extern "C" LLVMValueRef LLVMDIBuilderGetOrCreateArray(
+    DIBuilderRef Builder,
+    LLVMValueRef* Ptr, 
+    unsigned Count) {
+    return wrap(Builder->getOrCreateArray(
+        ArrayRef<Value*>(reinterpret_cast<Value**>(Ptr), Count)));
+}
+
+extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(
+    DIBuilderRef Builder,
+    LLVMValueRef Val,
+    LLVMValueRef VarInfo,
+    LLVMBasicBlockRef InsertAtEnd) {
+    return wrap(Builder->insertDeclare(
+        unwrap(Val), 
+        unwrapDI<DIVariable>(VarInfo), 
+        unwrap(InsertAtEnd)));
+}
+
+extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareBefore(
+    DIBuilderRef Builder,
+    LLVMValueRef Val,
+    LLVMValueRef VarInfo,
+    LLVMValueRef InsertBefore) {
+    return wrap(Builder->insertDeclare(
+        unwrap(Val), 
+        unwrapDI<DIVariable>(VarInfo), 
+        unwrap<Instruction>(InsertBefore)));
+}
diff --git a/src/rustllvm/rustllvm.def.in b/src/rustllvm/rustllvm.def.in
index f5397165781..d5f03ac604b 100644
--- a/src/rustllvm/rustllvm.def.in
+++ b/src/rustllvm/rustllvm.def.in
@@ -588,3 +588,23 @@ LLVMInlineAsm
 LLVMInitializePasses
 LLVMAddPass
 LLVMCreatePass
+LLVMDestroyPass
+LLVMDIBuilderCreate
+LLVMDIBuilderDispose
+LLVMDIBuilderFinalize
+LLVMDIBuilderCreateCompileUnit
+LLVMDIBuilderCreateLocalVariable
+LLVMDIBuilderCreateFunction
+LLVMDIBuilderCreateFile
+LLVMDIBuilderCreateLexicalBlock
+LLVMDIBuilderCreateBasicType
+LLVMDIBuilderCreatePointerType
+LLVMDIBuilderCreateMemberType
+LLVMDIBuilderCreateStructType
+LLVMDIBuilderGetOrCreateSubrange
+LLVMDIBuilderCreateArrayType
+LLVMDIBuilderCreateVectorType
+LLVMDIBuilderCreateSubroutineType
+LLVMDIBuilderGetOrCreateArray
+LLVMDIBuilderInsertDeclareAtEnd
+LLVMDIBuilderInsertDeclareBefore
diff --git a/src/rustllvm/rustllvm.h b/src/rustllvm/rustllvm.h
index 6f11202800c..d4202abd285 100644
--- a/src/rustllvm/rustllvm.h
+++ b/src/rustllvm/rustllvm.h
@@ -43,6 +43,8 @@
 #include "llvm/Transforms/IPO.h"
 #include "llvm/Transforms/Instrumentation.h"
 #include "llvm/Transforms/Vectorize.h"
+#include "llvm/DebugInfo.h"
+#include "llvm/DIBuilder.h"
 #include "llvm-c/Core.h"
 #include "llvm-c/BitReader.h"
 #include "llvm-c/ExecutionEngine.h"
diff --git a/src/snapshots.txt b/src/snapshots.txt
index a68d2205cfb..1aaf5fee26a 100644
--- a/src/snapshots.txt
+++ b/src/snapshots.txt
@@ -1,3 +1,11 @@
+S 2013-06-21 6759ce4
+  macos-i386 6e5395d2fda1db356f64af28ba525031bf9871c7
+  macos-x86_64 7b8ded4e1ba1e999a5614eea3a4acacb2c7cef1d
+  winnt-i386 8337460667b1ea67d5a7aeeb7ba34c0b87e44b83
+  freebsd-x86_64 21e5219ac858795c757a3ac894a6c3e88b43f74d
+  linux-i386 f02609c28f05d9feb9ba4b5f34940a77f22d76f2
+  linux-x86_64 951c9fe9082393c5761bac3163ea59c253f1bece
+
 S 2013-05-17 2d28d64
   macos-i386 abadafb33c9f858543351c822fb468195163559f
   macos-x86_64 4a484693f73bcc8ce2a85708fd4f0c3f6e34969d
diff --git a/src/test/auxiliary/cci_capture_clause.rs b/src/test/auxiliary/cci_capture_clause.rs
index e58b28aa3de..e45bfc8ea5d 100644
--- a/src/test/auxiliary/cci_capture_clause.rs
+++ b/src/test/auxiliary/cci_capture_clause.rs
@@ -14,7 +14,7 @@ use std::task;
 pub fn foo<T:Owned + Copy>(x: T) -> Port<T> {
     let (p, c) = stream();
     do task::spawn() {
-        c.send(x);
+        c.send(copy x);
     }
     p
 }
diff --git a/src/test/auxiliary/cci_nested_lib.rs b/src/test/auxiliary/cci_nested_lib.rs
index 5701912b5f6..c0b98f2af07 100644
--- a/src/test/auxiliary/cci_nested_lib.rs
+++ b/src/test/auxiliary/cci_nested_lib.rs
@@ -25,7 +25,7 @@ pub fn alist_add<A:Copy,B:Copy>(lst: &alist<A,B>, k: A, v: B) {
 pub fn alist_get<A:Copy,B:Copy>(lst: &alist<A,B>, k: A) -> B {
     let eq_fn = lst.eq_fn;
     for lst.data.each |entry| {
-        if eq_fn(entry.key, k) { return entry.value; }
+        if eq_fn(copy entry.key, copy k) { return copy entry.value; }
     }
     fail!();
 }
diff --git a/src/test/bench/msgsend-pipes-shared.rs b/src/test/bench/msgsend-pipes-shared.rs
index 9fbc1d4590d..7a9be754884 100644
--- a/src/test/bench/msgsend-pipes-shared.rs
+++ b/src/test/bench/msgsend-pipes-shared.rs
@@ -30,9 +30,7 @@ use std::ptr;
 use std::uint;
 use std::vec;
 
-macro_rules! move_out (
-    { $x:expr } => { unsafe { let y = *ptr::to_unsafe_ptr(&($x)); y } }
-)
+fn move_out<T>(x: T) {}
 
 enum request {
     get_count,
@@ -91,7 +89,7 @@ fn run(args: &[~str]) {
 
     //error!("sending stop message");
     to_child.send(stop);
-    move_out!(to_child);
+    move_out(to_child);
     let result = from_child.recv();
     let end = extra::time::precise_time_s();
     let elapsed = end - start;
diff --git a/src/test/bench/msgsend-pipes.rs b/src/test/bench/msgsend-pipes.rs
index 2663bb26670..796072c8485 100644
--- a/src/test/bench/msgsend-pipes.rs
+++ b/src/test/bench/msgsend-pipes.rs
@@ -25,9 +25,7 @@ use std::task;
 use std::uint;
 use std::vec;
 
-macro_rules! move_out (
-    { $x:expr } => { unsafe { let y = *ptr::to_unsafe_ptr(&($x)); y } }
-)
+fn move_out<T>(x: T) {}
 
 enum request {
     get_count,
@@ -87,7 +85,7 @@ fn run(args: &[~str]) {
 
     //error!("sending stop message");
     to_child.send(stop);
-    move_out!(to_child);
+    move_out(to_child);
     let result = from_child.recv();
     let end = extra::time::precise_time_s();
     let elapsed = end - start;
diff --git a/src/test/bench/msgsend-ring-pipes.rs b/src/test/bench/msgsend-ring-pipes.rs
index f2bb77b26ef..0f6ca37a3fb 100644
--- a/src/test/bench/msgsend-ring-pipes.rs
+++ b/src/test/bench/msgsend-ring-pipes.rs
@@ -34,10 +34,6 @@ proto! ring (
     }
 )
 
-macro_rules! move_out (
-    ($x:expr) => { unsafe { let y = *ptr::to_unsafe_ptr(&$x); y } }
-)
-
 fn thread_ring(i: uint,
                count: uint,
                num_chan: ring::client::num,
@@ -54,7 +50,7 @@ fn thread_ring(i: uint,
         match recv(port) {
           ring::num(_n, p) => {
             //log(error, _n);
-            num_port = Some(move_out!(p));
+            num_port = Some(p);
           }
         }
     };
diff --git a/src/test/bench/shootout-fasta-redux.rs b/src/test/bench/shootout-fasta-redux.rs
index 8b587f02ad6..8c8b26afa08 100644
--- a/src/test/bench/shootout-fasta-redux.rs
+++ b/src/test/bench/shootout-fasta-redux.rs
@@ -95,7 +95,8 @@ impl RepeatFasta {
             let alu: &[u8] = self.alu.as_bytes();
 
             copy_memory(buf, alu, alu_len);
-            copy_memory(vec::mut_slice(buf, alu_len, buf.len()),
+            let buf_len = buf.len();
+            copy_memory(vec::mut_slice(buf, alu_len, buf_len),
                         alu,
                         LINE_LEN);
 
diff --git a/src/test/bench/shootout-k-nucleotide-pipes.rs b/src/test/bench/shootout-k-nucleotide-pipes.rs
index b7969fb0552..e12df5811ee 100644
--- a/src/test/bench/shootout-k-nucleotide-pipes.rs
+++ b/src/test/bench/shootout-k-nucleotide-pipes.rs
@@ -36,15 +36,15 @@ fn sort_and_fmt(mm: &HashMap<~[u8], uint>, total: uint) -> ~str {
 
    fn le_by_val<TT:Copy,UU:Copy + Ord>(kv0: &(TT,UU),
                                          kv1: &(TT,UU)) -> bool {
-      let (_, v0) = *kv0;
-      let (_, v1) = *kv1;
+      let (_, v0) = copy *kv0;
+      let (_, v1) = copy *kv1;
       return v0 >= v1;
    }
 
    fn le_by_key<TT:Copy + Ord,UU:Copy>(kv0: &(TT,UU),
                                          kv1: &(TT,UU)) -> bool {
-      let (k0, _) = *kv0;
-      let (k1, _) = *kv1;
+      let (k0, _) = copy *kv0;
+      let (k1, _) = copy *kv1;
       return k0 <= k1;
    }
 
diff --git a/src/test/bench/task-perf-one-million.rs b/src/test/bench/task-perf-one-million.rs
index e1a5253444f..e1366a3a869 100644
--- a/src/test/bench/task-perf-one-million.rs
+++ b/src/test/bench/task-perf-one-million.rs
@@ -10,6 +10,8 @@
 
 // Test for concurrent tasks
 
+// xfail-test OOM on linux-32 without opts
+
 use std::comm::*;
 use std::os;
 use std::task;
diff --git a/src/test/compile-fail/infinite-instantiation.rs b/src/test/compile-fail/infinite-instantiation.rs
index 605453d1bca..377b2016bcb 100644
--- a/src/test/compile-fail/infinite-instantiation.rs
+++ b/src/test/compile-fail/infinite-instantiation.rs
@@ -23,7 +23,7 @@ impl to_opt for uint {
 
 impl<T:Copy> to_opt for Option<T> {
     fn to_option(&self) -> Option<Option<T>> {
-        Some(*self)
+        Some(copy *self)
     }
 }
 
diff --git a/src/test/compile-fail/kindck-owned.rs b/src/test/compile-fail/kindck-owned.rs
index 27cc07ed123..ec84551f7b0 100644
--- a/src/test/compile-fail/kindck-owned.rs
+++ b/src/test/compile-fail/kindck-owned.rs
@@ -9,12 +9,13 @@
 // except according to those terms.
 
 fn copy1<T:Copy>(t: T) -> @fn() -> T {
-    let result: @fn() -> T = || t; //~ ERROR value may contain borrowed pointers
+    let result: @fn() -> T = || copy t;
+    //~^ ERROR value may contain borrowed pointers
     result
 }
 
 fn copy2<T:Copy + 'static>(t: T) -> @fn() -> T {
-    let result: @fn() -> T = || t;
+    let result: @fn() -> T = || copy t;
     result
 }
 
diff --git a/src/test/debug-info/basic-types.rs b/src/test/debug-info/basic-types.rs
index 20da6b557f1..616740c850c 100644
--- a/src/test/debug-info/basic-types.rs
+++ b/src/test/debug-info/basic-types.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// xfail-test
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
 
 // Caveats - gdb prints any 8-bit value (meaning rust i8 and u8 values)
 // as its numerical value along with its associated ASCII char, there
@@ -17,8 +17,9 @@
 // its numerical value.
 
 // compile-flags:-Z extra-debug-info
-// debugger:break 67
+// debugger:break _zzz
 // debugger:run
+// debugger:finish
 // debugger:print b
 // check:$1 = false
 // debugger:print i
@@ -66,5 +67,7 @@ fn main() {
     let f: float = 1.5;
     let f32: f32 = 2.5;
     let f64: f64 = 3.5;
-    let _z = ();
+    _zzz();
 }
+
+fn _zzz() {()}
diff --git a/src/test/debug-info/box.rs b/src/test/debug-info/box.rs
index 54aa0c12578..4a3a65a9055 100644
--- a/src/test/debug-info/box.rs
+++ b/src/test/debug-info/box.rs
@@ -12,8 +12,9 @@
 
 // compile-flags:-Z extra-debug-info
 // debugger:set print pretty off
-// debugger:break 29
+// debugger:break _zzz
 // debugger:run
+// debugger:finish
 // debugger:print a->boxed
 // check:$1 = 1
 // debugger:print b->boxed
@@ -28,5 +29,7 @@ fn main() {
     let b = ~(2, 3.5);
     let c = @4;
     let d = @false;
-    let _z = 0;
+    _zzz();
 }
+
+fn _zzz() {()}
diff --git a/src/test/debug-info/struct.rs b/src/test/debug-info/struct.rs
index 16ba6cda590..ddfac9cbeea 100644
--- a/src/test/debug-info/struct.rs
+++ b/src/test/debug-info/struct.rs
@@ -8,12 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// xfail-test
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
 
 // compile-flags:-Z extra-debug-info
 // debugger:set print pretty off
-// debugger:break 29
+// debugger:break _zzz
 // debugger:run
+// debugger:finish
 // debugger:print pair
 // check:$1 = {x = 1, y = 2}
 // debugger:print pair.x
@@ -28,5 +29,7 @@ struct Pair {
 
 fn main() {
     let pair = Pair { x: 1, y: 2 };
-    let _z = ();
+    _zzz();
 }
+
+fn _zzz() {()}
\ No newline at end of file
diff --git a/src/test/debug-info/tuple.rs b/src/test/debug-info/tuple.rs
index 35e2977f562..a50996871ce 100644
--- a/src/test/debug-info/tuple.rs
+++ b/src/test/debug-info/tuple.rs
@@ -8,16 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// xfail-test
+// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
 
 // compile-flags:-Z extra-debug-info
 // debugger:set print pretty off
-// debugger:break 20
+// debugger:break _zzz
 // debugger:run
+// debugger:finish
 // debugger:print t
 // check:$1 = {4, 5.5, true}
 
 fn main() {
     let t = (4, 5.5, true);
-    let _z = ();
+    _zzz();
 }
+
+fn _zzz() {()}
\ No newline at end of file
diff --git a/src/test/debug-info/vec.rs b/src/test/debug-info/vec.rs
index 3876f1c46d4..f198a53729e 100644
--- a/src/test/debug-info/vec.rs
+++ b/src/test/debug-info/vec.rs
@@ -12,8 +12,9 @@
 
 // compile-flags:-Z extra-debug-info
 // debugger:set print pretty off
-// debugger:break 29
+// debugger:break _zzz
 // debugger:run
+// debugger:finish
 // debugger:print a
 // check:$1 = {1, 2, 3}
 // debugger:print b.vec[0]
@@ -28,5 +29,7 @@ fn main() {
     let b = &[4, 5, 6];
     let c = @[7, 8, 9];
     let d = ~[10, 11, 12];
-    let _z = 0;
+    _zzz();
 }
+
+fn _zzz() {()}
diff --git a/src/test/run-pass/alignment-gep-tup-like-1.rs b/src/test/run-pass/alignment-gep-tup-like-1.rs
index bf96d6cfab5..6f1b4b81521 100644
--- a/src/test/run-pass/alignment-gep-tup-like-1.rs
+++ b/src/test/run-pass/alignment-gep-tup-like-1.rs
@@ -13,7 +13,7 @@ struct pair<A,B> {
 }
 
 fn f<A:Copy + 'static>(a: A, b: u16) -> @fn() -> (A, u16) {
-    let result: @fn() -> (A, u16) = || (a, b);
+    let result: @fn() -> (A, u16) = || (copy a, b);
     result
 }
 
diff --git a/src/test/run-pass/alignment-gep-tup-like-2.rs b/src/test/run-pass/alignment-gep-tup-like-2.rs
index 6bf4e96bc05..753e5339de9 100644
--- a/src/test/run-pass/alignment-gep-tup-like-2.rs
+++ b/src/test/run-pass/alignment-gep-tup-like-2.rs
@@ -24,7 +24,7 @@ fn make_cycle<A:Copy>(a: A) {
 }
 
 fn f<A:Owned + Copy,B:Owned + Copy>(a: A, b: B) -> @fn() -> (A, B) {
-    let result: @fn() -> (A, B) = || (a, b);
+    let result: @fn() -> (A, B) = || (copy a, copy b);
     result
 }
 
diff --git a/src/test/run-pass/auto-encode.rs b/src/test/run-pass/auto-encode.rs
index 7b03a699e78..6e5b837e0aa 100644
--- a/src/test/run-pass/auto-encode.rs
+++ b/src/test/run-pass/auto-encode.rs
@@ -41,6 +41,10 @@ fn test_ebml<A:
     let d = EBReader::Doc(@bytes);
     let mut decoder = EBReader::Decoder(d);
     let a2: A = Decodable::decode(&mut decoder);
+    if !(*a1 == a2) {
+        ::std::sys::FailWithCause::fail_with(~"explicit failure" + "foo",
+                                             "auto-encode.rs", 43u);
+    }
     assert!(*a1 == a2);
 }
 
@@ -137,42 +141,47 @@ pub fn main() {
     let a = &Plus(@Minus(@Val(3u), @Val(10u)), @Plus(@Val(22u), @Val(5u)));
     test_ebml(a);
 
-    let a = &Spanned {lo: 0u, hi: 5u, node: 22u};
-    test_ebml(a);
-
-    let a = &Point {x: 3u, y: 5u};
-    test_ebml(a);
-
-    let a = &@[1u, 2u, 3u];
-    test_ebml(a);
-
-    let a = &Top(22u);
-    test_ebml(a);
-
-    let a = &Bottom(222u);
-    test_ebml(a);
-
-    let a = &A;
-    test_ebml(a);
+//    let a = &Spanned {lo: 0u, hi: 5u, node: 22u};
+//    test_ebml(a);
 
-    let a = &B;
-    test_ebml(a);
+//    let a = &Point {x: 3u, y: 5u};
+//    test_ebml(a);
+//
+//    let a = &@[1u, 2u, 3u];
+//    test_ebml(a);
+//
+//    let a = &Top(22u);
+//    test_ebml(a);
+//
+//    let a = &Bottom(222u);
+//    test_ebml(a);
+//
+//    let a = &A;
+//    test_ebml(a);
+//
+//    let a = &B;
+//    test_ebml(a);
 
+    println("Hi1");
     let a = &time::now();
     test_ebml(a);
 
-    test_ebml(&1.0f32);
-    test_ebml(&1.0f64);
+    println("Hi2");
+//    test_ebml(&1.0f32);
+//    test_ebml(&1.0f64);
     test_ebml(&1.0f);
-    test_ebml(&'a');
+//    println("Hi3");
+//    test_ebml(&'a');
 
+    println("Hi4");
     let mut a = HashMap::new();
     test_ebml(&a);
     a.insert(1, 2);
+    println("Hi4");
     test_ebml(&a);
 
-    let mut a = HashSet::new();
-    test_ebml(&a);
-    a.insert(1);
-    test_ebml(&a);
+//    let mut a = HashSet::new();
+//    test_ebml(&a);
+//    a.insert(1);
+//    test_ebml(&a);
 }
diff --git a/src/test/run-pass/borrowck-move-from-unsafe-ptr-ok.rs b/src/test/run-pass/borrowck-move-from-unsafe-ptr-ok.rs
deleted file mode 100644
index 2d83e9746b5..00000000000
--- a/src/test/run-pass/borrowck-move-from-unsafe-ptr-ok.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// just make sure this compiles:
-
-fn bar(x: *~int) -> ~int {
-    unsafe {
-        let y = *x;
-        return y;
-    }
-}
-
-pub fn main() {
-}
diff --git a/src/test/run-pass/borrowed-ptr-pattern.rs b/src/test/run-pass/borrowed-ptr-pattern.rs
index e0af2e80508..86e8f600cd5 100644
--- a/src/test/run-pass/borrowed-ptr-pattern.rs
+++ b/src/test/run-pass/borrowed-ptr-pattern.rs
@@ -10,7 +10,7 @@
 
 fn foo<T:Copy>(x: &T) -> T{
     match x {
-        &a => a
+        &ref a => copy *a
     }
 }
 
diff --git a/src/test/run-pass/box-unbox.rs b/src/test/run-pass/box-unbox.rs
index e7dc4365679..f4fb10fea72 100644
--- a/src/test/run-pass/box-unbox.rs
+++ b/src/test/run-pass/box-unbox.rs
@@ -12,7 +12,7 @@
 
 struct Box<T> {c: @T}
 
-fn unbox<T:Copy>(b: Box<T>) -> T { return *b.c; }
+fn unbox<T:Copy>(b: Box<T>) -> T { return copy *b.c; }
 
 pub fn main() {
     let foo: int = 17;
diff --git a/src/test/run-pass/close-over-big-then-small-data.rs b/src/test/run-pass/close-over-big-then-small-data.rs
index 736c0f91941..69da3c8d986 100644
--- a/src/test/run-pass/close-over-big-then-small-data.rs
+++ b/src/test/run-pass/close-over-big-then-small-data.rs
@@ -17,7 +17,7 @@ struct Pair<A,B> {
 }
 
 fn f<A:Copy + 'static>(a: A, b: u16) -> @fn() -> (A, u16) {
-    let result: @fn() -> (A, u16) = || (a, b);
+    let result: @fn() -> (A, u16) = || (copy a, b);
     result
 }
 
diff --git a/src/test/run-pass/deriving-zero.rs b/src/test/run-pass/deriving-zero.rs
new file mode 100644
index 00000000000..2ee57624112
--- /dev/null
+++ b/src/test/run-pass/deriving-zero.rs
@@ -0,0 +1,40 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::util;
+use std::num::Zero;
+
+#[deriving(Zero)]
+struct A;
+#[deriving(Zero)]
+struct B(int);
+#[deriving(Zero)]
+struct C(int, int);
+#[deriving(Zero)]
+struct D { a: int }
+#[deriving(Zero)]
+struct E { a: int, b: int }
+
+#[deriving(Zero)]
+struct Lots {
+    a: ~str,
+    b: @str,
+    c: Option<util::NonCopyable>,
+    d: u8,
+    e: char,
+    f: float,
+    g: (f32, char),
+    h: ~[util::NonCopyable],
+    i: @mut (int, int),
+}
+
+fn main() {
+    assert!(Zero::zero::<Lots>().is_zero());
+}
diff --git a/src/test/run-pass/expr-block-generic-box2.rs b/src/test/run-pass/expr-block-generic-box2.rs
index 5d26fbdd789..9cf047d425c 100644
--- a/src/test/run-pass/expr-block-generic-box2.rs
+++ b/src/test/run-pass/expr-block-generic-box2.rs
@@ -14,7 +14,7 @@
 type compare<T> = @fn(T, T) -> bool;
 
 fn test_generic<T:Copy>(expected: T, eq: compare<T>) {
-    let actual: T = { expected };
+    let actual: T = { copy expected };
     assert!((eq(expected, actual)));
 }
 
diff --git a/src/test/run-pass/expr-block-generic-unique2.rs b/src/test/run-pass/expr-block-generic-unique2.rs
index 0d70bff3649..25bf553ff35 100644
--- a/src/test/run-pass/expr-block-generic-unique2.rs
+++ b/src/test/run-pass/expr-block-generic-unique2.rs
@@ -14,7 +14,7 @@
 type compare<T> = @fn(T, T) -> bool;
 
 fn test_generic<T:Copy>(expected: T, eq: compare<T>) {
-    let actual: T = { expected };
+    let actual: T = { copy expected };
     assert!((eq(expected, actual)));
 }
 
diff --git a/src/test/run-pass/expr-block-generic.rs b/src/test/run-pass/expr-block-generic.rs
index e507700e6b2..afb1a4c76bb 100644
--- a/src/test/run-pass/expr-block-generic.rs
+++ b/src/test/run-pass/expr-block-generic.rs
@@ -16,7 +16,7 @@
 type compare<T> = @fn(T, T) -> bool;
 
 fn test_generic<T:Copy>(expected: T, eq: compare<T>) {
-    let actual: T = { expected };
+    let actual: T = { copy expected };
     assert!((eq(expected, actual)));
 }
 
diff --git a/src/test/run-pass/expr-if-generic-box2.rs b/src/test/run-pass/expr-if-generic-box2.rs
index 12193037e11..186d15c3490 100644
--- a/src/test/run-pass/expr-if-generic-box2.rs
+++ b/src/test/run-pass/expr-if-generic-box2.rs
@@ -14,7 +14,7 @@
 type compare<T> = @fn(T, T) -> bool;
 
 fn test_generic<T:Copy>(expected: T, not_expected: T, eq: compare<T>) {
-    let actual: T = if true { expected } else { not_expected };
+    let actual: T = if true { copy expected } else { not_expected };
     assert!((eq(expected, actual)));
 }
 
diff --git a/src/test/run-pass/expr-if-generic.rs b/src/test/run-pass/expr-if-generic.rs
index 8d2ce83c879..2e6db3bba07 100644
--- a/src/test/run-pass/expr-if-generic.rs
+++ b/src/test/run-pass/expr-if-generic.rs
@@ -15,7 +15,7 @@
 type compare<T> = @fn(T, T) -> bool;
 
 fn test_generic<T:Copy>(expected: T, not_expected: T, eq: compare<T>) {
-    let actual: T = if true { expected } else { not_expected };
+    let actual: T = if true { copy expected } else { not_expected };
     assert!((eq(expected, actual)));
 }
 
diff --git a/src/test/run-pass/expr-match-generic-box2.rs b/src/test/run-pass/expr-match-generic-box2.rs
index c5c89b42825..64aa4ce3609 100644
--- a/src/test/run-pass/expr-match-generic-box2.rs
+++ b/src/test/run-pass/expr-match-generic-box2.rs
@@ -14,7 +14,7 @@
 type compare<T> = @fn(T, T) -> bool;
 
 fn test_generic<T:Copy>(expected: T, eq: compare<T>) {
-    let actual: T = match true { true => { expected }, _ => fail!("wat") };
+    let actual: T = match true { true => { copy expected }, _ => fail!("wat") };
     assert!((eq(expected, actual)));
 }
 
diff --git a/src/test/run-pass/expr-match-generic.rs b/src/test/run-pass/expr-match-generic.rs
index 04a229f2280..bd87e7207d1 100644
--- a/src/test/run-pass/expr-match-generic.rs
+++ b/src/test/run-pass/expr-match-generic.rs
@@ -14,7 +14,7 @@
 type compare<T> = @fn(T, T) -> bool;
 
 fn test_generic<T:Copy>(expected: T, eq: compare<T>) {
-  let actual: T = match true { true => { expected }, _ => fail!("wat") };
+  let actual: T = match true { true => { copy expected }, _ => fail!("wat") };
     assert!((eq(expected, actual)));
 }
 
diff --git a/src/test/run-pass/extern-pub.rs b/src/test/run-pass/extern-pub.rs
index 29b0457fc05..e722c4f5c6a 100644
--- a/src/test/run-pass/extern-pub.rs
+++ b/src/test/run-pass/extern-pub.rs
@@ -1,11 +1,7 @@
 use std::libc;
-use std::sys;
-use std::vec;
 
 extern {
-    pub unsafe fn vec_reserve_shared_actual(t: *sys::TypeDesc,
-                                            v: **vec::raw::VecRepr,
-                                            n: libc::size_t);
+    pub unsafe fn debug_get_stk_seg() -> *libc::c_void;
 }
 
 pub fn main() {
diff --git a/src/test/run-pass/generic-derived-type.rs b/src/test/run-pass/generic-derived-type.rs
index 9e266a3f208..649fe3433b4 100644
--- a/src/test/run-pass/generic-derived-type.rs
+++ b/src/test/run-pass/generic-derived-type.rs
@@ -15,8 +15,7 @@ fn g<X:Copy>(x: X) -> X { return x; }
 struct Pair<T> {a: T, b: T}
 
 fn f<T:Copy>(t: T) -> Pair<T> {
-
-    let x: Pair<T> = Pair {a: t, b: t};
+    let x: Pair<T> = Pair {a: copy t, b: t};
     return g::<Pair<T>>(x);
 }
 
diff --git a/src/test/run-pass/issue-2718.rs b/src/test/run-pass/issue-2718.rs
index 4ef83e405be..014aebeff9d 100644
--- a/src/test/run-pass/issue-2718.rs
+++ b/src/test/run-pass/issue-2718.rs
@@ -233,9 +233,7 @@ pub mod pingpong {
             let addr : *::pipes::send_packet<pong> = match &p {
               &ping(ref x) => { cast::transmute(x) }
             };
-            let liberated_value = *addr;
-            cast::forget(p);
-            liberated_value
+            fail!()
         }
     }
 
@@ -244,9 +242,7 @@ pub mod pingpong {
             let addr : *::pipes::send_packet<ping> = match &p {
               &pong(ref x) => { cast::transmute(x) }
             };
-            let liberated_value = *addr;
-            cast::forget(p);
-            liberated_value
+            fail!()
         }
     }
 
diff --git a/src/test/run-pass/ivec-add.rs b/src/test/run-pass/ivec-add.rs
index 80168daf62d..7cee6b4e8de 100644
--- a/src/test/run-pass/ivec-add.rs
+++ b/src/test/run-pass/ivec-add.rs
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn double<T:Copy>(a: T) -> ~[T] { return ~[a] + ~[a]; }
+fn double<T:Copy>(a: T) -> ~[T] { return ~[copy a] + ~[a]; }
 
-fn double_int(a: int) -> ~[int] { return ~[a] + ~[a]; }
+fn double_int(a: int) -> ~[int] { return ~[copy a] + ~[a]; }
 
 pub fn main() {
     let mut d = double(1);
diff --git a/src/test/run-pass/kindck-owned-trait-contains-1.rs b/src/test/run-pass/kindck-owned-trait-contains-1.rs
index 35b5e077e7a..c51094d26c8 100644
--- a/src/test/run-pass/kindck-owned-trait-contains-1.rs
+++ b/src/test/run-pass/kindck-owned-trait-contains-1.rs
@@ -11,7 +11,7 @@
 trait repeat<A> { fn get(&self) -> A; }
 
 impl<A:Copy> repeat<A> for @A {
-    fn get(&self) -> A { **self }
+    fn get(&self) -> A { copy **self }
 }
 
 fn repeater<A:Copy>(v: @A) -> @repeat<A> {
diff --git a/src/test/run-pass/morestack6.rs b/src/test/run-pass/morestack6.rs
index 1dc8503aeb2..0e0bf2a13e1 100644
--- a/src/test/run-pass/morestack6.rs
+++ b/src/test/run-pass/morestack6.rs
@@ -23,7 +23,6 @@ mod rustrt {
         pub fn rust_get_sched_id() -> libc::intptr_t;
         pub fn rust_get_argc() -> libc::c_int;
         pub fn get_task_id() -> libc::intptr_t;
-        pub fn rust_sched_threads();
         pub fn rust_get_task();
     }
 }
@@ -31,7 +30,6 @@ mod rustrt {
 fn calllink01() { unsafe { rustrt::rust_get_sched_id(); } }
 fn calllink02() { unsafe { rustrt::rust_get_argc(); } }
 fn calllink08() { unsafe { rustrt::get_task_id(); } }
-fn calllink09() { unsafe { rustrt::rust_sched_threads(); } }
 fn calllink10() { unsafe { rustrt::rust_get_task(); } }
 
 fn runtest(f: extern fn(), frame_backoff: u32) {
@@ -64,7 +62,6 @@ pub fn main() {
         calllink01,
         calllink02,
         calllink08,
-        calllink09,
         calllink10
     ];
     let mut rng = rand::rng();
diff --git a/src/test/run-pass/pipe-bank-proto.rs b/src/test/run-pass/pipe-bank-proto.rs
index d723fa32209..7ac38966faa 100644
--- a/src/test/run-pass/pipe-bank-proto.rs
+++ b/src/test/run-pass/pipe-bank-proto.rs
@@ -45,24 +45,18 @@ proto! bank (
     }
 )
 
-macro_rules! move_it (
-    { $x:expr } => { unsafe { let y = *ptr::to_unsafe_ptr(&($x)); y } }
-)
-
 fn switch<T:Owned,U>(endp: pipes::RecvPacket<T>,
                      f: &fn(v: Option<T>) -> U) -> U {
     f(pipes::try_recv(endp))
 }
 
-fn move_it<T>(x: T) -> T { x }
-
 macro_rules! follow (
     {
         $($message:path$(($($x: ident),+))||* -> $next:ident $e:expr)+
     } => (
         |m| match m {
           $(Some($message($($($x,)+)* next)) => {
-            let $next = move_it!(next);
+            let $next = next;
             $e })+
           _ => { fail!() }
         }
@@ -96,7 +90,7 @@ fn bank_client(bank: bank::client::login) {
     let bank = client::login(bank, ~"theincredibleholk", ~"1234");
     let bank = match try_recv(bank) {
       Some(ok(connected)) => {
-        move_it!(connected)
+        connected
       }
       Some(invalid(_)) => { fail!("login unsuccessful") }
       None => { fail!("bank closed the connection") }
diff --git a/src/test/run-pass/reflect-visit-data.rs b/src/test/run-pass/reflect-visit-data.rs
index f4ccd038afe..e091554a357 100644
--- a/src/test/run-pass/reflect-visit-data.rs
+++ b/src/test/run-pass/reflect-visit-data.rs
@@ -486,9 +486,9 @@ struct Stuff {
 }
 
 impl my_visitor {
-    pub fn get<T>(&self, f: &fn(T)) {
+    pub fn get<T:Copy>(&self, f: &fn(T)) {
         unsafe {
-            f(*(self.ptr1 as *T));
+            f(copy *(self.ptr1 as *T));
         }
     }
 
diff --git a/src/test/run-pass/resource-generic.rs b/src/test/run-pass/resource-generic.rs
index 41eafb0293a..7a18cd02c2d 100644
--- a/src/test/run-pass/resource-generic.rs
+++ b/src/test/run-pass/resource-generic.rs
@@ -20,7 +20,7 @@ struct finish<T> {
 impl<T:Copy> Drop for finish<T> {
     fn finalize(&self) {
         unsafe {
-            (self.arg.fin)(self.arg.val);
+            (self.arg.fin)(copy self.arg.val);
         }
     }
 }
diff --git a/src/test/run-pass/sized-borrowed-pointer b/src/test/run-pass/sized-borrowed-pointer
deleted file mode 100755
index 275622161d3..00000000000
--- a/src/test/run-pass/sized-borrowed-pointer
+++ /dev/null
Binary files differdiff --git a/src/test/run-pass/sized-owned-pointer b/src/test/run-pass/sized-owned-pointer
deleted file mode 100755
index 3a290ba47ff..00000000000
--- a/src/test/run-pass/sized-owned-pointer
+++ /dev/null
Binary files differdiff --git a/src/test/run-pass/static-method-test.rs b/src/test/run-pass/static-method-test.rs
index 4dde143f686..2d6b2141c5c 100644
--- a/src/test/run-pass/static-method-test.rs
+++ b/src/test/run-pass/static-method-test.rs
@@ -21,7 +21,7 @@ trait bool_like {
 }
 
 fn andand<T:bool_like + Copy>(x1: T, x2: T) -> T {
-    bool_like::select(x1, x2, x1)
+    bool_like::select(copy x1, x2, x1)
 }
 
 impl bool_like for bool {
diff --git a/src/test/run-pass/unfoldr-cross-crate.rs b/src/test/run-pass/unfoldr-cross-crate.rs
new file mode 100644
index 00000000000..4e98543ae82
--- /dev/null
+++ b/src/test/run-pass/unfoldr-cross-crate.rs
@@ -0,0 +1,34 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::iterator::*;
+
+// UnfoldrIterator had a bug with 'self that mean it didn't work
+// cross-crate
+
+fn main() {
+    fn count(st: &mut uint) -> Option<uint> {
+        if *st < 10 {
+            let ret = Some(*st);
+            *st += 1;
+            ret
+        } else {
+            None
+        }
+    }
+
+    let mut it = UnfoldrIterator::new(count, 0);
+    let mut i = 0;
+    for it.advance |counted| {
+        assert_eq!(counted, i);
+        i += 1;
+    }
+    assert_eq!(i, 10);
+}