about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiletest/common.rs3
-rw-r--r--src/compiletest/compiletest.rs3
-rw-r--r--src/compiletest/runtest.rs9
-rw-r--r--src/doc/reference.md12
-rw-r--r--src/doc/trpl/ffi.md6
-rw-r--r--src/doc/trpl/patterns.md2
-rw-r--r--src/liballoc/arc.rs15
-rw-r--r--src/liballoc/boxed.rs25
-rw-r--r--src/liballoc/lib.rs1
-rw-r--r--src/liballoc/rc.rs19
-rw-r--r--src/libarena/lib.rs6
-rw-r--r--src/libcollections/binary_heap.rs7
-rw-r--r--src/libcollections/bit.rs1078
-rw-r--r--src/libcollections/borrow.rs316
-rw-r--r--src/libcollections/borrow_stage0.rs313
-rw-r--r--src/libcollections/btree/map.rs57
-rw-r--r--src/libcollections/btree/node.rs93
-rw-r--r--src/libcollections/btree/set.rs10
-rw-r--r--src/libcollections/enum_set.rs32
-rw-r--r--src/libcollections/lib.rs54
-rw-r--r--src/libcollections/linked_list.rs (renamed from src/libcollections/dlist.rs)257
-rw-r--r--src/libcollections/slice.rs31
-rw-r--r--src/libcollections/str.rs113
-rw-r--r--src/libcollections/string.rs70
-rw-r--r--src/libcollections/vec.rs106
-rw-r--r--src/libcollections/vec_deque.rs (renamed from src/libcollections/ring_buf.rs)446
-rw-r--r--src/libcollections/vec_map.rs25
-rw-r--r--src/libcore/array.rs40
-rw-r--r--src/libcore/atomic.rs5
-rw-r--r--src/libcore/borrow.rs265
-rw-r--r--src/libcore/cmp.rs12
-rw-r--r--src/libcore/default.rs16
-rw-r--r--src/libcore/fmt/mod.rs7
-rw-r--r--src/libcore/hash/mod.rs471
-rw-r--r--src/libcore/hash/sip.rs45
-rw-r--r--src/libcore/intrinsics.rs24
-rw-r--r--src/libcore/iter.rs52
-rw-r--r--src/libcore/lib.rs1
-rw-r--r--src/libcore/marker.rs393
-rw-r--r--src/libcore/nonzero.rs9
-rw-r--r--src/libcore/option.rs6
-rw-r--r--src/libcore/ptr.rs56
-rw-r--r--src/libcore/result.rs7
-rw-r--r--src/libcore/slice.rs14
-rw-r--r--src/libcore/str/mod.rs2
-rw-r--r--src/libcoretest/hash/mod.rs24
-rw-r--r--src/libcoretest/iter.rs46
-rw-r--r--src/libcoretest/mem.rs2
-rw-r--r--src/libcoretest/ptr.rs4
-rw-r--r--src/libcoretest/slice.rs12
-rw-r--r--src/libflate/lib.rs8
-rw-r--r--src/libfmt_macros/lib.rs4
-rw-r--r--src/libgetopts/lib.rs30
-rw-r--r--src/libgraphviz/lib.rs31
-rw-r--r--src/liblog/lib.rs6
-rw-r--r--src/librand/distributions/mod.rs11
-rw-r--r--src/librand/isaac.rs4
-rw-r--r--src/librand/lib.rs4
-rw-r--r--src/librustc/lint/builtin.rs20
-rw-r--r--src/librustc/lint/context.rs34
-rw-r--r--src/librustc/lint/mod.rs8
-rw-r--r--src/librustc/metadata/creader.rs12
-rw-r--r--src/librustc/metadata/cstore.rs5
-rw-r--r--src/librustc/metadata/encoder.rs52
-rw-r--r--src/librustc/metadata/loader.rs14
-rw-r--r--src/librustc/metadata/tydecode.rs2
-rw-r--r--src/librustc/middle/astencode.rs2
-rw-r--r--src/librustc/middle/cfg/graphviz.rs2
-rw-r--r--src/librustc/middle/check_match.rs22
-rw-r--r--src/librustc/middle/const_eval.rs12
-rw-r--r--src/librustc/middle/dataflow.rs8
-rw-r--r--src/librustc/middle/dead.rs2
-rw-r--r--src/librustc/middle/dependency_format.rs2
-rw-r--r--src/librustc/middle/expr_use_visitor.rs15
-rw-r--r--src/librustc/middle/graph.rs6
-rw-r--r--src/librustc/middle/infer/bivariate.rs145
-rw-r--r--src/librustc/middle/infer/combine.rs146
-rw-r--r--src/librustc/middle/infer/equate.rs27
-rw-r--r--src/librustc/middle/infer/error_reporting.rs32
-rw-r--r--src/librustc/middle/infer/glb.rs47
-rw-r--r--src/librustc/middle/infer/higher_ranked/mod.rs4
-rw-r--r--src/librustc/middle/infer/lub.rs47
-rw-r--r--src/librustc/middle/infer/mod.rs6
-rw-r--r--src/librustc/middle/infer/region_inference/mod.rs2
-rw-r--r--src/librustc/middle/infer/sub.rs48
-rw-r--r--src/librustc/middle/infer/type_variable.rs10
-rw-r--r--src/librustc/middle/infer/unify.rs9
-rw-r--r--src/librustc/middle/lang_items.rs19
-rw-r--r--src/librustc/middle/liveness.rs8
-rw-r--r--src/librustc/middle/region.rs2
-rw-r--r--src/librustc/middle/resolve_lifetime.rs2
-rw-r--r--src/librustc/middle/subst.rs2
-rw-r--r--src/librustc/middle/traits/coherence.rs101
-rw-r--r--src/librustc/middle/traits/mod.rs11
-rw-r--r--src/librustc/middle/traits/object_safety.rs55
-rw-r--r--src/librustc/middle/traits/select.rs19
-rw-r--r--src/librustc/middle/ty.rs92
-rw-r--r--src/librustc/middle/weak_lang_items.rs2
-rw-r--r--src/librustc/plugin/load.rs6
-rw-r--r--src/librustc/session/config.rs10
-rw-r--r--src/librustc/session/mod.rs4
-rw-r--r--src/librustc/util/common.rs93
-rw-r--r--src/librustc/util/lev_distance.rs2
-rw-r--r--src/librustc/util/nodemap.rs28
-rw-r--r--src/librustc/util/ppaux.rs46
-rw-r--r--src/librustc_back/archive.rs20
-rw-r--r--src/librustc_back/rpath.rs19
-rw-r--r--src/librustc_back/target/mod.rs6
-rw-r--r--src/librustc_borrowck/borrowck/check_loans.rs2
-rw-r--r--src/librustc_borrowck/borrowck/fragments.rs28
-rw-r--r--src/librustc_borrowck/borrowck/mod.rs2
-rw-r--r--src/librustc_borrowck/graphviz.rs2
-rw-r--r--src/librustc_borrowck/lib.rs1
-rw-r--r--src/librustc_driver/driver.rs8
-rw-r--r--src/librustc_driver/lib.rs10
-rw-r--r--src/librustc_driver/pretty.rs12
-rw-r--r--src/librustc_driver/test.rs4
-rw-r--r--src/librustc_llvm/archive_ro.rs4
-rw-r--r--src/librustc_llvm/lib.rs3
-rw-r--r--src/librustc_privacy/lib.rs6
-rw-r--r--src/librustc_resolve/lib.rs70
-rw-r--r--src/librustc_trans/back/link.rs46
-rw-r--r--src/librustc_trans/back/lto.rs4
-rw-r--r--src/librustc_trans/back/write.rs52
-rw-r--r--src/librustc_trans/lib.rs1
-rw-r--r--src/librustc_trans/save/mod.rs88
-rw-r--r--src/librustc_trans/save/recorder.rs12
-rw-r--r--src/librustc_trans/trans/_match.rs18
-rw-r--r--src/librustc_trans/trans/adt.rs42
-rw-r--r--src/librustc_trans/trans/asm.rs16
-rw-r--r--src/librustc_trans/trans/base.rs75
-rw-r--r--src/librustc_trans/trans/builder.rs12
-rw-r--r--src/librustc_trans/trans/callee.rs8
-rw-r--r--src/librustc_trans/trans/cleanup.rs4
-rw-r--r--src/librustc_trans/trans/closure.rs6
-rw-r--r--src/librustc_trans/trans/common.rs11
-rw-r--r--src/librustc_trans/trans/consts.rs26
-rw-r--r--src/librustc_trans/trans/context.rs12
-rw-r--r--src/librustc_trans/trans/controlflow.rs6
-rw-r--r--src/librustc_trans/trans/debuginfo.rs124
-rw-r--r--src/librustc_trans/trans/expr.rs20
-rw-r--r--src/librustc_trans/trans/foreign.rs14
-rw-r--r--src/librustc_trans/trans/glue.rs8
-rw-r--r--src/librustc_trans/trans/intrinsic.rs8
-rw-r--r--src/librustc_trans/trans/monomorphize.rs10
-rw-r--r--src/librustc_trans/trans/tvec.rs80
-rw-r--r--src/librustc_trans/trans/type_.rs2
-rw-r--r--src/librustc_trans/trans/type_of.rs10
-rw-r--r--src/librustc_typeck/astconv.rs33
-rw-r--r--src/librustc_typeck/check/_match.rs2
-rw-r--r--src/librustc_typeck/check/callee.rs2
-rw-r--r--src/librustc_typeck/check/implicator.rs8
-rw-r--r--src/librustc_typeck/check/method/probe.rs2
-rw-r--r--src/librustc_typeck/check/method/suggest.rs8
-rw-r--r--src/librustc_typeck/check/mod.rs38
-rw-r--r--src/librustc_typeck/check/regionck.rs20
-rw-r--r--src/librustc_typeck/check/vtable.rs7
-rw-r--r--src/librustc_typeck/check/wf.rs158
-rw-r--r--src/librustc_typeck/collect.rs66
-rw-r--r--src/librustc_typeck/constrained_type_params.rs61
-rw-r--r--src/librustc_typeck/lib.rs1
-rw-r--r--src/librustc_typeck/variance.rs396
-rw-r--r--src/librustdoc/flock.rs2
-rw-r--r--src/librustdoc/html/highlight.rs2
-rw-r--r--src/librustdoc/html/markdown.rs4
-rw-r--r--src/librustdoc/html/render.rs3
-rw-r--r--src/librustdoc/html/static/main.css4
-rw-r--r--src/librustdoc/lib.rs1
-rw-r--r--src/librustdoc/passes.rs2
-rw-r--r--src/librustdoc/visit_ast.rs2
-rw-r--r--src/libserialize/collection_impls.rs94
-rw-r--r--src/libserialize/json.rs12
-rw-r--r--src/libserialize/lib.rs1
-rw-r--r--src/libserialize/serialize.rs2
-rw-r--r--src/libstd/collections/hash/map.rs139
-rw-r--r--src/libstd/collections/hash/map_stage0.rs2330
-rw-r--r--src/libstd/collections/hash/mod.rs8
-rw-r--r--src/libstd/collections/hash/set.rs128
-rw-r--r--src/libstd/collections/hash/set_stage0.rs1252
-rw-r--r--src/libstd/collections/hash/state.rs7
-rw-r--r--src/libstd/collections/hash/table.rs79
-rw-r--r--src/libstd/collections/mod.rs42
-rw-r--r--src/libstd/dynamic_lib.rs8
-rw-r--r--src/libstd/env.rs8
-rw-r--r--src/libstd/ffi/c_str.rs402
-rw-r--r--src/libstd/ffi/mod.rs4
-rw-r--r--src/libstd/ffi/os_str.rs36
-rw-r--r--src/libstd/io/buffered.rs4
-rw-r--r--src/libstd/io/cursor.rs14
-rw-r--r--src/libstd/lib.rs2
-rw-r--r--src/libstd/net/addr.rs16
-rw-r--r--src/libstd/net/ip.rs16
-rw-r--r--src/libstd/old_io/buffered.rs6
-rw-r--r--src/libstd/old_io/mod.rs10
-rw-r--r--src/libstd/old_io/net/pipe.rs6
-rw-r--r--src/libstd/old_io/process.rs40
-rw-r--r--src/libstd/old_path/mod.rs4
-rw-r--r--src/libstd/old_path/posix.rs13
-rw-r--r--src/libstd/old_path/windows.rs56
-rw-r--r--src/libstd/os.rs5
-rw-r--r--src/libstd/panicking.rs2
-rwxr-xr-xsrc/libstd/path.rs28
-rw-r--r--src/libstd/rand/mod.rs2
-rw-r--r--src/libstd/rt/args.rs9
-rw-r--r--src/libstd/sys/common/net.rs17
-rw-r--r--src/libstd/sys/common/net2.rs2
-rw-r--r--src/libstd/sys/common/wtf8.rs38
-rw-r--r--src/libstd/sys/unix/backtrace.rs6
-rw-r--r--src/libstd/sys/unix/ext.rs12
-rw-r--r--src/libstd/sys/unix/fs.rs42
-rw-r--r--src/libstd/sys/unix/fs2.rs44
-rw-r--r--src/libstd/sys/unix/mod.rs5
-rw-r--r--src/libstd/sys/unix/net.rs4
-rw-r--r--src/libstd/sys/unix/os.rs28
-rw-r--r--src/libstd/sys/unix/pipe.rs6
-rw-r--r--src/libstd/sys/unix/process.rs249
-rw-r--r--src/libstd/sys/unix/process2.rs9
-rw-r--r--src/libstd/sys/unix/thread.rs6
-rw-r--r--src/libstd/sys/windows/backtrace.rs4
-rw-r--r--src/libstd/sys/windows/c.rs2
-rw-r--r--src/libstd/sys/windows/mod.rs4
-rw-r--r--src/libstd/sys/windows/os.rs10
-rw-r--r--src/libstd/sys/windows/process.rs195
-rw-r--r--src/libstd/thread.rs6
-rw-r--r--src/libsyntax/ast.rs2
-rw-r--r--src/libsyntax/ast_map/mod.rs26
-rw-r--r--src/libsyntax/ast_util.rs6
-rw-r--r--src/libsyntax/attr.rs32
-rw-r--r--src/libsyntax/codemap.rs2
-rw-r--r--src/libsyntax/config.rs2
-rw-r--r--src/libsyntax/diagnostic.rs65
-rw-r--r--src/libsyntax/diagnostics/plugin.rs8
-rw-r--r--src/libsyntax/diagnostics/registry.rs4
-rw-r--r--src/libsyntax/ext/base.rs2
-rw-r--r--src/libsyntax/ext/concat.rs2
-rw-r--r--src/libsyntax/ext/concat_idents.rs2
-rw-r--r--src/libsyntax/ext/deriving/bounds.rs2
-rw-r--r--src/libsyntax/ext/deriving/generic/mod.rs42
-rw-r--r--src/libsyntax/ext/deriving/hash.rs25
-rw-r--r--src/libsyntax/ext/deriving/mod.rs2
-rw-r--r--src/libsyntax/ext/deriving/show.rs2
-rw-r--r--src/libsyntax/ext/env.rs6
-rw-r--r--src/libsyntax/ext/expand.rs26
-rw-r--r--src/libsyntax/ext/format.rs8
-rw-r--r--src/libsyntax/ext/quote.rs4
-rw-r--r--src/libsyntax/ext/source_util.rs16
-rw-r--r--src/libsyntax/ext/tt/macro_parser.rs18
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs14
-rw-r--r--src/libsyntax/ext/tt/transcribe.rs4
-rw-r--r--src/libsyntax/feature_gate.rs22
-rw-r--r--src/libsyntax/lib.rs1
-rw-r--r--src/libsyntax/owned_slice.rs6
-rw-r--r--src/libsyntax/parse/lexer/comments.rs10
-rw-r--r--src/libsyntax/parse/lexer/mod.rs13
-rw-r--r--src/libsyntax/parse/mod.rs24
-rw-r--r--src/libsyntax/parse/obsolete.rs35
-rw-r--r--src/libsyntax/parse/parser.rs147
-rw-r--r--src/libsyntax/parse/token.rs4
-rw-r--r--src/libsyntax/print/pp.rs6
-rw-r--r--src/libsyntax/print/pprust.rs173
-rw-r--r--src/libsyntax/ptr.rs7
-rw-r--r--src/libsyntax/std_inject.rs13
-rw-r--r--src/libsyntax/test.rs14
-rw-r--r--src/libsyntax/util/interner.rs96
-rw-r--r--src/libsyntax/util/small_vector.rs6
-rw-r--r--src/libterm/lib.rs1
-rw-r--r--src/libterm/terminfo/mod.rs2
-rw-r--r--src/libterm/terminfo/parm.rs2
-rw-r--r--src/libterm/terminfo/searcher.rs4
-rw-r--r--src/libtest/lib.rs5
-rw-r--r--src/libtest/stats.rs4
m---------src/llvm0
-rw-r--r--src/rustbook/build.rs2
-rw-r--r--src/rustbook/error.rs4
-rw-r--r--src/rustbook/test.rs2
-rw-r--r--src/test/auxiliary/coherence-orphan-lib.rs2
-rw-r--r--src/test/auxiliary/default_type_params_xc.rs3
-rw-r--r--src/test/auxiliary/inner_static.rs12
-rw-r--r--src/test/auxiliary/issue-14421.rs5
-rw-r--r--src/test/auxiliary/issue-16643.rs2
-rw-r--r--src/test/auxiliary/issue-17662.rs2
-rw-r--r--src/test/auxiliary/issue-2380.rs5
-rw-r--r--src/test/auxiliary/issue-2526.rs8
-rw-r--r--src/test/auxiliary/issue_20389.rs1
-rw-r--r--src/test/auxiliary/issue_3907.rs4
-rw-r--r--src/test/auxiliary/issue_8401.rs4
-rw-r--r--src/test/auxiliary/issue_9123.rs1
-rw-r--r--src/test/auxiliary/lang-item-public.rs10
-rw-r--r--src/test/auxiliary/lint_group_plugin_test.rs4
-rw-r--r--src/test/auxiliary/lint_plugin_test.rs2
-rw-r--r--src/test/auxiliary/lint_stability.rs2
-rw-r--r--src/test/auxiliary/nested_item.rs2
-rw-r--r--src/test/auxiliary/orphan_check_diagnostics.rs2
-rw-r--r--src/test/auxiliary/overloaded_autoderef_xc.rs5
-rw-r--r--src/test/auxiliary/plugin_args.rs2
-rw-r--r--src/test/auxiliary/private_trait_xc.rs2
-rw-r--r--src/test/auxiliary/svh-a-base.rs6
-rw-r--r--src/test/auxiliary/svh-a-change-lit.rs6
-rw-r--r--src/test/auxiliary/svh-a-change-significant-cfg.rs6
-rw-r--r--src/test/auxiliary/svh-a-change-trait-bound.rs6
-rw-r--r--src/test/auxiliary/svh-a-change-type-arg.rs6
-rw-r--r--src/test/auxiliary/svh-a-change-type-ret.rs6
-rw-r--r--src/test/auxiliary/svh-a-change-type-static.rs6
-rw-r--r--src/test/auxiliary/svh-a-comment.rs6
-rw-r--r--src/test/auxiliary/svh-a-doc.rs6
-rw-r--r--src/test/auxiliary/svh-a-macro.rs6
-rw-r--r--src/test/auxiliary/svh-a-no-change.rs6
-rw-r--r--src/test/auxiliary/svh-a-redundant-cfg.rs6
-rw-r--r--src/test/auxiliary/svh-a-whitespace.rs6
-rw-r--r--src/test/auxiliary/trait_bounds_on_structs_and_enums_xc.rs4
-rw-r--r--src/test/auxiliary/trait_impl_conflict.rs2
-rw-r--r--src/test/auxiliary/use_from_trait_xc.rs2
-rw-r--r--src/test/bench/core-set.rs11
-rw-r--r--src/test/bench/shootout-fasta.rs2
-rw-r--r--src/test/bench/shootout-meteor.rs4
-rw-r--r--src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs6
-rw-r--r--src/test/compile-fail/associated-types-coherence-failure.rs3
-rw-r--r--src/test/compile-fail/associated-types-eq-expr-path.rs2
-rw-r--r--src/test/compile-fail/associated-types-issue-17359.rs2
-rw-r--r--src/test/compile-fail/associated-types-multiple-types-one-trait.rs2
-rw-r--r--src/test/compile-fail/associated-types-no-suitable-supertrait.rs2
-rw-r--r--src/test/compile-fail/associated-types-path-2.rs2
-rw-r--r--src/test/compile-fail/associated-types-unconstrained.rs2
-rw-r--r--src/test/compile-fail/bad-mid-path-type-params.rs7
-rw-r--r--src/test/compile-fail/bad-sized.rs2
-rw-r--r--src/test/compile-fail/coherence-blanket-conflicts-with-blanket-implemented.rs5
-rw-r--r--src/test/compile-fail/coherence-blanket-conflicts-with-blanket-unimplemented.rs4
-rw-r--r--src/test/compile-fail/coherence-conflicting-negative-trait-impl.rs8
-rw-r--r--src/test/compile-fail/coherence-subtyping.rs50
-rw-r--r--src/test/compile-fail/cross-borrow-trait.rs2
-rw-r--r--src/test/compile-fail/destructure-trait-ref.rs2
-rw-r--r--src/test/compile-fail/dst-bad-coerce1.rs2
-rw-r--r--src/test/compile-fail/dst-bad-coerce2.rs2
-rw-r--r--src/test/compile-fail/dst-bad-coerce3.rs2
-rw-r--r--src/test/compile-fail/dst-bad-coercions.rs4
-rw-r--r--src/test/compile-fail/dst-object-from-unsized-type.rs2
-rw-r--r--src/test/compile-fail/exclusive-drop-and-copy.rs2
-rw-r--r--src/test/compile-fail/generic-impl-less-params-with-defaults.rs7
-rw-r--r--src/test/compile-fail/generic-impl-more-params-with-defaults.rs7
-rw-r--r--src/test/compile-fail/generic-lifetime-trait-impl.rs5
-rw-r--r--src/test/compile-fail/generic-type-less-params-with-defaults.rs5
-rw-r--r--src/test/compile-fail/generic-type-more-params-with-defaults.rs5
-rw-r--r--src/test/compile-fail/generic-type-params-name-repr.rs8
-rw-r--r--src/test/compile-fail/issue-11515.rs2
-rw-r--r--src/test/compile-fail/issue-13853-2.rs4
-rw-r--r--src/test/compile-fail/issue-13853-3.rs5
-rw-r--r--src/test/compile-fail/issue-13853.rs4
-rw-r--r--src/test/compile-fail/issue-14285.rs4
-rw-r--r--src/test/compile-fail/issue-14853.rs3
-rw-r--r--src/test/compile-fail/issue-16747.rs4
-rw-r--r--src/test/compile-fail/issue-17431-4.rs4
-rw-r--r--src/test/compile-fail/issue-17431-5.rs4
-rw-r--r--src/test/compile-fail/issue-17551.rs6
-rw-r--r--src/test/compile-fail/issue-17904-2.rs16
-rw-r--r--src/test/compile-fail/issue-18107.rs4
-rw-r--r--src/test/compile-fail/issue-18611.rs4
-rw-r--r--src/test/compile-fail/issue-18783.rs1
-rw-r--r--src/test/compile-fail/issue-18819.rs4
-rw-r--r--src/test/compile-fail/issue-19660.rs6
-rw-r--r--src/test/compile-fail/issue-2063.rs3
-rw-r--r--src/test/compile-fail/issue-20831-debruijn.rs5
-rw-r--r--src/test/compile-fail/issue-21160.rs2
-rw-r--r--src/test/compile-fail/issue-2611-4.rs4
-rw-r--r--src/test/compile-fail/issue-3008-3.rs4
-rw-r--r--src/test/compile-fail/issue-4972.rs4
-rw-r--r--src/test/compile-fail/issue-5035-2.rs4
-rw-r--r--src/test/compile-fail/issue-5543.rs2
-rw-r--r--src/test/compile-fail/issue-5883.rs6
-rw-r--r--src/test/compile-fail/issue-6458.rs6
-rw-r--r--src/test/compile-fail/issue-7575.rs8
-rw-r--r--src/test/compile-fail/issue-8727.rs10
-rw-r--r--src/test/compile-fail/kindck-copy.rs4
-rw-r--r--src/test/compile-fail/kindck-impl-type-params-2.rs4
-rw-r--r--src/test/compile-fail/kindck-impl-type-params.rs20
-rw-r--r--src/test/compile-fail/kindck-inherited-copy-bound.rs1
-rw-r--r--src/test/compile-fail/kindck-send-object.rs4
-rw-r--r--src/test/compile-fail/kindck-send-object1.rs4
-rw-r--r--src/test/compile-fail/kindck-send-object2.rs4
-rw-r--r--src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs4
-rw-r--r--src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs4
-rw-r--r--src/test/compile-fail/lint-missing-doc.rs20
-rw-r--r--src/test/compile-fail/lint-non-camel-case-types.rs1
-rw-r--r--src/test/compile-fail/lint-stability.rs4
-rw-r--r--src/test/compile-fail/lint-visible-private-types.rs8
-rw-r--r--src/test/compile-fail/liveness-use-after-send.rs4
-rw-r--r--src/test/compile-fail/map-types.rs5
-rw-r--r--src/test/compile-fail/method-ambig-one-trait-coerce.rs50
-rw-r--r--src/test/compile-fail/mod_file_disambig.rs (renamed from src/test/parse-fail/mod_file_disambig.rs)0
-rw-r--r--src/test/compile-fail/mod_file_not_owning.rs (renamed from src/test/parse-fail/mod_file_not_owning.rs)0
-rw-r--r--src/test/compile-fail/object-does-not-impl-trait.rs3
-rw-r--r--src/test/compile-fail/object-lifetime-default-mybox.rs1
-rw-r--r--src/test/compile-fail/object-safety-issue-22040.rs50
-rw-r--r--src/test/compile-fail/object-safety-no-static.rs2
-rw-r--r--src/test/compile-fail/object-safety-phantom-fn.rs34
-rw-r--r--src/test/compile-fail/object-safety-supertrait-mentions-Self.rs32
-rw-r--r--src/test/compile-fail/on-unimplemented-bad-anno.rs18
-rw-r--r--src/test/compile-fail/on-unimplemented.rs6
-rw-r--r--src/test/compile-fail/orphan-check-diagnostics.rs2
-rw-r--r--src/test/compile-fail/priv-in-bad-locations.rs4
-rw-r--r--src/test/compile-fail/privacy-ns2.rs8
-rw-r--r--src/test/compile-fail/privacy1.rs8
-rw-r--r--src/test/compile-fail/privacy4.rs8
-rw-r--r--src/test/compile-fail/region-object-lifetime-in-coercion.rs2
-rw-r--r--src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs7
-rw-r--r--src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs6
-rw-r--r--src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs7
-rw-r--r--src/test/compile-fail/regions-assoc-type-outlives-container.rs8
-rw-r--r--src/test/compile-fail/regions-assoc-type-region-bound-in-trait-not-met.rs5
-rw-r--r--src/test/compile-fail/regions-assoc-type-static-bound-in-trait-not-met.rs5
-rw-r--r--src/test/compile-fail/regions-bound-missing-bound-in-impl.rs5
-rw-r--r--src/test/compile-fail/regions-bounded-method-type-parameters-trait-bound.rs6
-rw-r--r--src/test/compile-fail/regions-close-associated-type-into-object.rs4
-rw-r--r--src/test/compile-fail/regions-close-object-into-object-1.rs9
-rw-r--r--src/test/compile-fail/regions-close-object-into-object-2.rs6
-rw-r--r--src/test/compile-fail/regions-close-object-into-object-3.rs6
-rw-r--r--src/test/compile-fail/regions-close-object-into-object-4.rs6
-rw-r--r--src/test/compile-fail/regions-close-object-into-object-5.rs30
-rw-r--r--src/test/compile-fail/regions-close-over-borrowed-ref-in-obj.rs4
-rw-r--r--src/test/compile-fail/regions-close-param-into-object.rs2
-rw-r--r--src/test/compile-fail/regions-infer-contravariance-due-to-decl.rs2
-rw-r--r--src/test/compile-fail/regions-infer-covariance-due-to-decl.rs2
-rw-r--r--src/test/compile-fail/regions-infer-invariance-due-to-decl.rs2
-rw-r--r--src/test/compile-fail/required-lang-item.rs6
-rw-r--r--src/test/compile-fail/shadowed-type-parameter.rs6
-rw-r--r--src/test/compile-fail/slice-1.rs8
-rw-r--r--src/test/compile-fail/slightly-nice-generic-literal-messages.rs6
-rw-r--r--src/test/compile-fail/staticness-mismatch.rs2
-rw-r--r--src/test/compile-fail/trait-as-struct-constructor.rs2
-rw-r--r--src/test/compile-fail/trait-bounds-cant-coerce.rs1
-rw-r--r--src/test/compile-fail/trait-bounds-impl-comparison-1.rs14
-rw-r--r--src/test/compile-fail/trait-bounds-impl-comparison-2.rs4
-rw-r--r--src/test/compile-fail/trait-bounds-not-on-bare-trait.rs1
-rw-r--r--src/test/compile-fail/trait-bounds-on-structs-and-enums-locals.rs4
-rw-r--r--src/test/compile-fail/trait-bounds-on-structs-and-enums-static.rs4
-rw-r--r--src/test/compile-fail/trait-bounds-on-structs-and-enums.rs10
-rw-r--r--src/test/compile-fail/trait-bounds-sugar.rs3
-rw-r--r--src/test/compile-fail/trait-impl-1.rs4
-rw-r--r--src/test/compile-fail/trait-object-safety.rs1
-rw-r--r--src/test/compile-fail/trait-static-method-generic-inference.rs1
-rw-r--r--src/test/compile-fail/type-parameter-defaults-referencing-Self-ppaux.rs26
-rw-r--r--src/test/compile-fail/type-parameter-defaults-referencing-Self.rs23
-rw-r--r--src/test/compile-fail/typeck-negative-impls-builtin.rs4
-rw-r--r--src/test/compile-fail/typeck_type_placeholder_mismatch.rs10
-rw-r--r--src/test/compile-fail/ufcs-qpath-missing-params.rs3
-rw-r--r--src/test/compile-fail/unboxed-closure-feature-gate.rs4
-rw-r--r--src/test/compile-fail/unboxed-closure-sugar-default.rs2
-rw-r--r--src/test/compile-fail/unboxed-closure-sugar-equiv.rs4
-rw-r--r--src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs4
-rw-r--r--src/test/compile-fail/unboxed-closure-sugar-region.rs2
-rw-r--r--src/test/compile-fail/unboxed-closures-recursive-fn-using-fn-mut.rs6
-rw-r--r--src/test/compile-fail/unnecessary-private.rs4
-rw-r--r--src/test/compile-fail/unsized-inherent-impl-self-type.rs2
-rw-r--r--src/test/compile-fail/unsized-trait-impl-self-type.rs3
-rw-r--r--src/test/compile-fail/unsized-trait-impl-trait-arg.rs3
-rw-r--r--src/test/compile-fail/unsized3.rs5
-rw-r--r--src/test/compile-fail/unsized6.rs3
-rw-r--r--src/test/compile-fail/unsized7.rs8
-rw-r--r--src/test/compile-fail/unused-attr.rs4
-rw-r--r--src/test/compile-fail/useless-priv.rs8
-rw-r--r--src/test/compile-fail/useless-priv2.rs6
-rw-r--r--src/test/compile-fail/variance-contravariant-arg-object.rs31
-rw-r--r--src/test/compile-fail/variance-contravariant-arg-trait-match.rs31
-rw-r--r--src/test/compile-fail/variance-contravariant-self-trait-match.rs31
-rw-r--r--src/test/compile-fail/variance-covariant-arg-object.rs31
-rw-r--r--src/test/compile-fail/variance-covariant-arg-trait-match.rs31
-rw-r--r--src/test/compile-fail/variance-covariant-self-trait-match.rs31
-rw-r--r--src/test/compile-fail/variance-deprecated-markers.rs35
-rw-r--r--src/test/compile-fail/variance-invariant-arg-object.rs31
-rw-r--r--src/test/compile-fail/variance-invariant-arg-trait-match.rs31
-rw-r--r--src/test/compile-fail/variance-invariant-self-trait-match.rs31
-rw-r--r--src/test/compile-fail/variance-issue-20533.rs54
-rw-r--r--src/test/compile-fail/variance-regions-direct.rs1
-rw-r--r--src/test/compile-fail/variance-regions-indirect.rs4
-rw-r--r--src/test/compile-fail/variance-regions-unused-direct.rs (renamed from src/test/run-pass/regions-infer-bivariance.rs)17
-rw-r--r--src/test/compile-fail/variance-regions-unused-indirect.rs (renamed from src/test/run-pass/export-non-interference.rs)11
-rw-r--r--src/test/compile-fail/variance-trait-bounds.rs65
-rw-r--r--src/test/compile-fail/variance-trait-object-bound.rs2
-rw-r--r--src/test/compile-fail/variance-types-bounds.rs76
-rw-r--r--src/test/compile-fail/variance-types.rs52
-rw-r--r--src/test/compile-fail/variance-unused-region-param.rs17
-rw-r--r--src/test/compile-fail/variance-unused-type-param.rs36
-rw-r--r--src/test/compile-fail/variance-use-contravariant-struct-1.rs26
-rw-r--r--src/test/compile-fail/variance-use-contravariant-struct-2.rs27
-rw-r--r--src/test/compile-fail/variance-use-covariant-struct-1.rs23
-rw-r--r--src/test/compile-fail/variance-use-covariant-struct-2.rs26
-rw-r--r--src/test/compile-fail/variance-use-invariant-struct-1.rs33
-rw-r--r--src/test/compile-fail/visible-private-types-generics.rs4
-rw-r--r--src/test/compile-fail/visible-private-types-supertrait.rs4
-rw-r--r--src/test/compile-fail/where-clause-method-substituion.rs4
-rw-r--r--src/test/compile-fail/where-clauses-not-parameter.rs4
-rw-r--r--src/test/debuginfo/type-names.rs17
-rw-r--r--src/test/parse-fail/ascii-only-character-escape.rs (renamed from src/test/compile-fail/ascii-only-character-escape.rs)0
-rw-r--r--src/test/parse-fail/attr-before-eof.rs (renamed from src/test/compile-fail/attr-before-eof.rs)0
-rw-r--r--src/test/parse-fail/attr-before-ext.rs (renamed from src/test/compile-fail/attr-before-ext.rs)0
-rw-r--r--src/test/parse-fail/attr-before-let.rs (renamed from src/test/compile-fail/attr-before-let.rs)0
-rw-r--r--src/test/parse-fail/attr-before-stmt.rs (renamed from src/test/compile-fail/attr-before-stmt.rs)0
-rw-r--r--src/test/parse-fail/attr-dangling-in-fn.rs (renamed from src/test/compile-fail/attr-dangling-in-fn.rs)0
-rw-r--r--src/test/parse-fail/attr-dangling-in-mod.rs (renamed from src/test/compile-fail/attr-dangling-in-mod.rs)0
-rw-r--r--src/test/parse-fail/attr.rs (renamed from src/test/compile-fail/attr.rs)0
-rw-r--r--src/test/parse-fail/attrs-after-extern-mod.rs (renamed from src/test/compile-fail/attrs-after-extern-mod.rs)0
-rw-r--r--src/test/parse-fail/bad-char-literals.rs (renamed from src/test/compile-fail/bad-char-literals.rs)0
-rw-r--r--src/test/parse-fail/bad-lit-suffixes.rs (renamed from src/test/compile-fail/bad-lit-suffixes.rs)0
-rw-r--r--src/test/parse-fail/bad-value-ident-false.rs (renamed from src/test/compile-fail/bad-value-ident-false.rs)0
-rw-r--r--src/test/parse-fail/bad-value-ident-true.rs (renamed from src/test/compile-fail/bad-value-ident-true.rs)0
-rw-r--r--src/test/parse-fail/doc-before-attr.rs (renamed from src/test/compile-fail/doc-before-attr.rs)0
-rw-r--r--src/test/parse-fail/doc-before-eof.rs (renamed from src/test/compile-fail/doc-before-eof.rs)0
-rw-r--r--src/test/parse-fail/doc-before-extern-rbrace.rs (renamed from src/test/compile-fail/doc-before-extern-rbrace.rs)0
-rw-r--r--src/test/parse-fail/doc-before-macro.rs (renamed from src/test/compile-fail/doc-before-macro.rs)0
-rw-r--r--src/test/parse-fail/doc-before-rbrace.rs (renamed from src/test/compile-fail/doc-before-rbrace.rs)0
-rw-r--r--src/test/parse-fail/doc-before-semi.rs (renamed from src/test/compile-fail/doc-before-semi.rs)0
-rw-r--r--src/test/parse-fail/extern-crate-as-no-string-help.rs (renamed from src/test/compile-fail/extern-crate-as-no-string-help.rs)0
-rw-r--r--src/test/parse-fail/generic-non-trailing-defaults.rs (renamed from src/test/compile-fail/generic-non-trailing-defaults.rs)0
-rw-r--r--src/test/parse-fail/int-literal-too-large-span.rs (renamed from src/test/compile-fail/int-literal-too-large-span.rs)0
-rw-r--r--src/test/parse-fail/issue-10412.rs (renamed from src/test/compile-fail/issue-10412.rs)0
-rw-r--r--src/test/parse-fail/issue-12560-1.rs (renamed from src/test/compile-fail/issue-12560-1.rs)0
-rw-r--r--src/test/parse-fail/issue-14182.rs (renamed from src/test/compile-fail/issue-14182.rs)0
-rw-r--r--src/test/parse-fail/issue-17383.rs (renamed from src/test/compile-fail/issue-17383.rs)0
-rw-r--r--src/test/parse-fail/issue-17718-const-mut.rs (renamed from src/test/compile-fail/issue-17718-const-mut.rs)0
-rw-r--r--src/test/parse-fail/issue-1802-2.rs (renamed from src/test/compile-fail/issue-1802-2.rs)0
-rw-r--r--src/test/parse-fail/issue-5544-a.rs (renamed from src/test/compile-fail/issue-5544-a.rs)0
-rw-r--r--src/test/parse-fail/issue-5544-b.rs (renamed from src/test/compile-fail/issue-5544-b.rs)0
-rw-r--r--src/test/parse-fail/issue-8537.rs (renamed from src/test/compile-fail/issue-8537.rs)0
-rw-r--r--src/test/parse-fail/keyword-as-as-identifier.rs (renamed from src/test/compile-fail/keyword-as-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-break-as-identifier.rs (renamed from src/test/compile-fail/keyword-break-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-else-as-identifier.rs (renamed from src/test/compile-fail/keyword-else-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-enum-as-identifier.rs (renamed from src/test/compile-fail/keyword-enum-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-extern-as-identifier.rs (renamed from src/test/compile-fail/keyword-extern-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-fn-as-identifier.rs (renamed from src/test/compile-fail/keyword-fn-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-for-as-identifier.rs (renamed from src/test/compile-fail/keyword-for-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-if-as-identifier.rs (renamed from src/test/compile-fail/keyword-if-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-impl-as-identifier.rs (renamed from src/test/compile-fail/keyword-impl-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-let-as-identifier.rs (renamed from src/test/compile-fail/keyword-let-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-loop-as-identifier.rs (renamed from src/test/compile-fail/keyword-loop-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-match-as-identifier.rs (renamed from src/test/compile-fail/keyword-match-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-mod-as-identifier.rs (renamed from src/test/compile-fail/keyword-mod-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-pub-as-identifier.rs (renamed from src/test/compile-fail/keyword-pub-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-return-as-identifier.rs (renamed from src/test/compile-fail/keyword-return-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-self-as-identifier.rs (renamed from src/test/compile-fail/keyword-self-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-static-as-identifier.rs (renamed from src/test/compile-fail/keyword-static-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-struct-as-identifier.rs (renamed from src/test/compile-fail/keyword-struct-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-super-as-identifier.rs (renamed from src/test/compile-fail/keyword-super-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-super.rs (renamed from src/test/compile-fail/keyword-super.rs)0
-rw-r--r--src/test/parse-fail/keyword-trait-as-identifier.rs (renamed from src/test/compile-fail/keyword-trait-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-type-as-identifier.rs (renamed from src/test/compile-fail/keyword-type-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-unsafe-as-identifier.rs (renamed from src/test/compile-fail/keyword-unsafe-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-use-as-identifier.rs (renamed from src/test/compile-fail/keyword-use-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-while-as-identifier.rs (renamed from src/test/compile-fail/keyword-while-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword.rs (renamed from src/test/compile-fail/keyword.rs)0
-rw-r--r--src/test/parse-fail/keywords-followed-by-double-colon.rs (renamed from src/test/compile-fail/keywords-followed-by-double-colon.rs)0
-rw-r--r--src/test/parse-fail/lex-bad-numeric-literals.rs (renamed from src/test/compile-fail/lex-bad-numeric-literals.rs)0
-rw-r--r--src/test/parse-fail/lex-bare-cr-string-literal-doc-comment.rs (renamed from src/test/compile-fail/lex-bare-cr-string-literal-doc-comment.rs)0
-rw-r--r--src/test/parse-fail/lifetime-no-keyword.rs (renamed from src/test/compile-fail/lifetime-no-keyword.rs)0
-rw-r--r--src/test/parse-fail/lifetime-obsoleted-self.rs (renamed from src/test/compile-fail/lifetime-obsoleted-self.rs)0
-rw-r--r--src/test/parse-fail/macros-no-semicolon-items.rs (renamed from src/test/compile-fail/macros-no-semicolon-items.rs)0
-rw-r--r--src/test/parse-fail/no-binary-float-literal.rs (renamed from src/test/compile-fail/no-binary-float-literal.rs)0
-rw-r--r--src/test/parse-fail/no-hex-float-literal.rs (renamed from src/test/compile-fail/no-hex-float-literal.rs)0
-rw-r--r--src/test/parse-fail/no-unsafe-self.rs (renamed from src/test/compile-fail/no-unsafe-self.rs)0
-rw-r--r--src/test/parse-fail/non-str-meta.rs (renamed from src/test/compile-fail/non-str-meta.rs)0
-rw-r--r--src/test/parse-fail/obsolete-for-sized.rs (renamed from src/test/compile-fail/obsolete-for-sized.rs)0
-rw-r--r--src/test/parse-fail/obsolete-proc.rs (renamed from src/test/compile-fail/obsolete-proc.rs)0
-rw-r--r--src/test/parse-fail/qquote-1.rs (renamed from src/test/compile-fail/qquote-1.rs)0
-rw-r--r--src/test/parse-fail/qquote-2.rs (renamed from src/test/compile-fail/qquote-2.rs)0
-rw-r--r--src/test/parse-fail/regions-fn-bound.rs (renamed from src/test/compile-fail/regions-fn-bound.rs)0
-rw-r--r--src/test/parse-fail/require-parens-for-chained-comparison.rs (renamed from src/test/compile-fail/require-parens-for-chained-comparison.rs)0
-rw-r--r--src/test/parse-fail/struct-no-fields-2.rs (renamed from src/test/compile-fail/struct-no-fields-2.rs)0
-rw-r--r--src/test/parse-fail/struct-no-fields-3.rs (renamed from src/test/compile-fail/struct-no-fields-3.rs)0
-rw-r--r--src/test/parse-fail/struct-no-fields-4.rs (renamed from src/test/compile-fail/struct-no-fields-4.rs)0
-rw-r--r--src/test/parse-fail/struct-no-fields-5.rs (renamed from src/test/compile-fail/struct-no-fields-5.rs)0
-rw-r--r--src/test/parse-fail/struct-variant-no-fields.rs (renamed from src/test/compile-fail/struct-variant-no-fields.rs)0
-rw-r--r--src/test/parse-fail/struct-variant-no-pub.rs (renamed from src/test/compile-fail/struct-variant-no-pub.rs)0
-rw-r--r--src/test/parse-fail/syntax-trait-polarity.rs (renamed from src/test/compile-fail/syntax-trait-polarity.rs)0
-rw-r--r--src/test/parse-fail/tag-variant-disr-non-nullary.rs (renamed from src/test/compile-fail/tag-variant-disr-non-nullary.rs)0
-rw-r--r--src/test/parse-fail/trailing-carriage-return-in-string.rs (renamed from src/test/compile-fail/trailing-carriage-return-in-string.rs)0
-rw-r--r--src/test/parse-fail/trailing-plus-in-bounds.rs (renamed from src/test/compile-fail/trailing-plus-in-bounds.rs)0
-rw-r--r--src/test/parse-fail/trait-bounds-not-on-impl.rs (renamed from src/test/compile-fail/trait-bounds-not-on-impl.rs)0
-rw-r--r--src/test/parse-fail/type-parameters-in-field-exprs.rs (renamed from src/test/compile-fail/type-parameters-in-field-exprs.rs)0
-rw-r--r--src/test/parse-fail/unsized2.rs (renamed from src/test/compile-fail/unsized2.rs)0
-rw-r--r--src/test/parse-fail/virtual-structs.rs (renamed from src/test/compile-fail/virtual-structs.rs)0
-rw-r--r--src/test/parse-fail/where-clauses-no-bounds-or-predicates.rs (renamed from src/test/compile-fail/where-clauses-no-bounds-or-predicates.rs)0
-rw-r--r--src/test/pretty/empty-impl.rs4
-rw-r--r--src/test/pretty/path-type-bounds.rs4
-rw-r--r--src/test/run-fail/bug-811.rs4
-rw-r--r--src/test/run-make/rustdoc-json/foo.rs2
-rw-r--r--src/test/run-make/rustdoc-negative-impl/foo.rs2
-rw-r--r--src/test/run-make/rustdoc-search-index/index.rs2
-rw-r--r--src/test/run-make/rustdoc-smoke/foo.rs2
-rw-r--r--src/test/run-make/rustdoc-viewpath-self/foo.rs2
-rw-r--r--src/test/run-make/rustdoc-where/foo.rs15
-rw-r--r--src/test/run-make/save-analysis/foo.rs3
-rwxr-xr-xsrc/test/run-make/simd-ffi/simd.rs8
-rw-r--r--src/test/run-make/symbols-are-reasonable/lib.rs2
-rw-r--r--src/test/run-make/target-specs/foo.rs8
-rw-r--r--src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs2
-rw-r--r--src/test/run-pass-valgrind/dst-dtor-1.rs2
-rw-r--r--src/test/run-pass/associated-types-basic.rs4
-rw-r--r--src/test/run-pass/associated-types-conditional-dispatch.rs7
-rw-r--r--src/test/run-pass/associated-types-issue-20371.rs4
-rw-r--r--src/test/run-pass/associated-types-issue-21212.rs3
-rw-r--r--src/test/run-pass/associated-types-nested-projections.rs5
-rw-r--r--src/test/run-pass/associated-types-normalize-in-bounds-binding.rs6
-rw-r--r--src/test/run-pass/associated-types-normalize-in-bounds-ufcs.rs10
-rw-r--r--src/test/run-pass/associated-types-normalize-in-bounds.rs10
-rw-r--r--src/test/run-pass/associated-types-normalize-unifield-struct.rs5
-rw-r--r--src/test/run-pass/associated-types-projection-from-known-type-in-impl.rs2
-rw-r--r--src/test/run-pass/associated-types-projection-in-object-type.rs2
-rw-r--r--src/test/run-pass/associated-types-projection-in-supertrait.rs2
-rw-r--r--src/test/run-pass/associated-types-projection-in-where-clause.rs2
-rw-r--r--src/test/run-pass/associated-types-ref-in-struct-literal.rs2
-rw-r--r--src/test/run-pass/associated-types-resolve-lifetime.rs2
-rw-r--r--src/test/run-pass/associated-types-struct-field-named.rs2
-rw-r--r--src/test/run-pass/associated-types-struct-field-numbered.rs2
-rw-r--r--src/test/run-pass/associated-types-sugar-path.rs3
-rw-r--r--src/test/run-pass/bitv-perf-test.rs6
-rw-r--r--src/test/run-pass/borrowck-trait-lifetime.rs5
-rw-r--r--src/test/run-pass/bug-7295.rs6
-rw-r--r--src/test/run-pass/builtin-superkinds-in-metadata.rs1
-rw-r--r--src/test/run-pass/builtin-superkinds-phantom-typaram.rs6
-rw-r--r--src/test/run-pass/c-stack-returning-int64.rs4
-rw-r--r--src/test/run-pass/class-typarams.rs7
-rw-r--r--src/test/run-pass/const-polymorphic-paths.rs10
-rw-r--r--src/test/run-pass/deriving-hash.rs2
-rw-r--r--src/test/run-pass/deriving-meta-multiple.rs2
-rw-r--r--src/test/run-pass/deriving-meta.rs2
-rw-r--r--src/test/run-pass/dst-coercions.rs2
-rw-r--r--src/test/run-pass/enum-null-pointer-opt.rs2
-rw-r--r--src/test/run-pass/explicit-self-generic.rs8
-rw-r--r--src/test/run-pass/foreign-fn-linkname.rs2
-rw-r--r--src/test/run-pass/generic-default-type-params-cross-crate.rs10
-rw-r--r--src/test/run-pass/hrtb-opt-in-copy.rs4
-rw-r--r--src/test/run-pass/inner-static.rs6
-rw-r--r--src/test/run-pass/issue-10456.rs4
-rw-r--r--src/test/run-pass/issue-10802.rs2
-rw-r--r--src/test/run-pass/issue-10902.rs4
-rw-r--r--src/test/run-pass/issue-11205.rs2
-rw-r--r--src/test/run-pass/issue-11384.rs2
-rw-r--r--src/test/run-pass/issue-11612.rs2
-rw-r--r--src/test/run-pass/issue-11677.rs9
-rw-r--r--src/test/run-pass/issue-11736.rs4
-rw-r--r--src/test/run-pass/issue-13105.rs4
-rw-r--r--src/test/run-pass/issue-14399.rs2
-rw-r--r--src/test/run-pass/issue-14589.rs7
-rw-r--r--src/test/run-pass/issue-14958.rs2
-rw-r--r--src/test/run-pass/issue-14959.rs8
-rw-r--r--src/test/run-pass/issue-15858.rs12
-rw-r--r--src/test/run-pass/issue-16596.rs2
-rw-r--r--src/test/run-pass/issue-16643.rs2
-rw-r--r--src/test/run-pass/issue-17662.rs6
-rw-r--r--src/test/run-pass/issue-17732.rs3
-rw-r--r--src/test/run-pass/issue-17771.rs2
-rw-r--r--src/test/run-pass/issue-17816.rs6
-rw-r--r--src/test/run-pass/issue-17904.rs4
-rw-r--r--src/test/run-pass/issue-18232.rs4
-rw-r--r--src/test/run-pass/issue-18906.rs2
-rw-r--r--src/test/run-pass/issue-19121.rs2
-rw-r--r--src/test/run-pass/issue-19129-2.rs2
-rw-r--r--src/test/run-pass/issue-19135.rs6
-rw-r--r--src/test/run-pass/issue-19358.rs2
-rw-r--r--src/test/run-pass/issue-19398.rs4
-rw-r--r--src/test/run-pass/issue-19479.rs6
-rw-r--r--src/test/run-pass/issue-19631.rs1
-rw-r--r--src/test/run-pass/issue-19632.rs1
-rw-r--r--src/test/run-pass/issue-20055-box-trait.rs4
-rw-r--r--src/test/run-pass/issue-20343.rs2
-rw-r--r--src/test/run-pass/issue-20763-1.rs5
-rw-r--r--src/test/run-pass/issue-20763-2.rs5
-rw-r--r--src/test/run-pass/issue-21363.rs1
-rw-r--r--src/test/run-pass/issue-21909.rs6
-rw-r--r--src/test/run-pass/issue-2311-2.rs5
-rw-r--r--src/test/run-pass/issue-2311.rs2
-rw-r--r--src/test/run-pass/issue-2312.rs2
-rw-r--r--src/test/run-pass/issue-2383.rs4
-rw-r--r--src/test/run-pass/issue-2611-3.rs4
-rw-r--r--src/test/run-pass/issue-2734.rs4
-rw-r--r--src/test/run-pass/issue-2735.rs4
-rw-r--r--src/test/run-pass/issue-4107.rs12
-rw-r--r--src/test/run-pass/issue-5192.rs1
-rw-r--r--src/test/run-pass/issue-5708.rs4
-rw-r--r--src/test/run-pass/issue-6128.rs4
-rw-r--r--src/test/run-pass/issue-6318.rs4
-rw-r--r--src/test/run-pass/issue-7575.rs1
-rw-r--r--src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs5
-rw-r--r--src/test/run-pass/issue-7911.rs4
-rw-r--r--src/test/run-pass/issue-8248.rs4
-rw-r--r--src/test/run-pass/issue-8249.rs4
-rw-r--r--src/test/run-pass/issue-9719.rs8
-rw-r--r--src/test/run-pass/lint-cstack.rs2
-rw-r--r--src/test/run-pass/method-early-bound-lifetimes-on-self.rs8
-rw-r--r--src/test/run-pass/method-recursive-blanket-impl.rs8
-rw-r--r--src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs3
-rw-r--r--src/test/run-pass/overloaded-autoderef-vtable.rs6
-rw-r--r--src/test/run-pass/overloaded-calls-param-vtables.rs5
-rw-r--r--src/test/run-pass/parameterized-trait-with-bounds.rs8
-rw-r--r--src/test/run-pass/privacy-ns.rs3
-rw-r--r--src/test/run-pass/regions-assoc-type-static-bound.rs5
-rw-r--r--src/test/run-pass/regions-bound-lists-feature-gate-2.rs4
-rw-r--r--src/test/run-pass/regions-bound-lists-feature-gate.rs5
-rw-r--r--src/test/run-pass/regions-early-bound-lifetime-in-assoc-fn.rs6
-rw-r--r--src/test/run-pass/regions-early-bound-trait-param.rs6
-rw-r--r--src/test/run-pass/regions-issue-21422.rs25
-rw-r--r--src/test/run-pass/regions-no-bound-in-argument-cleanup.rs4
-rw-r--r--src/test/run-pass/regions-no-variance-from-fn-generics.rs10
-rw-r--r--src/test/run-pass/regions-refcell.rs8
-rw-r--r--src/test/run-pass/rename-directory.rs6
-rw-r--r--src/test/run-pass/self-impl.rs1
-rw-r--r--src/test/run-pass/send_str_hashmap.rs2
-rw-r--r--src/test/run-pass/send_str_treemap.rs2
-rw-r--r--src/test/run-pass/simple-match-generic-tag.rs9
-rw-r--r--src/test/run-pass/syntax-trait-polarity.rs6
-rw-r--r--src/test/run-pass/trailing-comma.rs4
-rw-r--r--src/test/run-pass/trait-bounds-basic.rs2
-rw-r--r--src/test/run-pass/trait-bounds-on-structs-and-enums.rs6
-rw-r--r--src/test/run-pass/trait-bounds-recursion.rs8
-rw-r--r--src/test/run-pass/trait-default-method-bound-subst4.rs1
-rw-r--r--src/test/run-pass/trait-impl.rs4
-rw-r--r--src/test/run-pass/trait-inheritance-num2.rs3
-rw-r--r--src/test/run-pass/trait-inheritance-static2.rs4
-rw-r--r--src/test/run-pass/trait-object-generics.rs11
-rw-r--r--src/test/run-pass/trait-static-method-overwriting.rs10
-rw-r--r--src/test/run-pass/traits-issue-22019.rs6
-rw-r--r--src/test/run-pass/unboxed-closures-infer-recursive-fn.rs6
-rw-r--r--src/test/run-pass/unique-object-move.rs2
-rw-r--r--src/test/run-pass/unsized.rs24
-rw-r--r--src/test/run-pass/unsized2.rs12
-rw-r--r--src/test/run-pass/variadic-ffi.rs8
-rw-r--r--src/test/run-pass/variance-intersection-of-ref-and-opt-ref.rs34
-rw-r--r--src/test/run-pass/variance-trait-matching.rs49
-rw-r--r--src/test/run-pass/variance-vec-covariant.rs28
-rw-r--r--src/test/run-pass/visible-private-types-feature-gate.rs2
-rw-r--r--src/test/run-pass/where-clause-bounds-inconsistency.rs4
-rw-r--r--src/test/run-pass/where-clause-early-bound-lifetimes.rs2
-rw-r--r--src/test/run-pass/where-clause-method-substituion.rs4
-rw-r--r--src/test/run-pass/where-for-self.rs10
732 files changed, 12288 insertions, 4569 deletions
diff --git a/src/compiletest/common.rs b/src/compiletest/common.rs
index df2981a6c83..2c046d25279 100644
--- a/src/compiletest/common.rs
+++ b/src/compiletest/common.rs
@@ -15,6 +15,7 @@ use std::str::FromStr;
 #[derive(Clone, Copy, PartialEq, Debug)]
 pub enum Mode {
     CompileFail,
+    ParseFail,
     RunFail,
     RunPass,
     RunPassValgrind,
@@ -29,6 +30,7 @@ impl FromStr for Mode {
     fn from_str(s: &str) -> Result<Mode, ()> {
         match s {
           "compile-fail" => Ok(CompileFail),
+          "parse-fail" => Ok(ParseFail),
           "run-fail" => Ok(RunFail),
           "run-pass" => Ok(RunPass),
           "run-pass-valgrind" => Ok(RunPassValgrind),
@@ -45,6 +47,7 @@ impl fmt::Display for Mode {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         fmt::Display::fmt(match *self {
             CompileFail => "compile-fail",
+            ParseFail => "parse-fail",
             RunFail => "run-fail",
             RunPass => "run-pass",
             RunPassValgrind => "run-pass-valgrind",
diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs
index 86710d50d8a..278ce5565d9 100644
--- a/src/compiletest/compiletest.rs
+++ b/src/compiletest/compiletest.rs
@@ -21,6 +21,7 @@
 #![feature(test)]
 #![feature(unicode)]
 #![feature(env)]
+#![feature(core)]
 
 #![deny(warnings)]
 
@@ -72,7 +73,7 @@ pub fn parse_config(args: Vec<String> ) -> Config {
           reqopt("", "aux-base", "directory to find auxiliary test files", "PATH"),
           reqopt("", "stage-id", "the target-stage identifier", "stageN-TARGET"),
           reqopt("", "mode", "which sort of compile tests to run",
-                 "(compile-fail|run-fail|run-pass|run-pass-valgrind|pretty|debug-info)"),
+                 "(compile-fail|parse-fail|run-fail|run-pass|run-pass-valgrind|pretty|debug-info)"),
           optflag("", "ignored", "run tests marked as ignored"),
           optopt("", "runtool", "supervisor program to run tests under \
                                  (eg. emulator, valgrind)", "PROGRAM"),
diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs
index 658c0cb3f4e..1cbb8742bbc 100644
--- a/src/compiletest/runtest.rs
+++ b/src/compiletest/runtest.rs
@@ -11,7 +11,7 @@
 use self::TargetLocation::*;
 
 use common::Config;
-use common::{CompileFail, Pretty, RunFail, RunPass, RunPassValgrind, DebugInfoGdb};
+use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind, DebugInfoGdb};
 use common::{Codegen, DebugInfoLldb};
 use errors;
 use header::TestProps;
@@ -66,6 +66,7 @@ pub fn run_metrics(config: Config, testfile: String, mm: &mut MetricMap) {
     debug!("loaded props");
     match config.mode {
       CompileFail => run_cfail_test(&config, &props, &testfile),
+      ParseFail => run_cfail_test(&config, &props, &testfile),
       RunFail => run_rfail_test(&config, &props, &testfile),
       RunPass => run_rpass_test(&config, &props, &testfile),
       RunPassValgrind => run_valgrind_test(&config, &props, &testfile),
@@ -88,7 +89,7 @@ fn run_cfail_test(config: &Config, props: &TestProps, testfile: &Path) {
     let proc_res = compile_test(config, props, testfile);
 
     if proc_res.status.success() {
-        fatal_proc_rec("compile-fail test compiled successfully!",
+        fatal_proc_rec(&format!("{} test compiled successfully!", config.mode)[],
                       &proc_res);
     }
 
@@ -688,7 +689,7 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path)
                                                .unwrap()
                                                .to_string();
 
-    script_str.push_str(&format!("command script import {}\n", &rust_pp_module_abs_path[])[]);
+    script_str.push_str(&format!("command script import {}\n", &rust_pp_module_abs_path[..])[]);
     script_str.push_str("type summary add --no-value ");
     script_str.push_str("--python-function lldb_rust_formatters.print_val ");
     script_str.push_str("-x \".*\" --category Rust\n");
@@ -1133,7 +1134,7 @@ fn compile_test_(config: &Config, props: &TestProps,
     // FIXME (#9639): This needs to handle non-utf8 paths
     let mut link_args = vec!("-L".to_string(),
                              aux_dir.as_str().unwrap().to_string());
-    link_args.extend(extra_args.iter().map(|s| s.clone()));
+    link_args.extend(extra_args.iter().cloned());
     let args = make_compile_args(config,
                                  props,
                                  link_args,
diff --git a/src/doc/reference.md b/src/doc/reference.md
index 70baebf0d30..db940947040 100644
--- a/src/doc/reference.md
+++ b/src/doc/reference.md
@@ -572,7 +572,7 @@ the final namespace qualifier is omitted.
 Two examples of paths with type arguments:
 
 ```
-# struct HashMap<K, V>;
+# struct HashMap<K, V>(K,V);
 # fn f() {
 # fn id<T>(t: T) -> T { t }
 type T = HashMap<i32,String>; // Type arguments used in a type expression
@@ -1599,7 +1599,7 @@ pointer values (pointing to a type for which an implementation of the given
 trait is in scope) to pointers to the trait name, used as a type.
 
 ```
-# trait Shape { }
+# trait Shape { fn dummy(&self) { } }
 # impl Shape for i32 { }
 # let mycircle = 0i32;
 let myshape: Box<Shape> = Box::new(mycircle) as Box<Shape>;
@@ -1630,8 +1630,8 @@ let x: f64 = Num::from_i32(42);
 Traits may inherit from other traits. For example, in
 
 ```
-trait Shape { fn area() -> f64; }
-trait Circle : Shape { fn radius() -> f64; }
+trait Shape { fn area(&self) -> f64; }
+trait Circle : Shape { fn radius(&self) -> f64; }
 ```
 
 the syntax `Circle : Shape` means that types that implement `Circle` must also
@@ -1725,7 +1725,7 @@ type parameters taken by the trait it implements. Implementation parameters
 are written after the `impl` keyword.
 
 ```
-# trait Seq<T> { }
+# trait Seq<T> { fn dummy(&self, _: T) { } }
 impl<T> Seq<T> for Vec<T> {
    /* ... */
 }
@@ -3583,7 +3583,7 @@ An example of each kind:
 ```{rust}
 let vec: Vec<i32> = vec![1, 2, 3];
 let arr: [i32; 3] = [1, 2, 3];
-let s: &[i32] = &vec[];
+let s: &[i32] = &vec[..];
 ```
 
 As you can see, the `vec!` macro allows you to create a `Vec<T>` easily. The
diff --git a/src/doc/trpl/ffi.md b/src/doc/trpl/ffi.md
index f2b95f19edc..97e826579fd 100644
--- a/src/doc/trpl/ffi.md
+++ b/src/doc/trpl/ffi.md
@@ -435,8 +435,8 @@ extern {
 }
 
 fn main() {
-    let prompt = CString::from_slice(b"[my-awesome-shell] $");
-    unsafe { 
+    let prompt = CString::new("[my-awesome-shell] $").unwrap();
+    unsafe {
         rl_prompt = prompt.as_ptr();
 
         println!("{:?}", rl_prompt);
@@ -541,6 +541,6 @@ pub extern fn hello_rust() -> *const u8 {
 
 The `extern` makes this function adhere to the C calling convention, as
 discussed above in "[Foreign Calling
-Conventions](guide-ffi.html#foreign-calling-conventions)". The `no_mangle`
+Conventions](ffi.html#foreign-calling-conventions)". The `no_mangle`
 attribute turns off Rust's name mangling, so that it is easier to link to.
 
diff --git a/src/doc/trpl/patterns.md b/src/doc/trpl/patterns.md
index 122cffe3697..9e82e48fd18 100644
--- a/src/doc/trpl/patterns.md
+++ b/src/doc/trpl/patterns.md
@@ -180,7 +180,7 @@ If you want to match against a slice or array, you can use `&`:
 fn main() {
     let v = vec!["match_this", "1"];
 
-    match &v[] {
+    match &v[..] {
         ["match_this", second] => println!("The second element is {}", second),
         _ => {},
     }
diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs
index 3830d7fe295..934e6ab2159 100644
--- a/src/liballoc/arc.rs
+++ b/src/liballoc/arc.rs
@@ -73,7 +73,6 @@ use core::prelude::*;
 
 use core::atomic;
 use core::atomic::Ordering::{Relaxed, Release, Acquire, SeqCst};
-use core::borrow::BorrowFrom;
 use core::fmt;
 use core::cmp::{Ordering};
 use core::default::Default;
@@ -244,12 +243,6 @@ impl<T> Clone for Arc<T> {
     }
 }
 
-impl<T> BorrowFrom<Arc<T>> for T {
-    fn borrow_from(owned: &Arc<T>) -> &T {
-        &**owned
-    }
-}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> Deref for Arc<T> {
     type Target = T;
@@ -605,11 +598,19 @@ impl<T: Default + Sync + Send> Default for Arc<T> {
     fn default() -> Arc<T> { Arc::new(Default::default()) }
 }
 
+#[cfg(stage0)]
 impl<H: Hasher, T: Hash<H>> Hash<H> for Arc<T> {
     fn hash(&self, state: &mut H) {
         (**self).hash(state)
     }
 }
+#[cfg(not(stage0))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: Hash> Hash for Arc<T> {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        (**self).hash(state)
+    }
+}
 
 #[cfg(test)]
 mod tests {
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index 340a8d59612..a3516bd667b 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -10,13 +10,14 @@
 
 //! A pointer type for heap allocation.
 //!
-//! `Box<T>`, casually referred to as a 'box', provides the simplest form of heap allocation in
-//! Rust. Boxes provide ownership for this allocation, and drop their contents when they go out of
-//! scope.
+//! `Box<T>`, casually referred to as a 'box', provides the simplest form of
+//! heap allocation in Rust. Boxes provide ownership for this allocation, and
+//! drop their contents when they go out of scope.
 //!
-//! Boxes are useful in two situations: recursive data structures, and occasionally when returning
-//! data. [The Pointer chapter of the Book](../../../book/pointers.html#best-practices-1) explains
-//! these cases in detail.
+//! Boxes are useful in two situations: recursive data structures, and
+//! occasionally when returning data. [The Pointer chapter of the
+//! Book](../../../book/pointers.html#best-practices-1) explains these cases in
+//! detail.
 //!
 //! # Examples
 //!
@@ -58,8 +59,8 @@ use core::ops::{Deref, DerefMut};
 use core::ptr::Unique;
 use core::raw::TraitObject;
 
-/// A value that represents the heap. This is the default place that the `box` keyword allocates
-/// into when no place is supplied.
+/// A value that represents the heap. This is the default place that the `box`
+/// keyword allocates into when no place is supplied.
 ///
 /// The following two examples are equivalent:
 ///
@@ -219,12 +220,20 @@ impl<T: ?Sized + Ord> Ord for Box<T> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized + Eq> Eq for Box<T> {}
 
+#[cfg(stage0)]
 impl<S: hash::Hasher, T: ?Sized + Hash<S>> Hash<S> for Box<T> {
     #[inline]
     fn hash(&self, state: &mut S) {
         (**self).hash(state);
     }
 }
+#[cfg(not(stage0))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: ?Sized + Hash> Hash for Box<T> {
+    fn hash<H: hash::Hasher>(&self, state: &mut H) {
+        (**self).hash(state);
+    }
+}
 
 /// Extension methods for an owning `Any` trait object.
 #[unstable(feature = "alloc",
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index b3c2638f3ae..bc349ebebde 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -73,7 +73,6 @@
 #![feature(unboxed_closures)]
 #![feature(unsafe_no_drop_flag)]
 #![feature(core)]
-#![feature(hash)]
 #![cfg_attr(all(not(feature = "external_funcs"), not(feature = "external_crate")),
             feature(libc))]
 
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index f361c36ec8f..9d395115431 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -144,13 +144,12 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use core::borrow::BorrowFrom;
 use core::cell::Cell;
 use core::clone::Clone;
 use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering};
 use core::default::Default;
 use core::fmt;
-use core::hash::{self, Hash};
+use core::hash::{Hasher, Hash};
 use core::marker;
 use core::mem::{transmute, min_align_of, size_of, forget};
 use core::nonzero::NonZero;
@@ -349,12 +348,6 @@ impl<T: Clone> Rc<T> {
     }
 }
 
-impl<T> BorrowFrom<Rc<T>> for T {
-    fn borrow_from(owned: &Rc<T>) -> &T {
-        &**owned
-    }
-}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> Deref for Rc<T> {
     type Target = T;
@@ -599,12 +592,20 @@ impl<T: Ord> Ord for Rc<T> {
 }
 
 // FIXME (#18248) Make `T` `Sized?`
-impl<S: hash::Hasher, T: Hash<S>> Hash<S> for Rc<T> {
+#[cfg(stage0)]
+impl<S: Hasher, T: Hash<S>> Hash<S> for Rc<T> {
     #[inline]
     fn hash(&self, state: &mut S) {
         (**self).hash(state);
     }
 }
+#[cfg(not(stage0))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: Hash> Hash for Rc<T> {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        (**self).hash(state);
+    }
+}
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: fmt::Display> fmt::Display for Rc<T> {
diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs
index 4cd3d587580..b43f9adfb26 100644
--- a/src/libarena/lib.rs
+++ b/src/libarena/lib.rs
@@ -96,7 +96,7 @@ pub struct Arena<'longer_than_self> {
     head: RefCell<Chunk>,
     copy_head: RefCell<Chunk>,
     chunks: RefCell<Vec<Chunk>>,
-    _invariant: marker::InvariantLifetime<'longer_than_self>,
+    _marker: marker::PhantomData<*mut &'longer_than_self()>,
 }
 
 impl<'a> Arena<'a> {
@@ -111,7 +111,7 @@ impl<'a> Arena<'a> {
             head: RefCell::new(chunk(initial_size, false)),
             copy_head: RefCell::new(chunk(initial_size, true)),
             chunks: RefCell::new(Vec::new()),
-            _invariant: marker::InvariantLifetime,
+            _marker: marker::PhantomData,
         }
     }
 }
@@ -361,6 +361,8 @@ pub struct TypedArena<T> {
 }
 
 struct TypedArenaChunk<T> {
+    marker: marker::PhantomData<T>,
+
     /// Pointer to the next arena segment.
     next: *mut TypedArenaChunk<T>,
 
diff --git a/src/libcollections/binary_heap.rs b/src/libcollections/binary_heap.rs
index 6196d94b5a6..9f549fd7237 100644
--- a/src/libcollections/binary_heap.rs
+++ b/src/libcollections/binary_heap.rs
@@ -650,8 +650,8 @@ impl<'a, T: 'a> ExactSizeIterator for Drain<'a, T> {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Ord> FromIterator<T> for BinaryHeap<T> {
-    fn from_iter<Iter: Iterator<Item=T>>(iter: Iter) -> BinaryHeap<T> {
-        BinaryHeap::from_vec(iter.collect())
+    fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> BinaryHeap<T> {
+        BinaryHeap::from_vec(iter.into_iter().collect())
     }
 }
 
@@ -677,7 +677,8 @@ impl<'a, T> IntoIterator for &'a BinaryHeap<T> where T: Ord {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Ord> Extend<T> for BinaryHeap<T> {
-    fn extend<Iter: Iterator<Item=T>>(&mut self, iter: Iter) {
+    fn extend<I: IntoIterator<Item=T>>(&mut self, iterable: I) {
+        let iter = iterable.into_iter();
         let (lower, _) = iter.size_hint();
 
         self.reserve(lower);
diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs
index 0b762788b20..11c576eab15 100644
--- a/src/libcollections/bit.rs
+++ b/src/libcollections/bit.rs
@@ -8,13 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// FIXME(Gankro): Bitv and BitvSet are very tightly coupled. Ideally (for
-// maintenance), they should be in separate files/modules, with BitvSet only
-// using Bitv's public API. This will be hard for performance though, because
-// `Bitv` will not want to leak its internal representation while its internal
+// FIXME(Gankro): BitVec and BitSet are very tightly coupled. Ideally (for
+// maintenance), they should be in separate files/modules, with BitSet only
+// using BitVec's public API. This will be hard for performance though, because
+// `BitVec` will not want to leak its internal representation while its internal
 // representation as `u32`s must be assumed for best performance.
 
-// FIXME(tbu-): `Bitv`'s methods shouldn't be `union`, `intersection`, but
+// FIXME(tbu-): `BitVec`'s methods shouldn't be `union`, `intersection`, but
 // rather `or` and `and`.
 
 // (1) Be careful, most things can overflow here because the amount of bits in
@@ -25,8 +25,8 @@
 //     methods rely on it (for *CORRECTNESS*).
 // (3) Make sure that the unused bits in the last word are zeroed out, again
 //     other methods rely on it for *CORRECTNESS*.
-// (4) `BitvSet` is tightly coupled with `Bitv`, so any changes you make in
-// `Bitv` will need to be reflected in `BitvSet`.
+// (4) `BitSet` is tightly coupled with `BitVec`, so any changes you make in
+// `BitVec` will need to be reflected in `BitSet`.
 
 //! Collections implemented with bit vectors.
 //!
@@ -38,17 +38,17 @@
 //! [sieve]: http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
 //!
 //! ```
-//! use std::collections::{BitvSet, Bitv};
+//! use std::collections::{BitSet, BitVec};
 //! use std::num::Float;
 //! use std::iter;
 //!
 //! let max_prime = 10000;
 //!
-//! // Store the primes as a BitvSet
+//! // Store the primes as a BitSet
 //! let primes = {
 //!     // Assume all numbers are prime to begin, and then we
 //!     // cross off non-primes progressively
-//!     let mut bv = Bitv::from_elem(max_prime, true);
+//!     let mut bv = BitVec::from_elem(max_prime, true);
 //!
 //!     // Neither 0 nor 1 are prime
 //!     bv.set(0, false);
@@ -62,7 +62,7 @@
 //!             for j in iter::range_step(i * i, max_prime, i) { bv.set(j, false) }
 //!         }
 //!     }
-//!     BitvSet::from_bitv(bv)
+//!     BitSet::from_bit_vec(bv)
 //! };
 //!
 //! // Simple primality tests below our max bound
@@ -75,7 +75,7 @@
 //! }
 //! println!("");
 //!
-//! // We can manipulate the internal Bitv
+//! // We can manipulate the internal BitVec
 //! let num_primes = primes.get_ref().iter().filter(|x| *x).count();
 //! println!("There are {} primes below {}", num_primes, max_prime);
 //! ```
@@ -94,7 +94,7 @@ use core::num::Int;
 use core::ops::Index;
 use core::slice;
 use core::{u8, u32, usize};
-use bitv_set; //so meta
+use bit_set; //so meta
 
 use Vec;
 
@@ -112,7 +112,7 @@ fn reverse_bits(byte: u8) -> u8 {
 
 // Take two BitV's, and return iterators of their words, where the shorter one
 // has been padded with 0's
-fn match_words <'a,'b>(a: &'a Bitv, b: &'b Bitv) -> (MatchWords<'a>, MatchWords<'b>) {
+fn match_words <'a,'b>(a: &'a BitVec, b: &'b BitVec) -> (MatchWords<'a>, MatchWords<'b>) {
     let a_len = a.storage.len();
     let b_len = b.storage.len();
 
@@ -134,9 +134,9 @@ static FALSE: bool = false;
 /// # Examples
 ///
 /// ```rust
-/// use std::collections::Bitv;
+/// use std::collections::BitVec;
 ///
-/// let mut bv = Bitv::from_elem(10, false);
+/// let mut bv = BitVec::from_elem(10, false);
 ///
 /// // insert all primes less than 10
 /// bv.set(2, true);
@@ -158,7 +158,7 @@ static FALSE: bool = false;
 /// ```
 #[unstable(feature = "collections",
            reason = "RFC 509")]
-pub struct Bitv {
+pub struct BitVec {
     /// Internal representation of the bit vector
     storage: Vec<u32>,
     /// The number of valid bits in the internal representation
@@ -166,7 +166,7 @@ pub struct Bitv {
 }
 
 // FIXME(Gankro): NopeNopeNopeNopeNope (wait for IndexGet to be a thing)
-impl Index<usize> for Bitv {
+impl Index<usize> for BitVec {
     type Output = bool;
 
     #[inline]
@@ -202,12 +202,12 @@ fn mask_for_bits(bits: usize) -> u32 {
     !0u32 >> (u32::BITS - bits % u32::BITS) % u32::BITS
 }
 
-impl Bitv {
+impl BitVec {
     /// Applies the given operation to the blocks of self and other, and sets
     /// self to be the result. This relies on the caller not to corrupt the
     /// last word.
     #[inline]
-    fn process<F>(&mut self, other: &Bitv, mut op: F) -> bool where F: FnMut(u32, u32) -> u32 {
+    fn process<F>(&mut self, other: &BitVec, mut op: F) -> bool where F: FnMut(u32, u32) -> u32 {
         assert_eq!(self.len(), other.len());
         // This could theoretically be a `debug_assert!`.
         assert_eq!(self.storage.len(), other.storage.len());
@@ -235,7 +235,7 @@ impl Bitv {
     }
 
     /// An operation might screw up the unused bits in the last block of the
-    /// `Bitv`. As per (3), it's assumed to be all 0s. This method fixes it up.
+    /// `BitVec`. As per (3), it's assumed to be all 0s. This method fixes it up.
     fn fix_last_block(&mut self) {
         let extra_bits = self.len() % u32::BITS;
         if extra_bits > 0 {
@@ -245,44 +245,44 @@ impl Bitv {
         }
     }
 
-    /// Creates an empty `Bitv`.
+    /// Creates an empty `BitVec`.
     ///
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
-    /// let mut bv = Bitv::new();
+    /// use std::collections::BitVec;
+    /// let mut bv = BitVec::new();
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn new() -> Bitv {
-        Bitv { storage: Vec::new(), nbits: 0 }
+    pub fn new() -> BitVec {
+        BitVec { storage: Vec::new(), nbits: 0 }
     }
 
-    /// Creates a `Bitv` that holds `nbits` elements, setting each element
+    /// Creates a `BitVec` that holds `nbits` elements, setting each element
     /// to `bit`.
     ///
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let mut bv = Bitv::from_elem(10, false);
+    /// let mut bv = BitVec::from_elem(10, false);
     /// assert_eq!(bv.len(), 10);
     /// for x in bv.iter() {
     ///     assert_eq!(x, false);
     /// }
     /// ```
-    pub fn from_elem(nbits: usize, bit: bool) -> Bitv {
+    pub fn from_elem(nbits: usize, bit: bool) -> BitVec {
         let nblocks = blocks_for_bits(nbits);
-        let mut bitv = Bitv {
+        let mut bit_vec = BitVec {
             storage: repeat(if bit { !0u32 } else { 0u32 }).take(nblocks).collect(),
             nbits: nbits
         };
-        bitv.fix_last_block();
-        bitv
+        bit_vec.fix_last_block();
+        bit_vec
     }
 
-    /// Constructs a new, empty `Bitv` with the specified capacity.
+    /// Constructs a new, empty `BitVec` with the specified capacity.
     ///
     /// The bitvector will be able to hold at least `capacity` bits without
     /// reallocating. If `capacity` is 0, it will not allocate.
@@ -290,38 +290,38 @@ impl Bitv {
     /// It is important to note that this function does not specify the
     /// *length* of the returned bitvector, but only the *capacity*.
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn with_capacity(nbits: usize) -> Bitv {
-        Bitv {
+    pub fn with_capacity(nbits: usize) -> BitVec {
+        BitVec {
             storage: Vec::with_capacity(blocks_for_bits(nbits)),
             nbits: 0,
         }
     }
 
-    /// Transforms a byte-vector into a `Bitv`. Each byte becomes eight bits,
+    /// Transforms a byte-vector into a `BitVec`. Each byte becomes eight bits,
     /// with the most significant bits of each byte coming first. Each
     /// bit becomes `true` if equal to 1 or `false` if equal to 0.
     ///
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let bv = Bitv::from_bytes(&[0b10100000, 0b00010010]);
+    /// let bv = BitVec::from_bytes(&[0b10100000, 0b00010010]);
     /// assert!(bv.eq_vec(&[true, false, true, false,
     ///                     false, false, false, false,
     ///                     false, false, false, true,
     ///                     false, false, true, false]));
     /// ```
-    pub fn from_bytes(bytes: &[u8]) -> Bitv {
+    pub fn from_bytes(bytes: &[u8]) -> BitVec {
         let len = bytes.len().checked_mul(u8::BITS).expect("capacity overflow");
-        let mut bitv = Bitv::with_capacity(len);
+        let mut bit_vec = BitVec::with_capacity(len);
         let complete_words = bytes.len() / 4;
         let extra_bytes = bytes.len() % 4;
 
-        bitv.nbits = len;
+        bit_vec.nbits = len;
 
         for i in 0..complete_words {
-            bitv.storage.push(
+            bit_vec.storage.push(
                 ((reverse_bits(bytes[i * 4 + 0]) as u32) << 0) |
                 ((reverse_bits(bytes[i * 4 + 1]) as u32) << 8) |
                 ((reverse_bits(bytes[i * 4 + 2]) as u32) << 16) |
@@ -334,29 +334,29 @@ impl Bitv {
             for (i, &byte) in bytes[complete_words*4..].iter().enumerate() {
                 last_word |= (reverse_bits(byte) as u32) << (i * 8);
             }
-            bitv.storage.push(last_word);
+            bit_vec.storage.push(last_word);
         }
 
-        bitv
+        bit_vec
     }
 
-    /// Creates a `Bitv` of the specified length where the value at each index
+    /// Creates a `BitVec` of the specified length where the value at each index
     /// is `f(index)`.
     ///
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let bv = Bitv::from_fn(5, |i| { i % 2 == 0 });
+    /// let bv = BitVec::from_fn(5, |i| { i % 2 == 0 });
     /// assert!(bv.eq_vec(&[true, false, true, false, true]));
     /// ```
-    pub fn from_fn<F>(len: usize, mut f: F) -> Bitv where F: FnMut(usize) -> bool {
-        let mut bitv = Bitv::from_elem(len, false);
+    pub fn from_fn<F>(len: usize, mut f: F) -> BitVec where F: FnMut(usize) -> bool {
+        let mut bit_vec = BitVec::from_elem(len, false);
         for i in 0..len {
-            bitv.set(i, f(i));
+            bit_vec.set(i, f(i));
         }
-        bitv
+        bit_vec
     }
 
     /// Retrieves the value at index `i`, or `None` if the index is out of bounds.
@@ -364,9 +364,9 @@ impl Bitv {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let bv = Bitv::from_bytes(&[0b01100000]);
+    /// let bv = BitVec::from_bytes(&[0b01100000]);
     /// assert_eq!(bv.get(0), Some(false));
     /// assert_eq!(bv.get(1), Some(true));
     /// assert_eq!(bv.get(100), None);
@@ -396,9 +396,9 @@ impl Bitv {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let mut bv = Bitv::from_elem(5, false);
+    /// let mut bv = BitVec::from_elem(5, false);
     /// bv.set(3, true);
     /// assert_eq!(bv[3], true);
     /// ```
@@ -420,14 +420,14 @@ impl Bitv {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
     /// let before = 0b01100000;
     /// let after  = 0b11111111;
     ///
-    /// let mut bv = Bitv::from_bytes(&[before]);
+    /// let mut bv = BitVec::from_bytes(&[before]);
     /// bv.set_all();
-    /// assert_eq!(bv, Bitv::from_bytes(&[after]));
+    /// assert_eq!(bv, BitVec::from_bytes(&[after]));
     /// ```
     #[inline]
     pub fn set_all(&mut self) {
@@ -440,14 +440,14 @@ impl Bitv {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
     /// let before = 0b01100000;
     /// let after  = 0b10011111;
     ///
-    /// let mut bv = Bitv::from_bytes(&[before]);
+    /// let mut bv = BitVec::from_bytes(&[before]);
     /// bv.negate();
-    /// assert_eq!(bv, Bitv::from_bytes(&[after]));
+    /// assert_eq!(bv, BitVec::from_bytes(&[after]));
     /// ```
     #[inline]
     pub fn negate(&mut self) {
@@ -468,20 +468,20 @@ impl Bitv {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
     /// let a   = 0b01100100;
     /// let b   = 0b01011010;
     /// let res = 0b01111110;
     ///
-    /// let mut a = Bitv::from_bytes(&[a]);
-    /// let b = Bitv::from_bytes(&[b]);
+    /// let mut a = BitVec::from_bytes(&[a]);
+    /// let b = BitVec::from_bytes(&[b]);
     ///
     /// assert!(a.union(&b));
-    /// assert_eq!(a, Bitv::from_bytes(&[res]));
+    /// assert_eq!(a, BitVec::from_bytes(&[res]));
     /// ```
     #[inline]
-    pub fn union(&mut self, other: &Bitv) -> bool {
+    pub fn union(&mut self, other: &BitVec) -> bool {
         self.process(other, |w1, w2| w1 | w2)
     }
 
@@ -498,20 +498,20 @@ impl Bitv {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
     /// let a   = 0b01100100;
     /// let b   = 0b01011010;
     /// let res = 0b01000000;
     ///
-    /// let mut a = Bitv::from_bytes(&[a]);
-    /// let b = Bitv::from_bytes(&[b]);
+    /// let mut a = BitVec::from_bytes(&[a]);
+    /// let b = BitVec::from_bytes(&[b]);
     ///
     /// assert!(a.intersect(&b));
-    /// assert_eq!(a, Bitv::from_bytes(&[res]));
+    /// assert_eq!(a, BitVec::from_bytes(&[res]));
     /// ```
     #[inline]
-    pub fn intersect(&mut self, other: &Bitv) -> bool {
+    pub fn intersect(&mut self, other: &BitVec) -> bool {
         self.process(other, |w1, w2| w1 & w2)
     }
 
@@ -528,27 +528,27 @@ impl Bitv {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
     /// let a   = 0b01100100;
     /// let b   = 0b01011010;
     /// let a_b = 0b00100100; // a - b
     /// let b_a = 0b00011010; // b - a
     ///
-    /// let mut bva = Bitv::from_bytes(&[a]);
-    /// let bvb = Bitv::from_bytes(&[b]);
+    /// let mut bva = BitVec::from_bytes(&[a]);
+    /// let bvb = BitVec::from_bytes(&[b]);
     ///
     /// assert!(bva.difference(&bvb));
-    /// assert_eq!(bva, Bitv::from_bytes(&[a_b]));
+    /// assert_eq!(bva, BitVec::from_bytes(&[a_b]));
     ///
-    /// let bva = Bitv::from_bytes(&[a]);
-    /// let mut bvb = Bitv::from_bytes(&[b]);
+    /// let bva = BitVec::from_bytes(&[a]);
+    /// let mut bvb = BitVec::from_bytes(&[b]);
     ///
     /// assert!(bvb.difference(&bva));
-    /// assert_eq!(bvb, Bitv::from_bytes(&[b_a]));
+    /// assert_eq!(bvb, BitVec::from_bytes(&[b_a]));
     /// ```
     #[inline]
-    pub fn difference(&mut self, other: &Bitv) -> bool {
+    pub fn difference(&mut self, other: &BitVec) -> bool {
         self.process(other, |w1, w2| w1 & !w2)
     }
 
@@ -557,9 +557,9 @@ impl Bitv {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let mut bv = Bitv::from_elem(5, true);
+    /// let mut bv = BitVec::from_elem(5, true);
     /// assert_eq!(bv.all(), true);
     ///
     /// bv.set(1, false);
@@ -581,15 +581,15 @@ impl Bitv {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let bv = Bitv::from_bytes(&[0b01110100, 0b10010010]);
+    /// let bv = BitVec::from_bytes(&[0b01110100, 0b10010010]);
     /// assert_eq!(bv.iter().filter(|x| *x).count(), 7);
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn iter(&self) -> Iter {
-        Iter { bitv: self, next_idx: 0, end_idx: self.nbits }
+        Iter { bit_vec: self, next_idx: 0, end_idx: self.nbits }
     }
 
     /// Returns `true` if all bits are 0.
@@ -597,9 +597,9 @@ impl Bitv {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let mut bv = Bitv::from_elem(10, false);
+    /// let mut bv = BitVec::from_elem(10, false);
     /// assert_eq!(bv.none(), true);
     ///
     /// bv.set(3, true);
@@ -614,9 +614,9 @@ impl Bitv {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let mut bv = Bitv::from_elem(10, false);
+    /// let mut bv = BitVec::from_elem(10, false);
     /// assert_eq!(bv.any(), false);
     ///
     /// bv.set(3, true);
@@ -628,33 +628,33 @@ impl Bitv {
     }
 
     /// Organises the bits into bytes, such that the first bit in the
-    /// `Bitv` becomes the high-order bit of the first byte. If the
-    /// size of the `Bitv` is not a multiple of eight then trailing bits
+    /// `BitVec` becomes the high-order bit of the first byte. If the
+    /// size of the `BitVec` is not a multiple of eight then trailing bits
     /// will be filled-in with `false`.
     ///
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let mut bv = Bitv::from_elem(3, true);
+    /// let mut bv = BitVec::from_elem(3, true);
     /// bv.set(1, false);
     ///
     /// assert_eq!(bv.to_bytes(), vec!(0b10100000));
     ///
-    /// let mut bv = Bitv::from_elem(9, false);
+    /// let mut bv = BitVec::from_elem(9, false);
     /// bv.set(2, true);
     /// bv.set(8, true);
     ///
     /// assert_eq!(bv.to_bytes(), vec!(0b00100000, 0b10000000));
     /// ```
     pub fn to_bytes(&self) -> Vec<u8> {
-        fn bit(bitv: &Bitv, byte: usize, bit: usize) -> u8 {
+        fn bit(bit_vec: &BitVec, byte: usize, bit: usize) -> u8 {
             let offset = byte * 8 + bit;
-            if offset >= bitv.nbits {
+            if offset >= bit_vec.nbits {
                 0
             } else {
-                (bitv[offset] as u8) << (7 - bit)
+                (bit_vec[offset] as u8) << (7 - bit)
             }
         }
 
@@ -672,19 +672,19 @@ impl Bitv {
         ).collect()
     }
 
-    /// Compares a `Bitv` to a slice of `bool`s.
-    /// Both the `Bitv` and slice must have the same length.
+    /// Compares a `BitVec` to a slice of `bool`s.
+    /// Both the `BitVec` and slice must have the same length.
     ///
     /// # Panics
     ///
-    /// Panics if the `Bitv` and slice are of different length.
+    /// Panics if the `BitVec` and slice are of different length.
     ///
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let bv = Bitv::from_bytes(&[0b10100000]);
+    /// let bv = BitVec::from_bytes(&[0b10100000]);
     ///
     /// assert!(bv.eq_vec(&[true, false, true, false,
     ///                     false, false, false, false]));
@@ -694,7 +694,7 @@ impl Bitv {
         iter::order::eq(self.iter(), v.iter().cloned())
     }
 
-    /// Shortens a `Bitv`, dropping excess elements.
+    /// Shortens a `BitVec`, dropping excess elements.
     ///
     /// If `len` is greater than the vector's current length, this has no
     /// effect.
@@ -702,9 +702,9 @@ impl Bitv {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let mut bv = Bitv::from_bytes(&[0b01001011]);
+    /// let mut bv = BitVec::from_bytes(&[0b01001011]);
     /// bv.truncate(2);
     /// assert!(bv.eq_vec(&[false, true]));
     /// ```
@@ -719,7 +719,7 @@ impl Bitv {
     }
 
     /// Reserves capacity for at least `additional` more bits to be inserted in the given
-    /// `Bitv`. The collection may reserve more space to avoid frequent reallocations.
+    /// `BitVec`. The collection may reserve more space to avoid frequent reallocations.
     ///
     /// # Panics
     ///
@@ -728,9 +728,9 @@ impl Bitv {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let mut bv = Bitv::from_elem(3, false);
+    /// let mut bv = BitVec::from_elem(3, false);
     /// bv.reserve(10);
     /// assert_eq!(bv.len(), 3);
     /// assert!(bv.capacity() >= 13);
@@ -745,7 +745,7 @@ impl Bitv {
     }
 
     /// Reserves the minimum capacity for exactly `additional` more bits to be inserted in the
-    /// given `Bitv`. Does nothing if the capacity is already sufficient.
+    /// given `BitVec`. Does nothing if the capacity is already sufficient.
     ///
     /// Note that the allocator may give the collection more space than it requests. Therefore
     /// capacity can not be relied upon to be precisely minimal. Prefer `reserve` if future
@@ -758,9 +758,9 @@ impl Bitv {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let mut bv = Bitv::from_elem(3, false);
+    /// let mut bv = BitVec::from_elem(3, false);
     /// bv.reserve(10);
     /// assert_eq!(bv.len(), 3);
     /// assert!(bv.capacity() >= 13);
@@ -780,9 +780,9 @@ impl Bitv {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let mut bv = Bitv::new();
+    /// let mut bv = BitVec::new();
     /// bv.reserve(10);
     /// assert!(bv.capacity() >= 10);
     /// ```
@@ -792,7 +792,7 @@ impl Bitv {
         self.storage.capacity().checked_mul(u32::BITS).unwrap_or(usize::MAX)
     }
 
-    /// Grows the `Bitv` in-place, adding `n` copies of `value` to the `Bitv`.
+    /// Grows the `BitVec` in-place, adding `n` copies of `value` to the `BitVec`.
     ///
     /// # Panics
     ///
@@ -801,9 +801,9 @@ impl Bitv {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let mut bv = Bitv::from_bytes(&[0b01001011]);
+    /// let mut bv = BitVec::from_bytes(&[0b01001011]);
     /// bv.grow(2, true);
     /// assert_eq!(bv.len(), 10);
     /// assert_eq!(bv.to_bytes(), vec!(0b01001011, 0b11000000));
@@ -846,14 +846,14 @@ impl Bitv {
         self.fix_last_block();
     }
 
-    /// Removes the last bit from the Bitv, and returns it. Returns None if the Bitv is empty.
+    /// Removes the last bit from the BitVec, and returns it. Returns None if the BitVec is empty.
     ///
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let mut bv = Bitv::from_bytes(&[0b01001001]);
+    /// let mut bv = BitVec::from_bytes(&[0b01001001]);
     /// assert_eq!(bv.pop(), Some(true));
     /// assert_eq!(bv.pop(), Some(false));
     /// assert_eq!(bv.len(), 6);
@@ -881,9 +881,9 @@ impl Bitv {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let mut bv = Bitv::new();
+    /// let mut bv = BitVec::new();
     /// bv.push(true);
     /// bv.push(false);
     /// assert!(bv.eq_vec(&[true, false]));
@@ -917,24 +917,25 @@ impl Bitv {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl Default for Bitv {
+impl Default for BitVec {
     #[inline]
-    fn default() -> Bitv { Bitv::new() }
+    fn default() -> BitVec { BitVec::new() }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl FromIterator<bool> for Bitv {
-    fn from_iter<I:Iterator<Item=bool>>(iterator: I) -> Bitv {
-        let mut ret = Bitv::new();
-        ret.extend(iterator);
+impl FromIterator<bool> for BitVec {
+    fn from_iter<I: IntoIterator<Item=bool>>(iter: I) -> BitVec {
+        let mut ret = BitVec::new();
+        ret.extend(iter);
         ret
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl Extend<bool> for Bitv {
+impl Extend<bool> for BitVec {
     #[inline]
-    fn extend<I: Iterator<Item=bool>>(&mut self, iterator: I) {
+    fn extend<I: IntoIterator<Item=bool>>(&mut self, iterable: I) {
+        let iterator = iterable.into_iter();
         let (min, _) = iterator.size_hint();
         self.reserve(min);
         for element in iterator {
@@ -944,37 +945,37 @@ impl Extend<bool> for Bitv {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl Clone for Bitv {
+impl Clone for BitVec {
     #[inline]
-    fn clone(&self) -> Bitv {
-        Bitv { storage: self.storage.clone(), nbits: self.nbits }
+    fn clone(&self) -> BitVec {
+        BitVec { storage: self.storage.clone(), nbits: self.nbits }
     }
 
     #[inline]
-    fn clone_from(&mut self, source: &Bitv) {
+    fn clone_from(&mut self, source: &BitVec) {
         self.nbits = source.nbits;
         self.storage.clone_from(&source.storage);
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl PartialOrd for Bitv {
+impl PartialOrd for BitVec {
     #[inline]
-    fn partial_cmp(&self, other: &Bitv) -> Option<Ordering> {
+    fn partial_cmp(&self, other: &BitVec) -> Option<Ordering> {
         iter::order::partial_cmp(self.iter(), other.iter())
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl Ord for Bitv {
+impl Ord for BitVec {
     #[inline]
-    fn cmp(&self, other: &Bitv) -> Ordering {
+    fn cmp(&self, other: &BitVec) -> Ordering {
         iter::order::cmp(self.iter(), other.iter())
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Debug for Bitv {
+impl fmt::Debug for BitVec {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         for bit in self {
             try!(write!(fmt, "{}", if bit { 1u32 } else { 0u32 }));
@@ -984,7 +985,8 @@ impl fmt::Debug for Bitv {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<S: hash::Writer + hash::Hasher> hash::Hash<S> for Bitv {
+#[cfg(stage0)]
+impl<S: hash::Writer + hash::Hasher> hash::Hash<S> for BitVec {
     fn hash(&self, state: &mut S) {
         self.nbits.hash(state);
         for elem in self.blocks() {
@@ -992,11 +994,21 @@ impl<S: hash::Writer + hash::Hasher> hash::Hash<S> for Bitv {
         }
     }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
+#[cfg(not(stage0))]
+impl hash::Hash for BitVec {
+    fn hash<H: hash::Hasher>(&self, state: &mut H) {
+        self.nbits.hash(state);
+        for elem in self.blocks() {
+            elem.hash(state);
+        }
+    }
+}
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl cmp::PartialEq for Bitv {
+impl cmp::PartialEq for BitVec {
     #[inline]
-    fn eq(&self, other: &Bitv) -> bool {
+    fn eq(&self, other: &BitVec) -> bool {
         if self.nbits != other.nbits {
             return false;
         }
@@ -1005,13 +1017,13 @@ impl cmp::PartialEq for Bitv {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl cmp::Eq for Bitv {}
+impl cmp::Eq for BitVec {}
 
-/// An iterator for `Bitv`.
+/// An iterator for `BitVec`.
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Clone)]
 pub struct Iter<'a> {
-    bitv: &'a Bitv,
+    bit_vec: &'a BitVec,
     next_idx: usize,
     end_idx: usize,
 }
@@ -1025,7 +1037,7 @@ impl<'a> Iterator for Iter<'a> {
         if self.next_idx != self.end_idx {
             let idx = self.next_idx;
             self.next_idx += 1;
-            Some(self.bitv[idx])
+            Some(self.bit_vec[idx])
         } else {
             None
         }
@@ -1043,7 +1055,7 @@ impl<'a> DoubleEndedIterator for Iter<'a> {
     fn next_back(&mut self) -> Option<bool> {
         if self.next_idx != self.end_idx {
             self.end_idx -= 1;
-            Some(self.bitv[self.end_idx])
+            Some(self.bit_vec[self.end_idx])
         } else {
             None
         }
@@ -1065,13 +1077,13 @@ impl<'a> RandomAccessIterator for Iter<'a> {
         if index >= self.indexable() {
             None
         } else {
-            Some(self.bitv[index])
+            Some(self.bit_vec[index])
         }
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a> IntoIterator for &'a Bitv {
+impl<'a> IntoIterator for &'a BitVec {
     type Item = bool;
     type IntoIter = Iter<'a>;
 
@@ -1090,10 +1102,10 @@ impl<'a> IntoIterator for &'a Bitv {
 /// # Examples
 ///
 /// ```
-/// use std::collections::{BitvSet, Bitv};
+/// use std::collections::{BitSet, BitVec};
 ///
 /// // It's a regular set
-/// let mut s = BitvSet::new();
+/// let mut s = BitSet::new();
 /// s.insert(0);
 /// s.insert(3);
 /// s.insert(7);
@@ -1104,8 +1116,8 @@ impl<'a> IntoIterator for &'a Bitv {
 ///     println!("There is no 7");
 /// }
 ///
-/// // Can initialize from a `Bitv`
-/// let other = BitvSet::from_bitv(Bitv::from_bytes(&[0b11010000]));
+/// // Can initialize from a `BitVec`
+/// let other = BitSet::from_bit_vec(BitVec::from_bytes(&[0b11010000]));
 ///
 /// s.union_with(&other);
 ///
@@ -1114,115 +1126,115 @@ impl<'a> IntoIterator for &'a Bitv {
 ///     println!("{}", x);
 /// }
 ///
-/// // Can convert back to a `Bitv`
-/// let bv: Bitv = s.into_bitv();
+/// // Can convert back to a `BitVec`
+/// let bv: BitVec = s.into_bit_vec();
 /// assert!(bv[3]);
 /// ```
 #[derive(Clone)]
 #[unstable(feature = "collections",
            reason = "RFC 509")]
-pub struct BitvSet {
-    bitv: Bitv,
+pub struct BitSet {
+    bit_vec: BitVec,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl Default for BitvSet {
+impl Default for BitSet {
     #[inline]
-    fn default() -> BitvSet { BitvSet::new() }
+    fn default() -> BitSet { BitSet::new() }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl FromIterator<usize> for BitvSet {
-    fn from_iter<I:Iterator<Item=usize>>(iterator: I) -> BitvSet {
-        let mut ret = BitvSet::new();
-        ret.extend(iterator);
+impl FromIterator<usize> for BitSet {
+    fn from_iter<I: IntoIterator<Item=usize>>(iter: I) -> BitSet {
+        let mut ret = BitSet::new();
+        ret.extend(iter);
         ret
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl Extend<usize> for BitvSet {
+impl Extend<usize> for BitSet {
     #[inline]
-    fn extend<I: Iterator<Item=usize>>(&mut self, iterator: I) {
-        for i in iterator {
+    fn extend<I: IntoIterator<Item=usize>>(&mut self, iter: I) {
+        for i in iter {
             self.insert(i);
         }
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl PartialOrd for BitvSet {
+impl PartialOrd for BitSet {
     #[inline]
-    fn partial_cmp(&self, other: &BitvSet) -> Option<Ordering> {
+    fn partial_cmp(&self, other: &BitSet) -> Option<Ordering> {
         let (a_iter, b_iter) = match_words(self.get_ref(), other.get_ref());
         iter::order::partial_cmp(a_iter, b_iter)
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl Ord for BitvSet {
+impl Ord for BitSet {
     #[inline]
-    fn cmp(&self, other: &BitvSet) -> Ordering {
+    fn cmp(&self, other: &BitSet) -> Ordering {
         let (a_iter, b_iter) = match_words(self.get_ref(), other.get_ref());
         iter::order::cmp(a_iter, b_iter)
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl cmp::PartialEq for BitvSet {
+impl cmp::PartialEq for BitSet {
     #[inline]
-    fn eq(&self, other: &BitvSet) -> bool {
+    fn eq(&self, other: &BitSet) -> bool {
         let (a_iter, b_iter) = match_words(self.get_ref(), other.get_ref());
         iter::order::eq(a_iter, b_iter)
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl cmp::Eq for BitvSet {}
+impl cmp::Eq for BitSet {}
 
-impl BitvSet {
-    /// Creates a new empty `BitvSet`.
+impl BitSet {
+    /// Creates a new empty `BitSet`.
     ///
     /// # Examples
     ///
     /// ```
-    /// use std::collections::BitvSet;
+    /// use std::collections::BitSet;
     ///
-    /// let mut s = BitvSet::new();
+    /// let mut s = BitSet::new();
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn new() -> BitvSet {
-        BitvSet { bitv: Bitv::new() }
+    pub fn new() -> BitSet {
+        BitSet { bit_vec: BitVec::new() }
     }
 
-    /// Creates a new `BitvSet` with initially no contents, able to
+    /// Creates a new `BitSet` with initially no contents, able to
     /// hold `nbits` elements without resizing.
     ///
     /// # Examples
     ///
     /// ```
-    /// use std::collections::BitvSet;
+    /// use std::collections::BitSet;
     ///
-    /// let mut s = BitvSet::with_capacity(100);
+    /// let mut s = BitSet::with_capacity(100);
     /// assert!(s.capacity() >= 100);
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn with_capacity(nbits: usize) -> BitvSet {
-        let bitv = Bitv::from_elem(nbits, false);
-        BitvSet::from_bitv(bitv)
+    pub fn with_capacity(nbits: usize) -> BitSet {
+        let bit_vec = BitVec::from_elem(nbits, false);
+        BitSet::from_bit_vec(bit_vec)
     }
 
-    /// Creates a new `BitvSet` from the given bit vector.
+    /// Creates a new `BitSet` from the given bit vector.
     ///
     /// # Examples
     ///
     /// ```
-    /// use std::collections::{Bitv, BitvSet};
+    /// use std::collections::{BitVec, BitSet};
     ///
-    /// let bv = Bitv::from_bytes(&[0b01100000]);
-    /// let s = BitvSet::from_bitv(bv);
+    /// let bv = BitVec::from_bytes(&[0b01100000]);
+    /// let s = BitSet::from_bit_vec(bv);
     ///
     /// // Print 1, 2 in arbitrary order
     /// for x in s.iter() {
@@ -1230,8 +1242,16 @@ impl BitvSet {
     /// }
     /// ```
     #[inline]
-    pub fn from_bitv(bitv: Bitv) -> BitvSet {
-        BitvSet { bitv: bitv }
+    pub fn from_bit_vec(bit_vec: BitVec) -> BitSet {
+        BitSet { bit_vec: bit_vec }
+    }
+
+    /// Deprecated: use `from_bit_vec`.
+    #[inline]
+    #[deprecated(since = "1.0.0", reason = "renamed to from_bit_vec")]
+    #[unstable(feature = "collections")]
+    pub fn from_bitv(bit_vec: BitVec) -> BitSet {
+        BitSet { bit_vec: bit_vec }
     }
 
     /// Returns the capacity in bits for this bit vector. Inserting any
@@ -1240,19 +1260,19 @@ impl BitvSet {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::BitvSet;
+    /// use std::collections::BitSet;
     ///
-    /// let mut s = BitvSet::with_capacity(100);
+    /// let mut s = BitSet::with_capacity(100);
     /// assert!(s.capacity() >= 100);
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn capacity(&self) -> usize {
-        self.bitv.capacity()
+        self.bit_vec.capacity()
     }
 
-    /// Reserves capacity for the given `BitvSet` to contain `len` distinct elements. In the case
-    /// of `BitvSet` this means reallocations will not occur as long as all inserted elements
+    /// Reserves capacity for the given `BitSet` to contain `len` distinct elements. In the case
+    /// of `BitSet` this means reallocations will not occur as long as all inserted elements
     /// are less than `len`.
     ///
     /// The collection may reserve more space to avoid frequent reallocations.
@@ -1261,22 +1281,22 @@ impl BitvSet {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::BitvSet;
+    /// use std::collections::BitSet;
     ///
-    /// let mut s = BitvSet::new();
+    /// let mut s = BitSet::new();
     /// s.reserve_len(10);
     /// assert!(s.capacity() >= 10);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn reserve_len(&mut self, len: usize) {
-        let cur_len = self.bitv.len();
+        let cur_len = self.bit_vec.len();
         if len >= cur_len {
-            self.bitv.reserve(len - cur_len);
+            self.bit_vec.reserve(len - cur_len);
         }
     }
 
-    /// Reserves the minimum capacity for the given `BitvSet` to contain `len` distinct elements.
-    /// In the case of `BitvSet` this means reallocations will not occur as long as all inserted
+    /// Reserves the minimum capacity for the given `BitSet` to contain `len` distinct elements.
+    /// In the case of `BitSet` this means reallocations will not occur as long as all inserted
     /// elements are less than `len`.
     ///
     /// Note that the allocator may give the collection more space than it requests. Therefore
@@ -1287,17 +1307,17 @@ impl BitvSet {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::BitvSet;
+    /// use std::collections::BitSet;
     ///
-    /// let mut s = BitvSet::new();
+    /// let mut s = BitSet::new();
     /// s.reserve_len_exact(10);
     /// assert!(s.capacity() >= 10);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn reserve_len_exact(&mut self, len: usize) {
-        let cur_len = self.bitv.len();
+        let cur_len = self.bit_vec.len();
         if len >= cur_len {
-            self.bitv.reserve_exact(len - cur_len);
+            self.bit_vec.reserve_exact(len - cur_len);
         }
     }
 
@@ -1307,19 +1327,19 @@ impl BitvSet {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::BitvSet;
+    /// use std::collections::BitSet;
     ///
-    /// let mut s = BitvSet::new();
+    /// let mut s = BitSet::new();
     /// s.insert(0);
     /// s.insert(3);
     ///
-    /// let bv = s.into_bitv();
+    /// let bv = s.into_bit_vec();
     /// assert!(bv[0]);
     /// assert!(bv[3]);
     /// ```
     #[inline]
-    pub fn into_bitv(self) -> Bitv {
-        self.bitv
+    pub fn into_bit_vec(self) -> BitVec {
+        self.bit_vec
     }
 
     /// Returns a reference to the underlying bit vector.
@@ -1327,44 +1347,44 @@ impl BitvSet {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::BitvSet;
+    /// use std::collections::BitSet;
     ///
-    /// let mut s = BitvSet::new();
+    /// let mut s = BitSet::new();
     /// s.insert(0);
     ///
     /// let bv = s.get_ref();
     /// assert_eq!(bv[0], true);
     /// ```
     #[inline]
-    pub fn get_ref(&self) -> &Bitv {
-        &self.bitv
+    pub fn get_ref(&self) -> &BitVec {
+        &self.bit_vec
     }
 
     #[inline]
-    fn other_op<F>(&mut self, other: &BitvSet, mut f: F) where F: FnMut(u32, u32) -> u32 {
-        // Unwrap Bitvs
-        let self_bitv = &mut self.bitv;
-        let other_bitv = &other.bitv;
+    fn other_op<F>(&mut self, other: &BitSet, mut f: F) where F: FnMut(u32, u32) -> u32 {
+        // Unwrap BitVecs
+        let self_bit_vec = &mut self.bit_vec;
+        let other_bit_vec = &other.bit_vec;
 
-        let self_len = self_bitv.len();
-        let other_len = other_bitv.len();
+        let self_len = self_bit_vec.len();
+        let other_len = other_bit_vec.len();
 
         // Expand the vector if necessary
         if self_len < other_len {
-            self_bitv.grow(other_len - self_len, false);
+            self_bit_vec.grow(other_len - self_len, false);
         }
 
         // virtually pad other with 0's for equal lengths
         let other_words = {
-            let (_, result) = match_words(self_bitv, other_bitv);
+            let (_, result) = match_words(self_bit_vec, other_bit_vec);
             result
         };
 
         // Apply values found in other
         for (i, w) in other_words {
-            let old = self_bitv.storage[i];
+            let old = self_bit_vec.storage[i];
             let new = f(old, w);
-            self_bitv.storage[i] = new;
+            self_bit_vec.storage[i] = new;
         }
     }
 
@@ -1373,9 +1393,9 @@ impl BitvSet {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::BitvSet;
+    /// use std::collections::BitSet;
     ///
-    /// let mut s = BitvSet::new();
+    /// let mut s = BitSet::new();
     /// s.insert(32183231);
     /// s.remove(&32183231);
     ///
@@ -1389,25 +1409,25 @@ impl BitvSet {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn shrink_to_fit(&mut self) {
-        let bitv = &mut self.bitv;
+        let bit_vec = &mut self.bit_vec;
         // Obtain original length
-        let old_len = bitv.storage.len();
+        let old_len = bit_vec.storage.len();
         // Obtain coarse trailing zero length
-        let n = bitv.storage.iter().rev().take_while(|&&n| n == 0).count();
+        let n = bit_vec.storage.iter().rev().take_while(|&&n| n == 0).count();
         // Truncate
         let trunc_len = cmp::max(old_len - n, 1);
-        bitv.storage.truncate(trunc_len);
-        bitv.nbits = trunc_len * u32::BITS;
+        bit_vec.storage.truncate(trunc_len);
+        bit_vec.nbits = trunc_len * u32::BITS;
     }
 
-    /// Iterator over each u32 stored in the `BitvSet`.
+    /// Iterator over each u32 stored in the `BitSet`.
     ///
     /// # Examples
     ///
     /// ```
-    /// use std::collections::{Bitv, BitvSet};
+    /// use std::collections::{BitVec, BitSet};
     ///
-    /// let s = BitvSet::from_bitv(Bitv::from_bytes(&[0b01001010]));
+    /// let s = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01001010]));
     ///
     /// // Print 1, 4, 6 in arbitrary order
     /// for x in s.iter() {
@@ -1416,7 +1436,7 @@ impl BitvSet {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn iter(&self) -> bitv_set::Iter {
+    pub fn iter(&self) -> bit_set::Iter {
         SetIter {set: self, next_idx: 0}
     }
 
@@ -1426,10 +1446,10 @@ impl BitvSet {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::{Bitv, BitvSet};
+    /// use std::collections::{BitVec, BitSet};
     ///
-    /// let a = BitvSet::from_bitv(Bitv::from_bytes(&[0b01101000]));
-    /// let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100000]));
+    /// let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101000]));
+    /// let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100000]));
     ///
     /// // Print 0, 1, 2, 4 in arbitrary order
     /// for x in a.union(&b) {
@@ -1438,7 +1458,7 @@ impl BitvSet {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn union<'a>(&'a self, other: &'a BitvSet) -> Union<'a> {
+    pub fn union<'a>(&'a self, other: &'a BitSet) -> Union<'a> {
         fn or(w1: u32, w2: u32) -> u32 { w1 | w2 }
 
         Union(TwoBitPositions {
@@ -1456,10 +1476,10 @@ impl BitvSet {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::{Bitv, BitvSet};
+    /// use std::collections::{BitVec, BitSet};
     ///
-    /// let a = BitvSet::from_bitv(Bitv::from_bytes(&[0b01101000]));
-    /// let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100000]));
+    /// let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101000]));
+    /// let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100000]));
     ///
     /// // Print 2
     /// for x in a.intersection(&b) {
@@ -1468,9 +1488,9 @@ impl BitvSet {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn intersection<'a>(&'a self, other: &'a BitvSet) -> Intersection<'a> {
+    pub fn intersection<'a>(&'a self, other: &'a BitSet) -> Intersection<'a> {
         fn bitand(w1: u32, w2: u32) -> u32 { w1 & w2 }
-        let min = cmp::min(self.bitv.len(), other.bitv.len());
+        let min = cmp::min(self.bit_vec.len(), other.bit_vec.len());
         Intersection(TwoBitPositions {
             set: self,
             other: other,
@@ -1486,10 +1506,10 @@ impl BitvSet {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::{BitvSet, Bitv};
+    /// use std::collections::{BitSet, BitVec};
     ///
-    /// let a = BitvSet::from_bitv(Bitv::from_bytes(&[0b01101000]));
-    /// let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100000]));
+    /// let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101000]));
+    /// let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100000]));
     ///
     /// // Print 1, 4 in arbitrary order
     /// for x in a.difference(&b) {
@@ -1505,7 +1525,7 @@ impl BitvSet {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn difference<'a>(&'a self, other: &'a BitvSet) -> Difference<'a> {
+    pub fn difference<'a>(&'a self, other: &'a BitSet) -> Difference<'a> {
         fn diff(w1: u32, w2: u32) -> u32 { w1 & !w2 }
 
         Difference(TwoBitPositions {
@@ -1524,10 +1544,10 @@ impl BitvSet {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::{BitvSet, Bitv};
+    /// use std::collections::{BitSet, BitVec};
     ///
-    /// let a = BitvSet::from_bitv(Bitv::from_bytes(&[0b01101000]));
-    /// let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100000]));
+    /// let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101000]));
+    /// let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100000]));
     ///
     /// // Print 0, 1, 4 in arbitrary order
     /// for x in a.symmetric_difference(&b) {
@@ -1536,7 +1556,7 @@ impl BitvSet {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn symmetric_difference<'a>(&'a self, other: &'a BitvSet) -> SymmetricDifference<'a> {
+    pub fn symmetric_difference<'a>(&'a self, other: &'a BitSet) -> SymmetricDifference<'a> {
         fn bitxor(w1: u32, w2: u32) -> u32 { w1 ^ w2 }
 
         SymmetricDifference(TwoBitPositions {
@@ -1553,21 +1573,21 @@ impl BitvSet {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::{BitvSet, Bitv};
+    /// use std::collections::{BitSet, BitVec};
     ///
     /// let a   = 0b01101000;
     /// let b   = 0b10100000;
     /// let res = 0b11101000;
     ///
-    /// let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[a]));
-    /// let b = BitvSet::from_bitv(Bitv::from_bytes(&[b]));
-    /// let res = BitvSet::from_bitv(Bitv::from_bytes(&[res]));
+    /// let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[a]));
+    /// let b = BitSet::from_bit_vec(BitVec::from_bytes(&[b]));
+    /// let res = BitSet::from_bit_vec(BitVec::from_bytes(&[res]));
     ///
     /// a.union_with(&b);
     /// assert_eq!(a, res);
     /// ```
     #[inline]
-    pub fn union_with(&mut self, other: &BitvSet) {
+    pub fn union_with(&mut self, other: &BitSet) {
         self.other_op(other, |w1, w2| w1 | w2);
     }
 
@@ -1576,21 +1596,21 @@ impl BitvSet {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::{BitvSet, Bitv};
+    /// use std::collections::{BitSet, BitVec};
     ///
     /// let a   = 0b01101000;
     /// let b   = 0b10100000;
     /// let res = 0b00100000;
     ///
-    /// let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[a]));
-    /// let b = BitvSet::from_bitv(Bitv::from_bytes(&[b]));
-    /// let res = BitvSet::from_bitv(Bitv::from_bytes(&[res]));
+    /// let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[a]));
+    /// let b = BitSet::from_bit_vec(BitVec::from_bytes(&[b]));
+    /// let res = BitSet::from_bit_vec(BitVec::from_bytes(&[res]));
     ///
     /// a.intersect_with(&b);
     /// assert_eq!(a, res);
     /// ```
     #[inline]
-    pub fn intersect_with(&mut self, other: &BitvSet) {
+    pub fn intersect_with(&mut self, other: &BitSet) {
         self.other_op(other, |w1, w2| w1 & w2);
     }
 
@@ -1600,29 +1620,29 @@ impl BitvSet {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::{BitvSet, Bitv};
+    /// use std::collections::{BitSet, BitVec};
     ///
     /// let a   = 0b01101000;
     /// let b   = 0b10100000;
     /// let a_b = 0b01001000; // a - b
     /// let b_a = 0b10000000; // b - a
     ///
-    /// let mut bva = BitvSet::from_bitv(Bitv::from_bytes(&[a]));
-    /// let bvb = BitvSet::from_bitv(Bitv::from_bytes(&[b]));
-    /// let bva_b = BitvSet::from_bitv(Bitv::from_bytes(&[a_b]));
-    /// let bvb_a = BitvSet::from_bitv(Bitv::from_bytes(&[b_a]));
+    /// let mut bva = BitSet::from_bit_vec(BitVec::from_bytes(&[a]));
+    /// let bvb = BitSet::from_bit_vec(BitVec::from_bytes(&[b]));
+    /// let bva_b = BitSet::from_bit_vec(BitVec::from_bytes(&[a_b]));
+    /// let bvb_a = BitSet::from_bit_vec(BitVec::from_bytes(&[b_a]));
     ///
     /// bva.difference_with(&bvb);
     /// assert_eq!(bva, bva_b);
     ///
-    /// let bva = BitvSet::from_bitv(Bitv::from_bytes(&[a]));
-    /// let mut bvb = BitvSet::from_bitv(Bitv::from_bytes(&[b]));
+    /// let bva = BitSet::from_bit_vec(BitVec::from_bytes(&[a]));
+    /// let mut bvb = BitSet::from_bit_vec(BitVec::from_bytes(&[b]));
     ///
     /// bvb.difference_with(&bva);
     /// assert_eq!(bvb, bvb_a);
     /// ```
     #[inline]
-    pub fn difference_with(&mut self, other: &BitvSet) {
+    pub fn difference_with(&mut self, other: &BitSet) {
         self.other_op(other, |w1, w2| w1 & !w2);
     }
 
@@ -1632,21 +1652,21 @@ impl BitvSet {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::{BitvSet, Bitv};
+    /// use std::collections::{BitSet, BitVec};
     ///
     /// let a   = 0b01101000;
     /// let b   = 0b10100000;
     /// let res = 0b11001000;
     ///
-    /// let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[a]));
-    /// let b = BitvSet::from_bitv(Bitv::from_bytes(&[b]));
-    /// let res = BitvSet::from_bitv(Bitv::from_bytes(&[res]));
+    /// let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[a]));
+    /// let b = BitSet::from_bit_vec(BitVec::from_bytes(&[b]));
+    /// let res = BitSet::from_bit_vec(BitVec::from_bytes(&[res]));
     ///
     /// a.symmetric_difference_with(&b);
     /// assert_eq!(a, res);
     /// ```
     #[inline]
-    pub fn symmetric_difference_with(&mut self, other: &BitvSet) {
+    pub fn symmetric_difference_with(&mut self, other: &BitSet) {
         self.other_op(other, |w1, w2| w1 ^ w2);
     }
 
@@ -1654,57 +1674,57 @@ impl BitvSet {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn len(&self) -> usize  {
-        self.bitv.blocks().fold(0, |acc, n| acc + n.count_ones())
+        self.bit_vec.blocks().fold(0, |acc, n| acc + n.count_ones())
     }
 
     /// Returns whether there are no bits set in this set
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_empty(&self) -> bool {
-        self.bitv.none()
+        self.bit_vec.none()
     }
 
     /// Clears all bits in this set
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn clear(&mut self) {
-        self.bitv.clear();
+        self.bit_vec.clear();
     }
 
     /// Returns `true` if this set contains the specified integer.
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn contains(&self, value: &usize) -> bool {
-        let bitv = &self.bitv;
-        *value < bitv.nbits && bitv[*value]
+        let bit_vec = &self.bit_vec;
+        *value < bit_vec.nbits && bit_vec[*value]
     }
 
     /// Returns `true` if the set has no elements in common with `other`.
     /// This is equivalent to checking for an empty intersection.
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn is_disjoint(&self, other: &BitvSet) -> bool {
+    pub fn is_disjoint(&self, other: &BitSet) -> bool {
         self.intersection(other).next().is_none()
     }
 
     /// Returns `true` if the set is a subset of another.
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn is_subset(&self, other: &BitvSet) -> bool {
-        let self_bitv = &self.bitv;
-        let other_bitv = &other.bitv;
-        let other_blocks = blocks_for_bits(other_bitv.len());
+    pub fn is_subset(&self, other: &BitSet) -> bool {
+        let self_bit_vec = &self.bit_vec;
+        let other_bit_vec = &other.bit_vec;
+        let other_blocks = blocks_for_bits(other_bit_vec.len());
 
         // Check that `self` intersect `other` is self
-        self_bitv.blocks().zip(other_bitv.blocks()).all(|(w1, w2)| w1 & w2 == w1) &&
+        self_bit_vec.blocks().zip(other_bit_vec.blocks()).all(|(w1, w2)| w1 & w2 == w1) &&
         // Make sure if `self` has any more blocks than `other`, they're all 0
-        self_bitv.blocks().skip(other_blocks).all(|w| w == 0)
+        self_bit_vec.blocks().skip(other_blocks).all(|w| w == 0)
     }
 
     /// Returns `true` if the set is a superset of another.
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn is_superset(&self, other: &BitvSet) -> bool {
+    pub fn is_superset(&self, other: &BitSet) -> bool {
         other.is_subset(self)
     }
 
@@ -1717,12 +1737,12 @@ impl BitvSet {
         }
 
         // Ensure we have enough space to hold the new element
-        let len = self.bitv.len();
+        let len = self.bit_vec.len();
         if value >= len {
-            self.bitv.grow(value - len + 1, false)
+            self.bit_vec.grow(value - len + 1, false)
         }
 
-        self.bitv.set(value, true);
+        self.bit_vec.set(value, true);
         return true;
     }
 
@@ -1734,16 +1754,16 @@ impl BitvSet {
             return false;
         }
 
-        self.bitv.set(*value, false);
+        self.bit_vec.set(*value, false);
 
         return true;
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Debug for BitvSet {
+impl fmt::Debug for BitSet {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        try!(write!(fmt, "BitvSet {{"));
+        try!(write!(fmt, "BitSet {{"));
         let mut first = true;
         for n in self {
             if !first {
@@ -1756,27 +1776,37 @@ impl fmt::Debug for BitvSet {
     }
 }
 
-impl<S: hash::Writer + hash::Hasher> hash::Hash<S> for BitvSet {
+#[cfg(stage0)]
+impl<S: hash::Writer + hash::Hasher> hash::Hash<S> for BitSet {
     fn hash(&self, state: &mut S) {
         for pos in self {
             pos.hash(state);
         }
     }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
+#[cfg(not(stage0))]
+impl hash::Hash for BitSet {
+    fn hash<H: hash::Hasher>(&self, state: &mut H) {
+        for pos in self {
+            pos.hash(state);
+        }
+    }
+}
 
-/// An iterator for `BitvSet`.
+/// An iterator for `BitSet`.
 #[derive(Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct SetIter<'a> {
-    set: &'a BitvSet,
+    set: &'a BitSet,
     next_idx: usize
 }
 
-/// An iterator combining two `BitvSet` iterators.
+/// An iterator combining two `BitSet` iterators.
 #[derive(Clone)]
 struct TwoBitPositions<'a> {
-    set: &'a BitvSet,
-    other: &'a BitvSet,
+    set: &'a BitSet,
+    other: &'a BitSet,
     merge: fn(u32, u32) -> u32,
     current_word: u32,
     next_idx: usize
@@ -1796,7 +1826,7 @@ impl<'a> Iterator for SetIter<'a> {
     type Item = usize;
 
     fn next(&mut self) -> Option<usize> {
-        while self.next_idx < self.set.bitv.len() {
+        while self.next_idx < self.set.bit_vec.len() {
             let idx = self.next_idx;
             self.next_idx += 1;
 
@@ -1810,7 +1840,7 @@ impl<'a> Iterator for SetIter<'a> {
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
-        (0, Some(self.set.bitv.len() - self.next_idx))
+        (0, Some(self.set.bit_vec.len() - self.next_idx))
     }
 }
 
@@ -1819,20 +1849,20 @@ impl<'a> Iterator for TwoBitPositions<'a> {
     type Item = usize;
 
     fn next(&mut self) -> Option<usize> {
-        while self.next_idx < self.set.bitv.len() ||
-              self.next_idx < self.other.bitv.len() {
+        while self.next_idx < self.set.bit_vec.len() ||
+              self.next_idx < self.other.bit_vec.len() {
             let bit_idx = self.next_idx % u32::BITS;
             if bit_idx == 0 {
-                let s_bitv = &self.set.bitv;
-                let o_bitv = &self.other.bitv;
+                let s_bit_vec = &self.set.bit_vec;
+                let o_bit_vec = &self.other.bit_vec;
                 // Merging the two words is a bit of an awkward dance since
-                // one Bitv might be longer than the other
+                // one BitVec might be longer than the other
                 let word_idx = self.next_idx / u32::BITS;
-                let w1 = if word_idx < s_bitv.storage.len() {
-                             s_bitv.storage[word_idx]
+                let w1 = if word_idx < s_bit_vec.storage.len() {
+                             s_bit_vec.storage[word_idx]
                          } else { 0 };
-                let w2 = if word_idx < o_bitv.storage.len() {
-                             o_bitv.storage[word_idx]
+                let w2 = if word_idx < o_bit_vec.storage.len() {
+                             o_bit_vec.storage[word_idx]
                          } else { 0 };
                 self.current_word = (self.merge)(w1, w2);
             }
@@ -1847,7 +1877,7 @@ impl<'a> Iterator for TwoBitPositions<'a> {
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
-        let cap = cmp::max(self.set.bitv.len(), self.other.bitv.len());
+        let cap = cmp::max(self.set.bit_vec.len(), self.other.bit_vec.len());
         (0, Some(cap - self.next_idx))
     }
 }
@@ -1885,7 +1915,7 @@ impl<'a> Iterator for SymmetricDifference<'a> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a> IntoIterator for &'a BitvSet {
+impl<'a> IntoIterator for &'a BitSet {
     type Item = usize;
     type IntoIter = SetIter<'a>;
 
@@ -1899,20 +1929,20 @@ mod tests {
     use prelude::*;
     use core::u32;
 
-    use super::Bitv;
+    use super::BitVec;
 
     #[test]
     fn test_to_str() {
-        let zerolen = Bitv::new();
+        let zerolen = BitVec::new();
         assert_eq!(format!("{:?}", zerolen), "");
 
-        let eightbits = Bitv::from_elem(8, false);
+        let eightbits = BitVec::from_elem(8, false);
         assert_eq!(format!("{:?}", eightbits), "00000000")
     }
 
     #[test]
     fn test_0_elements() {
-        let act = Bitv::new();
+        let act = BitVec::new();
         let exp = Vec::new();
         assert!(act.eq_vec(&exp));
         assert!(act.none() && act.all());
@@ -1920,17 +1950,17 @@ mod tests {
 
     #[test]
     fn test_1_element() {
-        let mut act = Bitv::from_elem(1, false);
+        let mut act = BitVec::from_elem(1, false);
         assert!(act.eq_vec(&[false]));
         assert!(act.none() && !act.all());
-        act = Bitv::from_elem(1, true);
+        act = BitVec::from_elem(1, true);
         assert!(act.eq_vec(&[true]));
         assert!(!act.none() && act.all());
     }
 
     #[test]
     fn test_2_elements() {
-        let mut b = Bitv::from_elem(2, false);
+        let mut b = BitVec::from_elem(2, false);
         b.set(0, true);
         b.set(1, false);
         assert_eq!(format!("{:?}", b), "10");
@@ -1942,18 +1972,18 @@ mod tests {
         let mut act;
         // all 0
 
-        act = Bitv::from_elem(10, false);
+        act = BitVec::from_elem(10, false);
         assert!((act.eq_vec(
                     &[false, false, false, false, false, false, false, false, false, false])));
         assert!(act.none() && !act.all());
         // all 1
 
-        act = Bitv::from_elem(10, true);
+        act = BitVec::from_elem(10, true);
         assert!((act.eq_vec(&[true, true, true, true, true, true, true, true, true, true])));
         assert!(!act.none() && act.all());
         // mixed
 
-        act = Bitv::from_elem(10, false);
+        act = BitVec::from_elem(10, false);
         act.set(0, true);
         act.set(1, true);
         act.set(2, true);
@@ -1963,7 +1993,7 @@ mod tests {
         assert!(!act.none() && !act.all());
         // mixed
 
-        act = Bitv::from_elem(10, false);
+        act = BitVec::from_elem(10, false);
         act.set(5, true);
         act.set(6, true);
         act.set(7, true);
@@ -1973,7 +2003,7 @@ mod tests {
         assert!(!act.none() && !act.all());
         // mixed
 
-        act = Bitv::from_elem(10, false);
+        act = BitVec::from_elem(10, false);
         act.set(0, true);
         act.set(3, true);
         act.set(6, true);
@@ -1987,7 +2017,7 @@ mod tests {
         let mut act;
         // all 0
 
-        act = Bitv::from_elem(31, false);
+        act = BitVec::from_elem(31, false);
         assert!(act.eq_vec(
                 &[false, false, false, false, false, false, false, false, false, false, false,
                   false, false, false, false, false, false, false, false, false, false, false,
@@ -1995,7 +2025,7 @@ mod tests {
         assert!(act.none() && !act.all());
         // all 1
 
-        act = Bitv::from_elem(31, true);
+        act = BitVec::from_elem(31, true);
         assert!(act.eq_vec(
                 &[true, true, true, true, true, true, true, true, true, true, true, true, true,
                   true, true, true, true, true, true, true, true, true, true, true, true, true,
@@ -2003,7 +2033,7 @@ mod tests {
         assert!(!act.none() && act.all());
         // mixed
 
-        act = Bitv::from_elem(31, false);
+        act = BitVec::from_elem(31, false);
         act.set(0, true);
         act.set(1, true);
         act.set(2, true);
@@ -2019,7 +2049,7 @@ mod tests {
         assert!(!act.none() && !act.all());
         // mixed
 
-        act = Bitv::from_elem(31, false);
+        act = BitVec::from_elem(31, false);
         act.set(16, true);
         act.set(17, true);
         act.set(18, true);
@@ -2035,7 +2065,7 @@ mod tests {
         assert!(!act.none() && !act.all());
         // mixed
 
-        act = Bitv::from_elem(31, false);
+        act = BitVec::from_elem(31, false);
         act.set(24, true);
         act.set(25, true);
         act.set(26, true);
@@ -2050,7 +2080,7 @@ mod tests {
         assert!(!act.none() && !act.all());
         // mixed
 
-        act = Bitv::from_elem(31, false);
+        act = BitVec::from_elem(31, false);
         act.set(3, true);
         act.set(17, true);
         act.set(30, true);
@@ -2066,7 +2096,7 @@ mod tests {
         let mut act;
         // all 0
 
-        act = Bitv::from_elem(32, false);
+        act = BitVec::from_elem(32, false);
         assert!(act.eq_vec(
                 &[false, false, false, false, false, false, false, false, false, false, false,
                   false, false, false, false, false, false, false, false, false, false, false,
@@ -2074,7 +2104,7 @@ mod tests {
         assert!(act.none() && !act.all());
         // all 1
 
-        act = Bitv::from_elem(32, true);
+        act = BitVec::from_elem(32, true);
         assert!(act.eq_vec(
                 &[true, true, true, true, true, true, true, true, true, true, true, true, true,
                   true, true, true, true, true, true, true, true, true, true, true, true, true,
@@ -2082,7 +2112,7 @@ mod tests {
         assert!(!act.none() && act.all());
         // mixed
 
-        act = Bitv::from_elem(32, false);
+        act = BitVec::from_elem(32, false);
         act.set(0, true);
         act.set(1, true);
         act.set(2, true);
@@ -2098,7 +2128,7 @@ mod tests {
         assert!(!act.none() && !act.all());
         // mixed
 
-        act = Bitv::from_elem(32, false);
+        act = BitVec::from_elem(32, false);
         act.set(16, true);
         act.set(17, true);
         act.set(18, true);
@@ -2114,7 +2144,7 @@ mod tests {
         assert!(!act.none() && !act.all());
         // mixed
 
-        act = Bitv::from_elem(32, false);
+        act = BitVec::from_elem(32, false);
         act.set(24, true);
         act.set(25, true);
         act.set(26, true);
@@ -2130,7 +2160,7 @@ mod tests {
         assert!(!act.none() && !act.all());
         // mixed
 
-        act = Bitv::from_elem(32, false);
+        act = BitVec::from_elem(32, false);
         act.set(3, true);
         act.set(17, true);
         act.set(30, true);
@@ -2147,7 +2177,7 @@ mod tests {
         let mut act;
         // all 0
 
-        act = Bitv::from_elem(33, false);
+        act = BitVec::from_elem(33, false);
         assert!(act.eq_vec(
                 &[false, false, false, false, false, false, false, false, false, false, false,
                   false, false, false, false, false, false, false, false, false, false, false,
@@ -2155,7 +2185,7 @@ mod tests {
         assert!(act.none() && !act.all());
         // all 1
 
-        act = Bitv::from_elem(33, true);
+        act = BitVec::from_elem(33, true);
         assert!(act.eq_vec(
                 &[true, true, true, true, true, true, true, true, true, true, true, true, true,
                   true, true, true, true, true, true, true, true, true, true, true, true, true,
@@ -2163,7 +2193,7 @@ mod tests {
         assert!(!act.none() && act.all());
         // mixed
 
-        act = Bitv::from_elem(33, false);
+        act = BitVec::from_elem(33, false);
         act.set(0, true);
         act.set(1, true);
         act.set(2, true);
@@ -2179,7 +2209,7 @@ mod tests {
         assert!(!act.none() && !act.all());
         // mixed
 
-        act = Bitv::from_elem(33, false);
+        act = BitVec::from_elem(33, false);
         act.set(16, true);
         act.set(17, true);
         act.set(18, true);
@@ -2195,7 +2225,7 @@ mod tests {
         assert!(!act.none() && !act.all());
         // mixed
 
-        act = Bitv::from_elem(33, false);
+        act = BitVec::from_elem(33, false);
         act.set(24, true);
         act.set(25, true);
         act.set(26, true);
@@ -2211,7 +2241,7 @@ mod tests {
         assert!(!act.none() && !act.all());
         // mixed
 
-        act = Bitv::from_elem(33, false);
+        act = BitVec::from_elem(33, false);
         act.set(3, true);
         act.set(17, true);
         act.set(30, true);
@@ -2226,24 +2256,24 @@ mod tests {
 
     #[test]
     fn test_equal_differing_sizes() {
-        let v0 = Bitv::from_elem(10, false);
-        let v1 = Bitv::from_elem(11, false);
+        let v0 = BitVec::from_elem(10, false);
+        let v1 = BitVec::from_elem(11, false);
         assert!(v0 != v1);
     }
 
     #[test]
     fn test_equal_greatly_differing_sizes() {
-        let v0 = Bitv::from_elem(10, false);
-        let v1 = Bitv::from_elem(110, false);
+        let v0 = BitVec::from_elem(10, false);
+        let v1 = BitVec::from_elem(110, false);
         assert!(v0 != v1);
     }
 
     #[test]
     fn test_equal_sneaky_small() {
-        let mut a = Bitv::from_elem(1, false);
+        let mut a = BitVec::from_elem(1, false);
         a.set(0, true);
 
-        let mut b = Bitv::from_elem(1, true);
+        let mut b = BitVec::from_elem(1, true);
         b.set(0, true);
 
         assert_eq!(a, b);
@@ -2251,12 +2281,12 @@ mod tests {
 
     #[test]
     fn test_equal_sneaky_big() {
-        let mut a = Bitv::from_elem(100, false);
+        let mut a = BitVec::from_elem(100, false);
         for i in 0..100 {
             a.set(i, true);
         }
 
-        let mut b = Bitv::from_elem(100, true);
+        let mut b = BitVec::from_elem(100, true);
         for i in 0..100 {
             b.set(i, true);
         }
@@ -2266,18 +2296,18 @@ mod tests {
 
     #[test]
     fn test_from_bytes() {
-        let bitv = Bitv::from_bytes(&[0b10110110, 0b00000000, 0b11111111]);
+        let bit_vec = BitVec::from_bytes(&[0b10110110, 0b00000000, 0b11111111]);
         let str = concat!("10110110", "00000000", "11111111");
-        assert_eq!(format!("{:?}", bitv), str);
+        assert_eq!(format!("{:?}", bit_vec), str);
     }
 
     #[test]
     fn test_to_bytes() {
-        let mut bv = Bitv::from_elem(3, true);
+        let mut bv = BitVec::from_elem(3, true);
         bv.set(1, false);
         assert_eq!(bv.to_bytes(), vec!(0b10100000));
 
-        let mut bv = Bitv::from_elem(9, false);
+        let mut bv = BitVec::from_elem(9, false);
         bv.set(2, true);
         bv.set(8, true);
         assert_eq!(bv.to_bytes(), vec!(0b00100000, 0b10000000));
@@ -2286,32 +2316,32 @@ mod tests {
     #[test]
     fn test_from_bools() {
         let bools = vec![true, false, true, true];
-        let bitv: Bitv = bools.iter().map(|n| *n).collect();
-        assert_eq!(format!("{:?}", bitv), "1011");
+        let bit_vec: BitVec = bools.iter().map(|n| *n).collect();
+        assert_eq!(format!("{:?}", bit_vec), "1011");
     }
 
     #[test]
     fn test_to_bools() {
         let bools = vec![false, false, true, false, false, true, true, false];
-        assert_eq!(Bitv::from_bytes(&[0b00100110]).iter().collect::<Vec<bool>>(), bools);
+        assert_eq!(BitVec::from_bytes(&[0b00100110]).iter().collect::<Vec<bool>>(), bools);
     }
 
     #[test]
-    fn test_bitv_iterator() {
+    fn test_bit_vec_iterator() {
         let bools = vec![true, false, true, true];
-        let bitv: Bitv = bools.iter().map(|n| *n).collect();
+        let bit_vec: BitVec = bools.iter().map(|n| *n).collect();
 
-        assert_eq!(bitv.iter().collect::<Vec<bool>>(), bools);
+        assert_eq!(bit_vec.iter().collect::<Vec<bool>>(), bools);
 
         let long: Vec<_> = (0i32..10000).map(|i| i % 2 == 0).collect();
-        let bitv: Bitv = long.iter().map(|n| *n).collect();
-        assert_eq!(bitv.iter().collect::<Vec<bool>>(), long)
+        let bit_vec: BitVec = long.iter().map(|n| *n).collect();
+        assert_eq!(bit_vec.iter().collect::<Vec<bool>>(), long)
     }
 
     #[test]
     fn test_small_difference() {
-        let mut b1 = Bitv::from_elem(3, false);
-        let mut b2 = Bitv::from_elem(3, false);
+        let mut b1 = BitVec::from_elem(3, false);
+        let mut b2 = BitVec::from_elem(3, false);
         b1.set(0, true);
         b1.set(1, true);
         b2.set(1, true);
@@ -2324,8 +2354,8 @@ mod tests {
 
     #[test]
     fn test_big_difference() {
-        let mut b1 = Bitv::from_elem(100, false);
-        let mut b2 = Bitv::from_elem(100, false);
+        let mut b1 = BitVec::from_elem(100, false);
+        let mut b2 = BitVec::from_elem(100, false);
         b1.set(0, true);
         b1.set(40, true);
         b2.set(40, true);
@@ -2338,7 +2368,7 @@ mod tests {
 
     #[test]
     fn test_small_clear() {
-        let mut b = Bitv::from_elem(14, true);
+        let mut b = BitVec::from_elem(14, true);
         assert!(!b.none() && b.all());
         b.clear();
         assert!(b.none() && !b.all());
@@ -2346,16 +2376,16 @@ mod tests {
 
     #[test]
     fn test_big_clear() {
-        let mut b = Bitv::from_elem(140, true);
+        let mut b = BitVec::from_elem(140, true);
         assert!(!b.none() && b.all());
         b.clear();
         assert!(b.none() && !b.all());
     }
 
     #[test]
-    fn test_bitv_lt() {
-        let mut a = Bitv::from_elem(5, false);
-        let mut b = Bitv::from_elem(5, false);
+    fn test_bit_vec_lt() {
+        let mut a = BitVec::from_elem(5, false);
+        let mut b = BitVec::from_elem(5, false);
 
         assert!(!(a < b) && !(b < a));
         b.set(2, true);
@@ -2370,8 +2400,8 @@ mod tests {
 
     #[test]
     fn test_ord() {
-        let mut a = Bitv::from_elem(5, false);
-        let mut b = Bitv::from_elem(5, false);
+        let mut a = BitVec::from_elem(5, false);
+        let mut b = BitVec::from_elem(5, false);
 
         assert!(a <= b && a >= b);
         a.set(1, true);
@@ -2385,26 +2415,26 @@ mod tests {
 
 
     #[test]
-    fn test_small_bitv_tests() {
-        let v = Bitv::from_bytes(&[0]);
+    fn test_small_bit_vec_tests() {
+        let v = BitVec::from_bytes(&[0]);
         assert!(!v.all());
         assert!(!v.any());
         assert!(v.none());
 
-        let v = Bitv::from_bytes(&[0b00010100]);
+        let v = BitVec::from_bytes(&[0b00010100]);
         assert!(!v.all());
         assert!(v.any());
         assert!(!v.none());
 
-        let v = Bitv::from_bytes(&[0xFF]);
+        let v = BitVec::from_bytes(&[0xFF]);
         assert!(v.all());
         assert!(v.any());
         assert!(!v.none());
     }
 
     #[test]
-    fn test_big_bitv_tests() {
-        let v = Bitv::from_bytes(&[ // 88 bits
+    fn test_big_bit_vec_tests() {
+        let v = BitVec::from_bytes(&[ // 88 bits
             0, 0, 0, 0,
             0, 0, 0, 0,
             0, 0, 0]);
@@ -2412,7 +2442,7 @@ mod tests {
         assert!(!v.any());
         assert!(v.none());
 
-        let v = Bitv::from_bytes(&[ // 88 bits
+        let v = BitVec::from_bytes(&[ // 88 bits
             0, 0, 0b00010100, 0,
             0, 0, 0, 0b00110100,
             0, 0, 0]);
@@ -2420,7 +2450,7 @@ mod tests {
         assert!(v.any());
         assert!(!v.none());
 
-        let v = Bitv::from_bytes(&[ // 88 bits
+        let v = BitVec::from_bytes(&[ // 88 bits
             0xFF, 0xFF, 0xFF, 0xFF,
             0xFF, 0xFF, 0xFF, 0xFF,
             0xFF, 0xFF, 0xFF]);
@@ -2430,8 +2460,8 @@ mod tests {
     }
 
     #[test]
-    fn test_bitv_push_pop() {
-        let mut s = Bitv::from_elem(5 * u32::BITS - 2, false);
+    fn test_bit_vec_push_pop() {
+        let mut s = BitVec::from_elem(5 * u32::BITS - 2, false);
         assert_eq!(s.len(), 5 * u32::BITS - 2);
         assert_eq!(s[5 * u32::BITS - 3], false);
         s.push(true);
@@ -2453,29 +2483,29 @@ mod tests {
     }
 
     #[test]
-    fn test_bitv_truncate() {
-        let mut s = Bitv::from_elem(5 * u32::BITS, true);
+    fn test_bit_vec_truncate() {
+        let mut s = BitVec::from_elem(5 * u32::BITS, true);
 
-        assert_eq!(s, Bitv::from_elem(5 * u32::BITS, true));
+        assert_eq!(s, BitVec::from_elem(5 * u32::BITS, true));
         assert_eq!(s.len(), 5 * u32::BITS);
         s.truncate(4 * u32::BITS);
-        assert_eq!(s, Bitv::from_elem(4 * u32::BITS, true));
+        assert_eq!(s, BitVec::from_elem(4 * u32::BITS, true));
         assert_eq!(s.len(), 4 * u32::BITS);
         // Truncating to a size > s.len() should be a noop
         s.truncate(5 * u32::BITS);
-        assert_eq!(s, Bitv::from_elem(4 * u32::BITS, true));
+        assert_eq!(s, BitVec::from_elem(4 * u32::BITS, true));
         assert_eq!(s.len(), 4 * u32::BITS);
         s.truncate(3 * u32::BITS - 10);
-        assert_eq!(s, Bitv::from_elem(3 * u32::BITS - 10, true));
+        assert_eq!(s, BitVec::from_elem(3 * u32::BITS - 10, true));
         assert_eq!(s.len(), 3 * u32::BITS - 10);
         s.truncate(0);
-        assert_eq!(s, Bitv::from_elem(0, true));
+        assert_eq!(s, BitVec::from_elem(0, true));
         assert_eq!(s.len(), 0);
     }
 
     #[test]
-    fn test_bitv_reserve() {
-        let mut s = Bitv::from_elem(5 * u32::BITS, true);
+    fn test_bit_vec_reserve() {
+        let mut s = BitVec::from_elem(5 * u32::BITS, true);
         // Check capacity
         assert!(s.capacity() >= 5 * u32::BITS);
         s.reserve(2 * u32::BITS);
@@ -2498,25 +2528,25 @@ mod tests {
     }
 
     #[test]
-    fn test_bitv_grow() {
-        let mut bitv = Bitv::from_bytes(&[0b10110110, 0b00000000, 0b10101010]);
-        bitv.grow(32, true);
-        assert_eq!(bitv, Bitv::from_bytes(&[0b10110110, 0b00000000, 0b10101010,
+    fn test_bit_vec_grow() {
+        let mut bit_vec = BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010]);
+        bit_vec.grow(32, true);
+        assert_eq!(bit_vec, BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010,
                                      0xFF, 0xFF, 0xFF, 0xFF]));
-        bitv.grow(64, false);
-        assert_eq!(bitv, Bitv::from_bytes(&[0b10110110, 0b00000000, 0b10101010,
+        bit_vec.grow(64, false);
+        assert_eq!(bit_vec, BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010,
                                      0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0]));
-        bitv.grow(16, true);
-        assert_eq!(bitv, Bitv::from_bytes(&[0b10110110, 0b00000000, 0b10101010,
+        bit_vec.grow(16, true);
+        assert_eq!(bit_vec, BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010,
                                      0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF]));
     }
 
     #[test]
-    fn test_bitv_extend() {
-        let mut bitv = Bitv::from_bytes(&[0b10110110, 0b00000000, 0b11111111]);
-        let ext = Bitv::from_bytes(&[0b01001001, 0b10010010, 0b10111101]);
-        bitv.extend(ext.iter());
-        assert_eq!(bitv, Bitv::from_bytes(&[0b10110110, 0b00000000, 0b11111111,
+    fn test_bit_vec_extend() {
+        let mut bit_vec = BitVec::from_bytes(&[0b10110110, 0b00000000, 0b11111111]);
+        let ext = BitVec::from_bytes(&[0b01001001, 0b10010010, 0b10111101]);
+        bit_vec.extend(ext.iter());
+        assert_eq!(bit_vec, BitVec::from_bytes(&[0b10110110, 0b00000000, 0b11111111,
                                      0b01001001, 0b10010010, 0b10111101]));
     }
 }
@@ -2525,14 +2555,14 @@ mod tests {
 
 
 #[cfg(test)]
-mod bitv_bench {
+mod bit_vec_bench {
     use std::prelude::v1::*;
     use std::rand;
     use std::rand::Rng;
     use std::u32;
     use test::{Bencher, black_box};
 
-    use super::Bitv;
+    use super::BitVec;
 
     static BENCH_BITS : usize = 1 << 14;
 
@@ -2544,67 +2574,67 @@ mod bitv_bench {
     #[bench]
     fn bench_usize_small(b: &mut Bencher) {
         let mut r = rng();
-        let mut bitv = 0 as usize;
+        let mut bit_vec = 0 as usize;
         b.iter(|| {
             for _ in 0..100 {
-                bitv |= 1 << ((r.next_u32() as usize) % u32::BITS);
+                bit_vec |= 1 << ((r.next_u32() as usize) % u32::BITS);
             }
-            black_box(&bitv);
+            black_box(&bit_vec);
         });
     }
 
     #[bench]
-    fn bench_bitv_set_big_fixed(b: &mut Bencher) {
+    fn bench_bit_set_big_fixed(b: &mut Bencher) {
         let mut r = rng();
-        let mut bitv = Bitv::from_elem(BENCH_BITS, false);
+        let mut bit_vec = BitVec::from_elem(BENCH_BITS, false);
         b.iter(|| {
             for _ in 0..100 {
-                bitv.set((r.next_u32() as usize) % BENCH_BITS, true);
+                bit_vec.set((r.next_u32() as usize) % BENCH_BITS, true);
             }
-            black_box(&bitv);
+            black_box(&bit_vec);
         });
     }
 
     #[bench]
-    fn bench_bitv_set_big_variable(b: &mut Bencher) {
+    fn bench_bit_set_big_variable(b: &mut Bencher) {
         let mut r = rng();
-        let mut bitv = Bitv::from_elem(BENCH_BITS, false);
+        let mut bit_vec = BitVec::from_elem(BENCH_BITS, false);
         b.iter(|| {
             for _ in 0..100 {
-                bitv.set((r.next_u32() as usize) % BENCH_BITS, r.gen());
+                bit_vec.set((r.next_u32() as usize) % BENCH_BITS, r.gen());
             }
-            black_box(&bitv);
+            black_box(&bit_vec);
         });
     }
 
     #[bench]
-    fn bench_bitv_set_small(b: &mut Bencher) {
+    fn bench_bit_set_small(b: &mut Bencher) {
         let mut r = rng();
-        let mut bitv = Bitv::from_elem(u32::BITS, false);
+        let mut bit_vec = BitVec::from_elem(u32::BITS, false);
         b.iter(|| {
             for _ in 0..100 {
-                bitv.set((r.next_u32() as usize) % u32::BITS, true);
+                bit_vec.set((r.next_u32() as usize) % u32::BITS, true);
             }
-            black_box(&bitv);
+            black_box(&bit_vec);
         });
     }
 
     #[bench]
-    fn bench_bitv_big_union(b: &mut Bencher) {
-        let mut b1 = Bitv::from_elem(BENCH_BITS, false);
-        let b2 = Bitv::from_elem(BENCH_BITS, false);
+    fn bench_bit_vec_big_union(b: &mut Bencher) {
+        let mut b1 = BitVec::from_elem(BENCH_BITS, false);
+        let b2 = BitVec::from_elem(BENCH_BITS, false);
         b.iter(|| {
             b1.union(&b2)
         })
     }
 
     #[bench]
-    fn bench_bitv_small_iter(b: &mut Bencher) {
-        let bitv = Bitv::from_elem(u32::BITS, false);
+    fn bench_bit_vec_small_iter(b: &mut Bencher) {
+        let bit_vec = BitVec::from_elem(u32::BITS, false);
         b.iter(|| {
             let mut sum = 0;
             for _ in 0..10 {
-                for pres in &bitv {
+                for pres in &bit_vec {
                     sum += pres as usize;
                 }
             }
@@ -2613,11 +2643,11 @@ mod bitv_bench {
     }
 
     #[bench]
-    fn bench_bitv_big_iter(b: &mut Bencher) {
-        let bitv = Bitv::from_elem(BENCH_BITS, false);
+    fn bench_bit_vec_big_iter(b: &mut Bencher) {
+        let bit_vec = BitVec::from_elem(BENCH_BITS, false);
         b.iter(|| {
             let mut sum = 0;
-            for pres in &bitv {
+            for pres in &bit_vec {
                 sum += pres as usize;
             }
             sum
@@ -2632,27 +2662,27 @@ mod bitv_bench {
 
 
 #[cfg(test)]
-mod bitv_set_test {
+mod bit_set_test {
     use prelude::*;
     use std::iter::range_step;
 
-    use super::{Bitv, BitvSet};
+    use super::{BitVec, BitSet};
 
     #[test]
-    fn test_bitv_set_show() {
-        let mut s = BitvSet::new();
+    fn test_bit_set_show() {
+        let mut s = BitSet::new();
         s.insert(1);
         s.insert(10);
         s.insert(50);
         s.insert(2);
-        assert_eq!("BitvSet {1, 2, 10, 50}", format!("{:?}", s));
+        assert_eq!("BitSet {1, 2, 10, 50}", format!("{:?}", s));
     }
 
     #[test]
-    fn test_bitv_set_from_usizes() {
+    fn test_bit_set_from_usizes() {
         let usizes = vec![0, 2, 2, 3];
-        let a: BitvSet = usizes.into_iter().collect();
-        let mut b = BitvSet::new();
+        let a: BitSet = usizes.into_iter().collect();
+        let mut b = BitSet::new();
         b.insert(0);
         b.insert(2);
         b.insert(3);
@@ -2660,14 +2690,14 @@ mod bitv_set_test {
     }
 
     #[test]
-    fn test_bitv_set_iterator() {
+    fn test_bit_set_iterator() {
         let usizes = vec![0, 2, 2, 3];
-        let bitv: BitvSet = usizes.into_iter().collect();
+        let bit_vec: BitSet = usizes.into_iter().collect();
 
-        let idxs: Vec<_> = bitv.iter().collect();
+        let idxs: Vec<_> = bit_vec.iter().collect();
         assert_eq!(idxs, vec![0, 2, 3]);
 
-        let long: BitvSet = (0..10000).filter(|&n| n % 2 == 0).collect();
+        let long: BitSet = (0..10000).filter(|&n| n % 2 == 0).collect();
         let real: Vec<_> = range_step(0, 10000, 2).collect();
 
         let idxs: Vec<_> = long.iter().collect();
@@ -2675,12 +2705,12 @@ mod bitv_set_test {
     }
 
     #[test]
-    fn test_bitv_set_frombitv_init() {
+    fn test_bit_set_frombit_vec_init() {
         let bools = [true, false];
         let lengths = [10, 64, 100];
         for &b in &bools {
             for &l in &lengths {
-                let bitset = BitvSet::from_bitv(Bitv::from_elem(l, b));
+                let bitset = BitSet::from_bit_vec(BitVec::from_elem(l, b));
                 assert_eq!(bitset.contains(&1), b);
                 assert_eq!(bitset.contains(&(l-1)), b);
                 assert!(!bitset.contains(&l));
@@ -2689,9 +2719,9 @@ mod bitv_set_test {
     }
 
     #[test]
-    fn test_bitv_masking() {
-        let b = Bitv::from_elem(140, true);
-        let mut bs = BitvSet::from_bitv(b);
+    fn test_bit_vec_masking() {
+        let b = BitVec::from_elem(140, true);
+        let mut bs = BitSet::from_bit_vec(b);
         assert!(bs.contains(&139));
         assert!(!bs.contains(&140));
         assert!(bs.insert(150));
@@ -2702,8 +2732,8 @@ mod bitv_set_test {
     }
 
     #[test]
-    fn test_bitv_set_basic() {
-        let mut b = BitvSet::new();
+    fn test_bit_set_basic() {
+        let mut b = BitSet::new();
         assert!(b.insert(3));
         assert!(!b.insert(3));
         assert!(b.contains(&3));
@@ -2717,9 +2747,9 @@ mod bitv_set_test {
     }
 
     #[test]
-    fn test_bitv_set_intersection() {
-        let mut a = BitvSet::new();
-        let mut b = BitvSet::new();
+    fn test_bit_set_intersection() {
+        let mut a = BitSet::new();
+        let mut b = BitSet::new();
 
         assert!(a.insert(11));
         assert!(a.insert(1));
@@ -2740,9 +2770,9 @@ mod bitv_set_test {
     }
 
     #[test]
-    fn test_bitv_set_difference() {
-        let mut a = BitvSet::new();
-        let mut b = BitvSet::new();
+    fn test_bit_set_difference() {
+        let mut a = BitSet::new();
+        let mut b = BitSet::new();
 
         assert!(a.insert(1));
         assert!(a.insert(3));
@@ -2759,9 +2789,9 @@ mod bitv_set_test {
     }
 
     #[test]
-    fn test_bitv_set_symmetric_difference() {
-        let mut a = BitvSet::new();
-        let mut b = BitvSet::new();
+    fn test_bit_set_symmetric_difference() {
+        let mut a = BitSet::new();
+        let mut b = BitSet::new();
 
         assert!(a.insert(1));
         assert!(a.insert(3));
@@ -2780,9 +2810,9 @@ mod bitv_set_test {
     }
 
     #[test]
-    fn test_bitv_set_union() {
-        let mut a = BitvSet::new();
-        let mut b = BitvSet::new();
+    fn test_bit_set_union() {
+        let mut a = BitSet::new();
+        let mut b = BitSet::new();
         assert!(a.insert(1));
         assert!(a.insert(3));
         assert!(a.insert(5));
@@ -2805,9 +2835,9 @@ mod bitv_set_test {
     }
 
     #[test]
-    fn test_bitv_set_subset() {
-        let mut set1 = BitvSet::new();
-        let mut set2 = BitvSet::new();
+    fn test_bit_set_subset() {
+        let mut set1 = BitSet::new();
+        let mut set2 = BitSet::new();
 
         assert!(set1.is_subset(&set2)); //  {}  {}
         set2.insert(100);
@@ -2831,11 +2861,11 @@ mod bitv_set_test {
     }
 
     #[test]
-    fn test_bitv_set_is_disjoint() {
-        let a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010]));
-        let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b01000000]));
-        let c = BitvSet::new();
-        let d = BitvSet::from_bitv(Bitv::from_bytes(&[0b00110000]));
+    fn test_bit_set_is_disjoint() {
+        let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
+        let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01000000]));
+        let c = BitSet::new();
+        let d = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00110000]));
 
         assert!(!a.is_disjoint(&d));
         assert!(!d.is_disjoint(&a));
@@ -2849,19 +2879,19 @@ mod bitv_set_test {
     }
 
     #[test]
-    fn test_bitv_set_union_with() {
+    fn test_bit_set_union_with() {
         //a should grow to include larger elements
-        let mut a = BitvSet::new();
+        let mut a = BitSet::new();
         a.insert(0);
-        let mut b = BitvSet::new();
+        let mut b = BitSet::new();
         b.insert(5);
-        let expected = BitvSet::from_bitv(Bitv::from_bytes(&[0b10000100]));
+        let expected = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10000100]));
         a.union_with(&b);
         assert_eq!(a, expected);
 
         // Standard
-        let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010]));
-        let mut b = BitvSet::from_bitv(Bitv::from_bytes(&[0b01100010]));
+        let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
+        let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01100010]));
         let c = a.clone();
         a.union_with(&b);
         b.union_with(&c);
@@ -2870,10 +2900,10 @@ mod bitv_set_test {
     }
 
     #[test]
-    fn test_bitv_set_intersect_with() {
+    fn test_bit_set_intersect_with() {
         // Explicitly 0'ed bits
-        let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010]));
-        let mut b = BitvSet::from_bitv(Bitv::from_bytes(&[0b00000000]));
+        let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
+        let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00000000]));
         let c = a.clone();
         a.intersect_with(&b);
         b.intersect_with(&c);
@@ -2881,8 +2911,8 @@ mod bitv_set_test {
         assert!(b.is_empty());
 
         // Uninitialized bits should behave like 0's
-        let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010]));
-        let mut b = BitvSet::new();
+        let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
+        let mut b = BitSet::new();
         let c = a.clone();
         a.intersect_with(&b);
         b.intersect_with(&c);
@@ -2890,8 +2920,8 @@ mod bitv_set_test {
         assert!(b.is_empty());
 
         // Standard
-        let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010]));
-        let mut b = BitvSet::from_bitv(Bitv::from_bytes(&[0b01100010]));
+        let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
+        let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01100010]));
         let c = a.clone();
         a.intersect_with(&b);
         b.intersect_with(&c);
@@ -2900,22 +2930,22 @@ mod bitv_set_test {
     }
 
     #[test]
-    fn test_bitv_set_difference_with() {
+    fn test_bit_set_difference_with() {
         // Explicitly 0'ed bits
-        let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[0b00000000]));
-        let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010]));
+        let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00000000]));
+        let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
         a.difference_with(&b);
         assert!(a.is_empty());
 
         // Uninitialized bits should behave like 0's
-        let mut a = BitvSet::new();
-        let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b11111111]));
+        let mut a = BitSet::new();
+        let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b11111111]));
         a.difference_with(&b);
         assert!(a.is_empty());
 
         // Standard
-        let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010]));
-        let mut b = BitvSet::from_bitv(Bitv::from_bytes(&[0b01100010]));
+        let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
+        let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01100010]));
         let c = a.clone();
         a.difference_with(&b);
         b.difference_with(&c);
@@ -2924,27 +2954,27 @@ mod bitv_set_test {
     }
 
     #[test]
-    fn test_bitv_set_symmetric_difference_with() {
+    fn test_bit_set_symmetric_difference_with() {
         //a should grow to include larger elements
-        let mut a = BitvSet::new();
+        let mut a = BitSet::new();
         a.insert(0);
         a.insert(1);
-        let mut b = BitvSet::new();
+        let mut b = BitSet::new();
         b.insert(1);
         b.insert(5);
-        let expected = BitvSet::from_bitv(Bitv::from_bytes(&[0b10000100]));
+        let expected = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10000100]));
         a.symmetric_difference_with(&b);
         assert_eq!(a, expected);
 
-        let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010]));
-        let b = BitvSet::new();
+        let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
+        let b = BitSet::new();
         let c = a.clone();
         a.symmetric_difference_with(&b);
         assert_eq!(a, c);
 
         // Standard
-        let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[0b11100010]));
-        let mut b = BitvSet::from_bitv(Bitv::from_bytes(&[0b01101010]));
+        let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b11100010]));
+        let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101010]));
         let c = a.clone();
         a.symmetric_difference_with(&b);
         b.symmetric_difference_with(&c);
@@ -2953,10 +2983,10 @@ mod bitv_set_test {
     }
 
     #[test]
-    fn test_bitv_set_eq() {
-        let a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010]));
-        let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b00000000]));
-        let c = BitvSet::new();
+    fn test_bit_set_eq() {
+        let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
+        let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00000000]));
+        let c = BitSet::new();
 
         assert!(a == a);
         assert!(a != b);
@@ -2967,10 +2997,10 @@ mod bitv_set_test {
     }
 
     #[test]
-    fn test_bitv_set_cmp() {
-        let a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010]));
-        let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b00000000]));
-        let c = BitvSet::new();
+    fn test_bit_set_cmp() {
+        let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
+        let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00000000]));
+        let c = BitSet::new();
 
         assert_eq!(a.cmp(&b), Greater);
         assert_eq!(a.cmp(&c), Greater);
@@ -2981,8 +3011,8 @@ mod bitv_set_test {
     }
 
     #[test]
-    fn test_bitv_remove() {
-        let mut a = BitvSet::new();
+    fn test_bit_vec_remove() {
+        let mut a = BitSet::new();
 
         assert!(a.insert(1));
         assert!(a.remove(&1));
@@ -2996,8 +3026,8 @@ mod bitv_set_test {
     }
 
     #[test]
-    fn test_bitv_clone() {
-        let mut a = BitvSet::new();
+    fn test_bit_vec_clone() {
+        let mut a = BitSet::new();
 
         assert!(a.insert(1));
         assert!(a.insert(100));
@@ -3020,14 +3050,14 @@ mod bitv_set_test {
 
 
 #[cfg(test)]
-mod bitv_set_bench {
+mod bit_set_bench {
     use std::prelude::v1::*;
     use std::rand;
     use std::rand::Rng;
     use std::u32;
     use test::{Bencher, black_box};
 
-    use super::{Bitv, BitvSet};
+    use super::{BitVec, BitSet};
 
     static BENCH_BITS : usize = 1 << 14;
 
@@ -3037,36 +3067,36 @@ mod bitv_set_bench {
     }
 
     #[bench]
-    fn bench_bitvset_small(b: &mut Bencher) {
+    fn bench_bit_vecset_small(b: &mut Bencher) {
         let mut r = rng();
-        let mut bitv = BitvSet::new();
+        let mut bit_vec = BitSet::new();
         b.iter(|| {
             for _ in 0..100 {
-                bitv.insert((r.next_u32() as usize) % u32::BITS);
+                bit_vec.insert((r.next_u32() as usize) % u32::BITS);
             }
-            black_box(&bitv);
+            black_box(&bit_vec);
         });
     }
 
     #[bench]
-    fn bench_bitvset_big(b: &mut Bencher) {
+    fn bench_bit_vecset_big(b: &mut Bencher) {
         let mut r = rng();
-        let mut bitv = BitvSet::new();
+        let mut bit_vec = BitSet::new();
         b.iter(|| {
             for _ in 0..100 {
-                bitv.insert((r.next_u32() as usize) % BENCH_BITS);
+                bit_vec.insert((r.next_u32() as usize) % BENCH_BITS);
             }
-            black_box(&bitv);
+            black_box(&bit_vec);
         });
     }
 
     #[bench]
-    fn bench_bitvset_iter(b: &mut Bencher) {
-        let bitv = BitvSet::from_bitv(Bitv::from_fn(BENCH_BITS,
+    fn bench_bit_vecset_iter(b: &mut Bencher) {
+        let bit_vec = BitSet::from_bit_vec(BitVec::from_fn(BENCH_BITS,
                                               |idx| {idx % 3 == 0}));
         b.iter(|| {
             let mut sum = 0;
-            for idx in &bitv {
+            for idx in &bit_vec {
                 sum += idx as usize;
             }
             sum
diff --git a/src/libcollections/borrow.rs b/src/libcollections/borrow.rs
new file mode 100644
index 00000000000..901d7a73b51
--- /dev/null
+++ b/src/libcollections/borrow.rs
@@ -0,0 +1,316 @@
+// Copyright 2014 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.
+
+//! A module for working with borrowed data.
+
+#![stable(feature = "rust1", since = "1.0.0")]
+
+use core::clone::Clone;
+use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
+use core::hash::{Hash, Hasher};
+use core::marker::Sized;
+use core::ops::Deref;
+use core::option::Option;
+
+use fmt;
+use alloc::{rc, arc};
+
+use self::Cow::*;
+
+/// A trait for borrowing data.
+///
+/// In general, there may be several ways to "borrow" a piece of data.  The
+/// typical ways of borrowing a type `T` are `&T` (a shared borrow) and `&mut T`
+/// (a mutable borrow). But types like `Vec<T>` provide additional kinds of
+/// borrows: the borrowed slices `&[T]` and `&mut [T]`.
+///
+/// When writing generic code, it is often desirable to abstract over all ways
+/// of borrowing data from a given type. That is the role of the `Borrow`
+/// trait: if `T: Borrow<U>`, then `&U` can be borrowed from `&T`.  A given
+/// type can be borrowed as multiple different types. In particular, `Vec<T>:
+/// Borrow<Vec<T>>` and `Vec<T>: Borrow<[T]>`.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait Borrow<Borrowed: ?Sized> {
+    /// Immutably borrow from an owned value.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn borrow(&self) -> &Borrowed;
+}
+
+/// A trait for mutably borrowing data.
+///
+/// Similar to `Borrow`, but for mutable borrows.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait BorrowMut<Borrowed: ?Sized> : Borrow<Borrowed> {
+    /// Mutably borrow from an owned value.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn borrow_mut(&mut self) -> &mut Borrowed;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: ?Sized> Borrow<T> for T {
+    fn borrow(&self) -> &T { self }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: ?Sized> BorrowMut<T> for T {
+    fn borrow_mut(&mut self) -> &mut T { self }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T: ?Sized> Borrow<T> for &'a T {
+    fn borrow(&self) -> &T { &**self }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T: ?Sized> Borrow<T> for &'a mut T {
+    fn borrow(&self) -> &T { &**self }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T: ?Sized> BorrowMut<T> for &'a mut T {
+    fn borrow_mut(&mut self) -> &mut T { &mut **self }
+}
+
+impl<T> Borrow<T> for rc::Rc<T> {
+    fn borrow(&self) -> &T { &**self }
+}
+
+impl<T> Borrow<T> for arc::Arc<T> {
+    fn borrow(&self) -> &T { &**self }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> Borrow<B> for Cow<'a, B> where B: ToOwned, <B as ToOwned>::Owned: 'a {
+    fn borrow(&self) -> &B {
+        &**self
+    }
+}
+
+/// A generalization of Clone to borrowed data.
+///
+/// Some types make it possible to go from borrowed to owned, usually by
+/// implementing the `Clone` trait. But `Clone` works only for going from `&T`
+/// to `T`. The `ToOwned` trait generalizes `Clone` to construct owned data
+/// from any borrow of a given type.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait ToOwned {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    type Owned: Borrow<Self>;
+
+    /// Create owned data from borrowed data, usually by copying.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn to_owned(&self) -> Self::Owned;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> ToOwned for T where T: Clone {
+    type Owned = T;
+    fn to_owned(&self) -> T { self.clone() }
+}
+
+/// A clone-on-write smart pointer.
+///
+/// The type `Cow` is a smart pointer providing clone-on-write functionality: it
+/// can enclose and provide immutable access to borrowed data, and clone the
+/// data lazily when mutation or ownership is required. The type is designed to
+/// work with general borrowed data via the `Borrow` trait.
+///
+/// `Cow` implements both `Deref`, which means that you can call
+/// non-mutating methods directly on the data it encloses. If mutation
+/// is desired, `to_mut` will obtain a mutable references to an owned
+/// value, cloning if necessary.
+///
+/// # Example
+///
+/// ```rust
+/// use std::borrow::Cow;
+///
+/// fn abs_all(input: &mut Cow<[int]>) {
+///     for i in 0..input.len() {
+///         let v = input[i];
+///         if v < 0 {
+///             // clones into a vector the first time (if not already owned)
+///             input.to_mut()[i] = -v;
+///         }
+///     }
+/// }
+/// ```
+#[stable(feature = "rust1", since = "1.0.0")]
+pub enum Cow<'a, B: ?Sized + 'a> where B: ToOwned {
+    /// Borrowed data.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    Borrowed(&'a B),
+
+    /// Owned data.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    Owned(<B as ToOwned>::Owned)
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> Clone for Cow<'a, B> where B: ToOwned {
+    fn clone(&self) -> Cow<'a, B> {
+        match *self {
+            Borrowed(b) => Borrowed(b),
+            Owned(ref o) => {
+                let b: &B = o.borrow();
+                Owned(b.to_owned())
+            },
+        }
+    }
+}
+
+impl<'a, B: ?Sized> Cow<'a, B> where B: ToOwned {
+    /// Acquire a mutable reference to the owned form of the data.
+    ///
+    /// Copies the data if it is not already owned.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn to_mut(&mut self) -> &mut <B as ToOwned>::Owned {
+        match *self {
+            Borrowed(borrowed) => {
+                *self = Owned(borrowed.to_owned());
+                self.to_mut()
+            }
+            Owned(ref mut owned) => owned
+        }
+    }
+
+    /// Extract the owned data.
+    ///
+    /// Copies the data if it is not already owned.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn into_owned(self) -> <B as ToOwned>::Owned {
+        match self {
+            Borrowed(borrowed) => borrowed.to_owned(),
+            Owned(owned) => owned
+        }
+    }
+
+    /// Returns true if this `Cow` wraps a borrowed value
+    #[deprecated(since = "1.0.0", reason = "match on the enum instead")]
+    #[unstable(feature = "std_misc")]
+    pub fn is_borrowed(&self) -> bool {
+        match *self {
+            Borrowed(_) => true,
+            _ => false,
+        }
+    }
+
+    /// Returns true if this `Cow` wraps an owned value
+    #[deprecated(since = "1.0.0", reason = "match on the enum instead")]
+    #[unstable(feature = "std_misc")]
+    pub fn is_owned(&self) -> bool {
+        match *self {
+            Owned(_) => true,
+            _ => false,
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> Deref for Cow<'a, B> where B: ToOwned {
+    type Target = B;
+
+    fn deref(&self) -> &B {
+        match *self {
+            Borrowed(borrowed) => borrowed,
+            Owned(ref owned) => owned.borrow()
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> Eq for Cow<'a, B> where B: Eq + ToOwned {}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> Ord for Cow<'a, B> where B: Ord + ToOwned {
+    #[inline]
+    fn cmp(&self, other: &Cow<'a, B>) -> Ordering {
+        Ord::cmp(&**self, &**other)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, 'b, B: ?Sized, C: ?Sized> PartialEq<Cow<'b, C>> for Cow<'a, B> where
+    B: PartialEq<C> + ToOwned, C: ToOwned,
+{
+    #[inline]
+    fn eq(&self, other: &Cow<'b, C>) -> bool {
+        PartialEq::eq(&**self, &**other)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> PartialOrd for Cow<'a, B> where B: PartialOrd + ToOwned,
+{
+    #[inline]
+    fn partial_cmp(&self, other: &Cow<'a, B>) -> Option<Ordering> {
+        PartialOrd::partial_cmp(&**self, &**other)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> fmt::Debug for Cow<'a, B> where
+    B: fmt::Debug + ToOwned,
+    <B as ToOwned>::Owned: fmt::Debug,
+{
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            Borrowed(ref b) => fmt::Debug::fmt(b, f),
+            Owned(ref o) => fmt::Debug::fmt(o, f),
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> fmt::Display for Cow<'a, B> where
+    B: fmt::Display + ToOwned,
+    <B as ToOwned>::Owned: fmt::Display,
+{
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            Borrowed(ref b) => fmt::Display::fmt(b, f),
+            Owned(ref o) => fmt::Display::fmt(o, f),
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+#[cfg(stage0)]
+impl<'a, B: ?Sized, S: Hasher> Hash<S> for Cow<'a, B> where B: Hash<S> + ToOwned
+{
+    #[inline]
+    fn hash(&self, state: &mut S) {
+        Hash::hash(&**self, state)
+    }
+}
+#[stable(feature = "rust1", since = "1.0.0")]
+#[cfg(not(stage0))]
+impl<'a, B: ?Sized> Hash for Cow<'a, B> where B: Hash + ToOwned
+{
+    #[inline]
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        Hash::hash(&**self, state)
+    }
+}
+
+/// Trait for moving into a `Cow`
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait IntoCow<'a, B: ?Sized> where B: ToOwned {
+    /// Moves `self` into `Cow`
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn into_cow(self) -> Cow<'a, B>;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a,  B: ?Sized> IntoCow<'a, B> for Cow<'a, B> where B: ToOwned {
+    fn into_cow(self) -> Cow<'a, B> {
+        self
+    }
+}
diff --git a/src/libcollections/borrow_stage0.rs b/src/libcollections/borrow_stage0.rs
new file mode 100644
index 00000000000..c1d74b16ce6
--- /dev/null
+++ b/src/libcollections/borrow_stage0.rs
@@ -0,0 +1,313 @@
+// Copyright 2014 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.
+
+//! A module for working with borrowed data.
+
+#![stable(feature = "rust1", since = "1.0.0")]
+
+use core::clone::Clone;
+use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
+use core::hash::{Hash, Hasher};
+use core::marker::Sized;
+use core::ops::Deref;
+use core::option::Option;
+
+use fmt;
+use alloc::{rc, arc};
+
+use self::Cow::*;
+
+/// A trait for borrowing data.
+///
+/// In general, there may be several ways to "borrow" a piece of data.  The
+/// typical ways of borrowing a type `T` are `&T` (a shared borrow) and `&mut T`
+/// (a mutable borrow). But types like `Vec<T>` provide additional kinds of
+/// borrows: the borrowed slices `&[T]` and `&mut [T]`.
+///
+/// When writing generic code, it is often desirable to abstract over all ways
+/// of borrowing data from a given type. That is the role of the `Borrow`
+/// trait: if `T: Borrow<U>`, then `&U` can be borrowed from `&T`.  A given
+/// type can be borrowed as multiple different types. In particular, `Vec<T>:
+/// Borrow<Vec<T>>` and `Vec<T>: Borrow<[T]>`.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait Borrow<Borrowed: ?Sized> {
+    /// Immutably borrow from an owned value.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn borrow(&self) -> &Borrowed;
+}
+
+/// A trait for mutably borrowing data.
+///
+/// Similar to `Borrow`, but for mutable borrows.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait BorrowMut<Borrowed: ?Sized> : Borrow<Borrowed> {
+    /// Mutably borrow from an owned value.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn borrow_mut(&mut self) -> &mut Borrowed;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: ?Sized> Borrow<T> for T {
+    fn borrow(&self) -> &T { self }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: ?Sized> BorrowMut<T> for T {
+    fn borrow_mut(&mut self) -> &mut T { self }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T: ?Sized> Borrow<T> for &'a T {
+    fn borrow(&self) -> &T { &**self }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T: ?Sized> Borrow<T> for &'a mut T {
+    fn borrow(&self) -> &T { &**self }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T: ?Sized> BorrowMut<T> for &'a mut T {
+    fn borrow_mut(&mut self) -> &mut T { &mut **self }
+}
+
+impl<T> Borrow<T> for rc::Rc<T> {
+    fn borrow(&self) -> &T { &**self }
+}
+
+impl<T> Borrow<T> for arc::Arc<T> {
+    fn borrow(&self) -> &T { &**self }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> Borrow<B> for Cow<'a, B> where B: ToOwned, <B as ToOwned>::Owned: 'a {
+    fn borrow(&self) -> &B {
+        &**self
+    }
+}
+
+/// A generalization of Clone to borrowed data.
+///
+/// Some types make it possible to go from borrowed to owned, usually by
+/// implementing the `Clone` trait. But `Clone` works only for going from `&T`
+/// to `T`. The `ToOwned` trait generalizes `Clone` to construct owned data
+/// from any borrow of a given type.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait ToOwned {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    type Owned: Borrow<Self>;
+
+    /// Create owned data from borrowed data, usually by copying.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn to_owned(&self) -> Self::Owned;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> ToOwned for T where T: Clone {
+    type Owned = T;
+    fn to_owned(&self) -> T { self.clone() }
+}
+
+/// A clone-on-write smart pointer.
+///
+/// The type `Cow` is a smart pointer providing clone-on-write functionality: it
+/// can enclose and provide immutable access to borrowed data, and clone the
+/// data lazily when mutation or ownership is required. The type is designed to
+/// work with general borrowed data via the `Borrow` trait.
+///
+/// `Cow` implements both `Deref`, which means that you can call
+/// non-mutating methods directly on the data it encloses. If mutation
+/// is desired, `to_mut` will obtain a mutable references to an owned
+/// value, cloning if necessary.
+///
+/// # Example
+///
+/// ```rust
+/// use std::borrow::Cow;
+///
+/// fn abs_all(input: &mut Cow<[int]>) {
+///     for i in 0..input.len() {
+///         let v = input[i];
+///         if v < 0 {
+///             // clones into a vector the first time (if not already owned)
+///             input.to_mut()[i] = -v;
+///         }
+///     }
+/// }
+/// ```
+#[stable(feature = "rust1", since = "1.0.0")]
+pub enum Cow<'a, B: ?Sized + 'a> where B: ToOwned {
+    /// Borrowed data.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    Borrowed(&'a B),
+
+    /// Owned data.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    Owned(<B as ToOwned>::Owned)
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> Clone for Cow<'a, B> where B: ToOwned {
+    fn clone(&self) -> Cow<'a, B> {
+        match *self {
+            Borrowed(b) => Borrowed(b),
+            Owned(ref o) => {
+                let b: &B = o.borrow();
+                Owned(b.to_owned())
+            },
+        }
+    }
+}
+
+impl<'a, B: ?Sized> Cow<'a, B> where B: ToOwned, <B as ToOwned>::Owned: 'a {
+    /// Acquire a mutable reference to the owned form of the data.
+    ///
+    /// Copies the data if it is not already owned.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn to_mut(&mut self) -> &mut <B as ToOwned>::Owned where <B as ToOwned>::Owned: 'a {
+        match *self {
+            Borrowed(borrowed) => {
+                *self = Owned(borrowed.to_owned());
+                self.to_mut()
+            }
+            Owned(ref mut owned) => owned
+        }
+    }
+
+    /// Extract the owned data.
+    ///
+    /// Copies the data if it is not already owned.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn into_owned(self) -> <B as ToOwned>::Owned {
+        match self {
+            Borrowed(borrowed) => borrowed.to_owned(),
+            Owned(owned) => owned
+        }
+    }
+
+    /// Returns true if this `Cow` wraps a borrowed value
+    #[deprecated(since = "1.0.0", reason = "match on the enum instead")]
+    #[unstable(feature = "std_misc")]
+    pub fn is_borrowed(&self) -> bool {
+        match *self {
+            Borrowed(_) => true,
+            _ => false,
+        }
+    }
+
+    /// Returns true if this `Cow` wraps an owned value
+    #[deprecated(since = "1.0.0", reason = "match on the enum instead")]
+    #[unstable(feature = "std_misc")]
+    pub fn is_owned(&self) -> bool {
+        match *self {
+            Owned(_) => true,
+            _ => false,
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> Deref for Cow<'a, B> where
+    B: ToOwned, <B as ToOwned>::Owned: 'a
+{
+    type Target = B;
+
+    fn deref(&self) -> &B {
+        match *self {
+            Borrowed(borrowed) => borrowed,
+            Owned(ref owned) => owned.borrow()
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> Eq for Cow<'a, B> where B: Eq + ToOwned, <B as ToOwned>::Owned: 'a {}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> Ord for Cow<'a, B> where
+    B: Ord + ToOwned, <B as ToOwned>::Owned: 'a
+{
+    #[inline]
+    fn cmp(&self, other: &Cow<'a, B>) -> Ordering {
+        Ord::cmp(&**self, &**other)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, 'b, B: ?Sized, C: ?Sized> PartialEq<Cow<'b, C>> for Cow<'a, B> where
+    B: PartialEq<C> + ToOwned, C: ToOwned,
+    <B as ToOwned>::Owned: 'a, <C as ToOwned>::Owned: 'b,
+{
+    #[inline]
+    fn eq(&self, other: &Cow<'b, C>) -> bool {
+        PartialEq::eq(&**self, &**other)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> PartialOrd for Cow<'a, B> where
+    B: PartialOrd + ToOwned, <B as ToOwned>::Owned: 'a
+{
+    #[inline]
+    fn partial_cmp(&self, other: &Cow<'a, B>) -> Option<Ordering> {
+        PartialOrd::partial_cmp(&**self, &**other)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> fmt::Debug for Cow<'a, B> where
+    B: fmt::Debug + ToOwned,
+    <B as ToOwned>::Owned: fmt::Debug,
+{
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            Borrowed(ref b) => fmt::Debug::fmt(b, f),
+            Owned(ref o) => fmt::Debug::fmt(o, f),
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> fmt::Display for Cow<'a, B> where
+    B: fmt::Display + ToOwned,
+    <B as ToOwned>::Owned: fmt::Display,
+{
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            Borrowed(ref b) => fmt::Display::fmt(b, f),
+            Owned(ref o) => fmt::Display::fmt(o, f),
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized, S: Hasher> Hash<S> for Cow<'a, B> where
+    B: Hash<S> + ToOwned, <B as ToOwned>::Owned: 'a
+{
+    #[inline]
+    fn hash(&self, state: &mut S) {
+        Hash::hash(&**self, state)
+    }
+}
+
+/// Trait for moving into a `Cow`
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait IntoCow<'a, B: ?Sized> where B: ToOwned {
+    /// Moves `self` into `Cow`
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn into_cow(self) -> Cow<'a, B>;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a,  B: ?Sized> IntoCow<'a, B> for Cow<'a, B> where B: ToOwned {
+    fn into_cow(self) -> Cow<'a, B> {
+        self
+    }
+}
diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs
index 747211e9238..7823f536c7a 100644
--- a/src/libcollections/btree/map.rs
+++ b/src/libcollections/btree/map.rs
@@ -19,7 +19,6 @@ use self::Entry::*;
 
 use core::prelude::*;
 
-use core::borrow::BorrowFrom;
 use core::cmp::Ordering;
 use core::default::Default;
 use core::fmt::Debug;
@@ -29,7 +28,8 @@ use core::ops::{Index, IndexMut};
 use core::{iter, fmt, mem};
 use Bound::{self, Included, Excluded, Unbounded};
 
-use ring_buf::RingBuf;
+use borrow::Borrow;
+use vec_deque::VecDeque;
 
 use self::Continuation::{Continue, Finished};
 use self::StackOp::*;
@@ -75,7 +75,7 @@ pub struct BTreeMap<K, V> {
 
 /// An abstract base over-which all other BTree iterators are built.
 struct AbsIter<T> {
-    traversals: RingBuf<T>,
+    traversals: VecDeque<T>,
     size: usize,
 }
 
@@ -208,7 +208,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
     /// assert_eq!(map.get(&2), None);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn get<Q: ?Sized>(&self, key: &Q) -> Option<&V> where Q: BorrowFrom<K> + Ord {
+    pub fn get<Q: ?Sized>(&self, key: &Q) -> Option<&V> where K: Borrow<Q>, Q: Ord {
         let mut cur_node = &self.root;
         loop {
             match Node::search(cur_node, key) {
@@ -240,7 +240,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
     /// assert_eq!(map.contains_key(&2), false);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn contains_key<Q: ?Sized>(&self, key: &Q) -> bool where Q: BorrowFrom<K> + Ord {
+    pub fn contains_key<Q: ?Sized>(&self, key: &Q) -> bool where K: Borrow<Q>, Q: Ord {
         self.get(key).is_some()
     }
 
@@ -264,7 +264,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
     /// ```
     // See `get` for implementation notes, this is basically a copy-paste with mut's added
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn get_mut<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut V> where Q: BorrowFrom<K> + Ord {
+    pub fn get_mut<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut V> where K: Borrow<Q>, Q: Ord {
         // temp_node is a Borrowck hack for having a mutable value outlive a loop iteration
         let mut temp_node = &mut self.root;
         loop {
@@ -434,7 +434,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
     /// assert_eq!(map.remove(&1), None);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<V> where Q: BorrowFrom<K> + Ord {
+    pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<V> where K: Borrow<Q>, Q: Ord {
         // See `swap` for a more thorough description of the stuff going on in here
         let mut stack = stack::PartialSearchStack::new(self);
         loop {
@@ -512,13 +512,22 @@ mod stack {
     use super::super::node::handle;
     use vec::Vec;
 
+    struct InvariantLifetime<'id>(
+        marker::PhantomData<::core::cell::Cell<&'id ()>>);
+
+    impl<'id> InvariantLifetime<'id> {
+        fn new() -> InvariantLifetime<'id> {
+            InvariantLifetime(marker::PhantomData)
+        }
+    }
+
     /// A generic mutable reference, identical to `&mut` except for the fact that its lifetime
     /// parameter is invariant. This means that wherever an `IdRef` is expected, only an `IdRef`
     /// with the exact requested lifetime can be used. This is in contrast to normal references,
     /// where `&'static` can be used in any function expecting any lifetime reference.
     pub struct IdRef<'id, T: 'id> {
         inner: &'id mut T,
-        marker: marker::InvariantLifetime<'id>
+        _marker: InvariantLifetime<'id>,
     }
 
     impl<'id, T> Deref for IdRef<'id, T> {
@@ -560,7 +569,7 @@ mod stack {
     pub struct Pusher<'id, 'a, K:'a, V:'a> {
         map: &'a mut BTreeMap<K, V>,
         stack: Stack<K, V>,
-        marker: marker::InvariantLifetime<'id>
+        _marker: InvariantLifetime<'id>,
     }
 
     impl<'a, K, V> PartialSearchStack<'a, K, V> {
@@ -595,11 +604,11 @@ mod stack {
             let pusher = Pusher {
                 map: self.map,
                 stack: self.stack,
-                marker: marker::InvariantLifetime
+                _marker: InvariantLifetime::new(),
             };
             let node = IdRef {
                 inner: unsafe { &mut *self.next },
-                marker: marker::InvariantLifetime
+                _marker: InvariantLifetime::new(),
             };
 
             closure(pusher, node)
@@ -826,7 +835,7 @@ mod stack {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<K: Ord, V> FromIterator<(K, V)> for BTreeMap<K, V> {
-    fn from_iter<T: Iterator<Item=(K, V)>>(iter: T) -> BTreeMap<K, V> {
+    fn from_iter<T: IntoIterator<Item=(K, V)>>(iter: T) -> BTreeMap<K, V> {
         let mut map = BTreeMap::new();
         map.extend(iter);
         map
@@ -836,13 +845,14 @@ impl<K: Ord, V> FromIterator<(K, V)> for BTreeMap<K, V> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<K: Ord, V> Extend<(K, V)> for BTreeMap<K, V> {
     #[inline]
-    fn extend<T: Iterator<Item=(K, V)>>(&mut self, iter: T) {
+    fn extend<T: IntoIterator<Item=(K, V)>>(&mut self, iter: T) {
         for (k, v) in iter {
             self.insert(k, v);
         }
     }
 }
 
+#[cfg(stage0)]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<S: Hasher, K: Hash<S>, V: Hash<S>> Hash<S> for BTreeMap<K, V> {
     fn hash(&self, state: &mut S) {
@@ -851,6 +861,15 @@ impl<S: Hasher, K: Hash<S>, V: Hash<S>> Hash<S> for BTreeMap<K, V> {
         }
     }
 }
+#[cfg(not(stage0))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<K: Hash, V: Hash> Hash for BTreeMap<K, V> {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        for elt in self {
+            elt.hash(state);
+        }
+    }
+}
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<K: Ord, V> Default for BTreeMap<K, V> {
@@ -903,7 +922,7 @@ impl<K: Debug, V: Debug> Debug for BTreeMap<K, V> {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<K: Ord, Q: ?Sized, V> Index<Q> for BTreeMap<K, V>
-    where Q: BorrowFrom<K> + Ord
+    where K: Borrow<Q>, Q: Ord
 {
     type Output = V;
 
@@ -914,7 +933,7 @@ impl<K: Ord, Q: ?Sized, V> Index<Q> for BTreeMap<K, V>
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<K: Ord, Q: ?Sized, V> IndexMut<Q> for BTreeMap<K, V>
-    where Q: BorrowFrom<K> + Ord
+    where K: Borrow<Q>, Q: Ord
 {
     fn index_mut(&mut self, key: &Q) -> &mut V {
         self.get_mut(key).expect("no entry found for key")
@@ -1189,7 +1208,7 @@ impl<K, V> BTreeMap<K, V> {
     pub fn iter(&self) -> Iter<K, V> {
         let len = self.len();
         // NB. The initial capacity for ringbuf is large enough to avoid reallocs in many cases.
-        let mut lca = RingBuf::new();
+        let mut lca = VecDeque::new();
         lca.push_back(Traverse::traverse(&self.root));
         Iter {
             inner: AbsIter {
@@ -1221,7 +1240,7 @@ impl<K, V> BTreeMap<K, V> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn iter_mut(&mut self) -> IterMut<K, V> {
         let len = self.len();
-        let mut lca = RingBuf::new();
+        let mut lca = VecDeque::new();
         lca.push_back(Traverse::traverse(&mut self.root));
         IterMut {
             inner: AbsIter {
@@ -1250,7 +1269,7 @@ impl<K, V> BTreeMap<K, V> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_iter(self) -> IntoIter<K, V> {
         let len = self.len();
-        let mut lca = RingBuf::new();
+        let mut lca = VecDeque::new();
         lca.push_back(Traverse::traverse(self.root));
         IntoIter {
             inner: AbsIter {
@@ -1342,7 +1361,7 @@ macro_rules! range_impl {
             // A deque that encodes two search paths containing (left-to-right):
             // a series of truncated-from-the-left iterators, the LCA's doubly-truncated iterator,
             // and a series of truncated-from-the-right iterators.
-            let mut traversals = RingBuf::new();
+            let mut traversals = VecDeque::new();
             let (root, min, max) = ($root, $min, $max);
 
             let mut leftmost = None;
diff --git a/src/libcollections/btree/node.rs b/src/libcollections/btree/node.rs
index 24523d4dcc9..f0fc12da727 100644
--- a/src/libcollections/btree/node.rs
+++ b/src/libcollections/btree/node.rs
@@ -18,13 +18,15 @@ pub use self::TraversalItem::*;
 
 use core::prelude::*;
 
-use core::borrow::BorrowFrom;
 use core::cmp::Ordering::{Greater, Less, Equal};
 use core::iter::Zip;
+use core::marker::PhantomData;
 use core::ops::{Deref, DerefMut, Index, IndexMut};
 use core::ptr::Unique;
 use core::{slice, mem, ptr, cmp, num, raw};
-use alloc::heap;
+use alloc::heap::{self, EMPTY};
+
+use borrow::Borrow;
 
 /// Represents the result of an Insertion: either the item fit, or the node had to split
 pub enum InsertionResult<K, V> {
@@ -57,8 +59,8 @@ pub struct Node<K, V> {
     keys: Unique<K>,
     vals: Unique<V>,
 
-    // In leaf nodes, this will be null, and no space will be allocated for edges.
-    edges: Unique<Node<K, V>>,
+    // In leaf nodes, this will be None, and no space will be allocated for edges.
+    edges: Option<Unique<Node<K, V>>>,
 
     // At any given time, there will be `_len` keys, `_len` values, and (in an internal node)
     // `_len + 1` edges. In a leaf node, there will never be any edges.
@@ -278,8 +280,11 @@ impl<T> Drop for RawItems<T> {
 #[unsafe_destructor]
 impl<K, V> Drop for Node<K, V> {
     fn drop(&mut self) {
-        if self.keys.ptr.is_null() {
-            // We have already cleaned up this node.
+        if self.keys.is_null() {
+            // Since we have #[unsafe_no_drop_flag], we have to watch
+            // out for a null value being stored in self.keys. (Using
+            // null is technically a violation of the `Unique`
+            // requirements, though.)
             return;
         }
 
@@ -292,7 +297,7 @@ impl<K, V> Drop for Node<K, V> {
             self.destroy();
         }
 
-        self.keys.ptr = ptr::null_mut();
+        self.keys = unsafe { Unique::new(0 as *mut K) };
     }
 }
 
@@ -308,9 +313,9 @@ impl<K, V> Node<K, V> {
         let (vals_offset, edges_offset) = calculate_offsets_generic::<K, V>(capacity, false);
 
         Node {
-            keys: Unique(buffer as *mut K),
-            vals: Unique(buffer.offset(vals_offset as isize) as *mut V),
-            edges: Unique(buffer.offset(edges_offset as isize) as *mut Node<K, V>),
+            keys: Unique::new(buffer as *mut K),
+            vals: Unique::new(buffer.offset(vals_offset as isize) as *mut V),
+            edges: Some(Unique::new(buffer.offset(edges_offset as isize) as *mut Node<K, V>)),
             _len: 0,
             _capacity: capacity,
         }
@@ -326,9 +331,9 @@ impl<K, V> Node<K, V> {
         let (vals_offset, _) = calculate_offsets_generic::<K, V>(capacity, true);
 
         Node {
-            keys: Unique(buffer as *mut K),
-            vals: Unique(unsafe { buffer.offset(vals_offset as isize) as *mut V }),
-            edges: Unique(ptr::null_mut()),
+            keys: unsafe { Unique::new(buffer as *mut K) },
+            vals: unsafe { Unique::new(buffer.offset(vals_offset as isize) as *mut V) },
+            edges: None,
             _len: 0,
             _capacity: capacity,
         }
@@ -337,18 +342,18 @@ impl<K, V> Node<K, V> {
     unsafe fn destroy(&mut self) {
         let (alignment, size) =
                 calculate_allocation_generic::<K, V>(self.capacity(), self.is_leaf());
-        heap::deallocate(self.keys.ptr as *mut u8, size, alignment);
+        heap::deallocate(*self.keys as *mut u8, size, alignment);
     }
 
     #[inline]
     pub fn as_slices<'a>(&'a self) -> (&'a [K], &'a [V]) {
         unsafe {(
             mem::transmute(raw::Slice {
-                data: self.keys.ptr,
+                data: *self.keys as *const K,
                 len: self.len()
             }),
             mem::transmute(raw::Slice {
-                data: self.vals.ptr,
+                data: *self.vals as *const V,
                 len: self.len()
             })
         )}
@@ -367,8 +372,12 @@ impl<K, V> Node<K, V> {
             &[]
         } else {
             unsafe {
+                let data = match self.edges {
+                    None => heap::EMPTY as *const Node<K,V>,
+                    Some(ref p) => **p as *const Node<K,V>,
+                };
                 mem::transmute(raw::Slice {
-                    data: self.edges.ptr,
+                    data: data,
                     len: self.len() + 1
                 })
             }
@@ -524,7 +533,8 @@ impl<K: Clone, V: Clone> Clone for Node<K, V> {
 #[derive(Copy)]
 pub struct Handle<NodeRef, Type, NodeType> {
     node: NodeRef,
-    index: usize
+    index: usize,
+    marker: PhantomData<(Type, NodeType)>,
 }
 
 pub mod handle {
@@ -543,13 +553,13 @@ impl<K: Ord, V> Node<K, V> {
     /// `Found` will be yielded with the matching index. If it doesn't find an exact match,
     /// `GoDown` will be yielded with the index of the subtree the key must lie in.
     pub fn search<Q: ?Sized, NodeRef: Deref<Target=Node<K, V>>>(node: NodeRef, key: &Q)
-                  -> SearchResult<NodeRef> where Q: BorrowFrom<K> + Ord {
+                  -> SearchResult<NodeRef> where K: Borrow<Q>, Q: Ord {
         // FIXME(Gankro): Tune when to search linear or binary based on B (and maybe K/V).
         // For the B configured as of this writing (B = 6), binary search was *significantly*
         // worse for usizes.
         match node.as_slices_internal().search_linear(key) {
-            (index, true) => Found(Handle { node: node, index: index }),
-            (index, false) => GoDown(Handle { node: node, index: index }),
+            (index, true) => Found(Handle { node: node, index: index, marker: PhantomData }),
+            (index, false) => GoDown(Handle { node: node, index: index, marker: PhantomData }),
         }
     }
 }
@@ -586,7 +596,7 @@ impl <K, V> Node<K, V> {
 
     /// If the node has any children
     pub fn is_leaf(&self) -> bool {
-        self.edges.ptr.is_null()
+        self.edges.is_none()
     }
 
     /// if the node has too few elements
@@ -618,7 +628,8 @@ impl<K, V, NodeRef, Type, NodeType> Handle<NodeRef, Type, NodeType> where
     pub fn as_raw(&mut self) -> Handle<*mut Node<K, V>, Type, NodeType> {
         Handle {
             node: &mut *self.node as *mut _,
-            index: self.index
+            index: self.index,
+            marker: PhantomData,
         }
     }
 }
@@ -630,7 +641,8 @@ impl<K, V, Type, NodeType> Handle<*mut Node<K, V>, Type, NodeType> {
     pub unsafe fn from_raw<'a>(&'a self) -> Handle<&'a Node<K, V>, Type, NodeType> {
         Handle {
             node: &*self.node,
-            index: self.index
+            index: self.index,
+            marker: PhantomData,
         }
     }
 
@@ -640,7 +652,8 @@ impl<K, V, Type, NodeType> Handle<*mut Node<K, V>, Type, NodeType> {
     pub unsafe fn from_raw_mut<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, Type, NodeType> {
         Handle {
             node: &mut *self.node,
-            index: self.index
+            index: self.index,
+            marker: PhantomData,
         }
     }
 }
@@ -688,12 +701,14 @@ impl<K, V, NodeRef: Deref<Target=Node<K, V>>, Type> Handle<NodeRef, Type, handle
         if self.node.is_leaf() {
             Leaf(Handle {
                 node: self.node,
-                index: self.index
+                index: self.index,
+                marker: PhantomData,
             })
         } else {
             Internal(Handle {
                 node: self.node,
-                index: self.index
+                index: self.index,
+                marker: PhantomData,
             })
         }
     }
@@ -826,7 +841,8 @@ impl<K, V, NodeRef, NodeType> Handle<NodeRef, handle::Edge, NodeType> where
     unsafe fn left_kv<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, handle::KV, NodeType> {
         Handle {
             node: &mut *self.node,
-            index: self.index - 1
+            index: self.index - 1,
+            marker: PhantomData,
         }
     }
 
@@ -836,7 +852,8 @@ impl<K, V, NodeRef, NodeType> Handle<NodeRef, handle::Edge, NodeType> where
     unsafe fn right_kv<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, handle::KV, NodeType> {
         Handle {
             node: &mut *self.node,
-            index: self.index
+            index: self.index,
+            marker: PhantomData,
         }
     }
 }
@@ -876,7 +893,8 @@ impl<'a, K: 'a, V: 'a, NodeType> Handle<&'a mut Node<K, V>, handle::KV, NodeType
     pub fn into_left_edge(self) -> Handle<&'a mut Node<K, V>, handle::Edge, NodeType> {
         Handle {
             node: &mut *self.node,
-            index: self.index
+            index: self.index,
+            marker: PhantomData,
         }
     }
 }
@@ -926,7 +944,8 @@ impl<K, V, NodeRef, NodeType> Handle<NodeRef, handle::KV, NodeType> where
     pub fn left_edge<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, handle::Edge, NodeType> {
         Handle {
             node: &mut *self.node,
-            index: self.index
+            index: self.index,
+            marker: PhantomData,
         }
     }
 
@@ -935,7 +954,8 @@ impl<K, V, NodeRef, NodeType> Handle<NodeRef, handle::KV, NodeType> where
     pub fn right_edge<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, handle::Edge, NodeType> {
         Handle {
             node: &mut *self.node,
-            index: self.index + 1
+            index: self.index + 1,
+            marker: PhantomData,
         }
     }
 }
@@ -1044,7 +1064,8 @@ impl<K, V> Node<K, V> {
         debug_assert!(index < self.len(), "kv_handle index out of bounds");
         Handle {
             node: self,
-            index: index
+            index: index,
+            marker: PhantomData,
         }
     }
 
@@ -1064,7 +1085,7 @@ impl<K, V> Node<K, V> {
                     vals: RawItems::from_slice(self.vals()),
                     edges: RawItems::from_slice(self.edges()),
 
-                    ptr: self.keys.ptr as *mut u8,
+                    ptr: *self.keys as *mut u8,
                     capacity: self.capacity(),
                     is_leaf: self.is_leaf()
                 },
@@ -1491,9 +1512,9 @@ macro_rules! node_slice_impl {
         impl<'a, K: Ord + 'a, V: 'a> $NodeSlice<'a, K, V> {
             /// Performs linear search in a slice. Returns a tuple of (index, is_exact_match).
             fn search_linear<Q: ?Sized>(&self, key: &Q) -> (usize, bool)
-                    where Q: BorrowFrom<K> + Ord {
+                    where K: Borrow<Q>, Q: Ord {
                 for (i, k) in self.keys.iter().enumerate() {
-                    match key.cmp(BorrowFrom::borrow_from(k)) {
+                    match key.cmp(k.borrow()) {
                         Greater => {},
                         Equal => return (i, true),
                         Less => return (i, false),
diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs
index 7ef887b70cc..929b2f58043 100644
--- a/src/libcollections/btree/set.rs
+++ b/src/libcollections/btree/set.rs
@@ -13,7 +13,6 @@
 
 use core::prelude::*;
 
-use core::borrow::BorrowFrom;
 use core::cmp::Ordering::{self, Less, Greater, Equal};
 use core::default::Default;
 use core::fmt::Debug;
@@ -21,6 +20,7 @@ use core::fmt;
 use core::iter::{Peekable, Map, FromIterator, IntoIterator};
 use core::ops::{BitOr, BitAnd, BitXor, Sub};
 
+use borrow::Borrow;
 use btree_map::{BTreeMap, Keys};
 use Bound;
 
@@ -336,7 +336,7 @@ impl<T: Ord> BTreeSet<T> {
     /// assert_eq!(set.contains(&4), false);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool where Q: BorrowFrom<T> + Ord {
+    pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool where T: Borrow<Q>, Q: Ord {
         self.map.contains_key(value)
     }
 
@@ -466,14 +466,14 @@ impl<T: Ord> BTreeSet<T> {
     /// assert_eq!(set.remove(&2), false);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool where Q: BorrowFrom<T> + Ord {
+    pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool where T: Borrow<Q>, Q: Ord {
         self.map.remove(value).is_some()
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Ord> FromIterator<T> for BTreeSet<T> {
-    fn from_iter<Iter: Iterator<Item=T>>(iter: Iter) -> BTreeSet<T> {
+    fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> BTreeSet<T> {
         let mut set = BTreeSet::new();
         set.extend(iter);
         set
@@ -503,7 +503,7 @@ impl<'a, T> IntoIterator for &'a BTreeSet<T> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Ord> Extend<T> for BTreeSet<T> {
     #[inline]
-    fn extend<Iter: Iterator<Item=T>>(&mut self, iter: Iter) {
+    fn extend<Iter: IntoIterator<Item=T>>(&mut self, iter: Iter) {
         for elem in iter {
             self.insert(elem);
         }
diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs
index d5403ca5d9b..0c957426060 100644
--- a/src/libcollections/enum_set.rs
+++ b/src/libcollections/enum_set.rs
@@ -14,6 +14,7 @@
 //! representation to hold C-like enum variants.
 
 use core::prelude::*;
+use core::marker;
 use core::fmt;
 use core::num::Int;
 use core::iter::{FromIterator, IntoIterator};
@@ -26,7 +27,8 @@ use core::ops::{Sub, BitOr, BitAnd, BitXor};
 pub struct EnumSet<E> {
     // We must maintain the invariant that no bits are set
     // for which no variant exists
-    bits: usize
+    bits: usize,
+    marker: marker::PhantomData<E>,
 }
 
 impl<E> Copy for EnumSet<E> {}
@@ -86,7 +88,7 @@ impl<E:CLike> EnumSet<E> {
     #[unstable(feature = "collections",
                reason = "matches collection reform specification, waiting for dust to settle")]
     pub fn new() -> EnumSet<E> {
-        EnumSet {bits: 0}
+        EnumSet {bits: 0, marker: marker::PhantomData}
     }
 
     /// Returns the number of elements in the given `EnumSet`.
@@ -130,12 +132,14 @@ impl<E:CLike> EnumSet<E> {
 
     /// Returns the union of both `EnumSets`.
     pub fn union(&self, e: EnumSet<E>) -> EnumSet<E> {
-        EnumSet {bits: self.bits | e.bits}
+        EnumSet {bits: self.bits | e.bits,
+                 marker: marker::PhantomData}
     }
 
     /// Returns the intersection of both `EnumSets`.
     pub fn intersection(&self, e: EnumSet<E>) -> EnumSet<E> {
-        EnumSet {bits: self.bits & e.bits}
+        EnumSet {bits: self.bits & e.bits,
+                 marker: marker::PhantomData}
     }
 
     /// Adds an enum to the `EnumSet`, and returns `true` if it wasn't there before
@@ -175,7 +179,7 @@ impl<E:CLike> Sub for EnumSet<E> {
     type Output = EnumSet<E>;
 
     fn sub(self, e: EnumSet<E>) -> EnumSet<E> {
-        EnumSet {bits: self.bits & !e.bits}
+        EnumSet {bits: self.bits & !e.bits, marker: marker::PhantomData}
     }
 }
 
@@ -183,7 +187,7 @@ impl<E:CLike> BitOr for EnumSet<E> {
     type Output = EnumSet<E>;
 
     fn bitor(self, e: EnumSet<E>) -> EnumSet<E> {
-        EnumSet {bits: self.bits | e.bits}
+        EnumSet {bits: self.bits | e.bits, marker: marker::PhantomData}
     }
 }
 
@@ -191,7 +195,7 @@ impl<E:CLike> BitAnd for EnumSet<E> {
     type Output = EnumSet<E>;
 
     fn bitand(self, e: EnumSet<E>) -> EnumSet<E> {
-        EnumSet {bits: self.bits & e.bits}
+        EnumSet {bits: self.bits & e.bits, marker: marker::PhantomData}
     }
 }
 
@@ -199,7 +203,7 @@ impl<E:CLike> BitXor for EnumSet<E> {
     type Output = EnumSet<E>;
 
     fn bitxor(self, e: EnumSet<E>) -> EnumSet<E> {
-        EnumSet {bits: self.bits ^ e.bits}
+        EnumSet {bits: self.bits ^ e.bits, marker: marker::PhantomData}
     }
 }
 
@@ -207,6 +211,7 @@ impl<E:CLike> BitXor for EnumSet<E> {
 pub struct Iter<E> {
     index: usize,
     bits: usize,
+    marker: marker::PhantomData<E>,
 }
 
 // FIXME(#19839) Remove in favor of `#[derive(Clone)]`
@@ -215,13 +220,14 @@ impl<E> Clone for Iter<E> {
         Iter {
             index: self.index,
             bits: self.bits,
+            marker: marker::PhantomData,
         }
     }
 }
 
 impl<E:CLike> Iter<E> {
     fn new(bits: usize) -> Iter<E> {
-        Iter { index: 0, bits: bits }
+        Iter { index: 0, bits: bits, marker: marker::PhantomData }
     }
 }
 
@@ -250,9 +256,9 @@ impl<E:CLike> Iterator for Iter<E> {
 }
 
 impl<E:CLike> FromIterator<E> for EnumSet<E> {
-    fn from_iter<I:Iterator<Item=E>>(iterator: I) -> EnumSet<E> {
+    fn from_iter<I: IntoIterator<Item=E>>(iter: I) -> EnumSet<E> {
         let mut ret = EnumSet::new();
-        ret.extend(iterator);
+        ret.extend(iter);
         ret
     }
 }
@@ -268,8 +274,8 @@ impl<'a, E> IntoIterator for &'a EnumSet<E> where E: CLike {
 }
 
 impl<E:CLike> Extend<E> for EnumSet<E> {
-    fn extend<I: Iterator<Item=E>>(&mut self, iterator: I) {
-        for element in iterator {
+    fn extend<I: IntoIterator<Item=E>>(&mut self, iter: I) {
+        for element in iter {
             self.insert(element);
         }
     }
diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs
index cacbf3bce80..6569ab9c05a 100644
--- a/src/libcollections/lib.rs
+++ b/src/libcollections/lib.rs
@@ -26,7 +26,6 @@
 #![feature(box_syntax)]
 #![feature(box_patterns)]
 #![feature(core)]
-#![feature(hash)]
 #![feature(staged_api)]
 #![feature(unboxed_closures)]
 #![feature(unicode)]
@@ -49,17 +48,33 @@ extern crate alloc;
 #[cfg(test)] #[macro_use] extern crate log;
 
 pub use binary_heap::BinaryHeap;
-pub use bitv::Bitv;
-pub use bitv_set::BitvSet;
+pub use bit_vec::BitVec;
+pub use bit_set::BitSet;
 pub use btree_map::BTreeMap;
 pub use btree_set::BTreeSet;
-pub use dlist::DList;
+pub use linked_list::LinkedList;
 pub use enum_set::EnumSet;
-pub use ring_buf::RingBuf;
+pub use vec_deque::VecDeque;
 pub use string::String;
 pub use vec::Vec;
 pub use vec_map::VecMap;
 
+#[deprecated(since = "1.0.0", reason = "renamed to vec_deque")]
+#[unstable(feature = "collections")]
+pub use vec_deque as ring_buf;
+
+#[deprecated(since = "1.0.0", reason = "renamed to linked_list")]
+#[unstable(feature = "collections")]
+pub use linked_list as dlist;
+
+#[deprecated(since = "1.0.0", reason = "renamed to bit_vec")]
+#[unstable(feature = "collections")]
+pub use bit_vec as bitv;
+
+#[deprecated(since = "1.0.0", reason = "renamed to bit_set")]
+#[unstable(feature = "collections")]
+pub use bit_set as bitv_set;
+
 // Needed for the vec! macro
 pub use alloc::boxed;
 
@@ -71,27 +86,42 @@ mod macros;
 pub mod binary_heap;
 mod bit;
 mod btree;
-pub mod dlist;
+pub mod linked_list;
 pub mod enum_set;
 pub mod fmt;
-pub mod ring_buf;
+pub mod vec_deque;
 pub mod slice;
 pub mod str;
 pub mod string;
 pub mod vec;
 pub mod vec_map;
 
+#[cfg(stage0)]
+#[path = "borrow_stage0.rs"]
+pub mod borrow;
+
+#[cfg(not(stage0))]
+pub mod borrow;
+
 #[unstable(feature = "collections",
            reason = "RFC 509")]
-pub mod bitv {
-    pub use bit::{Bitv, Iter};
+pub mod bit_vec {
+    pub use bit::{BitVec, Iter};
+
+    #[deprecated(since = "1.0.0", reason = "renamed to BitVec")]
+    #[unstable(feature = "collections")]
+    pub use bit::BitVec as Bitv;
 }
 
 #[unstable(feature = "collections",
            reason = "RFC 509")]
-pub mod bitv_set {
-    pub use bit::{BitvSet, Union, Intersection, Difference, SymmetricDifference};
+pub mod bit_set {
+    pub use bit::{BitSet, Union, Intersection, Difference, SymmetricDifference};
     pub use bit::SetIter as Iter;
+
+    #[deprecated(since = "1.0.0", reason = "renamed to BitSet")]
+    #[unstable(feature = "collections")]
+    pub use bit::BitSet as BitvSet;
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -117,7 +147,6 @@ mod std {
 #[cfg(test)]
 mod prelude {
     // from core.
-    pub use core::borrow::IntoCow;
     pub use core::clone::Clone;
     pub use core::cmp::{PartialEq, Eq, PartialOrd, Ord};
     pub use core::cmp::Ordering::{Less, Equal, Greater};
@@ -143,6 +172,7 @@ mod prelude {
     pub use unicode::char::CharExt;
 
     // from collections.
+    pub use borrow::IntoCow;
     pub use slice::SliceConcatExt;
     pub use string::{String, ToString};
     pub use vec::Vec;
diff --git a/src/libcollections/dlist.rs b/src/libcollections/linked_list.rs
index eb1bf93c0aa..c142819a518 100644
--- a/src/libcollections/dlist.rs
+++ b/src/libcollections/linked_list.rs
@@ -10,13 +10,13 @@
 
 //! A doubly-linked list with owned nodes.
 //!
-//! The `DList` allows pushing and popping elements at either end and is thus
+//! The `LinkedList` allows pushing and popping elements at either end and is thus
 //! efficiently usable as a double-ended queue.
 
-// DList is constructed like a singly-linked list over the field `next`.
+// LinkedList is constructed like a singly-linked list over the field `next`.
 // including the last link being None; each Node owns its `next` field.
 //
-// Backlinks over DList::prev are raw pointers that form a full chain in
+// Backlinks over LinkedList::prev are raw pointers that form a full chain in
 // the reverse direction.
 
 #![stable(feature = "rust1", since = "1.0.0")]
@@ -27,14 +27,20 @@ use alloc::boxed::Box;
 use core::cmp::Ordering;
 use core::default::Default;
 use core::fmt;
-use core::hash::{Writer, Hasher, Hash};
+use core::hash::{Hasher, Hash};
+#[cfg(stage0)]
+use core::hash::Writer;
 use core::iter::{self, FromIterator, IntoIterator};
 use core::mem;
 use core::ptr;
 
+#[deprecated(since = "1.0.0", reason = "renamed to LinkedList")]
+#[unstable(feature = "collections")]
+pub use LinkedList as DList;
+
 /// A doubly-linked list.
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct DList<T> {
+pub struct LinkedList<T> {
     length: usize,
     list_head: Link<T>,
     list_tail: Rawlink<Node<T>>,
@@ -56,7 +62,7 @@ struct Node<T> {
     value: T,
 }
 
-/// An iterator over references to the items of a `DList`.
+/// An iterator over references to the items of a `LinkedList`.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Iter<'a, T:'a> {
     head: &'a Link<T>,
@@ -76,20 +82,20 @@ impl<'a, T> Clone for Iter<'a, T> {
     }
 }
 
-/// An iterator over mutable references to the items of a `DList`.
+/// An iterator over mutable references to the items of a `LinkedList`.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct IterMut<'a, T:'a> {
-    list: &'a mut DList<T>,
+    list: &'a mut LinkedList<T>,
     head: Rawlink<Node<T>>,
     tail: Rawlink<Node<T>>,
     nelem: usize,
 }
 
-/// An iterator over mutable references to the items of a `DList`.
+/// An iterator over mutable references to the items of a `LinkedList`.
 #[derive(Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct IntoIter<T> {
-    list: DList<T>
+    list: LinkedList<T>
 }
 
 /// Rawlink is a type like Option<T> but for holding a raw pointer
@@ -147,7 +153,7 @@ fn link_with_prev<T>(mut next: Box<Node<T>>, prev: Rawlink<Node<T>>)
 }
 
 // private methods
-impl<T> DList<T> {
+impl<T> LinkedList<T> {
     /// Add a Node first in the list
     #[inline]
     fn push_front_node(&mut self, mut new_head: Box<Node<T>>) {
@@ -207,18 +213,18 @@ impl<T> DList<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Default for DList<T> {
+impl<T> Default for LinkedList<T> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn default() -> DList<T> { DList::new() }
+    fn default() -> LinkedList<T> { LinkedList::new() }
 }
 
-impl<T> DList<T> {
-    /// Creates an empty `DList`.
+impl<T> LinkedList<T> {
+    /// Creates an empty `LinkedList`.
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn new() -> DList<T> {
-        DList{list_head: None, list_tail: Rawlink::none(), length: 0}
+    pub fn new() -> LinkedList<T> {
+        LinkedList{list_head: None, list_tail: Rawlink::none(), length: 0}
     }
 
     /// Moves all elements from `other` to the end of the list.
@@ -231,10 +237,10 @@ impl<T> DList<T> {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::DList;
+    /// use std::collections::LinkedList;
     ///
-    /// let mut a = DList::new();
-    /// let mut b = DList::new();
+    /// let mut a = LinkedList::new();
+    /// let mut b = LinkedList::new();
     /// a.push_back(1);
     /// a.push_back(2);
     /// b.push_back(3);
@@ -247,7 +253,7 @@ impl<T> DList<T> {
     /// }
     /// println!("{}", b.len()); // prints 0
     /// ```
-    pub fn append(&mut self, other: &mut DList<T>) {
+    pub fn append(&mut self, other: &mut LinkedList<T>) {
         match self.list_tail.resolve() {
             None => {
                 self.length = other.length;
@@ -301,16 +307,16 @@ impl<T> DList<T> {
         IntoIter{list: self}
     }
 
-    /// Returns `true` if the `DList` is empty.
+    /// Returns `true` if the `LinkedList` is empty.
     ///
     /// This operation should compute in O(1) time.
     ///
     /// # Examples
     ///
     /// ```
-    /// use std::collections::DList;
+    /// use std::collections::LinkedList;
     ///
-    /// let mut dl = DList::new();
+    /// let mut dl = LinkedList::new();
     /// assert!(dl.is_empty());
     ///
     /// dl.push_front("foo");
@@ -322,16 +328,16 @@ impl<T> DList<T> {
         self.list_head.is_none()
     }
 
-    /// Returns the length of the `DList`.
+    /// Returns the length of the `LinkedList`.
     ///
     /// This operation should compute in O(1) time.
     ///
     /// # Examples
     ///
     /// ```
-    /// use std::collections::DList;
+    /// use std::collections::LinkedList;
     ///
-    /// let mut dl = DList::new();
+    /// let mut dl = LinkedList::new();
     ///
     /// dl.push_front(2);
     /// assert_eq!(dl.len(), 1);
@@ -349,16 +355,16 @@ impl<T> DList<T> {
         self.length
     }
 
-    /// Removes all elements from the `DList`.
+    /// Removes all elements from the `LinkedList`.
     ///
     /// This operation should compute in O(n) time.
     ///
     /// # Examples
     ///
     /// ```
-    /// use std::collections::DList;
+    /// use std::collections::LinkedList;
     ///
-    /// let mut dl = DList::new();
+    /// let mut dl = LinkedList::new();
     ///
     /// dl.push_front(2);
     /// dl.push_front(1);
@@ -373,7 +379,7 @@ impl<T> DList<T> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn clear(&mut self) {
-        *self = DList::new()
+        *self = LinkedList::new()
     }
 
     /// Provides a reference to the front element, or `None` if the list is
@@ -382,9 +388,9 @@ impl<T> DList<T> {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::DList;
+    /// use std::collections::LinkedList;
     ///
-    /// let mut dl = DList::new();
+    /// let mut dl = LinkedList::new();
     /// assert_eq!(dl.front(), None);
     ///
     /// dl.push_front(1);
@@ -403,9 +409,9 @@ impl<T> DList<T> {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::DList;
+    /// use std::collections::LinkedList;
     ///
-    /// let mut dl = DList::new();
+    /// let mut dl = LinkedList::new();
     /// assert_eq!(dl.front(), None);
     ///
     /// dl.push_front(1);
@@ -430,9 +436,9 @@ impl<T> DList<T> {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::DList;
+    /// use std::collections::LinkedList;
     ///
-    /// let mut dl = DList::new();
+    /// let mut dl = LinkedList::new();
     /// assert_eq!(dl.back(), None);
     ///
     /// dl.push_back(1);
@@ -451,9 +457,9 @@ impl<T> DList<T> {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::DList;
+    /// use std::collections::LinkedList;
     ///
-    /// let mut dl = DList::new();
+    /// let mut dl = LinkedList::new();
     /// assert_eq!(dl.back(), None);
     ///
     /// dl.push_back(1);
@@ -479,9 +485,9 @@ impl<T> DList<T> {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::DList;
+    /// use std::collections::LinkedList;
     ///
-    /// let mut dl = DList::new();
+    /// let mut dl = LinkedList::new();
     ///
     /// dl.push_front(2);
     /// assert_eq!(dl.front().unwrap(), &2);
@@ -503,9 +509,9 @@ impl<T> DList<T> {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::DList;
+    /// use std::collections::LinkedList;
     ///
-    /// let mut d = DList::new();
+    /// let mut d = LinkedList::new();
     /// assert_eq!(d.pop_front(), None);
     ///
     /// d.push_front(1);
@@ -526,9 +532,9 @@ impl<T> DList<T> {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::DList;
+    /// use std::collections::LinkedList;
     ///
-    /// let mut d = DList::new();
+    /// let mut d = LinkedList::new();
     /// d.push_back(1);
     /// d.push_back(3);
     /// assert_eq!(3, *d.back().unwrap());
@@ -544,9 +550,9 @@ impl<T> DList<T> {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::DList;
+    /// use std::collections::LinkedList;
     ///
-    /// let mut d = DList::new();
+    /// let mut d = LinkedList::new();
     /// assert_eq!(d.pop_back(), None);
     /// d.push_back(1);
     /// d.push_back(3);
@@ -569,9 +575,9 @@ impl<T> DList<T> {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::DList;
+    /// use std::collections::LinkedList;
     ///
-    /// let mut d = DList::new();
+    /// let mut d = LinkedList::new();
     ///
     /// d.push_front(1);
     /// d.push_front(2);
@@ -583,13 +589,13 @@ impl<T> DList<T> {
     /// assert_eq!(splitted.pop_front(), None);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn split_off(&mut self, at: usize) -> DList<T> {
+    pub fn split_off(&mut self, at: usize) -> LinkedList<T> {
         let len = self.len();
         assert!(at <= len, "Cannot split off at a nonexistent index");
         if at == 0 {
-            return mem::replace(self, DList::new());
+            return mem::replace(self, LinkedList::new());
         } else if at == len {
-            return DList::new();
+            return LinkedList::new();
         }
 
         // Below, we iterate towards the `i-1`th node, either from the start or the end,
@@ -612,7 +618,7 @@ impl<T> DList<T> {
             iter.tail
         };
 
-        let mut splitted_list = DList {
+        let mut splitted_list = LinkedList {
             list_head: None,
             list_tail: self.list_tail,
             length: len - at
@@ -628,9 +634,9 @@ impl<T> DList<T> {
 
 #[unsafe_destructor]
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Drop for DList<T> {
+impl<T> Drop for LinkedList<T> {
     fn drop(&mut self) {
-        // Dissolve the dlist in backwards direction
+        // Dissolve the linked_list in backwards direction
         // Just dropping the list_head can lead to stack exhaustion
         // when length is >> 1_000_000
         let mut tail = self.list_tail;
@@ -761,9 +767,9 @@ impl<'a, A> IterMut<'a, A> {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::DList;
+    /// use std::collections::LinkedList;
     ///
-    /// let mut list: DList<_> = vec![1, 3, 4].into_iter().collect();
+    /// let mut list: LinkedList<_> = vec![1, 3, 4].into_iter().collect();
     ///
     /// {
     ///     let mut it = list.iter_mut();
@@ -788,9 +794,9 @@ impl<'a, A> IterMut<'a, A> {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::DList;
+    /// use std::collections::LinkedList;
     ///
-    /// let mut list: DList<_> = vec![1, 2, 3].into_iter().collect();
+    /// let mut list: LinkedList<_> = vec![1, 2, 3].into_iter().collect();
     ///
     /// let mut it = list.iter_mut();
     /// assert_eq!(it.next().unwrap(), &1);
@@ -829,16 +835,16 @@ impl<A> DoubleEndedIterator for IntoIter<A> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A> FromIterator<A> for DList<A> {
-    fn from_iter<T: Iterator<Item=A>>(iterator: T) -> DList<A> {
+impl<A> FromIterator<A> for LinkedList<A> {
+    fn from_iter<T: IntoIterator<Item=A>>(iter: T) -> LinkedList<A> {
         let mut ret = DList::new();
-        ret.extend(iterator);
+        ret.extend(iter);
         ret
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> IntoIterator for DList<T> {
+impl<T> IntoIterator for LinkedList<T> {
     type Item = T;
     type IntoIter = IntoIter<T>;
 
@@ -848,7 +854,7 @@ impl<T> IntoIterator for DList<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T> IntoIterator for &'a DList<T> {
+impl<'a, T> IntoIterator for &'a LinkedList<T> {
     type Item = &'a T;
     type IntoIter = Iter<'a, T>;
 
@@ -857,7 +863,7 @@ impl<'a, T> IntoIterator for &'a DList<T> {
     }
 }
 
-impl<'a, T> IntoIterator for &'a mut DList<T> {
+impl<'a, T> IntoIterator for &'a mut LinkedList<T> {
     type Item = &'a mut T;
     type IntoIter = IterMut<'a, T>;
 
@@ -867,54 +873,54 @@ impl<'a, T> IntoIterator for &'a mut DList<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A> Extend<A> for DList<A> {
-    fn extend<T: Iterator<Item=A>>(&mut self, iterator: T) {
-        for elt in iterator { self.push_back(elt); }
+impl<A> Extend<A> for LinkedList<A> {
+    fn extend<T: IntoIterator<Item=A>>(&mut self, iter: T) {
+        for elt in iter { self.push_back(elt); }
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A: PartialEq> PartialEq for DList<A> {
-    fn eq(&self, other: &DList<A>) -> bool {
+impl<A: PartialEq> PartialEq for LinkedList<A> {
+    fn eq(&self, other: &LinkedList<A>) -> bool {
         self.len() == other.len() &&
             iter::order::eq(self.iter(), other.iter())
     }
 
-    fn ne(&self, other: &DList<A>) -> bool {
+    fn ne(&self, other: &LinkedList<A>) -> bool {
         self.len() != other.len() ||
             iter::order::ne(self.iter(), other.iter())
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A: Eq> Eq for DList<A> {}
+impl<A: Eq> Eq for LinkedList<A> {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A: PartialOrd> PartialOrd for DList<A> {
-    fn partial_cmp(&self, other: &DList<A>) -> Option<Ordering> {
+impl<A: PartialOrd> PartialOrd for LinkedList<A> {
+    fn partial_cmp(&self, other: &LinkedList<A>) -> Option<Ordering> {
         iter::order::partial_cmp(self.iter(), other.iter())
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A: Ord> Ord for DList<A> {
+impl<A: Ord> Ord for LinkedList<A> {
     #[inline]
-    fn cmp(&self, other: &DList<A>) -> Ordering {
+    fn cmp(&self, other: &LinkedList<A>) -> Ordering {
         iter::order::cmp(self.iter(), other.iter())
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A: Clone> Clone for DList<A> {
-    fn clone(&self) -> DList<A> {
-        self.iter().map(|x| x.clone()).collect()
+impl<A: Clone> Clone for LinkedList<A> {
+    fn clone(&self) -> LinkedList<A> {
+        self.iter().cloned().collect()
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A: fmt::Debug> fmt::Debug for DList<A> {
+impl<A: fmt::Debug> fmt::Debug for LinkedList<A> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        try!(write!(f, "DList ["));
+        try!(write!(f, "LinkedList ["));
 
         for (i, e) in self.iter().enumerate() {
             if i != 0 { try!(write!(f, ", ")); }
@@ -926,7 +932,8 @@ impl<A: fmt::Debug> fmt::Debug for DList<A> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<S: Writer + Hasher, A: Hash<S>> Hash<S> for DList<A> {
+#[cfg(stage0)]
+impl<S: Writer + Hasher, A: Hash<S>> Hash<S> for LinkedList<A> {
     fn hash(&self, state: &mut S) {
         self.len().hash(state);
         for elt in self {
@@ -934,6 +941,16 @@ impl<S: Writer + Hasher, A: Hash<S>> Hash<S> for DList<A> {
         }
     }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
+#[cfg(not(stage0))]
+impl<A: Hash> Hash for LinkedList<A> {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        self.len().hash(state);
+        for elt in self {
+            elt.hash(state);
+        }
+    }
+}
 
 #[cfg(test)]
 mod tests {
@@ -944,9 +961,9 @@ mod tests {
     use test::Bencher;
     use test;
 
-    use super::{DList, Node};
+    use super::{LinkedList, Node};
 
-    pub fn check_links<T>(list: &DList<T>) {
+    pub fn check_links<T>(list: &LinkedList<T>) {
         let mut len = 0;
         let mut last_ptr: Option<&Node<T>> = None;
         let mut node_ptr: &Node<T>;
@@ -980,7 +997,7 @@ mod tests {
 
     #[test]
     fn test_basic() {
-        let mut m = DList::new();
+        let mut m = LinkedList::new();
         assert_eq!(m.pop_front(), None);
         assert_eq!(m.pop_back(), None);
         assert_eq!(m.pop_front(), None);
@@ -999,7 +1016,7 @@ mod tests {
         m.push_back(box 7);
         assert_eq!(m.pop_front(), Some(box 1));
 
-        let mut n = DList::new();
+        let mut n = LinkedList::new();
         n.push_front(2);
         n.push_front(3);
         {
@@ -1019,21 +1036,21 @@ mod tests {
     }
 
     #[cfg(test)]
-    fn generate_test() -> DList<i32> {
+    fn generate_test() -> LinkedList<i32> {
         list_from(&[0,1,2,3,4,5,6])
     }
 
     #[cfg(test)]
-    fn list_from<T: Clone>(v: &[T]) -> DList<T> {
-        v.iter().map(|x| (*x).clone()).collect()
+    fn list_from<T: Clone>(v: &[T]) -> LinkedList<T> {
+        v.iter().cloned().collect()
     }
 
     #[test]
     fn test_append() {
         // Empty to empty
         {
-            let mut m = DList::<i32>::new();
-            let mut n = DList::new();
+            let mut m = LinkedList::<i32>::new();
+            let mut n = LinkedList::new();
             m.append(&mut n);
             check_links(&m);
             assert_eq!(m.len(), 0);
@@ -1041,8 +1058,8 @@ mod tests {
         }
         // Non-empty to empty
         {
-            let mut m = DList::new();
-            let mut n = DList::new();
+            let mut m = LinkedList::new();
+            let mut n = LinkedList::new();
             n.push_back(2);
             m.append(&mut n);
             check_links(&m);
@@ -1053,8 +1070,8 @@ mod tests {
         }
         // Empty to non-empty
         {
-            let mut m = DList::new();
-            let mut n = DList::new();
+            let mut m = LinkedList::new();
+            let mut n = LinkedList::new();
             m.push_back(2);
             m.append(&mut n);
             check_links(&m);
@@ -1089,7 +1106,7 @@ mod tests {
     fn test_split_off() {
         // singleton
         {
-            let mut m = DList::new();
+            let mut m = LinkedList::new();
             m.push_back(1);
 
             let p = m.split_off(0);
@@ -1130,7 +1147,7 @@ mod tests {
 
         // no-op on the last index
         {
-            let mut m = DList::new();
+            let mut m = LinkedList::new();
             m.push_back(1);
 
             let p = m.split_off(1);
@@ -1148,7 +1165,7 @@ mod tests {
         for (i, elt) in m.iter().enumerate() {
             assert_eq!(i as i32, *elt);
         }
-        let mut n = DList::new();
+        let mut n = LinkedList::new();
         assert_eq!(n.iter().next(), None);
         n.push_front(4);
         let mut it = n.iter();
@@ -1160,7 +1177,7 @@ mod tests {
 
     #[test]
     fn test_iterator_clone() {
-        let mut n = DList::new();
+        let mut n = LinkedList::new();
         n.push_back(2);
         n.push_back(3);
         n.push_back(4);
@@ -1174,7 +1191,7 @@ mod tests {
 
     #[test]
     fn test_iterator_double_end() {
-        let mut n = DList::new();
+        let mut n = LinkedList::new();
         assert_eq!(n.iter().next(), None);
         n.push_front(4);
         n.push_front(5);
@@ -1196,7 +1213,7 @@ mod tests {
         for (i, elt) in m.iter().rev().enumerate() {
             assert_eq!((6 - i) as i32, *elt);
         }
-        let mut n = DList::new();
+        let mut n = LinkedList::new();
         assert_eq!(n.iter().rev().next(), None);
         n.push_front(4);
         let mut it = n.iter().rev();
@@ -1215,7 +1232,7 @@ mod tests {
             len -= 1;
         }
         assert_eq!(len, 0);
-        let mut n = DList::new();
+        let mut n = LinkedList::new();
         assert!(n.iter_mut().next().is_none());
         n.push_front(4);
         n.push_back(5);
@@ -1229,7 +1246,7 @@ mod tests {
 
     #[test]
     fn test_iterator_mut_double_end() {
-        let mut n = DList::new();
+        let mut n = LinkedList::new();
         assert!(n.iter_mut().next_back().is_none());
         n.push_front(4);
         n.push_front(5);
@@ -1278,7 +1295,7 @@ mod tests {
         for (i, elt) in m.iter_mut().rev().enumerate() {
             assert_eq!((6 - i) as i32, *elt);
         }
-        let mut n = DList::new();
+        let mut n = LinkedList::new();
         assert!(n.iter_mut().rev().next().is_none());
         n.push_front(4);
         let mut it = n.iter_mut().rev();
@@ -1313,8 +1330,8 @@ mod tests {
 
     #[test]
     fn test_hash() {
-      let mut x = DList::new();
-      let mut y = DList::new();
+      let mut x = LinkedList::new();
+      let mut y = LinkedList::new();
 
       assert!(hash::hash::<_, SipHasher>(&x) == hash::hash::<_, SipHasher>(&y));
 
@@ -1382,16 +1399,16 @@ mod tests {
 
     #[test]
     fn test_show() {
-        let list: DList<_> = (0..10).collect();
-        assert_eq!(format!("{:?}", list), "DList [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
+        let list: LinkedList<_> = (0..10).collect();
+        assert_eq!(format!("{:?}", list), "LinkedList [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
 
-        let list: DList<_> = vec!["just", "one", "test", "more"].iter().cloned().collect();
-        assert_eq!(format!("{:?}", list), "DList [\"just\", \"one\", \"test\", \"more\"]");
+        let list: LinkedList<_> = vec!["just", "one", "test", "more"].iter().cloned().collect();
+        assert_eq!(format!("{:?}", list), "LinkedList [\"just\", \"one\", \"test\", \"more\"]");
     }
 
     #[cfg(test)]
     fn fuzz_test(sz: i32) {
-        let mut m: DList<_> = DList::new();
+        let mut m: LinkedList<_> = LinkedList::new();
         let mut v = vec![];
         for i in 0..sz {
             check_links(&m);
@@ -1432,13 +1449,13 @@ mod tests {
     fn bench_collect_into(b: &mut test::Bencher) {
         let v = &[0; 64];
         b.iter(|| {
-            let _: DList<_> = v.iter().cloned().collect();
+            let _: LinkedList<_> = v.iter().cloned().collect();
         })
     }
 
     #[bench]
     fn bench_push_front(b: &mut test::Bencher) {
-        let mut m: DList<_> = DList::new();
+        let mut m: LinkedList<_> = LinkedList::new();
         b.iter(|| {
             m.push_front(0);
         })
@@ -1446,7 +1463,7 @@ mod tests {
 
     #[bench]
     fn bench_push_back(b: &mut test::Bencher) {
-        let mut m: DList<_> = DList::new();
+        let mut m: LinkedList<_> = LinkedList::new();
         b.iter(|| {
             m.push_back(0);
         })
@@ -1454,7 +1471,7 @@ mod tests {
 
     #[bench]
     fn bench_push_back_pop_back(b: &mut test::Bencher) {
-        let mut m: DList<_> = DList::new();
+        let mut m: LinkedList<_> = LinkedList::new();
         b.iter(|| {
             m.push_back(0);
             m.pop_back();
@@ -1463,7 +1480,7 @@ mod tests {
 
     #[bench]
     fn bench_push_front_pop_front(b: &mut test::Bencher) {
-        let mut m: DList<_> = DList::new();
+        let mut m: LinkedList<_> = LinkedList::new();
         b.iter(|| {
             m.push_front(0);
             m.pop_front();
@@ -1473,7 +1490,7 @@ mod tests {
     #[bench]
     fn bench_iter(b: &mut test::Bencher) {
         let v = &[0; 128];
-        let m: DList<_> = v.iter().cloned().collect();
+        let m: LinkedList<_> = v.iter().cloned().collect();
         b.iter(|| {
             assert!(m.iter().count() == 128);
         })
@@ -1481,7 +1498,7 @@ mod tests {
     #[bench]
     fn bench_iter_mut(b: &mut test::Bencher) {
         let v = &[0; 128];
-        let mut m: DList<_> = v.iter().cloned().collect();
+        let mut m: LinkedList<_> = v.iter().cloned().collect();
         b.iter(|| {
             assert!(m.iter_mut().count() == 128);
         })
@@ -1489,7 +1506,7 @@ mod tests {
     #[bench]
     fn bench_iter_rev(b: &mut test::Bencher) {
         let v = &[0; 128];
-        let m: DList<_> = v.iter().cloned().collect();
+        let m: LinkedList<_> = v.iter().cloned().collect();
         b.iter(|| {
             assert!(m.iter().rev().count() == 128);
         })
@@ -1497,7 +1514,7 @@ mod tests {
     #[bench]
     fn bench_iter_mut_rev(b: &mut test::Bencher) {
         let v = &[0; 128];
-        let mut m: DList<_> = v.iter().cloned().collect();
+        let mut m: LinkedList<_> = v.iter().cloned().collect();
         b.iter(|| {
             assert!(m.iter_mut().rev().count() == 128);
         })
diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs
index 06ae8127c00..776b8b3af14 100644
--- a/src/libcollections/slice.rs
+++ b/src/libcollections/slice.rs
@@ -88,7 +88,6 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use alloc::boxed::Box;
-use core::borrow::{BorrowFrom, BorrowFromMut, ToOwned};
 use core::clone::Clone;
 use core::cmp::Ordering::{self, Greater, Less};
 use core::cmp::{self, Ord, PartialEq};
@@ -105,6 +104,7 @@ use core::result::Result;
 use core::slice as core_slice;
 use self::Direction::*;
 
+use borrow::{Borrow, BorrowMut, ToOwned};
 use vec::Vec;
 
 pub use core::slice::{Chunks, AsSlice, Windows};
@@ -1175,18 +1175,19 @@ impl ElementSwaps {
 // Standard trait implementations for slices
 ////////////////////////////////////////////////////////////////////////////////
 
-#[unstable(feature = "collections", reason = "trait is unstable")]
-impl<T> BorrowFrom<Vec<T>> for [T] {
-    fn borrow_from(owned: &Vec<T>) -> &[T] { &owned[] }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> Borrow<[T]> for Vec<T> {
+    fn borrow(&self) -> &[T] { &self[..] }
 }
 
-#[unstable(feature = "collections", reason = "trait is unstable")]
-impl<T> BorrowFromMut<Vec<T>> for [T] {
-    fn borrow_from_mut(owned: &mut Vec<T>) -> &mut [T] { &mut owned[] }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> BorrowMut<[T]> for Vec<T> {
+    fn borrow_mut(&mut self) -> &mut [T] { &mut self[..] }
 }
 
-#[unstable(feature = "collections", reason = "trait is unstable")]
-impl<T: Clone> ToOwned<Vec<T>> for [T] {
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: Clone> ToOwned for [T] {
+    type Owned = Vec<T>;
     fn to_owned(&self) -> Vec<T> { self.to_vec() }
 }
 
@@ -1743,7 +1744,7 @@ mod tests {
     #[test]
     fn test_slice_from() {
         let vec: &[_] = &[1, 2, 3, 4];
-        assert_eq!(&vec[], vec);
+        assert_eq!(&vec[..], vec);
         let b: &[_] = &[3, 4];
         assert_eq!(&vec[2..], b);
         let b: &[_] = &[];
@@ -2264,15 +2265,15 @@ mod tests {
     #[test]
     fn test_total_ord() {
         let c = &[1, 2, 3];
-        [1, 2, 3, 4][].cmp(c) == Greater;
+        [1, 2, 3, 4][..].cmp(c) == Greater;
         let c = &[1, 2, 3, 4];
-        [1, 2, 3][].cmp(c) == Less;
+        [1, 2, 3][..].cmp(c) == Less;
         let c = &[1, 2, 3, 6];
-        [1, 2, 3, 4][].cmp(c) == Equal;
+        [1, 2, 3, 4][..].cmp(c) == Equal;
         let c = &[1, 2, 3, 4, 5, 6];
-        [1, 2, 3, 4, 5, 5, 5, 5][].cmp(c) == Less;
+        [1, 2, 3, 4, 5, 5, 5, 5][..].cmp(c) == Less;
         let c = &[1, 2, 3, 4];
-        [2, 2][].cmp(c) == Greater;
+        [2, 2][..].cmp(c) == Greater;
     }
 
     #[test]
diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs
index 2d4dc2bcf30..ec0a487acdc 100644
--- a/src/libcollections/str.rs
+++ b/src/libcollections/str.rs
@@ -55,7 +55,6 @@
 use self::RecompositionState::*;
 use self::DecompositionType::*;
 
-use core::borrow::{BorrowFrom, ToOwned};
 use core::char::CharExt;
 use core::clone::Clone;
 use core::iter::AdditiveIterator;
@@ -68,7 +67,8 @@ use core::slice::AsSlice;
 use core::str as core_str;
 use unicode::str::{UnicodeStr, Utf16Encoder};
 
-use ring_buf::RingBuf;
+use vec_deque::VecDeque;
+use borrow::{Borrow, ToOwned};
 use slice::SliceExt;
 use string::String;
 use unicode;
@@ -261,7 +261,7 @@ enum RecompositionState {
 pub struct Recompositions<'a> {
     iter: Decompositions<'a>,
     state: RecompositionState,
-    buffer: RingBuf<char>,
+    buffer: VecDeque<char>,
     composee: Option<char>,
     last_ccc: Option<u8>
 }
@@ -386,13 +386,14 @@ macro_rules! utf8_acc_cont_byte {
     ($ch:expr, $byte:expr) => (($ch << 6) | ($byte & 63u8) as u32)
 }
 
-#[unstable(feature = "collections", reason = "trait is unstable")]
-impl BorrowFrom<String> for str {
-    fn borrow_from(owned: &String) -> &str { &owned[] }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Borrow<str> for String {
+    fn borrow(&self) -> &str { &self[..] }
 }
 
-#[unstable(feature = "collections", reason = "trait is unstable")]
-impl ToOwned<String> for str {
+#[stable(feature = "rust1", since = "1.0.0")]
+impl ToOwned for str {
+    type Owned = String;
     fn to_owned(&self) -> String {
         unsafe {
             String::from_utf8_unchecked(self.as_bytes().to_owned())
@@ -466,7 +467,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
                reason = "this functionality may be moved to libunicode")]
     fn nfd_chars(&self) -> Decompositions {
         Decompositions {
-            iter: self[].chars(),
+            iter: self[..].chars(),
             buffer: Vec::new(),
             sorted: false,
             kind: Canonical
@@ -480,7 +481,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
                reason = "this functionality may be moved to libunicode")]
     fn nfkd_chars(&self) -> Decompositions {
         Decompositions {
-            iter: self[].chars(),
+            iter: self[..].chars(),
             buffer: Vec::new(),
             sorted: false,
             kind: Compatible
@@ -496,7 +497,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
         Recompositions {
             iter: self.nfd_chars(),
             state: Composing,
-            buffer: RingBuf::new(),
+            buffer: VecDeque::new(),
             composee: None,
             last_ccc: None
         }
@@ -511,7 +512,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
         Recompositions {
             iter: self.nfkd_chars(),
             state: Composing,
-            buffer: RingBuf::new(),
+            buffer: VecDeque::new(),
             composee: None,
             last_ccc: None
         }
@@ -530,7 +531,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn contains(&self, pat: &str) -> bool {
-        core_str::StrExt::contains(&self[], pat)
+        core_str::StrExt::contains(&self[..], pat)
     }
 
     /// Returns true if a string contains a char pattern.
@@ -547,7 +548,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     #[unstable(feature = "collections",
                reason = "might get removed in favour of a more generic contains()")]
     fn contains_char<P: CharEq>(&self, pat: P) -> bool {
-        core_str::StrExt::contains_char(&self[], pat)
+        core_str::StrExt::contains_char(&self[..], pat)
     }
 
     /// An iterator over the characters of `self`. Note, this iterates
@@ -561,7 +562,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn chars(&self) -> Chars {
-        core_str::StrExt::chars(&self[])
+        core_str::StrExt::chars(&self[..])
     }
 
     /// An iterator over the bytes of `self`
@@ -574,13 +575,13 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn bytes(&self) -> Bytes {
-        core_str::StrExt::bytes(&self[])
+        core_str::StrExt::bytes(&self[..])
     }
 
     /// An iterator over the characters of `self` and their byte offsets.
     #[stable(feature = "rust1", since = "1.0.0")]
     fn char_indices(&self) -> CharIndices {
-        core_str::StrExt::char_indices(&self[])
+        core_str::StrExt::char_indices(&self[..])
     }
 
     /// An iterator over substrings of `self`, separated by characters
@@ -603,7 +604,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn split<P: CharEq>(&self, pat: P) -> Split<P> {
-        core_str::StrExt::split(&self[], pat)
+        core_str::StrExt::split(&self[..], pat)
     }
 
     /// An iterator over substrings of `self`, separated by characters
@@ -630,7 +631,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn splitn<P: CharEq>(&self, count: usize, pat: P) -> SplitN<P> {
-        core_str::StrExt::splitn(&self[], count, pat)
+        core_str::StrExt::splitn(&self[..], count, pat)
     }
 
     /// An iterator over substrings of `self`, separated by characters
@@ -659,7 +660,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     /// ```
     #[unstable(feature = "collections", reason = "might get removed")]
     fn split_terminator<P: CharEq>(&self, pat: P) -> SplitTerminator<P> {
-        core_str::StrExt::split_terminator(&self[], pat)
+        core_str::StrExt::split_terminator(&self[..], pat)
     }
 
     /// An iterator over substrings of `self`, separated by characters
@@ -680,7 +681,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn rsplitn<P: CharEq>(&self, count: usize, pat: P) -> RSplitN<P> {
-        core_str::StrExt::rsplitn(&self[], count, pat)
+        core_str::StrExt::rsplitn(&self[..], count, pat)
     }
 
     /// An iterator over the start and end indices of the disjoint
@@ -706,7 +707,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     #[unstable(feature = "collections",
                reason = "might have its iterator type changed")]
     fn match_indices<'a>(&'a self, pat: &'a str) -> MatchIndices<'a> {
-        core_str::StrExt::match_indices(&self[], pat)
+        core_str::StrExt::match_indices(&self[..], pat)
     }
 
     /// An iterator over the substrings of `self` separated by the pattern `sep`.
@@ -723,7 +724,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     #[unstable(feature = "collections",
                reason = "might get removed in the future in favor of a more generic split()")]
     fn split_str<'a>(&'a self, pat: &'a str) -> SplitStr<'a> {
-        core_str::StrExt::split_str(&self[], pat)
+        core_str::StrExt::split_str(&self[..], pat)
     }
 
     /// An iterator over the lines of a string (subsequences separated
@@ -739,7 +740,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn lines(&self) -> Lines {
-        core_str::StrExt::lines(&self[])
+        core_str::StrExt::lines(&self[..])
     }
 
     /// An iterator over the lines of a string, separated by either
@@ -755,7 +756,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn lines_any(&self) -> LinesAny {
-        core_str::StrExt::lines_any(&self[])
+        core_str::StrExt::lines_any(&self[..])
     }
 
     /// Deprecated: use `s[a .. b]` instead.
@@ -802,7 +803,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     #[unstable(feature = "collections",
                reason = "may have yet to prove its worth")]
     fn slice_chars(&self, begin: usize, end: usize) -> &str {
-        core_str::StrExt::slice_chars(&self[], begin, end)
+        core_str::StrExt::slice_chars(&self[..], begin, end)
     }
 
     /// Takes a bytewise (not UTF-8) slice from a string.
@@ -813,7 +814,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     /// the entire slice as well.
     #[stable(feature = "rust1", since = "1.0.0")]
     unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str {
-        core_str::StrExt::slice_unchecked(&self[], begin, end)
+        core_str::StrExt::slice_unchecked(&self[..], begin, end)
     }
 
     /// Returns true if the pattern `pat` is a prefix of the string.
@@ -825,7 +826,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn starts_with(&self, pat: &str) -> bool {
-        core_str::StrExt::starts_with(&self[], pat)
+        core_str::StrExt::starts_with(&self[..], pat)
     }
 
     /// Returns true if the pattern `pat` is a suffix of the string.
@@ -837,7 +838,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn ends_with(&self, pat: &str) -> bool {
-        core_str::StrExt::ends_with(&self[], pat)
+        core_str::StrExt::ends_with(&self[..], pat)
     }
 
     /// Returns a string with all pre- and suffixes that match
@@ -857,7 +858,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn trim_matches<P: CharEq>(&self, pat: P) -> &str {
-        core_str::StrExt::trim_matches(&self[], pat)
+        core_str::StrExt::trim_matches(&self[..], pat)
     }
 
     /// Returns a string with all prefixes that match
@@ -877,7 +878,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn trim_left_matches<P: CharEq>(&self, pat: P) -> &str {
-        core_str::StrExt::trim_left_matches(&self[], pat)
+        core_str::StrExt::trim_left_matches(&self[..], pat)
     }
 
     /// Returns a string with all suffixes that match
@@ -897,7 +898,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn trim_right_matches<P: CharEq>(&self, pat: P) -> &str {
-        core_str::StrExt::trim_right_matches(&self[], pat)
+        core_str::StrExt::trim_right_matches(&self[..], pat)
     }
 
     /// Check that `index`-th byte lies at the start and/or end of a
@@ -926,7 +927,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     #[unstable(feature = "collections",
                reason = "naming is uncertain with container conventions")]
     fn is_char_boundary(&self, index: usize) -> bool {
-        core_str::StrExt::is_char_boundary(&self[], index)
+        core_str::StrExt::is_char_boundary(&self[..], index)
     }
 
     /// Pluck a character out of a string and return the index of the next
@@ -985,7 +986,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     #[unstable(feature = "collections",
                reason = "naming is uncertain with container conventions")]
     fn char_range_at(&self, start: usize) -> CharRange {
-        core_str::StrExt::char_range_at(&self[], start)
+        core_str::StrExt::char_range_at(&self[..], start)
     }
 
     /// Given a byte position and a str, return the previous char and its position.
@@ -1001,7 +1002,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     #[unstable(feature = "collections",
                reason = "naming is uncertain with container conventions")]
     fn char_range_at_reverse(&self, start: usize) -> CharRange {
-        core_str::StrExt::char_range_at_reverse(&self[], start)
+        core_str::StrExt::char_range_at_reverse(&self[..], start)
     }
 
     /// Plucks the character starting at the `i`th byte of a string.
@@ -1022,7 +1023,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     #[unstable(feature = "collections",
                reason = "naming is uncertain with container conventions")]
     fn char_at(&self, i: usize) -> char {
-        core_str::StrExt::char_at(&self[], i)
+        core_str::StrExt::char_at(&self[..], i)
     }
 
     /// Plucks the character ending at the `i`th byte of a string.
@@ -1034,7 +1035,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     #[unstable(feature = "collections",
                reason = "naming is uncertain with container conventions")]
     fn char_at_reverse(&self, i: usize) -> char {
-        core_str::StrExt::char_at_reverse(&self[], i)
+        core_str::StrExt::char_at_reverse(&self[..], i)
     }
 
     /// Work with the byte buffer of a string as a byte slice.
@@ -1046,7 +1047,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn as_bytes(&self) -> &[u8] {
-        core_str::StrExt::as_bytes(&self[])
+        core_str::StrExt::as_bytes(&self[..])
     }
 
     /// Returns the byte index of the first character of `self` that
@@ -1074,7 +1075,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn find<P: CharEq>(&self, pat: P) -> Option<usize> {
-        core_str::StrExt::find(&self[], pat)
+        core_str::StrExt::find(&self[..], pat)
     }
 
     /// Returns the byte index of the last character of `self` that
@@ -1102,7 +1103,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn rfind<P: CharEq>(&self, pat: P) -> Option<usize> {
-        core_str::StrExt::rfind(&self[], pat)
+        core_str::StrExt::rfind(&self[..], pat)
     }
 
     /// Returns the byte index of the first matching substring
@@ -1127,7 +1128,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     #[unstable(feature = "collections",
                reason = "might get removed in favor of a more generic find in the future")]
     fn find_str(&self, needle: &str) -> Option<usize> {
-        core_str::StrExt::find_str(&self[], needle)
+        core_str::StrExt::find_str(&self[..], needle)
     }
 
     /// Retrieves the first character from a string slice and returns
@@ -1151,7 +1152,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     #[unstable(feature = "collections",
                reason = "awaiting conventions about shifting and slices")]
     fn slice_shift_char(&self) -> Option<(char, &str)> {
-        core_str::StrExt::slice_shift_char(&self[])
+        core_str::StrExt::slice_shift_char(&self[..])
     }
 
     /// Returns the byte offset of an inner slice relative to an enclosing outer slice.
@@ -1171,7 +1172,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     #[unstable(feature = "collections",
                reason = "awaiting convention about comparability of arbitrary slices")]
     fn subslice_offset(&self, inner: &str) -> usize {
-        core_str::StrExt::subslice_offset(&self[], inner)
+        core_str::StrExt::subslice_offset(&self[..], inner)
     }
 
     /// Return an unsafe pointer to the strings buffer.
@@ -1182,14 +1183,14 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     fn as_ptr(&self) -> *const u8 {
-        core_str::StrExt::as_ptr(&self[])
+        core_str::StrExt::as_ptr(&self[..])
     }
 
     /// Return an iterator of `u16` over the string encoded as UTF-16.
     #[unstable(feature = "collections",
                reason = "this functionality may only be provided by libunicode")]
     fn utf16_units(&self) -> Utf16Units {
-        Utf16Units { encoder: Utf16Encoder::new(self[].chars()) }
+        Utf16Units { encoder: Utf16Encoder::new(self[..].chars()) }
     }
 
     /// Return the number of bytes in this string
@@ -1203,7 +1204,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     fn len(&self) -> usize {
-        core_str::StrExt::len(&self[])
+        core_str::StrExt::len(&self[..])
     }
 
     /// Returns true if this slice contains no bytes
@@ -1216,7 +1217,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn is_empty(&self) -> bool {
-        core_str::StrExt::is_empty(&self[])
+        core_str::StrExt::is_empty(&self[..])
     }
 
     /// Parse this string into the specified type.
@@ -1230,7 +1231,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn parse<F: FromStr>(&self) -> Result<F, F::Err> {
-        core_str::StrExt::parse(&self[])
+        core_str::StrExt::parse(&self[..])
     }
 
     /// Returns an iterator over the
@@ -1255,7 +1256,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     #[unstable(feature = "collections",
                reason = "this functionality may only be provided by libunicode")]
     fn graphemes(&self, is_extended: bool) -> Graphemes {
-        UnicodeStr::graphemes(&self[], is_extended)
+        UnicodeStr::graphemes(&self[..], is_extended)
     }
 
     /// Returns an iterator over the grapheme clusters of self and their byte offsets.
@@ -1271,7 +1272,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     #[unstable(feature = "collections",
                reason = "this functionality may only be provided by libunicode")]
     fn grapheme_indices(&self, is_extended: bool) -> GraphemeIndices {
-        UnicodeStr::grapheme_indices(&self[], is_extended)
+        UnicodeStr::grapheme_indices(&self[..], is_extended)
     }
 
     /// An iterator over the words of a string (subsequences separated
@@ -1288,7 +1289,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     #[unstable(feature = "str_words",
                reason = "the precise algorithm to use is unclear")]
     fn words(&self) -> Words {
-        UnicodeStr::words(&self[])
+        UnicodeStr::words(&self[..])
     }
 
     /// Returns a string's displayed width in columns, treating control
@@ -1303,25 +1304,25 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     #[unstable(feature = "collections",
                reason = "this functionality may only be provided by libunicode")]
     fn width(&self, is_cjk: bool) -> usize {
-        UnicodeStr::width(&self[], is_cjk)
+        UnicodeStr::width(&self[..], is_cjk)
     }
 
     /// Returns a string with leading and trailing whitespace removed.
     #[stable(feature = "rust1", since = "1.0.0")]
     fn trim(&self) -> &str {
-        UnicodeStr::trim(&self[])
+        UnicodeStr::trim(&self[..])
     }
 
     /// Returns a string with leading whitespace removed.
     #[stable(feature = "rust1", since = "1.0.0")]
     fn trim_left(&self) -> &str {
-        UnicodeStr::trim_left(&self[])
+        UnicodeStr::trim_left(&self[..])
     }
 
     /// Returns a string with trailing whitespace removed.
     #[stable(feature = "rust1", since = "1.0.0")]
     fn trim_right(&self) -> &str {
-        UnicodeStr::trim_right(&self[])
+        UnicodeStr::trim_right(&self[..])
     }
 }
 
@@ -2704,7 +2705,7 @@ mod tests {
             &["\u{378}\u{308}\u{903}"], &["\u{378}\u{308}", "\u{903}"]),
         ];
 
-        for &(s, g) in &test_same[] {
+        for &(s, g) in &test_same[..] {
             // test forward iterator
             assert!(order::equals(s.graphemes(true), g.iter().cloned()));
             assert!(order::equals(s.graphemes(false), g.iter().cloned()));
diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs
index 69fd28d1723..3b179d0b94c 100644
--- a/src/libcollections/string.rs
+++ b/src/libcollections/string.rs
@@ -16,12 +16,11 @@
 
 use core::prelude::*;
 
-use core::borrow::{Cow, IntoCow};
 use core::default::Default;
 use core::error::Error;
 use core::fmt;
 use core::hash;
-use core::iter::FromIterator;
+use core::iter::{IntoIterator, FromIterator};
 use core::mem;
 use core::ops::{self, Deref, Add, Index};
 use core::ptr;
@@ -29,6 +28,7 @@ use core::raw::Slice as RawSlice;
 use unicode::str as unicode_str;
 use unicode::str::Utf16Item;
 
+use borrow::{Cow, IntoCow};
 use str::{self, CharRange, FromStr, Utf8Error};
 use vec::{DerefVec, Vec, as_vec};
 
@@ -142,7 +142,7 @@ impl String {
     /// assert_eq!(output.as_slice(), "Hello \u{FFFD}World");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> CowString<'a> {
+    pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> Cow<'a, str> {
         let mut i = 0;
         match str::from_utf8(v) {
             Ok(s) => return Cow::Borrowed(s),
@@ -709,18 +709,18 @@ impl Error for FromUtf16Error {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl FromIterator<char> for String {
-    fn from_iter<I:Iterator<Item=char>>(iterator: I) -> String {
+    fn from_iter<I: IntoIterator<Item=char>>(iter: I) -> String {
         let mut buf = String::new();
-        buf.extend(iterator);
+        buf.extend(iter);
         buf
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> FromIterator<&'a str> for String {
-    fn from_iter<I:Iterator<Item=&'a str>>(iterator: I) -> String {
+    fn from_iter<I: IntoIterator<Item=&'a str>>(iter: I) -> String {
         let mut buf = String::new();
-        buf.extend(iterator);
+        buf.extend(iter);
         buf
     }
 }
@@ -728,7 +728,8 @@ impl<'a> FromIterator<&'a str> for String {
 #[unstable(feature = "collections",
            reason = "waiting on Extend stabilization")]
 impl Extend<char> for String {
-    fn extend<I:Iterator<Item=char>>(&mut self, iterator: I) {
+    fn extend<I: IntoIterator<Item=char>>(&mut self, iterable: I) {
+        let iterator = iterable.into_iter();
         let (lower_bound, _) = iterator.size_hint();
         self.reserve(lower_bound);
         for ch in iterator {
@@ -740,7 +741,8 @@ impl Extend<char> for String {
 #[unstable(feature = "collections",
            reason = "waiting on Extend stabilization")]
 impl<'a> Extend<&'a str> for String {
-    fn extend<I: Iterator<Item=&'a str>>(&mut self, iterator: I) {
+    fn extend<I: IntoIterator<Item=&'a str>>(&mut self, iterable: I) {
+        let iterator = iterable.into_iter();
         // A guess that at least one byte per iterator element will be needed.
         let (lower_bound, _) = iterator.size_hint();
         self.reserve(lower_bound);
@@ -780,10 +782,10 @@ macro_rules! impl_eq {
 }
 
 impl_eq! { String, &'a str }
-impl_eq! { CowString<'a>, String }
+impl_eq! { Cow<'a, str>, String }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, 'b> PartialEq<&'b str> for CowString<'a> {
+impl<'a, 'b> PartialEq<&'b str> for Cow<'a, str> {
     #[inline]
     fn eq(&self, other: &&'b str) -> bool { PartialEq::eq(&**self, &**other) }
     #[inline]
@@ -791,11 +793,11 @@ impl<'a, 'b> PartialEq<&'b str> for CowString<'a> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, 'b> PartialEq<CowString<'a>> for &'b str {
+impl<'a, 'b> PartialEq<Cow<'a, str>> for &'b str {
     #[inline]
-    fn eq(&self, other: &CowString<'a>) -> bool { PartialEq::eq(&**self, &**other) }
+    fn eq(&self, other: &Cow<'a, str>) -> bool { PartialEq::eq(&**self, &**other) }
     #[inline]
-    fn ne(&self, other: &CowString<'a>) -> bool { PartialEq::ne(&**self, &**other) }
+    fn ne(&self, other: &Cow<'a, str>) -> bool { PartialEq::ne(&**self, &**other) }
 }
 
 #[unstable(feature = "collections", reason = "waiting on Str stabilization")]
@@ -833,12 +835,21 @@ impl fmt::Debug for String {
 }
 
 #[unstable(feature = "collections", reason = "waiting on Hash stabilization")]
+#[cfg(stage0)]
 impl<H: hash::Writer + hash::Hasher> hash::Hash<H> for String {
     #[inline]
     fn hash(&self, hasher: &mut H) {
         (**self).hash(hasher)
     }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
+#[cfg(not(stage0))]
+impl hash::Hash for String {
+    #[inline]
+    fn hash<H: hash::Hasher>(&self, hasher: &mut H) {
+        (**self).hash(hasher)
+    }
+}
 
 #[unstable(feature = "collections",
            reason = "recent addition, needs more experience")]
@@ -857,7 +868,7 @@ impl ops::Index<ops::Range<usize>> for String {
     type Output = str;
     #[inline]
     fn index(&self, index: &ops::Range<usize>) -> &str {
-        &self[][*index]
+        &self[..][*index]
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -865,7 +876,7 @@ impl ops::Index<ops::RangeTo<usize>> for String {
     type Output = str;
     #[inline]
     fn index(&self, index: &ops::RangeTo<usize>) -> &str {
-        &self[][*index]
+        &self[..][*index]
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -873,7 +884,7 @@ impl ops::Index<ops::RangeFrom<usize>> for String {
     type Output = str;
     #[inline]
     fn index(&self, index: &ops::RangeFrom<usize>) -> &str {
-        &self[][*index]
+        &self[..][*index]
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -891,7 +902,7 @@ impl ops::Deref for String {
 
     #[inline]
     fn deref(&self) -> &str {
-        unsafe { mem::transmute(&self.vec[]) }
+        unsafe { mem::transmute(&self.vec[..]) }
     }
 }
 
@@ -958,31 +969,34 @@ impl<T: fmt::Display + ?Sized> ToString for T {
     }
 }
 
-impl IntoCow<'static, String, str> for String {
+#[stable(feature = "rust1", since = "1.0.0")]
+impl IntoCow<'static, str> for String {
     #[inline]
-    fn into_cow(self) -> CowString<'static> {
+    fn into_cow(self) -> Cow<'static, str> {
         Cow::Owned(self)
     }
 }
 
-impl<'a> IntoCow<'a, String, str> for &'a str {
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a> IntoCow<'a, str> for &'a str {
     #[inline]
-    fn into_cow(self) -> CowString<'a> {
+    fn into_cow(self) -> Cow<'a, str> {
         Cow::Borrowed(self)
     }
 }
 
-/// A clone-on-write string
-#[stable(feature = "rust1", since = "1.0.0")]
-pub type CowString<'a> = Cow<'a, String, str>;
-
-impl<'a> Str for CowString<'a> {
+impl<'a> Str for Cow<'a, str> {
     #[inline]
     fn as_slice<'b>(&'b self) -> &'b str {
         &**self
     }
 }
 
+/// A clone-on-write string
+#[deprecated(since = "1.0.0", reason = "use Cow<'a, str> instead")]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub type CowString<'a> = Cow<'a, str>;
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Write for String {
     #[inline]
@@ -1287,7 +1301,7 @@ mod tests {
     #[test]
     fn test_slicing() {
         let s = "foobar".to_string();
-        assert_eq!("foobar", &s[]);
+        assert_eq!("foobar", &s[..]);
         assert_eq!("foo", &s[..3]);
         assert_eq!("bar", &s[3..]);
         assert_eq!("oob", &s[1..4]);
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index bde733644b5..1cc2a5235ab 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -50,24 +50,26 @@ use core::prelude::*;
 
 use alloc::boxed::Box;
 use alloc::heap::{EMPTY, allocate, reallocate, deallocate};
-use core::borrow::{Cow, IntoCow};
 use core::cmp::max;
 use core::cmp::{Ordering};
 use core::default::Default;
 use core::fmt;
 use core::hash::{self, Hash};
+use core::intrinsics::assume;
 use core::iter::{repeat, FromIterator, IntoIterator};
-use core::marker::{self, ContravariantLifetime, InvariantType};
+use core::marker::PhantomData;
 use core::mem;
-use core::nonzero::NonZero;
 use core::num::{Int, UnsignedInt};
 use core::ops::{Index, IndexMut, Deref, Add};
 use core::ops;
 use core::ptr;
+use core::ptr::Unique;
 use core::raw::Slice as RawSlice;
 use core::slice;
 use core::usize;
 
+use borrow::{Cow, IntoCow};
+
 /// A growable list type, written `Vec<T>` but pronounced 'vector.'
 ///
 /// # Examples
@@ -137,10 +139,9 @@ use core::usize;
 #[unsafe_no_drop_flag]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Vec<T> {
-    ptr: NonZero<*mut T>,
+    ptr: Unique<T>,
     len: usize,
     cap: usize,
-    _own: marker::PhantomData<T>,
 }
 
 unsafe impl<T: Send> Send for Vec<T> { }
@@ -249,10 +250,9 @@ impl<T> Vec<T> {
     pub unsafe fn from_raw_parts(ptr: *mut T, length: usize,
                                  capacity: usize) -> Vec<T> {
         Vec {
-            ptr: NonZero::new(ptr),
+            ptr: Unique::new(ptr),
             len: length,
             cap: capacity,
-            _own: marker::PhantomData,
         }
     }
 
@@ -373,7 +373,7 @@ impl<T> Vec<T> {
                                      self.len * mem::size_of::<T>(),
                                      mem::min_align_of::<T>()) as *mut T;
                 if ptr.is_null() { ::alloc::oom() }
-                self.ptr = NonZero::new(ptr);
+                self.ptr = Unique::new(ptr);
             }
             self.cap = self.len;
         }
@@ -655,7 +655,7 @@ impl<T> Vec<T> {
             unsafe {
                 let ptr = alloc_or_realloc(*self.ptr, old_size, size);
                 if ptr.is_null() { ::alloc::oom() }
-                self.ptr = NonZero::new(ptr);
+                self.ptr = Unique::new(ptr);
             }
             self.cap = max(self.cap, 2) * 2;
         }
@@ -756,7 +756,7 @@ impl<T> Vec<T> {
             Drain {
                 ptr: begin,
                 end: end,
-                marker: ContravariantLifetime,
+                marker: PhantomData,
             }
         }
     }
@@ -871,6 +871,8 @@ impl<T> Vec<T> {
                 end_t: unsafe { start.offset(offset) },
                 start_u: start as *mut U,
                 end_u: start as *mut U,
+
+                _marker: PhantomData,
             };
             //  start_t
             //  start_u
@@ -967,8 +969,7 @@ impl<T> Vec<T> {
             let mut pv = PartialVecZeroSized::<T,U> {
                 num_t: vec.len(),
                 num_u: 0,
-                marker_t: InvariantType,
-                marker_u: InvariantType,
+                marker: PhantomData,
             };
             unsafe { mem::forget(vec); }
 
@@ -1226,7 +1227,7 @@ impl<T> Vec<T> {
             unsafe {
                 let ptr = alloc_or_realloc(*self.ptr, self.cap * mem::size_of::<T>(), size);
                 if ptr.is_null() { ::alloc::oom() }
-                self.ptr = NonZero::new(ptr);
+                self.ptr = Unique::new(ptr);
             }
             self.cap = capacity;
         }
@@ -1302,12 +1303,21 @@ impl<T:Clone> Clone for Vec<T> {
     }
 }
 
+#[cfg(stage0)]
 impl<S: hash::Writer + hash::Hasher, T: Hash<S>> Hash<S> for Vec<T> {
     #[inline]
     fn hash(&self, state: &mut S) {
         Hash::hash(&**self, state)
     }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
+#[cfg(not(stage0))]
+impl<T: Hash> Hash for Vec<T> {
+    #[inline]
+    fn hash<H: hash::Hasher>(&self, state: &mut H) {
+        Hash::hash(&**self, state)
+    }
+}
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> Index<usize> for Vec<T> {
@@ -1407,7 +1417,8 @@ impl<T> ops::DerefMut for Vec<T> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> FromIterator<T> for Vec<T> {
     #[inline]
-    fn from_iter<I:Iterator<Item=T>>(mut iterator: I) -> Vec<T> {
+    fn from_iter<I: IntoIterator<Item=T>>(iterable: I) -> Vec<T> {
+        let mut iterator = iterable.into_iter();
         let (lower, _) = iterator.size_hint();
         let mut vector = Vec::with_capacity(lower);
 
@@ -1480,7 +1491,8 @@ impl<'a, T> IntoIterator for &'a mut Vec<T> {
 #[unstable(feature = "collections", reason = "waiting on Extend stability")]
 impl<T> Extend<T> for Vec<T> {
     #[inline]
-    fn extend<I: Iterator<Item=T>>(&mut self, iterator: I) {
+    fn extend<I: IntoIterator<Item=T>>(&mut self, iterable: I) {
+        let iterator = iterable.into_iter();
         let (lower, _) = iterator.size_hint();
         self.reserve(lower);
         for element in iterator {
@@ -1517,34 +1529,34 @@ macro_rules! impl_eq {
 impl_eq! { Vec<A>, &'b [B] }
 impl_eq! { Vec<A>, &'b mut [B] }
 
-impl<'a, A, B> PartialEq<Vec<B>> for CowVec<'a, A> where A: PartialEq<B> + Clone {
+impl<'a, A, B> PartialEq<Vec<B>> for Cow<'a, [A]> where A: PartialEq<B> + Clone {
     #[inline]
     fn eq(&self, other: &Vec<B>) -> bool { PartialEq::eq(&**self, &**other) }
     #[inline]
     fn ne(&self, other: &Vec<B>) -> bool { PartialEq::ne(&**self, &**other) }
 }
 
-impl<'a, A, B> PartialEq<CowVec<'a, A>> for Vec<B> where A: Clone, B: PartialEq<A> {
+impl<'a, A, B> PartialEq<Cow<'a, [A]>> for Vec<B> where A: Clone, B: PartialEq<A> {
     #[inline]
-    fn eq(&self, other: &CowVec<'a, A>) -> bool { PartialEq::eq(&**self, &**other) }
+    fn eq(&self, other: &Cow<'a, [A]>) -> bool { PartialEq::eq(&**self, &**other) }
     #[inline]
-    fn ne(&self, other: &CowVec<'a, A>) -> bool { PartialEq::ne(&**self, &**other) }
+    fn ne(&self, other: &Cow<'a, [A]>) -> bool { PartialEq::ne(&**self, &**other) }
 }
 
 macro_rules! impl_eq_for_cowvec {
     ($rhs:ty) => {
-        impl<'a, 'b, A, B> PartialEq<$rhs> for CowVec<'a, A> where A: PartialEq<B> + Clone {
+        impl<'a, 'b, A, B> PartialEq<$rhs> for Cow<'a, [A]> where A: PartialEq<B> + Clone {
             #[inline]
             fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) }
             #[inline]
             fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&**self, &**other) }
         }
 
-        impl<'a, 'b, A, B> PartialEq<CowVec<'a, A>> for $rhs where A: Clone, B: PartialEq<A> {
+        impl<'a, 'b, A, B> PartialEq<Cow<'a, [A]>> for $rhs where A: Clone, B: PartialEq<A> {
             #[inline]
-            fn eq(&self, other: &CowVec<'a, A>) -> bool { PartialEq::eq(&**self, &**other) }
+            fn eq(&self, other: &Cow<'a, [A]>) -> bool { PartialEq::eq(&**self, &**other) }
             #[inline]
-            fn ne(&self, other: &CowVec<'a, A>) -> bool { PartialEq::ne(&**self, &**other) }
+            fn ne(&self, other: &Cow<'a, [A]>) -> bool { PartialEq::ne(&**self, &**other) }
         }
     }
 }
@@ -1552,8 +1564,7 @@ macro_rules! impl_eq_for_cowvec {
 impl_eq_for_cowvec! { &'b [B] }
 impl_eq_for_cowvec! { &'b mut [B] }
 
-#[unstable(feature = "collections",
-           reason = "waiting on PartialOrd stability")]
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<T: PartialOrd> PartialOrd for Vec<T> {
     #[inline]
     fn partial_cmp(&self, other: &Vec<T>) -> Option<Ordering> {
@@ -1561,10 +1572,10 @@ impl<T: PartialOrd> PartialOrd for Vec<T> {
     }
 }
 
-#[unstable(feature = "collections", reason = "waiting on Eq stability")]
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Eq> Eq for Vec<T> {}
 
-#[unstable(feature = "collections", reason = "waiting on Ord stability")]
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Ord> Ord for Vec<T> {
     #[inline]
     fn cmp(&self, other: &Vec<T>) -> Ordering {
@@ -1587,8 +1598,12 @@ impl<T> AsSlice<T> for Vec<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
     fn as_slice(&self) -> &[T] {
         unsafe {
+            let p = *self.ptr;
+            if cfg!(not(stage0)) { // NOTE remove cfg after next snapshot
+                assume(p != 0 as *mut T);
+            }
             mem::transmute(RawSlice {
-                data: *self.ptr,
+                data: p,
                 len: self.len
             })
         }
@@ -1643,26 +1658,26 @@ impl<T: fmt::Debug> fmt::Debug for Vec<T> {
 // Clone-on-write
 ////////////////////////////////////////////////////////////////////////////////
 
-#[unstable(feature = "collections",
-           reason = "unclear how valuable this alias is")]
 /// A clone-on-write vector
-pub type CowVec<'a, T> = Cow<'a, Vec<T>, [T]>;
+#[deprecated(since = "1.0.0", reason = "use Cow<'a, [T]> instead")]
+#[unstable(feature = "collections")]
+pub type CowVec<'a, T> = Cow<'a, [T]>;
 
 #[unstable(feature = "collections")]
-impl<'a, T> FromIterator<T> for CowVec<'a, T> where T: Clone {
-    fn from_iter<I: Iterator<Item=T>>(it: I) -> CowVec<'a, T> {
+impl<'a, T> FromIterator<T> for Cow<'a, [T]> where T: Clone {
+    fn from_iter<I: IntoIterator<Item=T>>(it: I) -> Cow<'a, [T]> {
         Cow::Owned(FromIterator::from_iter(it))
     }
 }
 
-impl<'a, T: 'a> IntoCow<'a, Vec<T>, [T]> for Vec<T> where T: Clone {
-    fn into_cow(self) -> CowVec<'a, T> {
+impl<'a, T: 'a> IntoCow<'a, [T]> for Vec<T> where T: Clone {
+    fn into_cow(self) -> Cow<'a, [T]> {
         Cow::Owned(self)
     }
 }
 
-impl<'a, T> IntoCow<'a, Vec<T>, [T]> for &'a [T] where T: Clone {
-    fn into_cow(self) -> CowVec<'a, T> {
+impl<'a, T> IntoCow<'a, [T]> for &'a [T] where T: Clone {
+    fn into_cow(self) -> Cow<'a, [T]> {
         Cow::Borrowed(self)
     }
 }
@@ -1779,10 +1794,10 @@ impl<T> Drop for IntoIter<T> {
 #[unsafe_no_drop_flag]
 #[unstable(feature = "collections",
            reason = "recently added as part of collections reform 2")]
-pub struct Drain<'a, T> {
+pub struct Drain<'a, T:'a> {
     ptr: *const T,
     end: *const T,
-    marker: ContravariantLifetime<'a>,
+    marker: PhantomData<&'a T>,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1867,9 +1882,9 @@ impl<'a, T> Drop for Drain<'a, T> {
 
 /// Wrapper type providing a `&Vec<T>` reference via `Deref`.
 #[unstable(feature = "collections")]
-pub struct DerefVec<'a, T> {
+pub struct DerefVec<'a, T:'a> {
     x: Vec<T>,
-    l: ContravariantLifetime<'a>
+    l: PhantomData<&'a T>,
 }
 
 #[unstable(feature = "collections")]
@@ -1897,7 +1912,7 @@ pub fn as_vec<'a, T>(x: &'a [T]) -> DerefVec<'a, T> {
     unsafe {
         DerefVec {
             x: Vec::from_raw_parts(x.as_ptr() as *mut T, x.len(), x.len()),
-            l: ContravariantLifetime::<'a>
+            l: PhantomData,
         }
     }
 }
@@ -1921,6 +1936,8 @@ struct PartialVecNonZeroSized<T,U> {
     end_u: *mut U,
     start_t: *mut T,
     end_t: *mut T,
+
+    _marker: PhantomData<U>,
 }
 
 /// An owned, partially type-converted vector of zero-sized elements.
@@ -1930,8 +1947,7 @@ struct PartialVecNonZeroSized<T,U> {
 struct PartialVecZeroSized<T,U> {
     num_t: usize,
     num_u: usize,
-    marker_t: InvariantType<T>,
-    marker_u: InvariantType<U>,
+    marker: PhantomData<::core::cell::Cell<(T,U)>>,
 }
 
 #[unsafe_destructor]
@@ -2589,7 +2605,7 @@ mod tests {
         b.bytes = src_len as u64;
 
         b.iter(|| {
-            let dst = src.clone()[].to_vec();
+            let dst = src.clone()[..].to_vec();
             assert_eq!(dst.len(), src_len);
             assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
         });
diff --git a/src/libcollections/ring_buf.rs b/src/libcollections/vec_deque.rs
index 6dcdb21f800..3ba22a41ff7 100644
--- a/src/libcollections/ring_buf.rs
+++ b/src/libcollections/vec_deque.rs
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! RingBuf is a double-ended queue, which is implemented with the help of a
-//! growing circular buffer.
+//! VecDeque is a double-ended queue, which is implemented with the help of a
+//! growing ring buffer.
 //!
 //! This queue has `O(1)` amortized inserts and removals from both ends of the
 //! container. It also has `O(1)` indexing like a vector. The contained elements
@@ -28,20 +28,26 @@ use core::marker;
 use core::mem;
 use core::num::{Int, UnsignedInt};
 use core::ops::{Index, IndexMut};
-use core::ptr;
+use core::ptr::{self, Unique};
 use core::raw::Slice as RawSlice;
 
-use core::hash::{Writer, Hash, Hasher};
+use core::hash::{Hash, Hasher};
+#[cfg(stage0)] use core::hash::Writer;
 use core::cmp;
 
 use alloc::heap;
 
+#[deprecated(since = "1.0.0", reason = "renamed to VecDeque")]
+#[unstable(feature = "collections")]
+pub use VecDeque as RingBuf;
+
 static INITIAL_CAPACITY: usize = 7; // 2^3 - 1
 static MINIMUM_CAPACITY: usize = 1; // 2 - 1
 
-/// `RingBuf` is a circular buffer, which can be used as a double-ended queue efficiently.
+/// `VecDeque` is a growable ring buffer, which can be used as a
+/// double-ended queue efficiently.
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct RingBuf<T> {
+pub struct VecDeque<T> {
     // tail and head are pointers into the buffer. Tail always points
     // to the first element that could be read, Head always points
     // to where data should be written.
@@ -51,30 +57,30 @@ pub struct RingBuf<T> {
     tail: usize,
     head: usize,
     cap: usize,
-    ptr: *mut T
+    ptr: Unique<T>,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-unsafe impl<T: Send> Send for RingBuf<T> {}
+unsafe impl<T: Send> Send for VecDeque<T> {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
-unsafe impl<T: Sync> Sync for RingBuf<T> {}
+unsafe impl<T: Sync> Sync for VecDeque<T> {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Clone> Clone for RingBuf<T> {
-    fn clone(&self) -> RingBuf<T> {
+impl<T: Clone> Clone for VecDeque<T> {
+    fn clone(&self) -> VecDeque<T> {
         self.iter().cloned().collect()
     }
 }
 
 #[unsafe_destructor]
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Drop for RingBuf<T> {
+impl<T> Drop for VecDeque<T> {
     fn drop(&mut self) {
         self.clear();
         unsafe {
             if mem::size_of::<T>() != 0 {
-                heap::deallocate(self.ptr as *mut u8,
+                heap::deallocate(*self.ptr as *mut u8,
                                  self.cap * mem::size_of::<T>(),
                                  mem::min_align_of::<T>())
             }
@@ -83,22 +89,22 @@ impl<T> Drop for RingBuf<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Default for RingBuf<T> {
+impl<T> Default for VecDeque<T> {
     #[inline]
-    fn default() -> RingBuf<T> { RingBuf::new() }
+    fn default() -> VecDeque<T> { VecDeque::new() }
 }
 
-impl<T> RingBuf<T> {
+impl<T> VecDeque<T> {
     /// Turn ptr into a slice
     #[inline]
     unsafe fn buffer_as_slice(&self) -> &[T] {
-        mem::transmute(RawSlice { data: self.ptr, len: self.cap })
+        mem::transmute(RawSlice { data: *self.ptr as *const T, len: self.cap })
     }
 
     /// Turn ptr into a mut slice
     #[inline]
     unsafe fn buffer_as_mut_slice(&mut self) -> &mut [T] {
-        mem::transmute(RawSlice { data: self.ptr, len: self.cap })
+        mem::transmute(RawSlice { data: *self.ptr as *const T, len: self.cap })
     }
 
     /// Moves an element out of the buffer
@@ -149,48 +155,48 @@ impl<T> RingBuf<T> {
     }
 }
 
-impl<T> RingBuf<T> {
-    /// Creates an empty `RingBuf`.
+impl<T> VecDeque<T> {
+    /// Creates an empty `VecDeque`.
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn new() -> RingBuf<T> {
-        RingBuf::with_capacity(INITIAL_CAPACITY)
+    pub fn new() -> VecDeque<T> {
+        VecDeque::with_capacity(INITIAL_CAPACITY)
     }
 
-    /// Creates an empty `RingBuf` with space for at least `n` elements.
+    /// Creates an empty `VecDeque` with space for at least `n` elements.
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn with_capacity(n: usize) -> RingBuf<T> {
+    pub fn with_capacity(n: usize) -> VecDeque<T> {
         // +1 since the ringbuffer always leaves one space empty
         let cap = cmp::max(n + 1, MINIMUM_CAPACITY + 1).next_power_of_two();
         assert!(cap > n, "capacity overflow");
         let size = cap.checked_mul(mem::size_of::<T>())
                       .expect("capacity overflow");
 
-        let ptr = if mem::size_of::<T>() != 0 {
-            unsafe {
+        let ptr = unsafe {
+            if mem::size_of::<T>() != 0 {
                 let ptr = heap::allocate(size, mem::min_align_of::<T>())  as *mut T;;
                 if ptr.is_null() { ::alloc::oom() }
-                ptr
+                Unique::new(ptr)
+            } else {
+                Unique::new(heap::EMPTY as *mut T)
             }
-        } else {
-            heap::EMPTY as *mut T
         };
 
-        RingBuf {
+        VecDeque {
             tail: 0,
             head: 0,
             cap: cap,
-            ptr: ptr
+            ptr: ptr,
         }
     }
 
-    /// Retrieves an element in the `RingBuf` by index.
+    /// Retrieves an element in the `VecDeque` by index.
     ///
     /// # Examples
     ///
     /// ```rust
-    /// use std::collections::RingBuf;
+    /// use std::collections::VecDeque;
     ///
-    /// let mut buf = RingBuf::new();
+    /// let mut buf = VecDeque::new();
     /// buf.push_back(3);
     /// buf.push_back(4);
     /// buf.push_back(5);
@@ -206,14 +212,14 @@ impl<T> RingBuf<T> {
         }
     }
 
-    /// Retrieves an element in the `RingBuf` mutably by index.
+    /// Retrieves an element in the `VecDeque` mutably by index.
     ///
     /// # Examples
     ///
     /// ```rust
-    /// use std::collections::RingBuf;
+    /// use std::collections::VecDeque;
     ///
-    /// let mut buf = RingBuf::new();
+    /// let mut buf = VecDeque::new();
     /// buf.push_back(3);
     /// buf.push_back(4);
     /// buf.push_back(5);
@@ -245,9 +251,9 @@ impl<T> RingBuf<T> {
     /// # Examples
     ///
     /// ```rust
-    /// use std::collections::RingBuf;
+    /// use std::collections::VecDeque;
     ///
-    /// let mut buf = RingBuf::new();
+    /// let mut buf = VecDeque::new();
     /// buf.push_back(3);
     /// buf.push_back(4);
     /// buf.push_back(5);
@@ -266,15 +272,15 @@ impl<T> RingBuf<T> {
         }
     }
 
-    /// Returns the number of elements the `RingBuf` can hold without
+    /// Returns the number of elements the `VecDeque` can hold without
     /// reallocating.
     ///
     /// # Examples
     ///
     /// ```
-    /// use std::collections::RingBuf;
+    /// use std::collections::VecDeque;
     ///
-    /// let buf: RingBuf<i32> = RingBuf::with_capacity(10);
+    /// let buf: VecDeque<i32> = VecDeque::with_capacity(10);
     /// assert!(buf.capacity() >= 10);
     /// ```
     #[inline]
@@ -282,7 +288,7 @@ impl<T> RingBuf<T> {
     pub fn capacity(&self) -> usize { self.cap - 1 }
 
     /// Reserves the minimum capacity for exactly `additional` more elements to be inserted in the
-    /// given `RingBuf`. Does nothing if the capacity is already sufficient.
+    /// given `VecDeque`. Does nothing if the capacity is already sufficient.
     ///
     /// Note that the allocator may give the collection more space than it requests. Therefore
     /// capacity can not be relied upon to be precisely minimal. Prefer `reserve` if future
@@ -295,9 +301,9 @@ impl<T> RingBuf<T> {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::RingBuf;
+    /// use std::collections::VecDeque;
     ///
-    /// let mut buf: RingBuf<i32> = vec![1].into_iter().collect();
+    /// let mut buf: VecDeque<i32> = vec![1].into_iter().collect();
     /// buf.reserve_exact(10);
     /// assert!(buf.capacity() >= 11);
     /// ```
@@ -316,9 +322,9 @@ impl<T> RingBuf<T> {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::RingBuf;
+    /// use std::collections::VecDeque;
     ///
-    /// let mut buf: RingBuf<i32> = vec![1].into_iter().collect();
+    /// let mut buf: VecDeque<i32> = vec![1].into_iter().collect();
     /// buf.reserve(10);
     /// assert!(buf.capacity() >= 11);
     /// ```
@@ -335,11 +341,12 @@ impl<T> RingBuf<T> {
                 let new = count.checked_mul(mem::size_of::<T>())
                                .expect("capacity overflow");
                 unsafe {
-                    self.ptr = heap::reallocate(self.ptr as *mut u8,
-                                                old,
-                                                new,
-                                                mem::min_align_of::<T>()) as *mut T;
-                    if self.ptr.is_null() { ::alloc::oom() }
+                    let ptr = heap::reallocate(*self.ptr as *mut u8,
+                                               old,
+                                               new,
+                                               mem::min_align_of::<T>()) as *mut T;
+                    if ptr.is_null() { ::alloc::oom() }
+                    self.ptr = Unique::new(ptr);
                 }
             }
 
@@ -390,9 +397,9 @@ impl<T> RingBuf<T> {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::RingBuf;
+    /// use std::collections::VecDeque;
     ///
-    /// let mut buf = RingBuf::with_capacity(15);
+    /// let mut buf = VecDeque::with_capacity(15);
     /// buf.extend(0..4);
     /// assert_eq!(buf.capacity(), 15);
     /// buf.shrink_to_fit();
@@ -453,11 +460,12 @@ impl<T> RingBuf<T> {
                 let old = self.cap * mem::size_of::<T>();
                 let new_size = target_cap * mem::size_of::<T>();
                 unsafe {
-                    self.ptr = heap::reallocate(self.ptr as *mut u8,
-                                                old,
-                                                new_size,
-                                                mem::min_align_of::<T>()) as *mut T;
-                    if self.ptr.is_null() { ::alloc::oom() }
+                    let ptr = heap::reallocate(*self.ptr as *mut u8,
+                                               old,
+                                               new_size,
+                                               mem::min_align_of::<T>()) as *mut T;
+                    if ptr.is_null() { ::alloc::oom() }
+                    self.ptr = Unique::new(ptr);
                 }
             }
             self.cap = target_cap;
@@ -475,9 +483,9 @@ impl<T> RingBuf<T> {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::RingBuf;
+    /// use std::collections::VecDeque;
     ///
-    /// let mut buf = RingBuf::new();
+    /// let mut buf = VecDeque::new();
     /// buf.push_back(5);
     /// buf.push_back(10);
     /// buf.push_back(15);
@@ -498,9 +506,9 @@ impl<T> RingBuf<T> {
     /// # Examples
     ///
     /// ```rust
-    /// use std::collections::RingBuf;
+    /// use std::collections::VecDeque;
     ///
-    /// let mut buf = RingBuf::new();
+    /// let mut buf = VecDeque::new();
     /// buf.push_back(5);
     /// buf.push_back(3);
     /// buf.push_back(4);
@@ -521,9 +529,9 @@ impl<T> RingBuf<T> {
     /// # Examples
     ///
     /// ```rust
-    /// use std::collections::RingBuf;
+    /// use std::collections::VecDeque;
     ///
-    /// let mut buf = RingBuf::new();
+    /// let mut buf = VecDeque::new();
     /// buf.push_back(5);
     /// buf.push_back(3);
     /// buf.push_back(4);
@@ -539,8 +547,8 @@ impl<T> RingBuf<T> {
             tail: self.tail,
             head: self.head,
             cap: self.cap,
-            ptr: self.ptr,
-            marker: marker::ContravariantLifetime,
+            ptr: *self.ptr,
+            marker: marker::PhantomData,
         }
     }
 
@@ -553,7 +561,7 @@ impl<T> RingBuf<T> {
     }
 
     /// Returns a pair of slices which contain, in order, the contents of the
-    /// `RingBuf`.
+    /// `VecDeque`.
     #[inline]
     #[unstable(feature = "collections",
                reason = "matches collection reform specification, waiting for dust to settle")]
@@ -573,7 +581,7 @@ impl<T> RingBuf<T> {
     }
 
     /// Returns a pair of slices which contain, in order, the contents of the
-    /// `RingBuf`.
+    /// `VecDeque`.
     #[inline]
     #[unstable(feature = "collections",
                reason = "matches collection reform specification, waiting for dust to settle")]
@@ -596,14 +604,14 @@ impl<T> RingBuf<T> {
         }
     }
 
-    /// Returns the number of elements in the `RingBuf`.
+    /// Returns the number of elements in the `VecDeque`.
     ///
     /// # Examples
     ///
     /// ```
-    /// use std::collections::RingBuf;
+    /// use std::collections::VecDeque;
     ///
-    /// let mut v = RingBuf::new();
+    /// let mut v = VecDeque::new();
     /// assert_eq!(v.len(), 0);
     /// v.push_back(1);
     /// assert_eq!(v.len(), 1);
@@ -616,9 +624,9 @@ impl<T> RingBuf<T> {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::RingBuf;
+    /// use std::collections::VecDeque;
     ///
-    /// let mut v = RingBuf::new();
+    /// let mut v = VecDeque::new();
     /// assert!(v.is_empty());
     /// v.push_front(1);
     /// assert!(!v.is_empty());
@@ -626,15 +634,15 @@ impl<T> RingBuf<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_empty(&self) -> bool { self.len() == 0 }
 
-    /// Creates a draining iterator that clears the `RingBuf` and iterates over
+    /// Creates a draining iterator that clears the `VecDeque` and iterates over
     /// the removed items from start to end.
     ///
     /// # Examples
     ///
     /// ```
-    /// use std::collections::RingBuf;
+    /// use std::collections::VecDeque;
     ///
-    /// let mut v = RingBuf::new();
+    /// let mut v = VecDeque::new();
     /// v.push_back(1);
     /// assert_eq!(v.drain().next(), Some(1));
     /// assert!(v.is_empty());
@@ -653,9 +661,9 @@ impl<T> RingBuf<T> {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::RingBuf;
+    /// use std::collections::VecDeque;
     ///
-    /// let mut v = RingBuf::new();
+    /// let mut v = VecDeque::new();
     /// v.push_back(1);
     /// v.clear();
     /// assert!(v.is_empty());
@@ -672,9 +680,9 @@ impl<T> RingBuf<T> {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::RingBuf;
+    /// use std::collections::VecDeque;
     ///
-    /// let mut d = RingBuf::new();
+    /// let mut d = VecDeque::new();
     /// assert_eq!(d.front(), None);
     ///
     /// d.push_back(1);
@@ -692,9 +700,9 @@ impl<T> RingBuf<T> {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::RingBuf;
+    /// use std::collections::VecDeque;
     ///
-    /// let mut d = RingBuf::new();
+    /// let mut d = VecDeque::new();
     /// assert_eq!(d.front_mut(), None);
     ///
     /// d.push_back(1);
@@ -716,9 +724,9 @@ impl<T> RingBuf<T> {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::RingBuf;
+    /// use std::collections::VecDeque;
     ///
-    /// let mut d = RingBuf::new();
+    /// let mut d = VecDeque::new();
     /// assert_eq!(d.back(), None);
     ///
     /// d.push_back(1);
@@ -736,9 +744,9 @@ impl<T> RingBuf<T> {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::RingBuf;
+    /// use std::collections::VecDeque;
     ///
-    /// let mut d = RingBuf::new();
+    /// let mut d = VecDeque::new();
     /// assert_eq!(d.back(), None);
     ///
     /// d.push_back(1);
@@ -761,9 +769,9 @@ impl<T> RingBuf<T> {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::RingBuf;
+    /// use std::collections::VecDeque;
     ///
-    /// let mut d = RingBuf::new();
+    /// let mut d = VecDeque::new();
     /// d.push_back(1);
     /// d.push_back(2);
     ///
@@ -787,9 +795,9 @@ impl<T> RingBuf<T> {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::RingBuf;
+    /// use std::collections::VecDeque;
     ///
-    /// let mut d = RingBuf::new();
+    /// let mut d = VecDeque::new();
     /// d.push_front(1);
     /// d.push_front(2);
     /// assert_eq!(d.front(), Some(&2));
@@ -811,9 +819,9 @@ impl<T> RingBuf<T> {
     /// # Examples
     ///
     /// ```rust
-    /// use std::collections::RingBuf;
+    /// use std::collections::VecDeque;
     ///
-    /// let mut buf = RingBuf::new();
+    /// let mut buf = VecDeque::new();
     /// buf.push_back(1);
     /// buf.push_back(3);
     /// assert_eq!(3, *buf.back().unwrap());
@@ -836,9 +844,9 @@ impl<T> RingBuf<T> {
     /// # Examples
     ///
     /// ```rust
-    /// use std::collections::RingBuf;
+    /// use std::collections::VecDeque;
     ///
-    /// let mut buf = RingBuf::new();
+    /// let mut buf = VecDeque::new();
     /// assert_eq!(buf.pop_back(), None);
     /// buf.push_back(1);
     /// buf.push_back(3);
@@ -870,9 +878,9 @@ impl<T> RingBuf<T> {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::RingBuf;
+    /// use std::collections::VecDeque;
     ///
-    /// let mut buf = RingBuf::new();
+    /// let mut buf = VecDeque::new();
     /// assert_eq!(buf.swap_back_remove(0), None);
     /// buf.push_back(5);
     /// buf.push_back(99);
@@ -903,9 +911,9 @@ impl<T> RingBuf<T> {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::RingBuf;
+    /// use std::collections::VecDeque;
     ///
-    /// let mut buf = RingBuf::new();
+    /// let mut buf = VecDeque::new();
     /// assert_eq!(buf.swap_front_remove(0), None);
     /// buf.push_back(15);
     /// buf.push_back(5);
@@ -936,9 +944,9 @@ impl<T> RingBuf<T> {
     ///
     /// # Examples
     /// ```rust
-    /// use std::collections::RingBuf;
+    /// use std::collections::VecDeque;
     ///
-    /// let mut buf = RingBuf::new();
+    /// let mut buf = VecDeque::new();
     /// buf.push_back(10);
     /// buf.push_back(12);
     /// buf.insert(1,11);
@@ -1138,9 +1146,9 @@ impl<T> RingBuf<T> {
     ///
     /// # Examples
     /// ```rust
-    /// use std::collections::RingBuf;
+    /// use std::collections::VecDeque;
     ///
-    /// let mut buf = RingBuf::new();
+    /// let mut buf = VecDeque::new();
     /// buf.push_back(5);
     /// buf.push_back(10);
     /// buf.push_back(12);
@@ -1309,9 +1317,9 @@ impl<T> RingBuf<T> {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::RingBuf;
+    /// use std::collections::VecDeque;
     ///
-    /// let mut buf: RingBuf<_> = vec![1,2,3].into_iter().collect();
+    /// let mut buf: VecDeque<_> = vec![1,2,3].into_iter().collect();
     /// let buf2 = buf.split_off(1);
     /// // buf = [1], buf2 = [2, 3]
     /// assert_eq!(buf.len(), 1);
@@ -1325,7 +1333,7 @@ impl<T> RingBuf<T> {
         assert!(at <= len, "`at` out of bounds");
 
         let other_len = len - at;
-        let mut other = RingBuf::with_capacity(other_len);
+        let mut other = VecDeque::with_capacity(other_len);
 
         unsafe {
             let (first_half, second_half) = self.as_slices();
@@ -1336,7 +1344,7 @@ impl<T> RingBuf<T> {
                 // `at` lies in the first half.
                 let amount_in_first = first_len - at;
 
-                ptr::copy_nonoverlapping_memory(other.ptr,
+                ptr::copy_nonoverlapping_memory(*other.ptr,
                                                 first_half.as_ptr().offset(at as isize),
                                                 amount_in_first);
 
@@ -1349,7 +1357,7 @@ impl<T> RingBuf<T> {
                 // in the first half.
                 let offset = at - first_len;
                 let amount_in_second = second_len - offset;
-                ptr::copy_nonoverlapping_memory(other.ptr,
+                ptr::copy_nonoverlapping_memory(*other.ptr,
                                                 second_half.as_ptr().offset(offset as isize),
                                                 amount_in_second);
             }
@@ -1371,10 +1379,10 @@ impl<T> RingBuf<T> {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::RingBuf;
+    /// use std::collections::VecDeque;
     ///
-    /// let mut buf: RingBuf<_> = vec![1, 2, 3].into_iter().collect();
-    /// let mut buf2: RingBuf<_> = vec![4, 5, 6].into_iter().collect();
+    /// let mut buf: VecDeque<_> = vec![1, 2, 3].into_iter().collect();
+    /// let mut buf2: VecDeque<_> = vec![4, 5, 6].into_iter().collect();
     /// buf.append(&mut buf2);
     /// assert_eq!(buf.len(), 6);
     /// assert_eq!(buf2.len(), 0);
@@ -1388,16 +1396,16 @@ impl<T> RingBuf<T> {
     }
 }
 
-impl<T: Clone> RingBuf<T> {
+impl<T: Clone> VecDeque<T> {
     /// Modifies the ringbuf in-place so that `len()` is equal to new_len,
     /// either by removing excess elements or by appending copies of a value to the back.
     ///
     /// # Examples
     ///
     /// ```
-    /// use std::collections::RingBuf;
+    /// use std::collections::VecDeque;
     ///
-    /// let mut buf = RingBuf::new();
+    /// let mut buf = VecDeque::new();
     /// buf.push_back(5);
     /// buf.push_back(10);
     /// buf.push_back(15);
@@ -1434,7 +1442,7 @@ fn count(tail: usize, head: usize, size: usize) -> usize {
     (head - tail) & (size - 1)
 }
 
-/// `RingBuf` iterator.
+/// `VecDeque` iterator.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Iter<'a, T:'a> {
     ring: &'a [T],
@@ -1511,14 +1519,14 @@ impl<'a, T> RandomAccessIterator for Iter<'a, T> {
 // FIXME This was implemented differently from Iter because of a problem
 //       with returning the mutable reference. I couldn't find a way to
 //       make the lifetime checker happy so, but there should be a way.
-/// `RingBuf` mutable iterator.
+/// `VecDeque` mutable iterator.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct IterMut<'a, T:'a> {
     ptr: *mut T,
     tail: usize,
     head: usize,
     cap: usize,
-    marker: marker::ContravariantLifetime<'a>,
+    marker: marker::PhantomData<&'a mut T>,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1563,10 +1571,10 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> ExactSizeIterator for IterMut<'a, T> {}
 
-/// A by-value RingBuf iterator
+/// A by-value VecDeque iterator
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct IntoIter<T> {
-    inner: RingBuf<T>,
+    inner: VecDeque<T>,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1596,11 +1604,11 @@ impl<T> DoubleEndedIterator for IntoIter<T> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ExactSizeIterator for IntoIter<T> {}
 
-/// A draining RingBuf iterator
+/// A draining VecDeque iterator
 #[unstable(feature = "collections",
            reason = "matches collection reform specification, waiting for dust to settle")]
 pub struct Drain<'a, T: 'a> {
-    inner: &'a mut RingBuf<T>,
+    inner: &'a mut VecDeque<T>,
 }
 
 #[unsafe_destructor]
@@ -1641,33 +1649,34 @@ impl<'a, T: 'a> DoubleEndedIterator for Drain<'a, T> {
 impl<'a, T: 'a> ExactSizeIterator for Drain<'a, T> {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A: PartialEq> PartialEq for RingBuf<A> {
-    fn eq(&self, other: &RingBuf<A>) -> bool {
+impl<A: PartialEq> PartialEq for VecDeque<A> {
+    fn eq(&self, other: &VecDeque<A>) -> bool {
         self.len() == other.len() &&
             self.iter().zip(other.iter()).all(|(a, b)| a.eq(b))
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A: Eq> Eq for RingBuf<A> {}
+impl<A: Eq> Eq for VecDeque<A> {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A: PartialOrd> PartialOrd for RingBuf<A> {
-    fn partial_cmp(&self, other: &RingBuf<A>) -> Option<Ordering> {
+impl<A: PartialOrd> PartialOrd for VecDeque<A> {
+    fn partial_cmp(&self, other: &VecDeque<A>) -> Option<Ordering> {
         iter::order::partial_cmp(self.iter(), other.iter())
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A: Ord> Ord for RingBuf<A> {
+impl<A: Ord> Ord for VecDeque<A> {
     #[inline]
-    fn cmp(&self, other: &RingBuf<A>) -> Ordering {
+    fn cmp(&self, other: &VecDeque<A>) -> Ordering {
         iter::order::cmp(self.iter(), other.iter())
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<S: Writer + Hasher, A: Hash<S>> Hash<S> for RingBuf<A> {
+#[cfg(stage0)]
+impl<S: Writer + Hasher, A: Hash<S>> Hash<S> for VecDeque<A> {
     fn hash(&self, state: &mut S) {
         self.len().hash(state);
         for elt in self {
@@ -1675,9 +1684,19 @@ impl<S: Writer + Hasher, A: Hash<S>> Hash<S> for RingBuf<A> {
         }
     }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
+#[cfg(not(stage0))]
+impl<A: Hash> Hash for VecDeque<A> {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        self.len().hash(state);
+        for elt in self {
+            elt.hash(state);
+        }
+    }
+}
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A> Index<usize> for RingBuf<A> {
+impl<A> Index<usize> for VecDeque<A> {
     type Output = A;
 
     #[inline]
@@ -1687,7 +1706,7 @@ impl<A> Index<usize> for RingBuf<A> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A> IndexMut<usize> for RingBuf<A> {
+impl<A> IndexMut<usize> for VecDeque<A> {
     #[inline]
     fn index_mut(&mut self, i: &usize) -> &mut A {
         self.get_mut(*i).expect("Out of bounds access")
@@ -1695,17 +1714,18 @@ impl<A> IndexMut<usize> for RingBuf<A> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A> FromIterator<A> for RingBuf<A> {
-    fn from_iter<T: Iterator<Item=A>>(iterator: T) -> RingBuf<A> {
+impl<A> FromIterator<A> for VecDeque<A> {
+    fn from_iter<T: IntoIterator<Item=A>>(iterable: T) -> VecDeque<A> {
+        let iterator = iterable.into_iter();
         let (lower, _) = iterator.size_hint();
-        let mut deq = RingBuf::with_capacity(lower);
+        let mut deq = VecDeque::with_capacity(lower);
         deq.extend(iterator);
         deq
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> IntoIterator for RingBuf<T> {
+impl<T> IntoIterator for VecDeque<T> {
     type Item = T;
     type IntoIter = IntoIter<T>;
 
@@ -1715,7 +1735,7 @@ impl<T> IntoIterator for RingBuf<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T> IntoIterator for &'a RingBuf<T> {
+impl<'a, T> IntoIterator for &'a VecDeque<T> {
     type Item = &'a T;
     type IntoIter = Iter<'a, T>;
 
@@ -1725,7 +1745,7 @@ impl<'a, T> IntoIterator for &'a RingBuf<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T> IntoIterator for &'a mut RingBuf<T> {
+impl<'a, T> IntoIterator for &'a mut VecDeque<T> {
     type Item = &'a mut T;
     type IntoIter = IterMut<'a, T>;
 
@@ -1735,18 +1755,18 @@ impl<'a, T> IntoIterator for &'a mut RingBuf<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A> Extend<A> for RingBuf<A> {
-    fn extend<T: Iterator<Item=A>>(&mut self, iterator: T) {
-        for elt in iterator {
+impl<A> Extend<A> for VecDeque<A> {
+    fn extend<T: IntoIterator<Item=A>>(&mut self, iter: T) {
+        for elt in iter {
             self.push_back(elt);
         }
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: fmt::Debug> fmt::Debug for RingBuf<T> {
+impl<T: fmt::Debug> fmt::Debug for VecDeque<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        try!(write!(f, "RingBuf ["));
+        try!(write!(f, "VecDeque ["));
 
         for (i, e) in self.iter().enumerate() {
             if i != 0 { try!(write!(f, ", ")); }
@@ -1768,12 +1788,12 @@ mod tests {
     use test::Bencher;
     use test;
 
-    use super::RingBuf;
+    use super::VecDeque;
 
     #[test]
     #[allow(deprecated)]
     fn test_simple() {
-        let mut d = RingBuf::new();
+        let mut d = VecDeque::new();
         assert_eq!(d.len(), 0);
         d.push_front(17);
         d.push_front(42);
@@ -1812,7 +1832,7 @@ mod tests {
 
     #[cfg(test)]
     fn test_parameterized<T:Clone + PartialEq + Debug>(a: T, b: T, c: T, d: T) {
-        let mut deq = RingBuf::new();
+        let mut deq = VecDeque::new();
         assert_eq!(deq.len(), 0);
         deq.push_front(a.clone());
         deq.push_front(b.clone());
@@ -1843,7 +1863,7 @@ mod tests {
 
     #[test]
     fn test_push_front_grow() {
-        let mut deq = RingBuf::new();
+        let mut deq = VecDeque::new();
         for i in 0..66 {
             deq.push_front(i);
         }
@@ -1853,7 +1873,7 @@ mod tests {
             assert_eq!(deq[i], 65 - i);
         }
 
-        let mut deq = RingBuf::new();
+        let mut deq = VecDeque::new();
         for i in 0..66 {
             deq.push_back(i);
         }
@@ -1865,7 +1885,7 @@ mod tests {
 
     #[test]
     fn test_index() {
-        let mut deq = RingBuf::new();
+        let mut deq = VecDeque::new();
         for i in 1..4 {
             deq.push_front(i);
         }
@@ -1875,7 +1895,7 @@ mod tests {
     #[test]
     #[should_fail]
     fn test_index_out_of_bounds() {
-        let mut deq = RingBuf::new();
+        let mut deq = VecDeque::new();
         for i in 1..4 {
             deq.push_front(i);
         }
@@ -1885,14 +1905,14 @@ mod tests {
     #[bench]
     fn bench_new(b: &mut test::Bencher) {
         b.iter(|| {
-            let ring: RingBuf<i32> = RingBuf::new();
+            let ring: VecDeque<i32> = VecDeque::new();
             test::black_box(ring);
         })
     }
 
     #[bench]
     fn bench_push_back_100(b: &mut test::Bencher) {
-        let mut deq = RingBuf::with_capacity(101);
+        let mut deq = VecDeque::with_capacity(101);
         b.iter(|| {
             for i in 0..100 {
                 deq.push_back(i);
@@ -1904,7 +1924,7 @@ mod tests {
 
     #[bench]
     fn bench_push_front_100(b: &mut test::Bencher) {
-        let mut deq = RingBuf::with_capacity(101);
+        let mut deq = VecDeque::with_capacity(101);
         b.iter(|| {
             for i in 0..100 {
                 deq.push_front(i);
@@ -1916,7 +1936,7 @@ mod tests {
 
     #[bench]
     fn bench_pop_back_100(b: &mut test::Bencher) {
-        let mut deq= RingBuf::<i32>::with_capacity(101);
+        let mut deq= VecDeque::<i32>::with_capacity(101);
 
         b.iter(|| {
             deq.head = 100;
@@ -1929,7 +1949,7 @@ mod tests {
 
     #[bench]
     fn bench_pop_front_100(b: &mut test::Bencher) {
-        let mut deq = RingBuf::<i32>::with_capacity(101);
+        let mut deq = VecDeque::<i32>::with_capacity(101);
 
         b.iter(|| {
             deq.head = 100;
@@ -1943,7 +1963,7 @@ mod tests {
     #[bench]
     fn bench_grow_1025(b: &mut test::Bencher) {
         b.iter(|| {
-            let mut deq = RingBuf::new();
+            let mut deq = VecDeque::new();
             for i in 0..1025 {
                 deq.push_front(i);
             }
@@ -1953,7 +1973,7 @@ mod tests {
 
     #[bench]
     fn bench_iter_1000(b: &mut test::Bencher) {
-        let ring: RingBuf<_> = (0..1000).collect();
+        let ring: VecDeque<_> = (0..1000).collect();
 
         b.iter(|| {
             let mut sum = 0;
@@ -1966,7 +1986,7 @@ mod tests {
 
     #[bench]
     fn bench_mut_iter_1000(b: &mut test::Bencher) {
-        let mut ring: RingBuf<_> = (0..1000).collect();
+        let mut ring: VecDeque<_> = (0..1000).collect();
 
         b.iter(|| {
             let mut sum = 0;
@@ -1986,9 +2006,9 @@ mod tests {
 
     #[derive(Clone, PartialEq, Debug)]
     enum Taggypar<T> {
-        Onepar(i32),
-        Twopar(i32, i32),
-        Threepar(i32, i32, i32),
+        Onepar(T),
+        Twopar(T, T),
+        Threepar(T, T, T),
     }
 
     #[derive(Clone, PartialEq, Debug)]
@@ -2027,17 +2047,17 @@ mod tests {
 
     #[test]
     fn test_with_capacity() {
-        let mut d = RingBuf::with_capacity(0);
+        let mut d = VecDeque::with_capacity(0);
         d.push_back(1);
         assert_eq!(d.len(), 1);
-        let mut d = RingBuf::with_capacity(50);
+        let mut d = VecDeque::with_capacity(50);
         d.push_back(1);
         assert_eq!(d.len(), 1);
     }
 
     #[test]
     fn test_with_capacity_non_power_two() {
-        let mut d3 = RingBuf::with_capacity(3);
+        let mut d3 = VecDeque::with_capacity(3);
         d3.push_back(1);
 
         // X = None, | = lo
@@ -2062,7 +2082,7 @@ mod tests {
 
         d3.push_back(15);
         // There used to be a bug here about how the
-        // RingBuf made growth assumptions about the
+        // VecDeque made growth assumptions about the
         // underlying Vec which didn't hold and lead
         // to corruption.
         // (Vec grows to next power of two)
@@ -2078,7 +2098,7 @@ mod tests {
 
     #[test]
     fn test_reserve_exact() {
-        let mut d = RingBuf::new();
+        let mut d = VecDeque::new();
         d.push_back(0);
         d.reserve_exact(50);
         assert!(d.capacity() >= 51);
@@ -2086,7 +2106,7 @@ mod tests {
 
     #[test]
     fn test_reserve() {
-        let mut d = RingBuf::new();
+        let mut d = VecDeque::new();
         d.push_back(0);
         d.reserve(50);
         assert!(d.capacity() >= 51);
@@ -2094,7 +2114,7 @@ mod tests {
 
     #[test]
     fn test_swap() {
-        let mut d: RingBuf<_> = (0..5).collect();
+        let mut d: VecDeque<_> = (0..5).collect();
         d.pop_front();
         d.swap(0, 3);
         assert_eq!(d.iter().cloned().collect::<Vec<_>>(), vec!(4, 2, 3, 1));
@@ -2102,7 +2122,7 @@ mod tests {
 
     #[test]
     fn test_iter() {
-        let mut d = RingBuf::new();
+        let mut d = VecDeque::new();
         assert_eq!(d.iter().next(), None);
         assert_eq!(d.iter().size_hint(), (0, Some(0)));
 
@@ -2134,7 +2154,7 @@ mod tests {
 
     #[test]
     fn test_rev_iter() {
-        let mut d = RingBuf::new();
+        let mut d = VecDeque::new();
         assert_eq!(d.iter().rev().next(), None);
 
         for i in 0..5 {
@@ -2154,7 +2174,7 @@ mod tests {
 
     #[test]
     fn test_mut_rev_iter_wrap() {
-        let mut d = RingBuf::with_capacity(3);
+        let mut d = VecDeque::with_capacity(3);
         assert!(d.iter_mut().rev().next().is_none());
 
         d.push_back(1);
@@ -2169,7 +2189,7 @@ mod tests {
 
     #[test]
     fn test_mut_iter() {
-        let mut d = RingBuf::new();
+        let mut d = VecDeque::new();
         assert!(d.iter_mut().next().is_none());
 
         for i in 0..3 {
@@ -2192,7 +2212,7 @@ mod tests {
 
     #[test]
     fn test_mut_rev_iter() {
-        let mut d = RingBuf::new();
+        let mut d = VecDeque::new();
         assert!(d.iter_mut().rev().next().is_none());
 
         for i in 0..3 {
@@ -2218,7 +2238,7 @@ mod tests {
 
         // Empty iter
         {
-            let d: RingBuf<i32> = RingBuf::new();
+            let d: VecDeque<i32> = VecDeque::new();
             let mut iter = d.into_iter();
 
             assert_eq!(iter.size_hint(), (0, Some(0)));
@@ -2228,7 +2248,7 @@ mod tests {
 
         // simple iter
         {
-            let mut d = RingBuf::new();
+            let mut d = VecDeque::new();
             for i in 0..5 {
                 d.push_back(i);
             }
@@ -2239,7 +2259,7 @@ mod tests {
 
         // wrapped iter
         {
-            let mut d = RingBuf::new();
+            let mut d = VecDeque::new();
             for i in 0..5 {
                 d.push_back(i);
             }
@@ -2253,7 +2273,7 @@ mod tests {
 
         // partially used
         {
-            let mut d = RingBuf::new();
+            let mut d = VecDeque::new();
             for i in 0..5 {
                 d.push_back(i);
             }
@@ -2277,7 +2297,7 @@ mod tests {
 
         // Empty iter
         {
-            let mut d: RingBuf<i32> = RingBuf::new();
+            let mut d: VecDeque<i32> = VecDeque::new();
 
             {
                 let mut iter = d.drain();
@@ -2292,7 +2312,7 @@ mod tests {
 
         // simple iter
         {
-            let mut d = RingBuf::new();
+            let mut d = VecDeque::new();
             for i in 0..5 {
                 d.push_back(i);
             }
@@ -2303,7 +2323,7 @@ mod tests {
 
         // wrapped iter
         {
-            let mut d = RingBuf::new();
+            let mut d = VecDeque::new();
             for i in 0..5 {
                 d.push_back(i);
             }
@@ -2317,7 +2337,7 @@ mod tests {
 
         // partially used
         {
-            let mut d: RingBuf<_> = RingBuf::new();
+            let mut d: VecDeque<_> = VecDeque::new();
             for i in 0..5 {
                 d.push_back(i);
             }
@@ -2343,12 +2363,12 @@ mod tests {
     fn test_from_iter() {
         use core::iter;
         let v = vec!(1,2,3,4,5,6,7);
-        let deq: RingBuf<_> = v.iter().cloned().collect();
+        let deq: VecDeque<_> = v.iter().cloned().collect();
         let u: Vec<_> = deq.iter().cloned().collect();
         assert_eq!(u, v);
 
         let seq = iter::count(0, 2).take(256);
-        let deq: RingBuf<_> = seq.collect();
+        let deq: VecDeque<_> = seq.collect();
         for (i, &x) in deq.iter().enumerate() {
             assert_eq!(2*i, x);
         }
@@ -2357,7 +2377,7 @@ mod tests {
 
     #[test]
     fn test_clone() {
-        let mut d = RingBuf::new();
+        let mut d = VecDeque::new();
         d.push_front(17);
         d.push_front(42);
         d.push_back(137);
@@ -2374,13 +2394,13 @@ mod tests {
 
     #[test]
     fn test_eq() {
-        let mut d = RingBuf::new();
-        assert!(d == RingBuf::with_capacity(0));
+        let mut d = VecDeque::new();
+        assert!(d == VecDeque::with_capacity(0));
         d.push_front(137);
         d.push_front(17);
         d.push_front(42);
         d.push_back(137);
-        let mut e = RingBuf::with_capacity(0);
+        let mut e = VecDeque::with_capacity(0);
         e.push_back(42);
         e.push_back(17);
         e.push_back(137);
@@ -2390,13 +2410,13 @@ mod tests {
         e.push_back(0);
         assert!(e != d);
         e.clear();
-        assert!(e == RingBuf::new());
+        assert!(e == VecDeque::new());
     }
 
     #[test]
     fn test_hash() {
-      let mut x = RingBuf::new();
-      let mut y = RingBuf::new();
+      let mut x = VecDeque::new();
+      let mut y = VecDeque::new();
 
       x.push_back(1);
       x.push_back(2);
@@ -2413,8 +2433,8 @@ mod tests {
 
     #[test]
     fn test_ord() {
-        let x = RingBuf::new();
-        let mut y = RingBuf::new();
+        let x = VecDeque::new();
+        let mut y = VecDeque::new();
         y.push_back(1);
         y.push_back(2);
         y.push_back(3);
@@ -2426,13 +2446,13 @@ mod tests {
 
     #[test]
     fn test_show() {
-        let ringbuf: RingBuf<_> = (0..10).collect();
-        assert_eq!(format!("{:?}", ringbuf), "RingBuf [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
+        let ringbuf: VecDeque<_> = (0..10).collect();
+        assert_eq!(format!("{:?}", ringbuf), "VecDeque [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
 
-        let ringbuf: RingBuf<_> = vec!["just", "one", "test", "more"].iter()
+        let ringbuf: VecDeque<_> = vec!["just", "one", "test", "more"].iter()
                                                                         .cloned()
                                                                         .collect();
-        assert_eq!(format!("{:?}", ringbuf), "RingBuf [\"just\", \"one\", \"test\", \"more\"]");
+        assert_eq!(format!("{:?}", ringbuf), "VecDeque [\"just\", \"one\", \"test\", \"more\"]");
     }
 
     #[test]
@@ -2445,7 +2465,7 @@ mod tests {
             }
         }
 
-        let mut ring = RingBuf::new();
+        let mut ring = VecDeque::new();
         ring.push_back(Elem);
         ring.push_front(Elem);
         ring.push_back(Elem);
@@ -2465,7 +2485,7 @@ mod tests {
             }
         }
 
-        let mut ring = RingBuf::new();
+        let mut ring = VecDeque::new();
         ring.push_back(Elem);
         ring.push_front(Elem);
         ring.push_back(Elem);
@@ -2489,7 +2509,7 @@ mod tests {
             }
         }
 
-        let mut ring = RingBuf::new();
+        let mut ring = VecDeque::new();
         ring.push_back(Elem);
         ring.push_front(Elem);
         ring.push_back(Elem);
@@ -2505,7 +2525,7 @@ mod tests {
     fn test_reserve_grow() {
         // test growth path A
         // [T o o H] -> [T o o H . . . . ]
-        let mut ring = RingBuf::with_capacity(4);
+        let mut ring = VecDeque::with_capacity(4);
         for i in 0..3 {
             ring.push_back(i);
         }
@@ -2516,7 +2536,7 @@ mod tests {
 
         // test growth path B
         // [H T o o] -> [. T o o H . . . ]
-        let mut ring = RingBuf::with_capacity(4);
+        let mut ring = VecDeque::with_capacity(4);
         for i in 0..1 {
             ring.push_back(i);
             assert_eq!(ring.pop_front(), Some(i));
@@ -2531,7 +2551,7 @@ mod tests {
 
         // test growth path C
         // [o o H T] -> [o o H . . . . T ]
-        let mut ring = RingBuf::with_capacity(4);
+        let mut ring = VecDeque::with_capacity(4);
         for i in 0..3 {
             ring.push_back(i);
             assert_eq!(ring.pop_front(), Some(i));
@@ -2547,7 +2567,7 @@ mod tests {
 
     #[test]
     fn test_get() {
-        let mut ring = RingBuf::new();
+        let mut ring = VecDeque::new();
         ring.push_back(0);
         assert_eq!(ring.get(0), Some(&0));
         assert_eq!(ring.get(1), None);
@@ -2579,7 +2599,7 @@ mod tests {
 
     #[test]
     fn test_get_mut() {
-        let mut ring = RingBuf::new();
+        let mut ring = VecDeque::new();
         for i in 0..3 {
             ring.push_back(i);
         }
@@ -2605,7 +2625,7 @@ mod tests {
         fn test(back: bool) {
             // This test checks that every single combination of tail position and length is tested.
             // Capacity 15 should be large enough to cover every case.
-            let mut tester = RingBuf::with_capacity(15);
+            let mut tester = VecDeque::with_capacity(15);
             let usable_cap = tester.capacity();
             let final_len = usable_cap / 2;
 
@@ -2649,7 +2669,7 @@ mod tests {
         // This test checks that every single combination of tail position, length, and
         // insertion position is tested. Capacity 15 should be large enough to cover every case.
 
-        let mut tester = RingBuf::with_capacity(15);
+        let mut tester = VecDeque::with_capacity(15);
         // can't guarantee we got 15, so have to get what we got.
         // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
         // this test isn't covering what it wants to
@@ -2683,7 +2703,7 @@ mod tests {
         // This test checks that every single combination of tail position, length, and
         // removal position is tested. Capacity 15 should be large enough to cover every case.
 
-        let mut tester = RingBuf::with_capacity(15);
+        let mut tester = VecDeque::with_capacity(15);
         // can't guarantee we got 15, so have to get what we got.
         // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
         // this test isn't covering what it wants to
@@ -2720,7 +2740,7 @@ mod tests {
         // This test checks that every single combination of head and tail position,
         // is tested. Capacity 15 should be large enough to cover every case.
 
-        let mut tester = RingBuf::with_capacity(15);
+        let mut tester = VecDeque::with_capacity(15);
         // can't guarantee we got 15, so have to get what we got.
         // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
         // this test isn't covering what it wants to
@@ -2749,7 +2769,7 @@ mod tests {
 
     #[test]
     fn test_front() {
-        let mut ring = RingBuf::new();
+        let mut ring = VecDeque::new();
         ring.push_back(10);
         ring.push_back(20);
         assert_eq!(ring.front(), Some(&10));
@@ -2761,7 +2781,7 @@ mod tests {
 
     #[test]
     fn test_as_slices() {
-        let mut ring: RingBuf<i32> = RingBuf::with_capacity(127);
+        let mut ring: VecDeque<i32> = VecDeque::with_capacity(127);
         let cap = ring.capacity() as i32;
         let first = cap/2;
         let last  = cap - first;
@@ -2789,7 +2809,7 @@ mod tests {
 
     #[test]
     fn test_as_mut_slices() {
-        let mut ring: RingBuf<i32> = RingBuf::with_capacity(127);
+        let mut ring: VecDeque<i32> = VecDeque::with_capacity(127);
         let cap = ring.capacity() as i32;
         let first = cap/2;
         let last  = cap - first;
@@ -2820,7 +2840,7 @@ mod tests {
         // This test checks that every single combination of tail position, length, and
         // split position is tested. Capacity 15 should be large enough to cover every case.
 
-        let mut tester = RingBuf::with_capacity(15);
+        let mut tester = VecDeque::with_capacity(15);
         // can't guarantee we got 15, so have to get what we got.
         // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
         // this test isn't covering what it wants to
@@ -2855,8 +2875,8 @@ mod tests {
 
     #[test]
     fn test_append() {
-        let mut a: RingBuf<_> = vec![1, 2, 3].into_iter().collect();
-        let mut b: RingBuf<_> = vec![4, 5, 6].into_iter().collect();
+        let mut a: VecDeque<_> = vec![1, 2, 3].into_iter().collect();
+        let mut b: VecDeque<_> = vec![4, 5, 6].into_iter().collect();
 
         // normal append
         a.append(&mut b);
diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs
index 82ccfd0614f..54589a31423 100644
--- a/src/libcollections/vec_map.rs
+++ b/src/libcollections/vec_map.rs
@@ -20,7 +20,8 @@ use core::prelude::*;
 use core::cmp::Ordering;
 use core::default::Default;
 use core::fmt;
-use core::hash::{Hash, Writer, Hasher};
+use core::hash::{Hash, Hasher};
+#[cfg(stage0)] use core::hash::Writer;
 use core::iter::{Enumerate, FilterMap, Map, FromIterator, IntoIterator};
 use core::iter;
 use core::mem::replace;
@@ -99,6 +100,7 @@ impl<V> Default for VecMap<V> {
     fn default() -> VecMap<V> { VecMap::new() }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<V:Clone> Clone for VecMap<V> {
     #[inline]
     fn clone(&self) -> VecMap<V> {
@@ -111,6 +113,7 @@ impl<V:Clone> Clone for VecMap<V> {
     }
 }
 
+#[cfg(stage0)]
 impl<S: Writer + Hasher, V: Hash<S>> Hash<S> for VecMap<V> {
     fn hash(&self, state: &mut S) {
         // In order to not traverse the `VecMap` twice, count the elements
@@ -123,6 +126,20 @@ impl<S: Writer + Hasher, V: Hash<S>> Hash<S> for VecMap<V> {
         count.hash(state);
     }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
+#[cfg(not(stage0))]
+impl<V: Hash> Hash for VecMap<V> {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        // In order to not traverse the `VecMap` twice, count the elements
+        // during iteration.
+        let mut count: usize = 0;
+        for elt in self {
+            elt.hash(state);
+            count += 1;
+        }
+        count.hash(state);
+    }
+}
 
 impl<V> VecMap<V> {
     /// Creates an empty `VecMap`.
@@ -661,7 +678,7 @@ impl<V: fmt::Debug> fmt::Debug for VecMap<V> {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<V> FromIterator<(usize, V)> for VecMap<V> {
-    fn from_iter<Iter: Iterator<Item=(usize, V)>>(iter: Iter) -> VecMap<V> {
+    fn from_iter<I: IntoIterator<Item=(usize, V)>>(iter: I) -> VecMap<V> {
         let mut map = VecMap::new();
         map.extend(iter);
         map
@@ -700,7 +717,7 @@ impl<'a, T> IntoIterator for &'a mut VecMap<T> {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<V> Extend<(usize, V)> for VecMap<V> {
-    fn extend<Iter: Iterator<Item=(usize, V)>>(&mut self, iter: Iter) {
+    fn extend<I: IntoIterator<Item=(usize, V)>>(&mut self, iter: I) {
         for (k, v) in iter {
             self.insert(k, v);
         }
@@ -859,7 +876,7 @@ pub struct IntoIter<V> {
 }
 
 #[unstable(feature = "collections")]
-pub struct Drain<'a, V> {
+pub struct Drain<'a, V:'a> {
     iter: FilterMap<
     Enumerate<vec::Drain<'a, Option<V>>>,
     fn((usize, Option<V>)) -> Option<(usize, V)>>
diff --git a/src/libcore/array.rs b/src/libcore/array.rs
index 838ca4e478b..afb5d95c9f8 100644
--- a/src/libcore/array.rs
+++ b/src/libcore/array.rs
@@ -17,7 +17,7 @@
 use clone::Clone;
 use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
 use fmt;
-use hash::{Hash, Hasher, self};
+use hash::{Hash, self};
 use iter::IntoIterator;
 use marker::Copy;
 use ops::Deref;
@@ -35,16 +35,24 @@ macro_rules! array_impls {
                 }
             }
 
-            impl<S: hash::Writer + Hasher, T: Hash<S>> Hash<S> for [T; $N] {
+            #[cfg(stage0)]
+            impl<S: hash::Writer + hash::Hasher, T: Hash<S>> Hash<S> for [T; $N] {
                 fn hash(&self, state: &mut S) {
-                    Hash::hash(&self[], state)
+                    Hash::hash(&self[..], state)
+                }
+            }
+            #[cfg(not(stage0))]
+            #[stable(feature = "rust1", since = "1.0.0")]
+            impl<T: Hash> Hash for [T; $N] {
+                fn hash<H: hash::Hasher>(&self, state: &mut H) {
+                    Hash::hash(&self[..], state)
                 }
             }
 
             #[stable(feature = "rust1", since = "1.0.0")]
             impl<T: fmt::Debug> fmt::Debug for [T; $N] {
                 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-                    fmt::Debug::fmt(&&self[], f)
+                    fmt::Debug::fmt(&&self[..], f)
                 }
             }
 
@@ -72,11 +80,11 @@ macro_rules! array_impls {
             impl<A, B> PartialEq<[B; $N]> for [A; $N] where A: PartialEq<B> {
                 #[inline]
                 fn eq(&self, other: &[B; $N]) -> bool {
-                    &self[] == &other[]
+                    &self[..] == &other[..]
                 }
                 #[inline]
                 fn ne(&self, other: &[B; $N]) -> bool {
-                    &self[] != &other[]
+                    &self[..] != &other[..]
                 }
             }
 
@@ -87,11 +95,11 @@ macro_rules! array_impls {
             {
                 #[inline(always)]
                 fn eq(&self, other: &Rhs) -> bool {
-                    PartialEq::eq(&self[], &**other)
+                    PartialEq::eq(&self[..], &**other)
                 }
                 #[inline(always)]
                 fn ne(&self, other: &Rhs) -> bool {
-                    PartialEq::ne(&self[], &**other)
+                    PartialEq::ne(&self[..], &**other)
                 }
             }
 
@@ -102,11 +110,11 @@ macro_rules! array_impls {
             {
                 #[inline(always)]
                 fn eq(&self, other: &[B; $N]) -> bool {
-                    PartialEq::eq(&**self, &other[])
+                    PartialEq::eq(&**self, &other[..])
                 }
                 #[inline(always)]
                 fn ne(&self, other: &[B; $N]) -> bool {
-                    PartialEq::ne(&**self, &other[])
+                    PartialEq::ne(&**self, &other[..])
                 }
             }
 
@@ -117,23 +125,23 @@ macro_rules! array_impls {
             impl<T:PartialOrd> PartialOrd for [T; $N] {
                 #[inline]
                 fn partial_cmp(&self, other: &[T; $N]) -> Option<Ordering> {
-                    PartialOrd::partial_cmp(&&self[], &&other[])
+                    PartialOrd::partial_cmp(&&self[..], &&other[..])
                 }
                 #[inline]
                 fn lt(&self, other: &[T; $N]) -> bool {
-                    PartialOrd::lt(&&self[], &&other[])
+                    PartialOrd::lt(&&self[..], &&other[..])
                 }
                 #[inline]
                 fn le(&self, other: &[T; $N]) -> bool {
-                    PartialOrd::le(&&self[], &&other[])
+                    PartialOrd::le(&&self[..], &&other[..])
                 }
                 #[inline]
                 fn ge(&self, other: &[T; $N]) -> bool {
-                    PartialOrd::ge(&&self[], &&other[])
+                    PartialOrd::ge(&&self[..], &&other[..])
                 }
                 #[inline]
                 fn gt(&self, other: &[T; $N]) -> bool {
-                    PartialOrd::gt(&&self[], &&other[])
+                    PartialOrd::gt(&&self[..], &&other[..])
                 }
             }
 
@@ -141,7 +149,7 @@ macro_rules! array_impls {
             impl<T:Ord> Ord for [T; $N] {
                 #[inline]
                 fn cmp(&self, other: &[T; $N]) -> Ordering {
-                    Ord::cmp(&&self[], &&other[])
+                    Ord::cmp(&&self[..], &&other[..])
                 }
             }
         )+
diff --git a/src/libcore/atomic.rs b/src/libcore/atomic.rs
index 05d864accc1..6afe5b2257d 100644
--- a/src/libcore/atomic.rs
+++ b/src/libcore/atomic.rs
@@ -76,6 +76,7 @@ use marker::Sync;
 
 use intrinsics;
 use cell::UnsafeCell;
+use marker::PhantomData;
 
 /// A boolean type which can be safely shared between threads.
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -105,6 +106,7 @@ unsafe impl Sync for AtomicUsize {}
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct AtomicPtr<T> {
     p: UnsafeCell<usize>,
+    _marker: PhantomData<*mut T>,
 }
 
 unsafe impl<T> Sync for AtomicPtr<T> {}
@@ -791,7 +793,8 @@ impl<T> AtomicPtr<T> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(p: *mut T) -> AtomicPtr<T> {
-        AtomicPtr { p: UnsafeCell::new(p as usize) }
+        AtomicPtr { p: UnsafeCell::new(p as usize),
+                    _marker: PhantomData }
     }
 
     /// Loads a value from the pointer.
diff --git a/src/libcore/borrow.rs b/src/libcore/borrow.rs
deleted file mode 100644
index 035443e9c3f..00000000000
--- a/src/libcore/borrow.rs
+++ /dev/null
@@ -1,265 +0,0 @@
-// Copyright 2014 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.
-
-//! A module for working with borrowed data.
-//!
-//! # The `BorrowFrom` traits
-//!
-//! In general, there may be several ways to "borrow" a piece of data.  The
-//! typical ways of borrowing a type `T` are `&T` (a shared borrow) and `&mut T`
-//! (a mutable borrow). But types like `Vec<T>` provide additional kinds of
-//! borrows: the borrowed slices `&[T]` and `&mut [T]`.
-//!
-//! When writing generic code, it is often desirable to abstract over all ways
-//! of borrowing data from a given type. That is the role of the `BorrowFrom`
-//! trait: if `T: BorrowFrom<U>`, then `&T` can be borrowed from `&U`.  A given
-//! type can be borrowed as multiple different types. In particular, `Vec<T>:
-//! BorrowFrom<Vec<T>>` and `[T]: BorrowFrom<Vec<T>>`.
-//!
-//! # The `ToOwned` trait
-//!
-//! Some types make it possible to go from borrowed to owned, usually by
-//! implementing the `Clone` trait. But `Clone` works only for going from `&T`
-//! to `T`. The `ToOwned` trait generalizes `Clone` to construct owned data
-//! from any borrow of a given type.
-//!
-//! # The `Cow` (clone-on-write) type
-//!
-//! The type `Cow` is a smart pointer providing clone-on-write functionality: it
-//! can enclose and provide immutable access to borrowed data, and clone the
-//! data lazily when mutation or ownership is required. The type is designed to
-//! work with general borrowed data via the `BorrowFrom` trait.
-//!
-//! `Cow` implements both `Deref`, which means that you can call
-//! non-mutating methods directly on the data it encloses. If mutation
-//! is desired, `to_mut` will obtain a mutable references to an owned
-//! value, cloning if necessary.
-
-#![unstable(feature = "core",
-            reason = "recently added as part of collections reform")]
-
-use clone::Clone;
-use cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
-use fmt;
-use marker::Sized;
-use ops::Deref;
-use option::Option;
-use self::Cow::*;
-
-/// A trait for borrowing data.
-#[old_orphan_check]
-pub trait BorrowFrom<Owned: ?Sized> {
-    /// Immutably borrow from an owned value.
-    fn borrow_from(owned: &Owned) -> &Self;
-}
-
-/// A trait for mutably borrowing data.
-#[old_orphan_check]
-pub trait BorrowFromMut<Owned: ?Sized> : BorrowFrom<Owned> {
-    /// Mutably borrow from an owned value.
-    fn borrow_from_mut(owned: &mut Owned) -> &mut Self;
-}
-
-impl<T: ?Sized> BorrowFrom<T> for T {
-    fn borrow_from(owned: &T) -> &T { owned }
-}
-
-impl<T: ?Sized> BorrowFromMut<T> for T {
-    fn borrow_from_mut(owned: &mut T) -> &mut T { owned }
-}
-
-impl<'a, T: ?Sized> BorrowFrom<&'a T> for T {
-    fn borrow_from<'b>(owned: &'b &'a T) -> &'b T { &**owned }
-}
-
-impl<'a, T: ?Sized> BorrowFrom<&'a mut T> for T {
-    fn borrow_from<'b>(owned: &'b &'a mut T) -> &'b T { &**owned }
-}
-
-impl<'a, T: ?Sized> BorrowFromMut<&'a mut T> for T {
-    fn borrow_from_mut<'b>(owned: &'b mut &'a mut T) -> &'b mut T { &mut **owned }
-}
-
-impl<'a, T, B: ?Sized> BorrowFrom<Cow<'a, T, B>> for B where B: ToOwned<T> {
-    fn borrow_from<'b>(owned: &'b Cow<'a, T, B>) -> &'b B {
-        &**owned
-    }
-}
-
-/// Trait for moving into a `Cow`
-#[old_orphan_check]
-pub trait IntoCow<'a, T, B: ?Sized> {
-    /// Moves `self` into `Cow`
-    fn into_cow(self) -> Cow<'a, T, B>;
-}
-
-impl<'a, T, B: ?Sized> IntoCow<'a, T, B> for Cow<'a, T, B> where B: ToOwned<T> {
-    fn into_cow(self) -> Cow<'a, T, B> {
-        self
-    }
-}
-
-/// A generalization of Clone to borrowed data.
-#[old_orphan_check]
-pub trait ToOwned<Owned>: BorrowFrom<Owned> {
-    /// Create owned data from borrowed data, usually by copying.
-    fn to_owned(&self) -> Owned;
-}
-
-impl<T> ToOwned<T> for T where T: Clone {
-    fn to_owned(&self) -> T { self.clone() }
-}
-
-/// A clone-on-write smart pointer.
-///
-/// # Example
-///
-/// ```rust
-/// use std::borrow::Cow;
-///
-/// fn abs_all(input: &mut Cow<Vec<int>, [int]>) {
-///     for i in 0..input.len() {
-///         let v = input[i];
-///         if v < 0 {
-///             // clones into a vector the first time (if not already owned)
-///             input.to_mut()[i] = -v;
-///         }
-///     }
-/// }
-/// ```
-pub enum Cow<'a, T, B: ?Sized + 'a> where B: ToOwned<T> {
-    /// Borrowed data.
-    Borrowed(&'a B),
-
-    /// Owned data.
-    Owned(T)
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, B: ?Sized> Clone for Cow<'a, T, B> where B: ToOwned<T> {
-    fn clone(&self) -> Cow<'a, T, B> {
-        match *self {
-            Borrowed(b) => Borrowed(b),
-            Owned(ref o) => {
-                let b: &B = BorrowFrom::borrow_from(o);
-                Owned(b.to_owned())
-            },
-        }
-    }
-}
-
-impl<'a, T, B: ?Sized> Cow<'a, T, B> where B: ToOwned<T> {
-    /// Acquire a mutable reference to the owned form of the data.
-    ///
-    /// Copies the data if it is not already owned.
-    pub fn to_mut(&mut self) -> &mut T {
-        match *self {
-            Borrowed(borrowed) => {
-                *self = Owned(borrowed.to_owned());
-                self.to_mut()
-            }
-            Owned(ref mut owned) => owned
-        }
-    }
-
-    /// Extract the owned data.
-    ///
-    /// Copies the data if it is not already owned.
-    pub fn into_owned(self) -> T {
-        match self {
-            Borrowed(borrowed) => borrowed.to_owned(),
-            Owned(owned) => owned
-        }
-    }
-
-    /// Returns true if this `Cow` wraps a borrowed value
-    pub fn is_borrowed(&self) -> bool {
-        match *self {
-            Borrowed(_) => true,
-            _ => false,
-        }
-    }
-
-    /// Returns true if this `Cow` wraps an owned value
-    pub fn is_owned(&self) -> bool {
-        match *self {
-            Owned(_) => true,
-            _ => false,
-        }
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, B: ?Sized> Deref for Cow<'a, T, B> where B: ToOwned<T>  {
-    type Target = B;
-
-    fn deref(&self) -> &B {
-        match *self {
-            Borrowed(borrowed) => borrowed,
-            Owned(ref owned) => BorrowFrom::borrow_from(owned)
-        }
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, B: ?Sized> Eq for Cow<'a, T, B> where B: Eq + ToOwned<T> {}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, B: ?Sized> Ord for Cow<'a, T, B> where B: Ord + ToOwned<T> {
-    #[inline]
-    fn cmp(&self, other: &Cow<'a, T, B>) -> Ordering {
-        Ord::cmp(&**self, &**other)
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, 'b, T, U, B: ?Sized, C: ?Sized> PartialEq<Cow<'b, U, C>> for Cow<'a, T, B> where
-    B: PartialEq<C> + ToOwned<T>,
-    C: ToOwned<U>,
-{
-    #[inline]
-    fn eq(&self, other: &Cow<'b, U, C>) -> bool {
-        PartialEq::eq(&**self, &**other)
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, B: ?Sized> PartialOrd for Cow<'a, T, B> where B: PartialOrd + ToOwned<T> {
-    #[inline]
-    fn partial_cmp(&self, other: &Cow<'a, T, B>) -> Option<Ordering> {
-        PartialOrd::partial_cmp(&**self, &**other)
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, B: ?Sized> fmt::Debug for Cow<'a, T, B> where
-    B: fmt::Debug + ToOwned<T>,
-    T: fmt::Debug,
-{
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match *self {
-            Borrowed(ref b) => fmt::Debug::fmt(b, f),
-            Owned(ref o) => fmt::Debug::fmt(o, f),
-        }
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, B: ?Sized> fmt::Display for Cow<'a, T, B> where
-    B: fmt::Display + ToOwned<T>,
-    T: fmt::Display,
-{
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match *self {
-            Borrowed(ref b) => fmt::Display::fmt(b, f),
-            Owned(ref o) => fmt::Display::fmt(o, f),
-        }
-    }
-}
diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index 19ec245300d..b37bad5f754 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -215,7 +215,7 @@ impl Ord for Ordering {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn cmp(&self, other: &Ordering) -> Ordering {
-        (*self as int).cmp(&(*other as int))
+        (*self as i32).cmp(&(*other as i32))
     }
 }
 
@@ -224,7 +224,7 @@ impl PartialOrd for Ordering {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn partial_cmp(&self, other: &Ordering) -> Option<Ordering> {
-        (*self as int).partial_cmp(&(*other as int))
+        (*self as i32).partial_cmp(&(*other as i32))
     }
 }
 
@@ -482,7 +482,7 @@ mod impls {
     }
 
     partial_eq_impl! {
-        bool char uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64
+        bool char usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64
     }
 
     macro_rules! eq_impl {
@@ -492,7 +492,7 @@ mod impls {
         )*)
     }
 
-    eq_impl! { () bool char uint u8 u16 u32 u64 int i8 i16 i32 i64 }
+    eq_impl! { () bool char usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
 
     macro_rules! partial_ord_impl {
         ($($t:ty)*) => ($(
@@ -535,7 +535,7 @@ mod impls {
         }
     }
 
-    partial_ord_impl! { char uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64 }
+    partial_ord_impl! { char usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
 
     macro_rules! ord_impl {
         ($($t:ty)*) => ($(
@@ -565,7 +565,7 @@ mod impls {
         }
     }
 
-    ord_impl! { char uint u8 u16 u32 u64 int i8 i16 i32 i64 }
+    ord_impl! { char usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
 
     // & pointers
 
diff --git a/src/libcore/default.rs b/src/libcore/default.rs
index d79b613f589..7f46d9cbe50 100644
--- a/src/libcore/default.rs
+++ b/src/libcore/default.rs
@@ -16,7 +16,7 @@
 //!
 //! ```
 //! struct SomeOptions {
-//!     foo: int,
+//!     foo: i32,
 //!     bar: f32,
 //! }
 //! ```
@@ -28,7 +28,7 @@
 //!
 //! #[derive(Default)]
 //! struct SomeOptions {
-//!     foo: int,
+//!     foo: i32,
 //!     bar: f32,
 //! }
 //!
@@ -56,7 +56,7 @@
 //!
 //! #[derive(Default)]
 //! struct SomeOptions {
-//!     foo: int,
+//!     foo: i32,
 //!     bar: f32,
 //!     baz: Kind,
 //! }
@@ -73,7 +73,7 @@
 //! # use std::default::Default;
 //! # #[derive(Default)]
 //! # struct SomeOptions {
-//! #     foo: int,
+//! #     foo: i32,
 //! #     bar: f32,
 //! # }
 //! fn main() {
@@ -93,7 +93,7 @@
 /// ```
 /// #[derive(Default)]
 /// struct SomeOptions {
-///     foo: int,
+///     foo: i32,
 ///     bar: f32,
 /// }
 /// ```
@@ -113,7 +113,7 @@ pub trait Default {
     ///
     /// let i: i8 = Default::default();
     /// let (x, y): (Option<String>, f64) = Default::default();
-    /// let (a, b, (c, d)): (int, uint, (bool, bool)) = Default::default();
+    /// let (a, b, (c, d)): (i32, u32, (bool, bool)) = Default::default();
     /// ```
     ///
     /// Making your own:
@@ -150,13 +150,13 @@ default_impl! { (), () }
 default_impl! { bool, false }
 default_impl! { char, '\x00' }
 
-default_impl! { uint, 0 }
+default_impl! { usize, 0 }
 default_impl! { u8, 0 }
 default_impl! { u16, 0 }
 default_impl! { u32, 0 }
 default_impl! { u64, 0 }
 
-default_impl! { int, 0 }
+default_impl! { isize, 0 }
 default_impl! { i8, 0 }
 default_impl! { i16, 0 }
 default_impl! { i32, 0 }
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 67c8c9fec09..a2c1bbc0331 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -16,7 +16,7 @@ use any;
 use cell::{Cell, RefCell, Ref, RefMut, BorrowState};
 use char::CharExt;
 use iter::{Iterator, IteratorExt};
-use marker::{Copy, Sized};
+use marker::{Copy, PhantomData, Sized};
 use mem;
 use option::Option;
 use option::Option::{Some, None};
@@ -914,6 +914,11 @@ impl Debug for () {
         f.pad("()")
     }
 }
+impl<T> Debug for PhantomData<T> {
+    fn fmt(&self, f: &mut Formatter) -> Result {
+        f.pad("PhantomData")
+    }
+}
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Copy + Debug> Debug for Cell<T> {
diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs
index a5d2618eff9..2e83334b937 100644
--- a/src/libcore/hash/mod.rs
+++ b/src/libcore/hash/mod.rs
@@ -35,7 +35,7 @@
 //! the trait `Hash`:
 //!
 //! ```rust
-//! use std::hash::{hash, Hash, Hasher, Writer, SipHasher};
+//! use std::hash::{hash, Hash, Hasher, SipHasher};
 //!
 //! struct Person {
 //!     id: uint,
@@ -43,8 +43,8 @@
 //!     phone: u64,
 //! }
 //!
-//! impl<H: Hasher + Writer> Hash<H> for Person {
-//!     fn hash(&self, state: &mut H) {
+//! impl Hash for Person {
+//!     fn hash<H: Hasher>(&self, state: &mut H) {
 //!         self.id.hash(state);
 //!         self.phone.hash(state);
 //!     }
@@ -56,15 +56,12 @@
 //! assert_eq!(hash::<_, SipHasher>(&person1), hash::<_, SipHasher>(&person2));
 //! ```
 
-#![unstable(feature = "hash",
-            reason = "module was recently redesigned")]
+#![stable(feature = "rust1", since = "1.0.0")]
 
 use prelude::*;
 
-use borrow::{Cow, ToOwned};
 use default::Default;
 use mem;
-use num::Int;
 
 pub use self::sip::SipHasher;
 
@@ -76,22 +73,123 @@ mod sip;
 /// to compute the hash. Specific implementations of this trait may specialize
 /// for particular instances of `H` in order to be able to optimize the hashing
 /// behavior.
+#[cfg(not(stage0))]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait Hash {
+    /// Feeds this value into the state given, updating the hasher as necessary.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn hash<H: Hasher>(&self, state: &mut H);
+
+    /// Feeds a slice of this type into the state provided.
+    #[unstable(feature = "hash", reason = "module was recently redesigned")]
+    fn hash_slice<H: Hasher>(data: &[Self], state: &mut H) where Self: Sized {
+        for piece in data {
+            piece.hash(state);
+        }
+    }
+}
+
+/// A hashable type.
+///
+/// The `H` type parameter is an abstract hash state that is used by the `Hash`
+/// to compute the hash. Specific implementations of this trait may specialize
+/// for particular instances of `H` in order to be able to optimize the hashing
+/// behavior.
+#[cfg(stage0)]
 pub trait Hash<H: Hasher> {
     /// Feeds this value into the state given, updating the hasher as necessary.
     fn hash(&self, state: &mut H);
 }
 
 /// A trait which represents the ability to hash an arbitrary stream of bytes.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub trait Hasher {
     /// Result type of one run of hashing generated by this hasher.
+    #[cfg(stage0)]
     type Output;
 
     /// Resets this hasher back to its initial state (as if it were just
     /// created).
+    #[cfg(stage0)]
     fn reset(&mut self);
 
     /// Completes a round of hashing, producing the output hash generated.
+    #[cfg(stage0)]
     fn finish(&self) -> Self::Output;
+
+    /// Completes a round of hashing, producing the output hash generated.
+    #[cfg(not(stage0))]
+    #[unstable(feature = "hash", reason = "module was recently redesigned")]
+    fn finish(&self) -> u64;
+
+    /// Writes some data into this `Hasher`
+    #[cfg(not(stage0))]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn write(&mut self, bytes: &[u8]);
+
+    /// Write a single `u8` into this hasher
+    #[cfg(not(stage0))]
+    #[inline]
+    #[unstable(feature = "hash", reason = "module was recently redesigned")]
+    fn write_u8(&mut self, i: u8) { self.write(&[i]) }
+    /// Write a single `u16` into this hasher.
+    #[cfg(not(stage0))]
+    #[inline]
+    #[unstable(feature = "hash", reason = "module was recently redesigned")]
+    fn write_u16(&mut self, i: u16) {
+        self.write(&unsafe { mem::transmute::<_, [u8; 2]>(i) })
+    }
+    /// Write a single `u32` into this hasher.
+    #[cfg(not(stage0))]
+    #[inline]
+    #[unstable(feature = "hash", reason = "module was recently redesigned")]
+    fn write_u32(&mut self, i: u32) {
+        self.write(&unsafe { mem::transmute::<_, [u8; 4]>(i) })
+    }
+    /// Write a single `u64` into this hasher.
+    #[cfg(not(stage0))]
+    #[inline]
+    #[unstable(feature = "hash", reason = "module was recently redesigned")]
+    fn write_u64(&mut self, i: u64) {
+        self.write(&unsafe { mem::transmute::<_, [u8; 8]>(i) })
+    }
+    /// Write a single `usize` into this hasher.
+    #[cfg(not(stage0))]
+    #[inline]
+    #[unstable(feature = "hash", reason = "module was recently redesigned")]
+    fn write_usize(&mut self, i: usize) {
+        if cfg!(target_pointer_width = "32") {
+            self.write_u32(i as u32)
+        } else {
+            self.write_u64(i as u64)
+        }
+    }
+
+    /// Write a single `i8` into this hasher.
+    #[cfg(not(stage0))]
+    #[inline]
+    #[unstable(feature = "hash", reason = "module was recently redesigned")]
+    fn write_i8(&mut self, i: i8) { self.write_u8(i as u8) }
+    /// Write a single `i16` into this hasher.
+    #[cfg(not(stage0))]
+    #[inline]
+    #[unstable(feature = "hash", reason = "module was recently redesigned")]
+    fn write_i16(&mut self, i: i16) { self.write_u16(i as u16) }
+    /// Write a single `i32` into this hasher.
+    #[cfg(not(stage0))]
+    #[inline]
+    #[unstable(feature = "hash", reason = "module was recently redesigned")]
+    fn write_i32(&mut self, i: i32) { self.write_u32(i as u32) }
+    /// Write a single `i64` into this hasher.
+    #[cfg(not(stage0))]
+    #[inline]
+    #[unstable(feature = "hash", reason = "module was recently redesigned")]
+    fn write_i64(&mut self, i: i64) { self.write_u64(i as u64) }
+    /// Write a single `isize` into this hasher.
+    #[cfg(not(stage0))]
+    #[inline]
+    #[unstable(feature = "hash", reason = "module was recently redesigned")]
+    fn write_isize(&mut self, i: isize) { self.write_usize(i as usize) }
 }
 
 /// A common bound on the `Hasher` parameter to `Hash` implementations in order
@@ -99,6 +197,7 @@ pub trait Hasher {
 #[unstable(feature = "hash",
            reason = "this trait will likely be replaced by io::Writer")]
 #[allow(missing_docs)]
+#[cfg(stage0)]
 pub trait Writer {
     fn write(&mut self, bytes: &[u8]);
 }
@@ -107,148 +206,292 @@ pub trait Writer {
 ///
 /// The specified value will be hashed with this hasher and then the resulting
 /// hash will be returned.
+#[cfg(stage0)]
 pub fn hash<T: Hash<H>, H: Hasher + Default>(value: &T) -> H::Output {
     let mut h: H = Default::default();
     value.hash(&mut h);
     h.finish()
 }
 
+/// Hash a value with the default SipHasher algorithm (two initial keys of 0).
+///
+/// The specified value will be hashed with this hasher and then the resulting
+/// hash will be returned.
+#[cfg(not(stage0))]
+#[unstable(feature = "hash", reason = "module was recently redesigned")]
+pub fn hash<T: Hash, H: Hasher + Default>(value: &T) -> u64 {
+    let mut h: H = Default::default();
+    value.hash(&mut h);
+    h.finish()
+}
+
 //////////////////////////////////////////////////////////////////////////////
 
-macro_rules! impl_hash {
-    ($ty:ident, $uty:ident) => {
-        impl<S: Writer + Hasher> Hash<S> for $ty {
-            #[inline]
-            fn hash(&self, state: &mut S) {
-                let a: [u8; ::$ty::BYTES] = unsafe {
-                    mem::transmute((*self as $uty).to_le() as $ty)
-                };
-                state.write(&a)
+#[cfg(stage0)]
+mod impls {
+    use prelude::*;
+
+    use mem;
+    use num::Int;
+    use super::*;
+
+    macro_rules! impl_hash {
+        ($ty:ident, $uty:ident) => {
+            impl<S: Writer + Hasher> Hash<S> for $ty {
+                #[inline]
+                fn hash(&self, state: &mut S) {
+                    let a: [u8; ::$ty::BYTES] = unsafe {
+                        mem::transmute(*self)
+                    };
+                    state.write(&a)
+                }
             }
         }
     }
-}
 
-impl_hash! { u8, u8 }
-impl_hash! { u16, u16 }
-impl_hash! { u32, u32 }
-impl_hash! { u64, u64 }
-impl_hash! { uint, uint }
-impl_hash! { i8, u8 }
-impl_hash! { i16, u16 }
-impl_hash! { i32, u32 }
-impl_hash! { i64, u64 }
-impl_hash! { int, uint }
-
-impl<S: Writer + Hasher> Hash<S> for bool {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        (*self as u8).hash(state);
+    impl_hash! { u8, u8 }
+    impl_hash! { u16, u16 }
+    impl_hash! { u32, u32 }
+    impl_hash! { u64, u64 }
+    impl_hash! { uint, uint }
+    impl_hash! { i8, u8 }
+    impl_hash! { i16, u16 }
+    impl_hash! { i32, u32 }
+    impl_hash! { i64, u64 }
+    impl_hash! { int, uint }
+
+    impl<S: Writer + Hasher> Hash<S> for bool {
+        #[inline]
+        fn hash(&self, state: &mut S) {
+            (*self as u8).hash(state);
+        }
     }
-}
 
-impl<S: Writer + Hasher> Hash<S> for char {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        (*self as u32).hash(state);
+    impl<S: Writer + Hasher> Hash<S> for char {
+        #[inline]
+        fn hash(&self, state: &mut S) {
+            (*self as u32).hash(state);
+        }
     }
-}
 
-impl<S: Writer + Hasher> Hash<S> for str {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        state.write(self.as_bytes());
-        0xffu8.hash(state)
+    impl<S: Writer + Hasher> Hash<S> for str {
+        #[inline]
+        fn hash(&self, state: &mut S) {
+            state.write(self.as_bytes());
+            0xffu8.hash(state)
+        }
     }
-}
 
-macro_rules! impl_hash_tuple {
-    () => (
-        impl<S: Hasher> Hash<S> for () {
-            #[inline]
-            fn hash(&self, _state: &mut S) {}
-        }
-    );
-
-    ( $($name:ident)+) => (
-        impl<S: Hasher, $($name: Hash<S>),*> Hash<S> for ($($name,)*) {
-            #[inline]
-            #[allow(non_snake_case)]
-            fn hash(&self, state: &mut S) {
-                match *self {
-                    ($(ref $name,)*) => {
-                        $(
-                            $name.hash(state);
-                        )*
+    macro_rules! impl_hash_tuple {
+        () => (
+            impl<S: Hasher> Hash<S> for () {
+                #[inline]
+                fn hash(&self, _state: &mut S) {}
+            }
+        );
+
+        ( $($name:ident)+) => (
+            impl<S: Hasher, $($name: Hash<S>),*> Hash<S> for ($($name,)*) {
+                #[inline]
+                #[allow(non_snake_case)]
+                fn hash(&self, state: &mut S) {
+                    match *self {
+                        ($(ref $name,)*) => {
+                            $(
+                                $name.hash(state);
+                            )*
+                        }
                     }
                 }
             }
+        );
+    }
+
+    impl_hash_tuple! {}
+    impl_hash_tuple! { A }
+    impl_hash_tuple! { A B }
+    impl_hash_tuple! { A B C }
+    impl_hash_tuple! { A B C D }
+    impl_hash_tuple! { A B C D E }
+    impl_hash_tuple! { A B C D E F }
+    impl_hash_tuple! { A B C D E F G }
+    impl_hash_tuple! { A B C D E F G H }
+    impl_hash_tuple! { A B C D E F G H I }
+    impl_hash_tuple! { A B C D E F G H I J }
+    impl_hash_tuple! { A B C D E F G H I J K }
+    impl_hash_tuple! { A B C D E F G H I J K L }
+
+    impl<S: Writer + Hasher, T: Hash<S>> Hash<S> for [T] {
+        #[inline]
+        fn hash(&self, state: &mut S) {
+            self.len().hash(state);
+            for elt in self {
+                elt.hash(state);
+            }
         }
-    );
-}
+    }
 
-impl_hash_tuple! {}
-impl_hash_tuple! { A }
-impl_hash_tuple! { A B }
-impl_hash_tuple! { A B C }
-impl_hash_tuple! { A B C D }
-impl_hash_tuple! { A B C D E }
-impl_hash_tuple! { A B C D E F }
-impl_hash_tuple! { A B C D E F G }
-impl_hash_tuple! { A B C D E F G H }
-impl_hash_tuple! { A B C D E F G H I }
-impl_hash_tuple! { A B C D E F G H I J }
-impl_hash_tuple! { A B C D E F G H I J K }
-impl_hash_tuple! { A B C D E F G H I J K L }
-
-impl<S: Writer + Hasher, T: Hash<S>> Hash<S> for [T] {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        self.len().hash(state);
-        for elt in self {
-            elt.hash(state);
+
+    impl<'a, S: Hasher, T: ?Sized + Hash<S>> Hash<S> for &'a T {
+        #[inline]
+        fn hash(&self, state: &mut S) {
+            (**self).hash(state);
         }
     }
-}
 
+    impl<'a, S: Hasher, T: ?Sized + Hash<S>> Hash<S> for &'a mut T {
+        #[inline]
+        fn hash(&self, state: &mut S) {
+            (**self).hash(state);
+        }
+    }
 
-impl<'a, S: Hasher, T: ?Sized + Hash<S>> Hash<S> for &'a T {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        (**self).hash(state);
+    impl<S: Writer + Hasher, T> Hash<S> for *const T {
+        #[inline]
+        fn hash(&self, state: &mut S) {
+            // NB: raw-pointer Hash does _not_ dereference
+            // to the target; it just gives you the pointer-bytes.
+            (*self as uint).hash(state);
+        }
     }
-}
 
-impl<'a, S: Hasher, T: ?Sized + Hash<S>> Hash<S> for &'a mut T {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        (**self).hash(state);
+    impl<S: Writer + Hasher, T> Hash<S> for *mut T {
+        #[inline]
+        fn hash(&self, state: &mut S) {
+            // NB: raw-pointer Hash does _not_ dereference
+            // to the target; it just gives you the pointer-bytes.
+            (*self as uint).hash(state);
+        }
     }
 }
 
-impl<S: Writer + Hasher, T> Hash<S> for *const T {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        // NB: raw-pointer Hash does _not_ dereference
-        // to the target; it just gives you the pointer-bytes.
-        (*self as uint).hash(state);
+#[cfg(not(stage0))]
+mod impls {
+    use prelude::*;
+
+    use slice;
+    use super::*;
+
+    macro_rules! impl_write {
+        ($(($ty:ident, $meth:ident),)*) => {$(
+            #[stable(feature = "rust1", since = "1.0.0")]
+            impl Hash for $ty {
+                fn hash<H: Hasher>(&self, state: &mut H) {
+                    state.$meth(*self)
+                }
+
+                fn hash_slice<H: Hasher>(data: &[$ty], state: &mut H) {
+                    let newlen = data.len() * ::$ty::BYTES;
+                    let ptr = data.as_ptr() as *const u8;
+                    state.write(unsafe { slice::from_raw_parts(ptr, newlen) })
+                }
+            }
+        )*}
     }
-}
 
-impl<S: Writer + Hasher, T> Hash<S> for *mut T {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        // NB: raw-pointer Hash does _not_ dereference
-        // to the target; it just gives you the pointer-bytes.
-        (*self as uint).hash(state);
+    impl_write! {
+        (u8, write_u8),
+        (u16, write_u16),
+        (u32, write_u32),
+        (u64, write_u64),
+        (usize, write_usize),
+        (i8, write_i8),
+        (i16, write_i16),
+        (i32, write_i32),
+        (i64, write_i64),
+        (isize, write_isize),
     }
-}
 
-impl<'a, T, B: ?Sized, S: Hasher> Hash<S> for Cow<'a, T, B>
-    where B: Hash<S> + ToOwned<T>
-{
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        Hash::hash(&**self, state)
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl Hash for bool {
+        fn hash<H: Hasher>(&self, state: &mut H) {
+            state.write_u8(*self as u8)
+        }
+    }
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl Hash for char {
+        fn hash<H: Hasher>(&self, state: &mut H) {
+            state.write_u32(*self as u32)
+        }
+    }
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl Hash for str {
+        fn hash<H: Hasher>(&self, state: &mut H) {
+            state.write(self.as_bytes());
+            state.write_u8(0xff)
+        }
+    }
+
+    macro_rules! impl_hash_tuple {
+        () => (
+            #[stable(feature = "rust1", since = "1.0.0")]
+            impl Hash for () {
+                fn hash<H: Hasher>(&self, _state: &mut H) {}
+            }
+        );
+
+        ( $($name:ident)+) => (
+            #[stable(feature = "rust1", since = "1.0.0")]
+            impl<$($name: Hash),*> Hash for ($($name,)*) {
+                #[allow(non_snake_case)]
+                fn hash<S: Hasher>(&self, state: &mut S) {
+                    let ($(ref $name,)*) = *self;
+                    $($name.hash(state);)*
+                }
+            }
+        );
+    }
+
+    impl_hash_tuple! {}
+    impl_hash_tuple! { A }
+    impl_hash_tuple! { A B }
+    impl_hash_tuple! { A B C }
+    impl_hash_tuple! { A B C D }
+    impl_hash_tuple! { A B C D E }
+    impl_hash_tuple! { A B C D E F }
+    impl_hash_tuple! { A B C D E F G }
+    impl_hash_tuple! { A B C D E F G H }
+    impl_hash_tuple! { A B C D E F G H I }
+    impl_hash_tuple! { A B C D E F G H I J }
+    impl_hash_tuple! { A B C D E F G H I J K }
+    impl_hash_tuple! { A B C D E F G H I J K L }
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<T: Hash> Hash for [T] {
+        fn hash<H: Hasher>(&self, state: &mut H) {
+            self.len().hash(state);
+            Hash::hash_slice(self, state)
+        }
+    }
+
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<'a, T: ?Sized + Hash> Hash for &'a T {
+        fn hash<H: Hasher>(&self, state: &mut H) {
+            (**self).hash(state);
+        }
+    }
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<'a, T: ?Sized + Hash> Hash for &'a mut T {
+        fn hash<H: Hasher>(&self, state: &mut H) {
+            (**self).hash(state);
+        }
+    }
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<T> Hash for *const T {
+        fn hash<H: Hasher>(&self, state: &mut H) {
+            state.write_usize(*self as usize)
+        }
+    }
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<T> Hash for *mut T {
+        fn hash<H: Hasher>(&self, state: &mut H) {
+            state.write_usize(*self as usize)
+        }
     }
 }
diff --git a/src/libcore/hash/sip.rs b/src/libcore/hash/sip.rs
index d405d0d28be..ce8917cc205 100644
--- a/src/libcore/hash/sip.rs
+++ b/src/libcore/hash/sip.rs
@@ -15,7 +15,9 @@
 use prelude::*;
 use default::Default;
 
-use super::{Hasher, Writer};
+use super::Hasher;
+#[cfg(stage0)]
+use super::Writer;
 
 /// An implementation of SipHash 2-4.
 ///
@@ -30,6 +32,7 @@ use super::{Hasher, Writer};
 /// strong, this implementation has not been reviewed for such purposes.
 /// As such, all cryptographic uses of this implementation are strongly
 /// discouraged.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct SipHasher {
     k0: u64,
     k1: u64,
@@ -88,12 +91,14 @@ macro_rules! compress {
 impl SipHasher {
     /// Creates a new `SipHasher` with the two initial keys set to 0.
     #[inline]
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new() -> SipHasher {
         SipHasher::new_with_keys(0, 0)
     }
 
     /// Creates a `SipHasher` that is keyed off the provided keys.
     #[inline]
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher {
         let mut state = SipHasher {
             k0: key0,
@@ -114,10 +119,16 @@ impl SipHasher {
     #[unstable(feature = "hash")]
     #[deprecated(since = "1.0.0", reason = "renamed to finish")]
     pub fn result(&self) -> u64 { self.finish() }
-}
 
-impl Writer for SipHasher {
-    #[inline]
+    fn reset(&mut self) {
+        self.length = 0;
+        self.v0 = self.k0 ^ 0x736f6d6570736575;
+        self.v1 = self.k1 ^ 0x646f72616e646f6d;
+        self.v2 = self.k0 ^ 0x6c7967656e657261;
+        self.v3 = self.k1 ^ 0x7465646279746573;
+        self.ntail = 0;
+    }
+
     fn write(&mut self, msg: &[u8]) {
         let length = msg.len();
         self.length += length;
@@ -164,16 +175,28 @@ impl Writer for SipHasher {
     }
 }
 
+#[cfg(stage0)]
+impl Writer for SipHasher {
+    #[inline]
+    fn write(&mut self, msg: &[u8]) {
+        self.write(msg)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Hasher for SipHasher {
+    #[cfg(stage0)]
     type Output = u64;
 
+    #[cfg(stage0)]
     fn reset(&mut self) {
-        self.length = 0;
-        self.v0 = self.k0 ^ 0x736f6d6570736575;
-        self.v1 = self.k1 ^ 0x646f72616e646f6d;
-        self.v2 = self.k0 ^ 0x6c7967656e657261;
-        self.v3 = self.k1 ^ 0x7465646279746573;
-        self.ntail = 0;
+        self.reset();
+    }
+
+    #[inline]
+    #[cfg(not(stage0))]
+    fn write(&mut self, msg: &[u8]) {
+        self.write(msg)
     }
 
     fn finish(&self) -> u64 {
@@ -199,6 +222,7 @@ impl Hasher for SipHasher {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Clone for SipHasher {
     #[inline]
     fn clone(&self) -> SipHasher {
@@ -216,6 +240,7 @@ impl Clone for SipHasher {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Default for SipHasher {
     fn default() -> SipHasher {
         SipHasher::new()
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index 050c144b742..b2ee9596387 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -50,10 +50,10 @@ pub type GlueFn = extern "Rust" fn(*const i8);
 #[derive(Copy)]
 pub struct TyDesc {
     // sizeof(T)
-    pub size: uint,
+    pub size: usize,
 
     // alignof(T)
-    pub align: uint,
+    pub align: usize,
 
     // Called when a value of type `T` is no longer needed
     pub drop_glue: GlueFn,
@@ -186,15 +186,15 @@ extern "rust-intrinsic" {
     /// would *exactly* overwrite a value. When laid out in vectors
     /// and structures there may be additional padding between
     /// elements.
-    pub fn size_of<T>() -> uint;
+    pub fn size_of<T>() -> usize;
 
     /// Move a value to an uninitialized memory location.
     ///
     /// Drop glue is not run on the destination.
     pub fn move_val_init<T>(dst: &mut T, src: T);
 
-    pub fn min_align_of<T>() -> uint;
-    pub fn pref_align_of<T>() -> uint;
+    pub fn min_align_of<T>() -> usize;
+    pub fn pref_align_of<T>() -> usize;
 
     /// Get a static pointer to a type descriptor.
     pub fn get_tydesc<T: ?Sized>() -> *const TyDesc;
@@ -253,7 +253,7 @@ extern "rust-intrinsic" {
     ///
     /// This is implemented as an intrinsic to avoid converting to and from an
     /// integer, since the conversion would throw away aliasing information.
-    pub fn offset<T>(dst: *const T, offset: int) -> *const T;
+    pub fn offset<T>(dst: *const T, offset: isize) -> *const T;
 
     /// Copies `count * size_of<T>` bytes from `src` to `dst`. The source
     /// and destination may *not* overlap.
@@ -294,7 +294,7 @@ extern "rust-intrinsic" {
     /// }
     /// ```
     #[unstable(feature = "core")]
-    pub fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: uint);
+    pub fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: usize);
 
     /// Copies `count * size_of<T>` bytes from `src` to `dst`. The source
     /// and destination may overlap.
@@ -324,13 +324,13 @@ extern "rust-intrinsic" {
     /// ```
     ///
     #[unstable(feature = "core")]
-    pub fn copy_memory<T>(dst: *mut T, src: *const T, count: uint);
+    pub fn copy_memory<T>(dst: *mut T, src: *const T, count: usize);
 
     /// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
     /// bytes of memory starting at `dst` to `c`.
     #[unstable(feature = "core",
                reason = "uncertain about naming and semantics")]
-    pub fn set_memory<T>(dst: *mut T, val: u8, count: uint);
+    pub fn set_memory<T>(dst: *mut T, val: u8, count: usize);
 
     /// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with
     /// a size of `count` * `size_of::<T>()` and an alignment of
@@ -338,19 +338,19 @@ extern "rust-intrinsic" {
     ///
     /// The volatile parameter parameter is set to `true`, so it will not be optimized out.
     pub fn volatile_copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T,
-                                                  count: uint);
+                                                  count: usize);
     /// Equivalent to the appropriate `llvm.memmove.p0i8.0i8.*` intrinsic, with
     /// a size of `count` * `size_of::<T>()` and an alignment of
     /// `min_align_of::<T>()`
     ///
     /// The volatile parameter parameter is set to `true`, so it will not be optimized out.
-    pub fn volatile_copy_memory<T>(dst: *mut T, src: *const T, count: uint);
+    pub fn volatile_copy_memory<T>(dst: *mut T, src: *const T, count: usize);
     /// Equivalent to the appropriate `llvm.memset.p0i8.*` intrinsic, with a
     /// size of `count` * `size_of::<T>()` and an alignment of
     /// `min_align_of::<T>()`.
     ///
     /// The volatile parameter parameter is set to `true`, so it will not be optimized out.
-    pub fn volatile_set_memory<T>(dst: *mut T, val: u8, count: uint);
+    pub fn volatile_set_memory<T>(dst: *mut T, val: u8, count: usize);
 
     /// Perform a volatile load from the `src` pointer.
     pub fn volatile_load<T>(src: *const T) -> T;
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index fffba1561a3..8fb10b5b2dc 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -62,6 +62,7 @@ use clone::Clone;
 use cmp;
 use cmp::Ord;
 use default::Default;
+use marker;
 use mem;
 use num::{ToPrimitive, Int};
 use ops::{Add, Deref, FnMut};
@@ -113,9 +114,9 @@ impl<'a, I: Iterator + ?Sized> Iterator for &'a mut I {
 #[rustc_on_unimplemented="a collection of type `{Self}` cannot be \
                           built from an iterator over elements of type `{A}`"]
 pub trait FromIterator<A> {
-    /// Build a container with elements from an external iterator.
+    /// Build a container with elements from something iterable.
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn from_iter<T: Iterator<Item=A>>(iterator: T) -> Self;
+    fn from_iter<T: IntoIterator<Item=A>>(iterator: T) -> Self;
 }
 
 /// Conversion into an `Iterator`
@@ -147,7 +148,7 @@ impl<I: Iterator> IntoIterator for I {
 pub trait Extend<A> {
     /// Extend a container with the elements yielded by an arbitrary iterator
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn extend<T: Iterator<Item=A>>(&mut self, iterator: T);
+    fn extend<T: IntoIterator<Item=A>>(&mut self, iterable: T);
 }
 
 /// An extension trait providing numerous methods applicable to all iterators.
@@ -332,7 +333,7 @@ pub trait IteratorExt: Iterator + Sized {
     ///
     /// ```
     /// let xs = [100, 200, 300];
-    /// let mut it = xs.iter().map(|x| *x).peekable();
+    /// let mut it = xs.iter().cloned().peekable();
     /// assert_eq!(*it.peek().unwrap(), 100);
     /// assert_eq!(it.next().unwrap(), 100);
     /// assert_eq!(it.next().unwrap(), 200);
@@ -522,11 +523,11 @@ pub trait IteratorExt: Iterator + Sized {
     ///
     /// let a = [1, 4, 2, 3, 8, 9, 6];
     /// let sum = a.iter()
-    ///             .map(|&x| x)
-    ///             .inspect(|&x| println!("filtering {}", x))
-    ///             .filter(|&x| x % 2 == 0)
-    ///             .inspect(|&x| println!("{} made it through", x))
-    ///             .sum();
+    ///            .map(|x| *x)
+    ///            .inspect(|&x| println!("filtering {}", x))
+    ///            .filter(|&x| x % 2 == 0)
+    ///            .inspect(|&x| println!("{} made it through", x))
+    ///            .sum();
     /// println!("{}", sum);
     /// ```
     #[inline]
@@ -561,7 +562,7 @@ pub trait IteratorExt: Iterator + Sized {
     ///
     /// ```
     /// let a = [1, 2, 3, 4, 5];
-    /// let b: Vec<_> = a.iter().map(|&x| x).collect();
+    /// let b: Vec<_> = a.iter().cloned().collect();
     /// assert_eq!(a, b);
     /// ```
     #[inline]
@@ -937,7 +938,7 @@ pub trait IteratorExt: Iterator + Sized {
     ///
     /// ```
     /// let a = [(1, 2), (3, 4)];
-    /// let (left, right): (Vec<_>, Vec<_>) = a.iter().map(|&x| x).unzip();
+    /// let (left, right): (Vec<_>, Vec<_>) = a.iter().cloned().unzip();
     /// assert_eq!([1, 3], left);
     /// assert_eq!([2, 4], right);
     /// ```
@@ -947,7 +948,7 @@ pub trait IteratorExt: Iterator + Sized {
         FromB: Default + Extend<B>,
         Self: Iterator<Item=(A, B)>,
     {
-        struct SizeHint<A>(usize, Option<usize>);
+        struct SizeHint<A>(usize, Option<usize>, marker::PhantomData<A>);
         impl<A> Iterator for SizeHint<A> {
             type Item = A;
 
@@ -961,8 +962,8 @@ pub trait IteratorExt: Iterator + Sized {
         let mut ts: FromA = Default::default();
         let mut us: FromB = Default::default();
 
-        ts.extend(SizeHint(lo, hi));
-        us.extend(SizeHint(lo, hi));
+        ts.extend(SizeHint(lo, hi, marker::PhantomData));
+        us.extend(SizeHint(lo, hi, marker::PhantomData));
 
         for (t, u) in self {
             ts.extend(Some(t).into_iter());
@@ -1142,7 +1143,7 @@ pub trait AdditiveIterator<A> {
     /// use std::iter::AdditiveIterator;
     ///
     /// let a = [1i32, 2, 3, 4, 5];
-    /// let mut it = a.iter().map(|&x| x);
+    /// let mut it = a.iter().cloned();
     /// assert!(it.sum() == 15);
     /// ```
     fn sum(self) -> A;
@@ -1305,6 +1306,23 @@ impl<T, D, I> ExactSizeIterator for Cloned<I> where
     I: ExactSizeIterator<Item=D>,
 {}
 
+#[unstable(feature = "core", reason = "trait is experimental")]
+impl<T, D, I> RandomAccessIterator for Cloned<I> where
+    T: Clone,
+    D: Deref<Target=T>,
+    I: RandomAccessIterator<Item=D>
+{
+    #[inline]
+    fn indexable(&self) -> usize {
+        self.it.indexable()
+    }
+
+    #[inline]
+    fn idx(&mut self, index: usize) -> Option<T> {
+        self.it.idx(index).cloned()
+    }
+}
+
 /// An iterator that repeats endlessly
 #[derive(Clone)]
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
@@ -2047,8 +2065,8 @@ pub struct Scan<I, St, F> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<B, I: Iterator, St, F> Iterator for Scan<I, St, F> where
-    F: FnMut(&mut St, I::Item) -> Option<B>,
+impl<A, B, I: Iterator<Item=A>, St, F> Iterator for Scan<I, St, F> where
+    F: FnMut(&mut St, A) -> Option<B>,
 {
     type Item = B;
 
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index f0c60ffe4bf..3c58480ff0c 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -126,7 +126,6 @@ pub mod default;
 
 pub mod any;
 pub mod atomic;
-pub mod borrow;
 pub mod cell;
 pub mod char;
 pub mod panicking;
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index 56e1c5dedc1..d284eb34179 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -26,6 +26,10 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use clone::Clone;
+use cmp;
+use option::Option;
+use hash::Hash;
+use hash::Hasher;
 
 /// Types able to be transferred across thread boundaries.
 #[unstable(feature = "core",
@@ -37,12 +41,11 @@ pub unsafe trait Send: 'static {
     // empty.
 }
 /// Types able to be transferred across thread boundaries.
-#[unstable(feature = "core",
-           reason = "will be overhauled with new lifetime rules; see RFC 458")]
+#[stable(feature = "rust1", since = "1.0.0")]
 #[lang="send"]
 #[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"]
 #[cfg(not(stage0))]
-pub unsafe trait Send {
+pub unsafe trait Send : MarkerTrait {
     // empty.
 }
 
@@ -50,7 +53,7 @@ pub unsafe trait Send {
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang="sized"]
 #[rustc_on_unimplemented = "`{Self}` does not have a constant size known at compile-time"]
-pub trait Sized {
+pub trait Sized : MarkerTrait {
     // Empty.
 }
 
@@ -155,7 +158,7 @@ pub trait Sized {
 /// change: that second example would fail to compile if we made `Foo` non-`Copy`.
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang="copy"]
-pub trait Copy {
+pub trait Copy : MarkerTrait {
     // Empty.
 }
 
@@ -204,236 +207,179 @@ pub trait Copy {
 /// around the value(s) which can be mutated when behind a `&`
 /// reference; not doing this is undefined behaviour (for example,
 /// `transmute`-ing from `&T` to `&mut T` is illegal).
-#[unstable(feature = "core",
-           reason = "will be overhauled with new lifetime rules; see RFC 458")]
+#[stable(feature = "rust1", since = "1.0.0")]
 #[lang="sync"]
 #[rustc_on_unimplemented = "`{Self}` cannot be shared between threads safely"]
-pub unsafe trait Sync {
+pub unsafe trait Sync : MarkerTrait {
     // Empty
 }
 
-/// A marker type that indicates to the compiler that the instances
-/// of the type itself owns instances of the type parameter `T`.
-///
-/// This is used to indicate that one or more instances of the type
-/// `T` could be dropped when instances of the type itself is dropped,
-/// though that may not be apparent from the other structure of the
-/// type itself. For example, the type may hold a `*mut T`, which the
-/// compiler does not automatically treat as owned.
+/// A type which is considered "not POD", meaning that it is not
+/// implicitly copyable. This is typically embedded in other types to
+/// ensure that they are never copied, even if they lack a destructor.
 #[unstable(feature = "core",
-           reason = "Newly added to deal with scoping and destructor changes")]
-#[lang="phantom_data"]
-#[derive(PartialEq, Eq, PartialOrd, Ord)]
-pub struct PhantomData<T: ?Sized>;
+           reason = "likely to change with new variance strategy")]
+#[lang="no_copy_bound"]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
+pub struct NoCopy;
 
-impl<T: ?Sized> Copy for PhantomData<T> {}
-impl<T: ?Sized> Clone for PhantomData<T> {
-    fn clone(&self) -> PhantomData<T> { *self }
+/// A type which is considered managed by the GC. This is typically
+/// embedded in other types.
+#[unstable(feature = "core",
+           reason = "likely to change with new variance strategy")]
+#[lang="managed_bound"]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
+pub struct Managed;
+
+macro_rules! impls{
+    ($t: ident) => (
+        #[cfg(stage0)]
+        impl<T:?Sized, S: Hasher> Hash<S> for $t<T> {
+            #[inline]
+            fn hash(&self, _: &mut S) {
+            }
+        }
+        #[cfg(not(stage0))]
+        impl<T:?Sized> Hash for $t<T> {
+            #[inline]
+            fn hash<H: Hasher>(&self, _: &mut H) {
+            }
+        }
+
+        impl<T:?Sized> cmp::PartialEq for $t<T> {
+            fn eq(&self, _other: &$t<T>) -> bool {
+                true
+            }
+        }
+
+        impl<T:?Sized> cmp::Eq for $t<T> {
+        }
+
+        impl<T:?Sized> cmp::PartialOrd for $t<T> {
+            fn partial_cmp(&self, _other: &$t<T>) -> Option<cmp::Ordering> {
+                Option::Some(cmp::Ordering::Equal)
+            }
+        }
+
+        impl<T:?Sized> cmp::Ord for $t<T> {
+            fn cmp(&self, _other: &$t<T>) -> cmp::Ordering {
+                cmp::Ordering::Equal
+            }
+        }
+
+        impl<T:?Sized> Copy for $t<T> { }
+
+        impl<T:?Sized> Clone for $t<T> {
+            fn clone(&self) -> $t<T> {
+                $t
+            }
+        }
+        )
 }
 
-/// A marker type whose type parameter `T` is considered to be
-/// covariant with respect to the type itself. This is (typically)
-/// used to indicate that an instance of the type `T` is being stored
-/// into memory and read from, even though that may not be apparent.
-///
-/// For more information about variance, refer to this Wikipedia
-/// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
-///
-/// *Note:* It is very unusual to have to add a covariant constraint.
-/// If you are not sure, you probably want to use `InvariantType`.
+/// `MarkerTrait` is intended to be used as the supertrait for traits
+/// that don't have any methods but instead serve just to designate
+/// categories of types. An example would be the `Send` trait, which
+/// indicates types that are sendable: `Send` does not itself offer
+/// any methods, but instead is used to gate access to data.
+///
+/// FIXME. Better documentation needed here!
+pub trait MarkerTrait : PhantomFn<Self> { }
+impl<T:?Sized> MarkerTrait for T { }
+
+/// `PhantomFn` is a marker trait for use with traits that contain
+/// type or lifetime parameters that do not appear in any of their
+/// methods. In that case, you can either remove those parameters, or
+/// add a `PhantomFn` supertrait that reflects the signature of
+/// methods that compiler should "pretend" exists. This most commonly
+/// occurs for traits with no methods: in that particular case, you
+/// can extend `MarkerTrait`, which is equivalent to
+/// `PhantomFn<Self>`.
 ///
 /// # Example
 ///
-/// Given a struct `S` that includes a type parameter `T`
-/// but does not actually *reference* that type parameter:
+/// As an example, consider a trait with no methods like `Even`, meant
+/// to represent types that are "even":
 ///
-/// ```ignore
-/// use std::mem;
-///
-/// struct S<T> { x: *() }
-/// fn get<T>(s: &S<T>) -> T {
-///    unsafe {
-///        let x: *T = mem::transmute(s.x);
-///        *x
-///    }
-/// }
+/// ```rust,ignore
+/// trait Even { }
 /// ```
 ///
-/// The type system would currently infer that the value of
-/// the type parameter `T` is irrelevant, and hence a `S<int>` is
-/// a subtype of `S<Box<int>>` (or, for that matter, `S<U>` for
-/// any `U`). But this is incorrect because `get()` converts the
-/// `*()` into a `*T` and reads from it. Therefore, we should include the
-/// a marker field `CovariantType<T>` to inform the type checker that
-/// `S<T>` is a subtype of `S<U>` if `T` is a subtype of `U`
-/// (for example, `S<&'static int>` is a subtype of `S<&'a int>`
-/// for some lifetime `'a`, but not the other way around).
-#[unstable(feature = "core",
-           reason = "likely to change with new variance strategy")]
-#[lang="covariant_type"]
-#[derive(PartialEq, Eq, PartialOrd, Ord)]
-pub struct CovariantType<T: ?Sized>;
-
-impl<T: ?Sized> Copy for CovariantType<T> {}
-impl<T: ?Sized> Clone for CovariantType<T> {
-    fn clone(&self) -> CovariantType<T> { *self }
-}
-
-/// A marker type whose type parameter `T` is considered to be
-/// contravariant with respect to the type itself. This is (typically)
-/// used to indicate that an instance of the type `T` will be consumed
-/// (but not read from), even though that may not be apparent.
+/// In this case, because the implicit parameter `Self` is unused, the
+/// compiler will issue an error. The only purpose of this trait is to
+/// categorize types (and hence instances of those types) as "even" or
+/// not, so if we *were* going to have a method, it might look like:
 ///
-/// For more information about variance, refer to this Wikipedia
-/// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
+/// ```rust,ignore
+/// trait Even {
+///     fn is_even(self) -> bool { true }
+/// }
+/// ```
 ///
-/// *Note:* It is very unusual to have to add a contravariant constraint.
-/// If you are not sure, you probably want to use `InvariantType`.
+/// Therefore, we can model a method like this as follows:
 ///
-/// # Example
+/// ```rust
+/// use std::marker::PhantomFn;
+/// trait Even : PhantomFn<Self> { }
+/// ```
 ///
-/// Given a struct `S` that includes a type parameter `T`
-/// but does not actually *reference* that type parameter:
+/// Another equivalent, but clearer, option would be to use
+/// `MarkerTrait`:
 ///
+/// ```rust
+/// use std::marker::MarkerTrait;
+/// trait Even : MarkerTrait { }
 /// ```
-/// use std::mem;
-///
-/// struct S<T> { x: *const () }
-/// fn get<T>(s: &S<T>, v: T) {
-///    unsafe {
-///        let x: fn(T) = mem::transmute(s.x);
-///        x(v)
-///    }
-/// }
-/// ```
-///
-/// The type system would currently infer that the value of
-/// the type parameter `T` is irrelevant, and hence a `S<int>` is
-/// a subtype of `S<Box<int>>` (or, for that matter, `S<U>` for
-/// any `U`). But this is incorrect because `get()` converts the
-/// `*()` into a `fn(T)` and then passes a value of type `T` to it.
-///
-/// Supplying a `ContravariantType` marker would correct the
-/// problem, because it would mark `S` so that `S<T>` is only a
-/// subtype of `S<U>` if `U` is a subtype of `T`; given that the
-/// function requires arguments of type `T`, it must also accept
-/// arguments of type `U`, hence such a conversion is safe.
-#[unstable(feature = "core",
-           reason = "likely to change with new variance strategy")]
-#[lang="contravariant_type"]
-#[derive(PartialEq, Eq, PartialOrd, Ord)]
-pub struct ContravariantType<T: ?Sized>;
-
-impl<T: ?Sized> Copy for ContravariantType<T> {}
-impl<T: ?Sized> Clone for ContravariantType<T> {
-    fn clone(&self) -> ContravariantType<T> { *self }
-}
-
-/// A marker type whose type parameter `T` is considered to be
-/// invariant with respect to the type itself. This is (typically)
-/// used to indicate that instances of the type `T` may be read or
-/// written, even though that may not be apparent.
 ///
-/// For more information about variance, refer to this Wikipedia
-/// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
+/// # Parameters
 ///
-/// # Example
+/// - `A` represents the type of the method's argument. You can use a
+///   tuple to represent "multiple" arguments. Any types appearing here
+///   will be considered "contravariant".
+/// - `R`, if supplied, represents the method's return type. This defaults
+///   to `()` as it is rarely needed.
 ///
-/// The Cell type is an example of an `InvariantType` which uses unsafe
-/// code to achieve "interior" mutability:
+/// # Additional reading
 ///
-/// ```
-/// struct Cell<T> { value: T }
-/// ```
+/// More details and background can be found in [RFC 738][738].
 ///
-/// The type system would infer that `value` is only read here
-/// and never written, but in fact `Cell` uses unsafe code to achieve
-/// interior mutability. In order to get correct behavior, the
-/// `InvariantType` marker must be applied.
-#[unstable(feature = "core",
-           reason = "likely to change with new variance strategy")]
-#[lang="invariant_type"]
-#[derive(PartialEq, Eq, PartialOrd, Ord)]
-pub struct InvariantType<T: ?Sized>;
-
-#[unstable(feature = "core",
-           reason = "likely to change with new variance strategy")]
-impl<T: ?Sized> Copy for InvariantType<T> {}
-#[unstable(feature = "core",
-           reason = "likely to change with new variance strategy")]
-impl<T: ?Sized> Clone for InvariantType<T> {
-    fn clone(&self) -> InvariantType<T> { *self }
-}
-
-/// As `CovariantType`, but for lifetime parameters. Using
-/// `CovariantLifetime<'a>` indicates that it is ok to substitute
-/// a *longer* lifetime for `'a` than the one you originally
-/// started with (e.g., you could convert any lifetime `'foo` to
-/// `'static`). You almost certainly want `ContravariantLifetime`
-/// instead, or possibly `InvariantLifetime`. The only case where
-/// it would be appropriate is that you have a (type-casted, and
-/// hence hidden from the type system) function pointer with a
-/// signature like `fn(&'a T)` (and no other uses of `'a`). In
-/// this case, it is ok to substitute a larger lifetime for `'a`
-/// (e.g., `fn(&'static T)`), because the function is only
-/// becoming more selective in terms of what it accepts as
-/// argument.
-///
-/// For more information about variance, refer to this Wikipedia
-/// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
-#[unstable(feature = "core",
-           reason = "likely to change with new variance strategy")]
-#[lang="covariant_lifetime"]
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
-pub struct CovariantLifetime<'a>;
+/// [738]: https://github.com/rust-lang/rfcs/blob/master/text/0738-variance.md
+#[lang="phantom_fn"]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait PhantomFn<A:?Sized,R:?Sized=()> { }
 
-/// As `ContravariantType`, but for lifetime parameters. Using
-/// `ContravariantLifetime<'a>` indicates that it is ok to
-/// substitute a *shorter* lifetime for `'a` than the one you
-/// originally started with (e.g., you could convert `'static` to
-/// any lifetime `'foo`). This is appropriate for cases where you
-/// have an unsafe pointer that is actually a pointer into some
-/// memory with lifetime `'a`, and thus you want to limit the
-/// lifetime of your data structure to `'a`. An example of where
-/// this is used is the iterator for vectors.
-///
-/// For more information about variance, refer to this Wikipedia
-/// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
-#[unstable(feature = "core",
-           reason = "likely to change with new variance strategy")]
-#[lang="contravariant_lifetime"]
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
-pub struct ContravariantLifetime<'a>;
+#[cfg(stage0)] // built into the trait matching system after stage0
+impl<A:?Sized, R:?Sized, U:?Sized> PhantomFn<A,R> for U { }
 
-/// As `InvariantType`, but for lifetime parameters. Using
-/// `InvariantLifetime<'a>` indicates that it is not ok to
-/// substitute any other lifetime for `'a` besides its original
-/// value. This is appropriate for cases where you have an unsafe
-/// pointer that is actually a pointer into memory with lifetime `'a`,
-/// and this pointer is itself stored in an inherently mutable
-/// location (such as a `Cell`).
-#[unstable(feature = "core",
-           reason = "likely to change with new variance strategy")]
-#[lang="invariant_lifetime"]
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
-pub struct InvariantLifetime<'a>;
+/// Specific to stage0. You should not be seeing these docs!
+#[cfg(stage0)]
+#[lang="covariant_type"] // only relevant to stage0
+pub struct PhantomData<T:?Sized>;
 
-/// A type which is considered "not POD", meaning that it is not
-/// implicitly copyable. This is typically embedded in other types to
-/// ensure that they are never copied, even if they lack a destructor.
-#[unstable(feature = "core",
-           reason = "likely to change with new variance strategy")]
-#[lang="no_copy_bound"]
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
-pub struct NoCopy;
+/// `PhantomData` is a way to tell the compiler about fake fields.
+/// Phantom data is required whenever type parameters are not used.
+/// The idea is that if the compiler encounters a `PhantomData<T>`
+/// instance, it will behave *as if* an instance of the type `T` were
+/// present for the purpose of various automatic analyses.
+///
+/// For example, embedding a `PhantomData<T>` will inform the compiler
+/// that one or more instances of the type `T` could be dropped when
+/// instances of the type itself is dropped, though that may not be
+/// apparent from the other structure of the type itself. This is
+/// commonly necessary if the structure is using an unsafe pointer
+/// like `*mut T` whose referent may be dropped when the type is
+/// dropped, as a `*mut T` is otherwise not treated as owned.
+///
+/// FIXME. Better documentation and examples of common patterns needed
+/// here! For now, please see [RFC 738][738] for more information.
+///
+/// [738]: https://github.com/rust-lang/rfcs/blob/master/text/0738-variance.md
+#[cfg(not(stage0))]
+#[lang="phantom_data"]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct PhantomData<T:?Sized>;
 
-/// A type which is considered managed by the GC. This is typically
-/// embedded in other types.
-#[unstable(feature = "core",
-           reason = "likely to change with new variance strategy")]
-#[lang="managed_bound"]
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
-pub struct Managed;
+impls! { PhantomData }
 
 #[cfg(not(stage0))]
 mod impls {
@@ -442,3 +388,40 @@ mod impls {
     unsafe impl<'a, T: Sync + ?Sized> Send for &'a T {}
     unsafe impl<'a, T: Send + ?Sized> Send for &'a mut T {}
 }
+
+/// Old-style marker trait. Deprecated.
+#[unstable(feature = "core", reason = "deprecated")]
+#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<&'a ()>`")]
+#[lang="contravariant_lifetime"]
+pub struct ContravariantLifetime<'a>;
+
+/// Old-style marker trait. Deprecated.
+#[unstable(feature = "core", reason = "deprecated")]
+#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<fn(&'a ())>`")]
+#[lang="covariant_lifetime"]
+pub struct CovariantLifetime<'a>;
+
+/// Old-style marker trait. Deprecated.
+#[unstable(feature = "core", reason = "deprecated")]
+#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<Cell<&'a ()>>`")]
+#[lang="invariant_lifetime"]
+pub struct InvariantLifetime<'a>;
+
+/// Old-style marker trait. Deprecated.
+#[unstable(feature = "core", reason = "deprecated")]
+#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<fn(T)>`")]
+#[lang="contravariant_type"]
+pub struct ContravariantType<T>;
+
+/// Old-style marker trait. Deprecated.
+#[unstable(feature = "core", reason = "deprecated")]
+#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<T>`")]
+#[lang="covariant_type"]
+#[cfg(not(stage0))]
+pub struct CovariantType<T>;
+
+/// Old-style marker trait. Deprecated.
+#[unstable(feature = "core", reason = "deprecated")]
+#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<Cell<T>>`")]
+#[lang="invariant_type"]
+pub struct InvariantType<T>;
diff --git a/src/libcore/nonzero.rs b/src/libcore/nonzero.rs
index 5644f763069..230587b726f 100644
--- a/src/libcore/nonzero.rs
+++ b/src/libcore/nonzero.rs
@@ -10,15 +10,14 @@
 
 //! Exposes the NonZero lang item which provides optimization hints.
 
+use marker::{Sized, MarkerTrait};
 use ops::Deref;
-use ptr::Unique;
 
 /// Unsafe trait to indicate what types are usable with the NonZero struct
-pub unsafe trait Zeroable {}
+pub unsafe trait Zeroable : MarkerTrait {}
 
-unsafe impl<T> Zeroable for *const T {}
-unsafe impl<T> Zeroable for *mut T {}
-unsafe impl<T> Zeroable for Unique<T> { }
+unsafe impl<T:?Sized> Zeroable for *const T {}
+unsafe impl<T:?Sized> Zeroable for *mut T {}
 unsafe impl Zeroable for isize {}
 unsafe impl Zeroable for usize {}
 unsafe impl Zeroable for i8 {}
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index 9a89682127f..abfef72a5db 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -149,7 +149,7 @@ use clone::Clone;
 use cmp::{Eq, Ord};
 use default::Default;
 use iter::{ExactSizeIterator};
-use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator};
+use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator, IntoIterator};
 use mem;
 use ops::{Deref, FnOnce};
 use result::Result::{Ok, Err};
@@ -909,7 +909,7 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn from_iter<I: Iterator<Item=Option<A>>>(iter: I) -> Option<V> {
+    fn from_iter<I: IntoIterator<Item=Option<A>>>(iter: I) -> Option<V> {
         // FIXME(#11084): This could be replaced with Iterator::scan when this
         // performance bug is closed.
 
@@ -934,7 +934,7 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> {
             }
         }
 
-        let mut adapter = Adapter { iter: iter, found_none: false };
+        let mut adapter = Adapter { iter: iter.into_iter(), found_none: false };
         let v: V = FromIterator::from_iter(adapter.by_ref());
 
         if adapter.found_none {
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index 072c60c7036..16b84dcf18e 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -91,8 +91,10 @@
 use mem;
 use clone::Clone;
 use intrinsics;
+use ops::Deref;
 use option::Option::{self, Some, None};
-use marker::{self, Send, Sized, Sync};
+use marker::{PhantomData, Send, Sized, Sync};
+use nonzero::NonZero;
 
 use cmp::{PartialEq, Eq, Ord, PartialOrd};
 use cmp::Ordering::{self, Less, Equal, Greater};
@@ -303,7 +305,7 @@ impl<T> PtrExt for *const T {
 
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_null(self) -> bool { self as usize == 0 }
+    fn is_null(self) -> bool { self == 0 as *const T }
 
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -330,7 +332,7 @@ impl<T> PtrExt for *mut T {
 
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_null(self) -> bool { self as usize == 0 }
+    fn is_null(self) -> bool { self == 0 as *mut T }
 
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -517,15 +519,16 @@ impl<T> PartialOrd for *mut T {
 
 /// A wrapper around a raw `*mut T` that indicates that the possessor
 /// of this wrapper owns the referent. This in turn implies that the
-/// `Unique<T>` is `Send`/`Sync` if `T` is `Send`/`Sync`, unlike a
-/// raw `*mut T` (which conveys no particular ownership semantics).
-/// Useful for building abstractions like `Vec<T>` or `Box<T>`, which
+/// `Unique<T>` is `Send`/`Sync` if `T` is `Send`/`Sync`, unlike a raw
+/// `*mut T` (which conveys no particular ownership semantics).  It
+/// also implies that the referent of the pointer should not be
+/// modified without a unique path to the `Unique` reference. Useful
+/// for building abstractions like `Vec<T>` or `Box<T>`, which
 /// internally use raw pointers to manage the memory that they own.
 #[unstable(feature = "core", reason = "recently added to this module")]
-pub struct Unique<T: ?Sized> {
-    /// The wrapped `*mut T`.
-    pub ptr: *mut T,
-    _own: marker::PhantomData<T>,
+pub struct Unique<T:?Sized> {
+    pointer: NonZero<*const T>,
+    _marker: PhantomData<T>,
 }
 
 /// `Unique` pointers are `Send` if `T` is `Send` because the data they
@@ -542,25 +545,34 @@ unsafe impl<T: Send + ?Sized> Send for Unique<T> { }
 #[unstable(feature = "core", reason = "recently added to this module")]
 unsafe impl<T: Sync + ?Sized> Sync for Unique<T> { }
 
-impl<T> Unique<T> {
-    /// Returns a null Unique.
+impl<T:?Sized> Unique<T> {
+    /// Create a new `Unique`.
     #[unstable(feature = "core",
                reason = "recently added to this module")]
-    pub fn null() -> Unique<T> {
-        Unique(null_mut())
+    pub unsafe fn new(ptr: *mut T) -> Unique<T> {
+        Unique { pointer: NonZero::new(ptr as *const T), _marker: PhantomData }
     }
 
-    /// Return an (unsafe) pointer into the memory owned by `self`.
+    /// Dereference the content.
     #[unstable(feature = "core",
                reason = "recently added to this module")]
-    pub unsafe fn offset(self, offset: isize) -> *mut T {
-        self.ptr.offset(offset)
+    pub unsafe fn get(&self) -> &T {
+        &**self.pointer
+    }
+
+    /// Mutably dereference the content.
+    #[unstable(feature = "core",
+               reason = "recently added to this module")]
+    pub unsafe fn get_mut(&mut self) -> &mut T {
+        &mut ***self
     }
 }
 
-/// Creates a `Unique` wrapped around `ptr`, taking ownership of the
-/// data referenced by `ptr`.
-#[allow(non_snake_case)]
-pub fn Unique<T: ?Sized>(ptr: *mut T) -> Unique<T> {
-    Unique { ptr: ptr, _own: marker::PhantomData }
+impl<T:?Sized> Deref for Unique<T> {
+    type Target = *mut T;
+
+    #[inline]
+    fn deref<'a>(&'a self) -> &'a *mut T {
+        unsafe { mem::transmute(&*self.pointer) }
+    }
 }
diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 1a874ee178b..23e936a75d7 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -230,7 +230,8 @@ use self::Result::{Ok, Err};
 
 use clone::Clone;
 use fmt;
-use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator, ExactSizeIterator};
+use iter::{Iterator, IteratorExt, DoubleEndedIterator,
+           FromIterator, ExactSizeIterator, IntoIterator};
 use ops::{FnMut, FnOnce};
 use option::Option::{self, None, Some};
 use slice::AsSlice;
@@ -906,7 +907,7 @@ impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> {
     /// assert!(res == Ok(vec!(2, 3)));
     /// ```
     #[inline]
-    fn from_iter<I: Iterator<Item=Result<A, E>>>(iter: I) -> Result<V, E> {
+    fn from_iter<I: IntoIterator<Item=Result<A, E>>>(iter: I) -> Result<V, E> {
         // FIXME(#11084): This could be replaced with Iterator::scan when this
         // performance bug is closed.
 
@@ -931,7 +932,7 @@ impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> {
             }
         }
 
-        let mut adapter = Adapter { iter: iter, err: None };
+        let mut adapter = Adapter { iter: iter.into_iter(), err: None };
         let v: V = FromIterator::from_iter(adapter.by_ref());
 
         match adapter.err {
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index bbfe7e58ef4..a86da53b372 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -140,11 +140,11 @@ impl<T> SliceExt for [T] {
             if mem::size_of::<T>() == 0 {
                 Iter {ptr: p,
                       end: (p as usize + self.len()) as *const T,
-                      marker: marker::ContravariantLifetime::<'a>}
+                      _marker: marker::PhantomData}
             } else {
                 Iter {ptr: p,
                       end: p.offset(self.len() as isize),
-                      marker: marker::ContravariantLifetime::<'a>}
+                      _marker: marker::PhantomData}
             }
         }
     }
@@ -279,11 +279,11 @@ impl<T> SliceExt for [T] {
             if mem::size_of::<T>() == 0 {
                 IterMut {ptr: p,
                          end: (p as usize + self.len()) as *mut T,
-                         marker: marker::ContravariantLifetime::<'a>}
+                         _marker: marker::PhantomData}
             } else {
                 IterMut {ptr: p,
                          end: p.offset(self.len() as isize),
-                         marker: marker::ContravariantLifetime::<'a>}
+                         _marker: marker::PhantomData}
             }
         }
     }
@@ -733,7 +733,7 @@ macro_rules! make_slice {
 pub struct Iter<'a, T: 'a> {
     ptr: *const T,
     end: *const T,
-    marker: marker::ContravariantLifetime<'a>
+    _marker: marker::PhantomData<&'a T>,
 }
 
 #[unstable(feature = "core")]
@@ -790,7 +790,7 @@ impl<'a, T> ExactSizeIterator for Iter<'a, T> {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> Clone for Iter<'a, T> {
-    fn clone(&self) -> Iter<'a, T> { Iter { ptr: self.ptr, end: self.end, marker: self.marker } }
+    fn clone(&self) -> Iter<'a, T> { Iter { ptr: self.ptr, end: self.end, _marker: self._marker } }
 }
 
 #[unstable(feature = "core", reason = "trait is experimental")]
@@ -823,7 +823,7 @@ impl<'a, T> RandomAccessIterator for Iter<'a, T> {
 pub struct IterMut<'a, T: 'a> {
     ptr: *mut T,
     end: *mut T,
-    marker: marker::ContravariantLifetime<'a>,
+    _marker: marker::PhantomData<&'a mut T>,
 }
 
 
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index ce26abe606d..eec997b9f10 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -1280,7 +1280,7 @@ mod traits {
 /// Any string that can be represented as a slice
 #[unstable(feature = "core",
            reason = "Instead of taking this bound generically, this trait will be \
-                     replaced with one of slicing syntax (&foo[]), deref coercions, or \
+                     replaced with one of slicing syntax (&foo[..]), deref coercions, or \
                      a more generic conversion trait")]
 pub trait Str {
     /// Work with `self` as a slice.
diff --git a/src/libcoretest/hash/mod.rs b/src/libcoretest/hash/mod.rs
index fd0d3c676a4..9b6af182f72 100644
--- a/src/libcoretest/hash/mod.rs
+++ b/src/libcoretest/hash/mod.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use std::mem;
-use std::hash::{Hash, Hasher, Writer};
+use std::hash::{Hash, Hasher};
 use std::default::Default;
 
 struct MyHasher {
@@ -22,25 +22,19 @@ impl Default for MyHasher {
     }
 }
 
-impl Writer for MyHasher {
-    // Most things we'll just add up the bytes.
+impl Hasher for MyHasher {
     fn write(&mut self, buf: &[u8]) {
         for byte in buf {
             self.hash += *byte as u64;
         }
     }
-}
-
-impl Hasher for MyHasher {
-    type Output = u64;
-    fn reset(&mut self) { self.hash = 0; }
     fn finish(&self) -> u64 { self.hash }
 }
 
 
 #[test]
 fn test_writer_hasher() {
-    fn hash<T: Hash<MyHasher>>(t: &T) -> u64 {
+    fn hash<T: Hash>(t: &T) -> u64 {
         ::std::hash::hash::<_, MyHasher>(t)
     }
 
@@ -90,9 +84,9 @@ struct Custom { hash: u64 }
 struct CustomHasher { output: u64 }
 
 impl Hasher for CustomHasher {
-    type Output = u64;
-    fn reset(&mut self) { self.output = 0; }
     fn finish(&self) -> u64 { self.output }
+    fn write(&mut self, data: &[u8]) { panic!() }
+    fn write_u64(&mut self, data: u64) { self.output = data; }
 }
 
 impl Default for CustomHasher {
@@ -101,15 +95,15 @@ impl Default for CustomHasher {
     }
 }
 
-impl Hash<CustomHasher> for Custom {
-    fn hash(&self, state: &mut CustomHasher) {
-        state.output = self.hash;
+impl Hash for Custom {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        state.write_u64(self.hash);
     }
 }
 
 #[test]
 fn test_custom_state() {
-    fn hash<T: Hash<CustomHasher>>(t: &T) -> u64 {
+    fn hash<T: Hash>(t: &T) -> u64 {
         ::std::hash::hash::<_, CustomHasher>(t)
     }
 
diff --git a/src/libcoretest/iter.rs b/src/libcoretest/iter.rs
index 7eb0fb97bed..39a590c7307 100644
--- a/src/libcoretest/iter.rs
+++ b/src/libcoretest/iter.rs
@@ -91,7 +91,7 @@ fn test_iterator_chain() {
     assert_eq!(i, expected.len());
 
     let ys = count(30, 10).take(4);
-    let mut it = xs.iter().map(|&x| x).chain(ys);
+    let mut it = xs.iter().cloned().chain(ys);
     let mut i = 0;
     for x in it {
         assert_eq!(x, expected[i]);
@@ -119,7 +119,7 @@ fn test_iterator_enumerate() {
 #[test]
 fn test_iterator_peekable() {
     let xs = vec![0, 1, 2, 3, 4, 5];
-    let mut it = xs.iter().map(|&x|x).peekable();
+    let mut it = xs.iter().cloned().peekable();
 
     assert_eq!(it.len(), 6);
     assert_eq!(it.peek().unwrap(), &0);
@@ -259,12 +259,12 @@ fn test_inspect() {
     let mut n = 0;
 
     let ys = xs.iter()
-               .map(|&x| x)
+               .cloned()
                .inspect(|_| n += 1)
                .collect::<Vec<uint>>();
 
     assert_eq!(n, xs.len());
-    assert_eq!(&xs[], &ys[]);
+    assert_eq!(&xs[..], &ys[..]);
 }
 
 #[test]
@@ -329,33 +329,33 @@ fn test_iterator_len() {
 #[test]
 fn test_iterator_sum() {
     let v: &[i32] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
-    assert_eq!(v[..4].iter().map(|&x| x).sum(), 6);
-    assert_eq!(v.iter().map(|&x| x).sum(), 55);
-    assert_eq!(v[..0].iter().map(|&x| x).sum(), 0);
+    assert_eq!(v[..4].iter().cloned().sum(), 6);
+    assert_eq!(v.iter().cloned().sum(), 55);
+    assert_eq!(v[..0].iter().cloned().sum(), 0);
 }
 
 #[test]
 fn test_iterator_product() {
     let v: &[i32] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
-    assert_eq!(v[..4].iter().map(|&x| x).product(), 0);
-    assert_eq!(v[1..5].iter().map(|&x| x).product(), 24);
-    assert_eq!(v[..0].iter().map(|&x| x).product(), 1);
+    assert_eq!(v[..4].iter().cloned().product(), 0);
+    assert_eq!(v[1..5].iter().cloned().product(), 24);
+    assert_eq!(v[..0].iter().cloned().product(), 1);
 }
 
 #[test]
 fn test_iterator_max() {
     let v: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
-    assert_eq!(v[..4].iter().map(|&x| x).max(), Some(3));
-    assert_eq!(v.iter().map(|&x| x).max(), Some(10));
-    assert_eq!(v[..0].iter().map(|&x| x).max(), None);
+    assert_eq!(v[..4].iter().cloned().max(), Some(3));
+    assert_eq!(v.iter().cloned().max(), Some(10));
+    assert_eq!(v[..0].iter().cloned().max(), None);
 }
 
 #[test]
 fn test_iterator_min() {
     let v: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
-    assert_eq!(v[..4].iter().map(|&x| x).min(), Some(0));
-    assert_eq!(v.iter().map(|&x| x).min(), Some(0));
-    assert_eq!(v[..0].iter().map(|&x| x).min(), None);
+    assert_eq!(v[..4].iter().cloned().min(), Some(0));
+    assert_eq!(v.iter().cloned().min(), Some(0));
+    assert_eq!(v[..0].iter().cloned().min(), None);
 }
 
 #[test]
@@ -373,7 +373,7 @@ fn test_iterator_size_hint() {
     assert_eq!(c.clone().take_while(|_| false).size_hint(), (0, None));
     assert_eq!(c.clone().skip_while(|_| false).size_hint(), (0, None));
     assert_eq!(c.clone().enumerate().size_hint(), (uint::MAX, None));
-    assert_eq!(c.clone().chain(vi.clone().map(|&i| i)).size_hint(), (uint::MAX, None));
+    assert_eq!(c.clone().chain(vi.clone().cloned()).size_hint(), (uint::MAX, None));
     assert_eq!(c.clone().zip(vi.clone()).size_hint(), (10, Some(10)));
     assert_eq!(c.clone().scan(0, |_,_| Some(0)).size_hint(), (0, None));
     assert_eq!(c.clone().filter(|_| false).size_hint(), (0, None));
@@ -398,7 +398,7 @@ fn test_iterator_size_hint() {
 #[test]
 fn test_collect() {
     let a = vec![1, 2, 3, 4, 5];
-    let b: Vec<int> = a.iter().map(|&x| x).collect();
+    let b: Vec<int> = a.iter().cloned().collect();
     assert!(a == b);
 }
 
@@ -471,7 +471,7 @@ fn test_rev() {
     let mut it = xs.iter();
     it.next();
     it.next();
-    assert!(it.rev().map(|&x| x).collect::<Vec<int>>() ==
+    assert!(it.rev().cloned().collect::<Vec<int>>() ==
             vec![16, 14, 12, 10, 8, 6]);
 }
 
@@ -508,7 +508,7 @@ fn test_double_ended_map() {
 #[test]
 fn test_double_ended_enumerate() {
     let xs = [1, 2, 3, 4, 5, 6];
-    let mut it = xs.iter().map(|&x| x).enumerate();
+    let mut it = xs.iter().cloned().enumerate();
     assert_eq!(it.next(), Some((0, 1)));
     assert_eq!(it.next(), Some((1, 2)));
     assert_eq!(it.next_back(), Some((5, 6)));
@@ -522,8 +522,8 @@ fn test_double_ended_enumerate() {
 fn test_double_ended_zip() {
     let xs = [1, 2, 3, 4, 5, 6];
     let ys = [1, 2, 3, 7];
-    let a = xs.iter().map(|&x| x);
-    let b = ys.iter().map(|&x| x);
+    let a = xs.iter().cloned();
+    let b = ys.iter().cloned();
     let mut it = a.zip(b);
     assert_eq!(it.next(), Some((1, 1)));
     assert_eq!(it.next(), Some((2, 2)));
@@ -713,7 +713,7 @@ fn test_random_access_inspect() {
 fn test_random_access_map() {
     let xs = [1, 2, 3, 4, 5];
 
-    let mut it = xs.iter().map(|x| *x);
+    let mut it = xs.iter().cloned();
     assert_eq!(xs.len(), it.indexable());
     for (i, elt) in xs.iter().enumerate() {
         assert_eq!(Some(*elt), it.idx(i));
diff --git a/src/libcoretest/mem.rs b/src/libcoretest/mem.rs
index 421ce76caaf..5aeb330b78b 100644
--- a/src/libcoretest/mem.rs
+++ b/src/libcoretest/mem.rs
@@ -92,7 +92,7 @@ fn test_transmute_copy() {
 
 #[test]
 fn test_transmute() {
-    trait Foo {}
+    trait Foo { fn dummy(&self) { } }
     impl Foo for int {}
 
     let a = box 100 as Box<Foo>;
diff --git a/src/libcoretest/ptr.rs b/src/libcoretest/ptr.rs
index 9c2e242c105..57456bfb1a7 100644
--- a/src/libcoretest/ptr.rs
+++ b/src/libcoretest/ptr.rs
@@ -171,8 +171,8 @@ fn test_set_memory() {
 #[test]
 fn test_unsized_unique() {
     let xs: &mut [_] = &mut [1, 2, 3];
-    let ptr = Unique(xs as *mut [_]);
-    let ys = unsafe { &mut *ptr.ptr };
+    let ptr = unsafe { Unique::new(xs as *mut [_]) };
+    let ys = unsafe { &mut **ptr };
     let zs: &mut [_] = &mut [1, 2, 3];
     assert!(ys == zs);
 }
diff --git a/src/libcoretest/slice.rs b/src/libcoretest/slice.rs
index 6d5cc38ef0a..46c7730cc64 100644
--- a/src/libcoretest/slice.rs
+++ b/src/libcoretest/slice.rs
@@ -43,13 +43,13 @@ fn iterator_to_slice() {
 
             {
                 let mut iter = data.iter();
-                assert_eq!(&iter[], &other_data[]);
+                assert_eq!(&iter[..], &other_data[..]);
 
                 iter.next();
-                assert_eq!(&iter[], &other_data[1..]);
+                assert_eq!(&iter[..], &other_data[1..]);
 
                 iter.next_back();
-                assert_eq!(&iter[], &other_data[1..2]);
+                assert_eq!(&iter[..], &other_data[1..2]);
 
                 let s = iter.as_slice();
                 iter.next();
@@ -57,17 +57,17 @@ fn iterator_to_slice() {
             }
             {
                 let mut iter = data.iter_mut();
-                assert_eq!(&iter[], &other_data[]);
+                assert_eq!(&iter[..], &other_data[..]);
                 // mutability:
                 assert!(&mut iter[] == other_data);
 
                 iter.next();
-                assert_eq!(&iter[], &other_data[1..]);
+                assert_eq!(&iter[..], &other_data[1..]);
                 assert!(&mut iter[] == &mut other_data[1..]);
 
                 iter.next_back();
 
-                assert_eq!(&iter[], &other_data[1..2]);
+                assert_eq!(&iter[..], &other_data[1..2]);
                 assert!(&mut iter[] == &mut other_data[1..2]);
 
                 let s = iter.into_slice();
diff --git a/src/libflate/lib.rs b/src/libflate/lib.rs
index ff6400a11df..24660b3f396 100644
--- a/src/libflate/lib.rs
+++ b/src/libflate/lib.rs
@@ -45,13 +45,13 @@ pub struct Bytes {
 impl Deref for Bytes {
     type Target = [u8];
     fn deref(&self) -> &[u8] {
-        unsafe { slice::from_raw_parts_mut(self.ptr.ptr, self.len) }
+        unsafe { slice::from_raw_parts(*self.ptr, self.len) }
     }
 }
 
 impl Drop for Bytes {
     fn drop(&mut self) {
-        unsafe { libc::free(self.ptr.ptr as *mut _); }
+        unsafe { libc::free(*self.ptr as *mut _); }
     }
 }
 
@@ -84,7 +84,7 @@ fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option<Bytes> {
                                              &mut outsz,
                                              flags);
         if !res.is_null() {
-            let res = Unique(res as *mut u8);
+            let res = Unique::new(res as *mut u8);
             Some(Bytes { ptr: res, len: outsz as uint })
         } else {
             None
@@ -110,7 +110,7 @@ fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option<Bytes> {
                                                &mut outsz,
                                                flags);
         if !res.is_null() {
-            let res = Unique(res as *mut u8);
+            let res = Unique::new(res as *mut u8);
             Some(Bytes { ptr: res, len: outsz as uint })
         } else {
             None
diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs
index 1c7e97d784c..be77622ac1d 100644
--- a/src/libfmt_macros/lib.rs
+++ b/src/libfmt_macros/lib.rs
@@ -215,11 +215,11 @@ impl<'a> Parser<'a> {
             }
             Some((_, other)) => {
                 self.err(&format!("expected `{:?}`, found `{:?}`", c,
-                                  other)[]);
+                                  other));
             }
             None => {
                 self.err(&format!("expected `{:?}` but string was terminated",
-                                  c)[]);
+                                  c));
             }
         }
     }
diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs
index c743119f409..fdd7f7395c2 100644
--- a/src/libgetopts/lib.rs
+++ b/src/libgetopts/lib.rs
@@ -287,7 +287,7 @@ impl OptGroup {
 
 impl Matches {
     fn opt_vals(&self, nm: &str) -> Vec<Optval> {
-        match find_opt(&self.opts[], Name::from_str(nm)) {
+        match find_opt(&self.opts[..], Name::from_str(nm)) {
             Some(id) => self.vals[id].clone(),
             None => panic!("No option '{}' defined", nm)
         }
@@ -326,7 +326,7 @@ impl Matches {
     /// Returns the string argument supplied to one of several matching options or `None`.
     pub fn opts_str(&self, names: &[String]) -> Option<String> {
         for nm in names {
-            match self.opt_val(&nm[]) {
+            match self.opt_val(&nm[..]) {
                 Some(Val(ref s)) => return Some(s.clone()),
                 _ => ()
             }
@@ -593,7 +593,7 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result {
     while i < l {
         let cur = args[i].clone();
         let curlen = cur.len();
-        if !is_arg(&cur[]) {
+        if !is_arg(&cur[..]) {
             free.push(cur);
         } else if cur == "--" {
             let mut j = i + 1;
@@ -667,7 +667,7 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result {
                         v.push(Val((i_arg.clone())
                             .unwrap()));
                     } else if name_pos < names.len() || i + 1 == l ||
-                            is_arg(&args[i + 1][]) {
+                            is_arg(&args[i + 1][..]) {
                         let v = &mut vals[optid];
                         v.push(Given);
                     } else {
@@ -730,7 +730,7 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> String {
             0 => {}
             1 => {
                 row.push('-');
-                row.push_str(&short_name[]);
+                row.push_str(&short_name[..]);
                 row.push(' ');
             }
             _ => panic!("the short name should only be 1 ascii char long"),
@@ -741,7 +741,7 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> String {
             0 => {}
             _ => {
                 row.push_str("--");
-                row.push_str(&long_name[]);
+                row.push_str(&long_name[..]);
                 row.push(' ');
             }
         }
@@ -749,10 +749,10 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> String {
         // arg
         match hasarg {
             No => {}
-            Yes => row.push_str(&hint[]),
+            Yes => row.push_str(&hint[..]),
             Maybe => {
                 row.push('[');
-                row.push_str(&hint[]);
+                row.push_str(&hint[..]);
                 row.push(']');
             }
         }
@@ -765,7 +765,7 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> String {
                 row.push(' ');
             }
         } else {
-            row.push_str(&desc_sep[]);
+            row.push_str(&desc_sep[..]);
         }
 
         // Normalize desc to contain words separated by one space character
@@ -777,14 +777,14 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> String {
 
         // FIXME: #5516 should be graphemes not codepoints
         let mut desc_rows = Vec::new();
-        each_split_within(&desc_normalized_whitespace[], 54, |substr| {
+        each_split_within(&desc_normalized_whitespace[..], 54, |substr| {
             desc_rows.push(substr.to_string());
             true
         });
 
         // FIXME: #5516 should be graphemes not codepoints
         // wrapped description
-        row.push_str(&desc_rows.connect(&desc_sep[])[]);
+        row.push_str(&desc_rows.connect(&desc_sep[..])[]);
 
         row
     });
@@ -803,10 +803,10 @@ fn format_option(opt: &OptGroup) -> String {
     // Use short_name is possible, but fallback to long_name.
     if opt.short_name.len() > 0 {
         line.push('-');
-        line.push_str(&opt.short_name[]);
+        line.push_str(&opt.short_name[..]);
     } else {
         line.push_str("--");
-        line.push_str(&opt.long_name[]);
+        line.push_str(&opt.long_name[..]);
     }
 
     if opt.hasarg != No {
@@ -814,7 +814,7 @@ fn format_option(opt: &OptGroup) -> String {
         if opt.hasarg == Maybe {
             line.push('[');
         }
-        line.push_str(&opt.hint[]);
+        line.push_str(&opt.hint[..]);
         if opt.hasarg == Maybe {
             line.push(']');
         }
@@ -836,7 +836,7 @@ pub fn short_usage(program_name: &str, opts: &[OptGroup]) -> String {
     line.push_str(&opts.iter()
                        .map(format_option)
                        .collect::<Vec<String>>()
-                       .connect(" ")[]);
+                       .connect(" ")[..]);
     line
 }
 
diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs
index 230deabee00..acd52c752e8 100644
--- a/src/libgraphviz/lib.rs
+++ b/src/libgraphviz/lib.rs
@@ -275,15 +275,12 @@
        html_root_url = "http://doc.rust-lang.org/nightly/")]
 #![feature(int_uint)]
 #![feature(collections)]
-#![feature(core)]
 #![feature(old_io)]
 
 use self::LabelText::*;
 
-use std::borrow::IntoCow;
+use std::borrow::{IntoCow, Cow};
 use std::old_io;
-use std::string::CowString;
-use std::vec::CowVec;
 
 /// The text for a graphviz label on a node or edge.
 pub enum LabelText<'a> {
@@ -291,7 +288,7 @@ pub enum LabelText<'a> {
     ///
     /// Occurrences of backslashes (`\`) are escaped, and thus appear
     /// as backslashes in the rendered label.
-    LabelStr(CowString<'a>),
+    LabelStr(Cow<'a, str>),
 
     /// This kind of label uses the graphviz label escString type:
     /// http://www.graphviz.org/content/attrs#kescString
@@ -303,7 +300,7 @@ pub enum LabelText<'a> {
     /// to break a line (centering the line preceding the `\n`), there
     /// are also the escape sequences `\l` which left-justifies the
     /// preceding line and `\r` which right-justifies it.
-    EscStr(CowString<'a>),
+    EscStr(Cow<'a, str>),
 }
 
 // There is a tension in the design of the labelling API.
@@ -340,7 +337,7 @@ pub enum LabelText<'a> {
 
 /// `Id` is a Graphviz `ID`.
 pub struct Id<'a> {
-    name: CowString<'a>,
+    name: Cow<'a, str>,
 }
 
 impl<'a> Id<'a> {
@@ -358,7 +355,7 @@ impl<'a> Id<'a> {
     ///
     /// Passing an invalid string (containing spaces, brackets,
     /// quotes, ...) will return an empty `Err` value.
-    pub fn new<Name: IntoCow<'a, String, str>>(name: Name) -> Result<Id<'a>, ()> {
+    pub fn new<Name: IntoCow<'a, str>>(name: Name) -> Result<Id<'a>, ()> {
         let name = name.into_cow();
         {
             let mut chars = name.chars();
@@ -387,7 +384,7 @@ impl<'a> Id<'a> {
         &*self.name
     }
 
-    pub fn name(self) -> CowString<'a> {
+    pub fn name(self) -> Cow<'a, str> {
         self.name
     }
 }
@@ -427,11 +424,11 @@ pub trait Labeller<'a,N,E> {
 }
 
 impl<'a> LabelText<'a> {
-    pub fn label<S:IntoCow<'a, String, str>>(s: S) -> LabelText<'a> {
+    pub fn label<S:IntoCow<'a, str>>(s: S) -> LabelText<'a> {
         LabelStr(s.into_cow())
     }
 
-    pub fn escaped<S:IntoCow<'a, String, str>>(s: S) -> LabelText<'a> {
+    pub fn escaped<S:IntoCow<'a, str>>(s: S) -> LabelText<'a> {
         EscStr(s.into_cow())
     }
 
@@ -455,7 +452,7 @@ impl<'a> LabelText<'a> {
     pub fn escape(&self) -> String {
         match self {
             &LabelStr(ref s) => s.escape_default(),
-            &EscStr(ref s) => LabelText::escape_str(&s[]),
+            &EscStr(ref s) => LabelText::escape_str(&s[..]),
         }
     }
 
@@ -463,7 +460,7 @@ impl<'a> LabelText<'a> {
     /// yields same content as self.  The result obeys the law
     /// render(`lt`) == render(`EscStr(lt.pre_escaped_content())`) for
     /// all `lt: LabelText`.
-    fn pre_escaped_content(self) -> CowString<'a> {
+    fn pre_escaped_content(self) -> Cow<'a, str> {
         match self {
             EscStr(s) => s,
             LabelStr(s) => if s.contains_char('\\') {
@@ -484,13 +481,13 @@ impl<'a> LabelText<'a> {
         let mut prefix = self.pre_escaped_content().into_owned();
         let suffix = suffix.pre_escaped_content();
         prefix.push_str(r"\n\n");
-        prefix.push_str(&suffix[]);
+        prefix.push_str(&suffix[..]);
         EscStr(prefix.into_cow())
     }
 }
 
-pub type Nodes<'a,N> = CowVec<'a,N>;
-pub type Edges<'a,E> = CowVec<'a,E>;
+pub type Nodes<'a,N> = Cow<'a,[N]>;
+pub type Edges<'a,E> = Cow<'a,[E]>;
 
 // (The type parameters in GraphWalk should be associated items,
 // when/if Rust supports such.)
@@ -678,7 +675,7 @@ mod tests {
 
     impl<'a> Labeller<'a, Node, &'a Edge> for LabelledGraph {
         fn graph_id(&'a self) -> Id<'a> {
-            Id::new(&self.name[]).unwrap()
+            Id::new(&self.name[..]).unwrap()
         }
         fn node_id(&'a self, n: &Node) -> Id<'a> {
             id_name(n)
diff --git a/src/liblog/lib.rs b/src/liblog/lib.rs
index 4dab07acfd2..c2c7f20ce9c 100644
--- a/src/liblog/lib.rs
+++ b/src/liblog/lib.rs
@@ -287,7 +287,7 @@ pub fn log(level: u32, loc: &'static LogLocation, args: fmt::Arguments) {
     // Test the literal string from args against the current filter, if there
     // is one.
     match unsafe { FILTER.as_ref() } {
-        Some(filter) if !args.to_string().contains(&filter[]) => return,
+        Some(filter) if !args.to_string().contains(&filter[..]) => return,
         _ => {}
     }
 
@@ -382,7 +382,7 @@ fn enabled(level: u32,
     // Search for the longest match, the vector is assumed to be pre-sorted.
     for directive in iter.rev() {
         match directive.name {
-            Some(ref name) if !module.starts_with(&name[]) => {},
+            Some(ref name) if !module.starts_with(&name[..]) => {},
             Some(..) | None => {
                 return level <= directive.level
             }
@@ -397,7 +397,7 @@ fn enabled(level: u32,
 /// `Once` primitive (and this function is called from that primitive).
 fn init() {
     let (mut directives, filter) = match env::var("RUST_LOG") {
-        Ok(spec) => directive::parse_logging_spec(&spec[]),
+        Ok(spec) => directive::parse_logging_spec(&spec[..]),
         Err(..) => (Vec::new(), None),
     };
 
diff --git a/src/librand/distributions/mod.rs b/src/librand/distributions/mod.rs
index d1d24cea871..5a85552dc38 100644
--- a/src/librand/distributions/mod.rs
+++ b/src/librand/distributions/mod.rs
@@ -21,6 +21,7 @@
 
 use core::prelude::*;
 use core::num::{Float, Int};
+use core::marker::PhantomData;
 
 use {Rng, Rand};
 
@@ -56,7 +57,13 @@ pub trait IndependentSample<Support>: Sample<Support> {
 
 /// A wrapper for generating types that implement `Rand` via the
 /// `Sample` & `IndependentSample` traits.
-pub struct RandSample<Sup>;
+pub struct RandSample<Sup> { _marker: PhantomData<Sup> }
+
+impl<Sup> RandSample<Sup> {
+    pub fn new() -> RandSample<Sup> {
+        RandSample { _marker: PhantomData }
+    }
+}
 
 impl<Sup: Rand> Sample<Sup> for RandSample<Sup> {
     fn sample<R: Rng>(&mut self, rng: &mut R) -> Sup { self.ind_sample(rng) }
@@ -285,7 +292,7 @@ mod tests {
 
     #[test]
     fn test_rand_sample() {
-        let mut rand_sample = RandSample::<ConstRand>;
+        let mut rand_sample = RandSample::<ConstRand>::new();
 
         assert_eq!(rand_sample.sample(&mut ::test::rng()), ConstRand(0));
         assert_eq!(rand_sample.ind_sample(&mut ::test::rng()), ConstRand(0));
diff --git a/src/librand/isaac.rs b/src/librand/isaac.rs
index f15523fc010..701749ff344 100644
--- a/src/librand/isaac.rs
+++ b/src/librand/isaac.rs
@@ -215,7 +215,7 @@ impl<'a> SeedableRng<&'a [u32]> for IsaacRng {
     fn reseed(&mut self, seed: &'a [u32]) {
         // make the seed into [seed[0], seed[1], ..., seed[seed.len()
         // - 1], 0, 0, ...], to fill rng.rsl.
-        let seed_iter = seed.iter().map(|&x| x).chain(repeat(0u32));
+        let seed_iter = seed.iter().cloned().chain(repeat(0u32));
 
         for (rsl_elem, seed_elem) in self.rsl.iter_mut().zip(seed_iter) {
             *rsl_elem = seed_elem;
@@ -458,7 +458,7 @@ impl<'a> SeedableRng<&'a [u64]> for Isaac64Rng {
     fn reseed(&mut self, seed: &'a [u64]) {
         // make the seed into [seed[0], seed[1], ..., seed[seed.len()
         // - 1], 0, 0, ...], to fill rng.rsl.
-        let seed_iter = seed.iter().map(|&x| x).chain(repeat(0u64));
+        let seed_iter = seed.iter().cloned().chain(repeat(0u64));
 
         for (rsl_elem, seed_elem) in self.rsl.iter_mut().zip(seed_iter) {
             *rsl_elem = seed_elem;
diff --git a/src/librand/lib.rs b/src/librand/lib.rs
index 915c70bbf8c..7588bf7c515 100644
--- a/src/librand/lib.rs
+++ b/src/librand/lib.rs
@@ -41,6 +41,7 @@ extern crate core;
 #[cfg(test)] #[macro_use] extern crate log;
 
 use core::prelude::*;
+use core::marker::PhantomData;
 
 pub use isaac::{IsaacRng, Isaac64Rng};
 pub use chacha::ChaChaRng;
@@ -206,7 +207,7 @@ pub trait Rng : Sized {
     ///                     .collect::<Vec<(f64, bool)>>());
     /// ```
     fn gen_iter<'a, T: Rand>(&'a mut self) -> Generator<'a, T, Self> {
-        Generator { rng: self }
+        Generator { rng: self, _marker: PhantomData }
     }
 
     /// Generate a random value in the range [`low`, `high`).
@@ -317,6 +318,7 @@ pub trait Rng : Sized {
 /// This iterator is created via the `gen_iter` method on `Rng`.
 pub struct Generator<'a, T, R:'a> {
     rng: &'a mut R,
+    _marker: PhantomData<T>
 }
 
 impl<'a, T: Rand, R: Rng> Iterator for Generator<'a, T, R> {
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index eb51046d7c9..dc81e89902b 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -37,7 +37,7 @@ use util::ppaux::{ty_to_string};
 use util::nodemap::{FnvHashMap, NodeSet};
 use lint::{Level, Context, LintPass, LintArray, Lint};
 
-use std::collections::BitvSet;
+use std::collections::BitSet;
 use std::collections::hash_map::Entry::{Occupied, Vacant};
 use std::num::SignedInt;
 use std::{cmp, slice};
@@ -508,7 +508,7 @@ impl BoxPointers {
         if n_uniq > 0 {
             let s = ty_to_string(cx.tcx, ty);
             let m = format!("type uses owned (Box type) pointers: {}", s);
-            cx.span_lint(BOX_POINTERS, span, &m[]);
+            cx.span_lint(BOX_POINTERS, span, &m[..]);
         }
     }
 }
@@ -736,7 +736,7 @@ impl LintPass for UnusedResults {
                     }
                 } else {
                     let attrs = csearch::get_item_attrs(&cx.sess().cstore, did);
-                    warned |= check_must_use(cx, &attrs[], s.span);
+                    warned |= check_must_use(cx, &attrs[..], s.span);
                 }
             }
             _ => {}
@@ -803,7 +803,7 @@ impl NonCamelCaseTypes {
             } else {
                 format!("{} `{}` should have a camel case name such as `{}`", sort, s, c)
             };
-            cx.span_lint(NON_CAMEL_CASE_TYPES, span, &m[]);
+            cx.span_lint(NON_CAMEL_CASE_TYPES, span, &m[..]);
         }
     }
 }
@@ -950,7 +950,7 @@ impl NonSnakeCase {
 
         if !is_snake_case(ident) {
             let sc = NonSnakeCase::to_snake_case(&s);
-            if sc != &s[] {
+            if sc != &s[..] {
                 cx.span_lint(NON_SNAKE_CASE, span,
                     &*format!("{} `{}` should have a snake case name such as `{}`",
                             sort, s, sc));
@@ -1033,7 +1033,7 @@ impl NonUpperCaseGlobals {
         if s.chars().any(|c| c.is_lowercase()) {
             let uc: String = NonSnakeCase::to_snake_case(&s).chars()
                                            .map(|c| c.to_uppercase()).collect();
-            if uc != &s[] {
+            if uc != &s[..] {
                 cx.span_lint(NON_UPPER_CASE_GLOBALS, span,
                     &format!("{} `{}` should have an upper case name such as `{}`",
                              sort, s, uc));
@@ -1196,7 +1196,7 @@ impl LintPass for UnusedImportBraces {
                                     let m = format!("braces around {} is unnecessary",
                                                     &token::get_ident(*name));
                                     cx.span_lint(UNUSED_IMPORT_BRACES, item.span,
-                                                 &m[]);
+                                                 &m[..]);
                                 },
                                 _ => ()
                             }
@@ -1474,7 +1474,7 @@ impl LintPass for MissingDoc {
         let doc_hidden = self.doc_hidden() || attrs.iter().any(|attr| {
             attr.check_name("doc") && match attr.meta_item_list() {
                 None => false,
-                Some(l) => attr::contains_name(&l[], "hidden"),
+                Some(l) => attr::contains_name(&l[..], "hidden"),
             }
         });
         self.doc_hidden_stack.push(doc_hidden);
@@ -1702,7 +1702,7 @@ impl Stability {
                 _ => format!("use of {} item", label)
             };
 
-            cx.span_lint(lint, span, &msg[]);
+            cx.span_lint(lint, span, &msg[..]);
         }
     }
 }
@@ -1791,7 +1791,7 @@ impl LintPass for UnconditionalRecursion {
         let mut work_queue = vec![cfg.entry];
         let mut reached_exit_without_self_call = false;
         let mut self_call_spans = vec![];
-        let mut visited = BitvSet::new();
+        let mut visited = BitSet::new();
 
         while let Some(idx) = work_queue.pop() {
             let cfg_id = idx.node_id();
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 42a6861f452..068c179d343 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -125,11 +125,11 @@ impl LintStore {
                 match (sess, from_plugin) {
                     // We load builtin lints first, so a duplicate is a compiler bug.
                     // Use early_error when handling -W help with no crate.
-                    (None, _) => early_error(&msg[]),
-                    (Some(sess), false) => sess.bug(&msg[]),
+                    (None, _) => early_error(&msg[..]),
+                    (Some(sess), false) => sess.bug(&msg[..]),
 
                     // A duplicate name from a plugin is a user error.
-                    (Some(sess), true)  => sess.err(&msg[]),
+                    (Some(sess), true)  => sess.err(&msg[..]),
                 }
             }
 
@@ -150,11 +150,11 @@ impl LintStore {
             match (sess, from_plugin) {
                 // We load builtin lints first, so a duplicate is a compiler bug.
                 // Use early_error when handling -W help with no crate.
-                (None, _) => early_error(&msg[]),
-                (Some(sess), false) => sess.bug(&msg[]),
+                (None, _) => early_error(&msg[..]),
+                (Some(sess), false) => sess.bug(&msg[..]),
 
                 // A duplicate name from a plugin is a user error.
-                (Some(sess), true)  => sess.err(&msg[]),
+                (Some(sess), true)  => sess.err(&msg[..]),
             }
         }
     }
@@ -251,8 +251,8 @@ impl LintStore {
                 let warning = format!("lint {} has been renamed to {}",
                                       lint_name, new_name);
                 match span {
-                    Some(span) => sess.span_warn(span, &warning[]),
-                    None => sess.warn(&warning[]),
+                    Some(span) => sess.span_warn(span, &warning[..]),
+                    None => sess.warn(&warning[..]),
                 };
                 Some(lint_id)
             }
@@ -262,13 +262,13 @@ impl LintStore {
 
     pub fn process_command_line(&mut self, sess: &Session) {
         for &(ref lint_name, level) in &sess.opts.lint_opts {
-            match self.find_lint(&lint_name[], sess, None) {
+            match self.find_lint(&lint_name[..], sess, None) {
                 Some(lint_id) => self.set_level(lint_id, (level, CommandLine)),
                 None => {
                     match self.lint_groups.iter().map(|(&x, pair)| (x, pair.0.clone()))
                                                  .collect::<FnvHashMap<&'static str,
                                                                        Vec<LintId>>>()
-                                                 .get(&lint_name[]) {
+                                                 .get(&lint_name[..]) {
                         Some(v) => {
                             v.iter()
                              .map(|lint_id: &LintId|
@@ -411,15 +411,15 @@ pub fn raw_emit_lint(sess: &Session, lint: &'static Lint,
     if level == Forbid { level = Deny; }
 
     match (level, span) {
-        (Warn, Some(sp)) => sess.span_warn(sp, &msg[]),
-        (Warn, None)     => sess.warn(&msg[]),
-        (Deny, Some(sp)) => sess.span_err(sp, &msg[]),
-        (Deny, None)     => sess.err(&msg[]),
+        (Warn, Some(sp)) => sess.span_warn(sp, &msg[..]),
+        (Warn, None)     => sess.warn(&msg[..]),
+        (Deny, Some(sp)) => sess.span_err(sp, &msg[..]),
+        (Deny, None)     => sess.err(&msg[..]),
         _ => sess.bug("impossible level in raw_emit_lint"),
     }
 
     if let Some(note) = note {
-        sess.note(&note[]);
+        sess.note(&note[..]);
     }
 
     if let Some(span) = def {
@@ -503,7 +503,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> {
                     match self.lints.find_lint(&lint_name, &self.tcx.sess, Some(span)) {
                         Some(lint_id) => vec![(lint_id, level, span)],
                         None => {
-                            match self.lints.lint_groups.get(&lint_name[]) {
+                            match self.lints.lint_groups.get(&lint_name[..]) {
                                 Some(&(ref v, _)) => v.iter()
                                                       .map(|lint_id: &LintId|
                                                            (*lint_id, level, span))
@@ -729,7 +729,7 @@ impl<'a, 'tcx> IdVisitingOperation for Context<'a, 'tcx> {
             None => {}
             Some(lints) => {
                 for (lint_id, span, msg) in lints {
-                    self.span_lint(lint_id.lint, span, &msg[])
+                    self.span_lint(lint_id.lint, span, &msg[..])
                 }
             }
         }
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index 5dc23d27ee1..bdcc10ebcec 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -185,12 +185,20 @@ impl PartialEq for LintId {
 
 impl Eq for LintId { }
 
+#[cfg(stage0)]
 impl<S: hash::Writer + hash::Hasher> hash::Hash<S> for LintId {
     fn hash(&self, state: &mut S) {
         let ptr = self.lint as *const Lint;
         ptr.hash(state);
     }
 }
+#[cfg(not(stage0))]
+impl hash::Hash for LintId {
+    fn hash<H: hash::Hasher>(&self, state: &mut H) {
+        let ptr = self.lint as *const Lint;
+        ptr.hash(state);
+    }
+}
 
 impl LintId {
     /// Get the `LintId` for a `Lint`.
diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs
index 0871c36d892..d48a404176a 100644
--- a/src/librustc/metadata/creader.rs
+++ b/src/librustc/metadata/creader.rs
@@ -183,7 +183,7 @@ impl<'a> CrateReader<'a> {
                 let name = match *path_opt {
                     Some((ref path_str, _)) => {
                         let name = path_str.to_string();
-                        validate_crate_name(Some(self.sess), &name[],
+                        validate_crate_name(Some(self.sess), &name[..],
                                             Some(i.span));
                         name
                     }
@@ -321,7 +321,7 @@ impl<'a> CrateReader<'a> {
             let source = self.sess.cstore.get_used_crate_source(cnum).unwrap();
             if let Some(locs) = self.sess.opts.externs.get(name) {
                 let found = locs.iter().any(|l| {
-                    let l = fs::realpath(&Path::new(&l[])).ok();
+                    let l = fs::realpath(&Path::new(&l[..])).ok();
                     source.dylib.as_ref().map(|p| &p.0) == l.as_ref() ||
                     source.rlib.as_ref().map(|p| &p.0) == l.as_ref()
                 });
@@ -459,8 +459,8 @@ impl<'a> CrateReader<'a> {
         let mut load_ctxt = loader::Context {
             sess: self.sess,
             span: span,
-            ident: &ident[],
-            crate_name: &name[],
+            ident: &ident[..],
+            crate_name: &name[..],
             hash: None,
             filesearch: self.sess.host_filesearch(PathKind::Crate),
             target: &self.sess.host,
@@ -562,7 +562,7 @@ impl<'a> CrateReader<'a> {
                                   name,
                                   config::host_triple(),
                                   self.sess.opts.target_triple);
-            self.sess.span_err(span, &message[]);
+            self.sess.span_err(span, &message[..]);
             self.sess.abort_if_errors();
         }
 
@@ -575,7 +575,7 @@ impl<'a> CrateReader<'a> {
                 let message = format!("plugin `{}` only found in rlib format, \
                                        but must be available in dylib format",
                                        name);
-                self.sess.span_err(span, &message[]);
+                self.sess.span_err(span, &message[..]);
                 // No need to abort because the loading code will just ignore this
                 // empty dylib.
                 None
diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs
index 0a3e173b35e..a3f7d57da67 100644
--- a/src/librustc/metadata/cstore.rs
+++ b/src/librustc/metadata/cstore.rs
@@ -139,8 +139,7 @@ impl CStore {
     pub fn get_used_crate_source(&self, cnum: ast::CrateNum)
                                      -> Option<CrateSource> {
         self.used_crate_sources.borrow_mut()
-            .iter().find(|source| source.cnum == cnum)
-            .map(|source| source.clone())
+            .iter().find(|source| source.cnum == cnum).cloned()
     }
 
     pub fn reset(&self) {
@@ -218,7 +217,7 @@ impl CStore {
 
     pub fn find_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId)
                                      -> Option<ast::CrateNum> {
-        self.extern_mod_crate_map.borrow().get(&emod_id).map(|x| *x)
+        self.extern_mod_crate_map.borrow().get(&emod_id).cloned()
     }
 }
 
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index 3123fa31abd..42a70cec5df 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -163,7 +163,7 @@ fn encode_variant_id(rbml_w: &mut Encoder, vid: DefId) {
     rbml_w.end_tag();
 
     rbml_w.start_tag(tag_mod_child);
-    rbml_w.wr_str(&s[]);
+    rbml_w.wr_str(&s[..]);
     rbml_w.end_tag();
 }
 
@@ -353,9 +353,9 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
                 let fields = ty::lookup_struct_fields(ecx.tcx, def_id);
                 let idx = encode_info_for_struct(ecx,
                                                  rbml_w,
-                                                 &fields[],
+                                                 &fields[..],
                                                  index);
-                encode_struct_fields(rbml_w, &fields[], def_id);
+                encode_struct_fields(rbml_w, &fields[..], def_id);
                 encode_index(rbml_w, idx, write_i64);
             }
         }
@@ -1158,7 +1158,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
            class itself */
         let idx = encode_info_for_struct(ecx,
                                          rbml_w,
-                                         &fields[],
+                                         &fields[..],
                                          index);
 
         /* Index the class*/
@@ -1181,7 +1181,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
         /* Encode def_ids for each field and method
          for methods, write all the stuff get_trait_method
         needs to know*/
-        encode_struct_fields(rbml_w, &fields[], def_id);
+        encode_struct_fields(rbml_w, &fields[..], def_id);
 
         encode_inlined_item(ecx, rbml_w, IIItemRef(item));
 
@@ -1588,6 +1588,7 @@ fn encode_info_for_items(ecx: &EncodeContext,
 
 // Path and definition ID indexing
 
+#[cfg(stage0)]
 fn encode_index<T, F>(rbml_w: &mut Encoder, index: Vec<entry<T>>, mut write_fn: F) where
     F: FnMut(&mut SeekableMemWriter, &T),
     T: Hash<SipHasher>,
@@ -1628,6 +1629,47 @@ fn encode_index<T, F>(rbml_w: &mut Encoder, index: Vec<entry<T>>, mut write_fn:
     rbml_w.end_tag();
     rbml_w.end_tag();
 }
+#[cfg(not(stage0))]
+fn encode_index<T, F>(rbml_w: &mut Encoder, index: Vec<entry<T>>, mut write_fn: F) where
+    F: FnMut(&mut SeekableMemWriter, &T),
+    T: Hash,
+{
+    let mut buckets: Vec<Vec<entry<T>>> = (0..256u16).map(|_| Vec::new()).collect();
+    for elt in index {
+        let mut s = SipHasher::new();
+        elt.val.hash(&mut s);
+        let h = s.finish() as uint;
+        (&mut buckets[h % 256]).push(elt);
+    }
+
+    rbml_w.start_tag(tag_index);
+    let mut bucket_locs = Vec::new();
+    rbml_w.start_tag(tag_index_buckets);
+    for bucket in &buckets {
+        bucket_locs.push(rbml_w.writer.tell().unwrap());
+        rbml_w.start_tag(tag_index_buckets_bucket);
+        for elt in bucket {
+            rbml_w.start_tag(tag_index_buckets_bucket_elt);
+            assert!(elt.pos < 0xffff_ffff);
+            {
+                let wr: &mut SeekableMemWriter = rbml_w.writer;
+                wr.write_be_u32(elt.pos as u32);
+            }
+            write_fn(rbml_w.writer, &elt.val);
+            rbml_w.end_tag();
+        }
+        rbml_w.end_tag();
+    }
+    rbml_w.end_tag();
+    rbml_w.start_tag(tag_index_table);
+    for pos in &bucket_locs {
+        assert!(*pos < 0xffff_ffff);
+        let wr: &mut SeekableMemWriter = rbml_w.writer;
+        wr.write_be_u32(*pos as u32);
+    }
+    rbml_w.end_tag();
+    rbml_w.end_tag();
+}
 
 fn write_i64(writer: &mut SeekableMemWriter, &n: &i64) {
     let wr: &mut SeekableMemWriter = writer;
diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs
index 3158ccd0765..01d1f4e7011 100644
--- a/src/librustc/metadata/loader.rs
+++ b/src/librustc/metadata/loader.rs
@@ -322,7 +322,7 @@ impl<'a> Context<'a> {
             &Some(ref r) => format!("{} which `{}` depends on",
                                     message, r.ident)
         };
-        self.sess.span_err(self.span, &message[]);
+        self.sess.span_err(self.span, &message[..]);
 
         if self.rejected_via_triple.len() > 0 {
             let mismatches = self.rejected_via_triple.iter();
@@ -404,7 +404,7 @@ impl<'a> Context<'a> {
                 None => return FileDoesntMatch,
                 Some(file) => file,
             };
-            let (hash, rlib) = if file.starts_with(&rlib_prefix[]) &&
+            let (hash, rlib) = if file.starts_with(&rlib_prefix[..]) &&
                                   file.ends_with(".rlib") {
                 (&file[(rlib_prefix.len()) .. (file.len() - ".rlib".len())],
                  true)
@@ -413,7 +413,7 @@ impl<'a> Context<'a> {
                 (&file[(dylib_prefix.len()) .. (file.len() - dypair.1.len())],
                  false)
             } else {
-                if file.starts_with(&staticlib_prefix[]) &&
+                if file.starts_with(&staticlib_prefix[..]) &&
                    file.ends_with(".a") {
                     staticlibs.push(CrateMismatch {
                         path: path.clone(),
@@ -627,7 +627,7 @@ impl<'a> Context<'a> {
         let mut rlibs = HashMap::new();
         let mut dylibs = HashMap::new();
         {
-            let locs = locs.iter().map(|l| Path::new(&l[])).filter(|loc| {
+            let locs = locs.iter().map(|l| Path::new(&l[..])).filter(|loc| {
                 if !loc.exists() {
                     sess.err(&format!("extern location for {} does not exist: {}",
                                      self.crate_name, loc.display())[]);
@@ -645,8 +645,8 @@ impl<'a> Context<'a> {
                     return true
                 } else {
                     let (ref prefix, ref suffix) = dylibname;
-                    if file.starts_with(&prefix[]) &&
-                       file.ends_with(&suffix[]) {
+                    if file.starts_with(&prefix[..]) &&
+                       file.ends_with(&suffix[..]) {
                         return true
                     }
                 }
@@ -744,7 +744,7 @@ fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result<MetadataBlo
         }
     }
     unsafe {
-        let buf = CString::from_slice(filename.as_vec());
+        let buf = CString::new(filename.as_vec()).unwrap();
         let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr());
         if mb as int == 0 {
             return Err(format!("error reading library: '{}'",
diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs
index 94654b84922..5805725a8fc 100644
--- a/src/librustc/metadata/tydecode.rs
+++ b/src/librustc/metadata/tydecode.rs
@@ -641,7 +641,7 @@ fn parse_abi_set(st: &mut PState) -> abi::Abi {
     assert_eq!(next(st), '[');
     scan(st, |c| c == ']', |bytes| {
         let abi_str = str::from_utf8(bytes).unwrap();
-        abi::lookup(&abi_str[]).expect(abi_str)
+        abi::lookup(&abi_str[..]).expect(abi_str)
     })
 }
 
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index c3302debdfa..ae10eb686b0 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -134,7 +134,7 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata,
             // Do an Option dance to use the path after it is moved below.
             let s = ast_map::path_to_string(path.iter().cloned());
             path_as_str = Some(s);
-            path_as_str.as_ref().map(|x| &x[])
+            path_as_str.as_ref().map(|x| &x[..])
         });
         let mut ast_dsr = reader::Decoder::new(ast_doc);
         let from_id_range = Decodable::decode(&mut ast_dsr).unwrap();
diff --git a/src/librustc/middle/cfg/graphviz.rs b/src/librustc/middle/cfg/graphviz.rs
index 1f0fe4f1aca..46b4a51c9d6 100644
--- a/src/librustc/middle/cfg/graphviz.rs
+++ b/src/librustc/middle/cfg/graphviz.rs
@@ -92,7 +92,7 @@ impl<'a, 'ast> dot::Labeller<'a, Node<'a>, Edge<'a>> for LabelledCFG<'a, 'ast> {
             let s = replace_newline_with_backslash_l(s);
             label.push_str(&format!("exiting scope_{} {}",
                                    i,
-                                   &s[])[]);
+                                   &s[..])[]);
         }
         dot::LabelText::EscStr(label.into_cow())
     }
diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs
index 03456f85290..86c59b24e3e 100644
--- a/src/librustc/middle/check_match.rs
+++ b/src/librustc/middle/check_match.rs
@@ -25,7 +25,7 @@ use middle::ty::*;
 use middle::ty;
 use std::cmp::Ordering;
 use std::fmt;
-use std::iter::{range_inclusive, AdditiveIterator, FromIterator, repeat};
+use std::iter::{range_inclusive, AdditiveIterator, FromIterator, IntoIterator, repeat};
 use std::num::Float;
 use std::slice;
 use syntax::ast::{self, DUMMY_NODE_ID, NodeId, Pat};
@@ -76,7 +76,7 @@ impl<'a> fmt::Debug for Matrix<'a> {
             pretty_printed_matrix.iter().map(|row| row[col].len()).max().unwrap_or(0)
         }).collect();
 
-        let total_width = column_widths.iter().map(|n| *n).sum() + column_count * 3 + 1;
+        let total_width = column_widths.iter().cloned().sum() + column_count * 3 + 1;
         let br = repeat('+').take(total_width).collect::<String>();
         try!(write!(f, "{}\n", br));
         for row in pretty_printed_matrix {
@@ -94,8 +94,8 @@ impl<'a> fmt::Debug for Matrix<'a> {
 }
 
 impl<'a> FromIterator<Vec<&'a Pat>> for Matrix<'a> {
-    fn from_iter<T: Iterator<Item=Vec<&'a Pat>>>(iterator: T) -> Matrix<'a> {
-        Matrix(iterator.collect())
+    fn from_iter<T: IntoIterator<Item=Vec<&'a Pat>>>(iter: T) -> Matrix<'a> {
+        Matrix(iter.into_iter().collect())
     }
 }
 
@@ -200,7 +200,7 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &ast::Expr) {
             }
 
             // Fourth, check for unreachable arms.
-            check_arms(cx, &inlined_arms[], source);
+            check_arms(cx, &inlined_arms[..], source);
 
             // Finally, check if the whole match expression is exhaustive.
             // Check for empty enum, because is_useful only works on inhabited types.
@@ -291,7 +291,7 @@ fn check_arms(cx: &MatchCheckCtxt,
         for pat in pats {
             let v = vec![&**pat];
 
-            match is_useful(cx, &seen, &v[], LeaveOutWitness) {
+            match is_useful(cx, &seen, &v[..], LeaveOutWitness) {
                 NotUseful => {
                     match source {
                         ast::MatchSource::IfLetDesugar { .. } => {
@@ -351,7 +351,7 @@ fn raw_pat<'a>(p: &'a Pat) -> &'a Pat {
 fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, matrix: &Matrix, source: ast::MatchSource) {
     match is_useful(cx, matrix, &[DUMMY_WILD_PAT], ConstructWitness) {
         UsefulWithWitness(pats) => {
-            let witness = match &pats[] {
+            let witness = match &pats[..] {
                 [ref witness] => &**witness,
                 [] => DUMMY_WILD_PAT,
                 _ => unreachable!()
@@ -360,7 +360,7 @@ fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, matrix: &Matrix, source: ast:
                 ast::MatchSource::ForLoopDesugar => {
                     // `witness` has the form `Some(<head>)`, peel off the `Some`
                     let witness = match witness.node {
-                        ast::PatEnum(_, Some(ref pats)) => match &pats[] {
+                        ast::PatEnum(_, Some(ref pats)) => match &pats[..] {
                             [ref pat] => &**pat,
                             _ => unreachable!(),
                         },
@@ -664,7 +664,7 @@ fn is_useful(cx: &MatchCheckCtxt,
                         UsefulWithWitness(pats) => UsefulWithWitness({
                             let arity = constructor_arity(cx, &c, left_ty);
                             let mut result = {
-                                let pat_slice = &pats[];
+                                let pat_slice = &pats[..];
                                 let subpats: Vec<_> = (0..arity).map(|i| {
                                     pat_slice.get(i).map_or(DUMMY_WILD_PAT, |p| &**p)
                                 }).collect();
@@ -711,10 +711,10 @@ fn is_useful_specialized(cx: &MatchCheckCtxt, &Matrix(ref m): &Matrix,
                          witness: WitnessPreference) -> Usefulness {
     let arity = constructor_arity(cx, &ctor, lty);
     let matrix = Matrix(m.iter().filter_map(|r| {
-        specialize(cx, &r[], &ctor, 0, arity)
+        specialize(cx, &r[..], &ctor, 0, arity)
     }).collect());
     match specialize(cx, v, &ctor, 0, arity) {
-        Some(v) => is_useful(cx, &matrix, &v[], witness),
+        Some(v) => is_useful(cx, &matrix, &v[..], witness),
         None => NotUseful
     }
 }
diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs
index 3d03cd946c4..5bf7422dbc0 100644
--- a/src/librustc/middle/const_eval.rs
+++ b/src/librustc/middle/const_eval.rs
@@ -62,7 +62,7 @@ fn lookup_variant_by_id<'a>(tcx: &'a ty::ctxt,
             None => None,
             Some(ast_map::NodeItem(it)) => match it.node {
                 ast::ItemEnum(ast::EnumDef { ref variants }, _) => {
-                    variant_expr(&variants[], variant_def.node)
+                    variant_expr(&variants[..], variant_def.node)
                 }
                 _ => None
             },
@@ -83,7 +83,7 @@ fn lookup_variant_by_id<'a>(tcx: &'a ty::ctxt,
                     // NOTE this doesn't do the right thing, it compares inlined
                     // NodeId's to the original variant_def's NodeId, but they
                     // come from different crates, so they will likely never match.
-                    variant_expr(&variants[], variant_def.node).map(|e| e.id)
+                    variant_expr(&variants[..], variant_def.node).map(|e| e.id)
                 }
                 _ => None
             },
@@ -209,7 +209,7 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P<ast::Pat>
 pub fn eval_const_expr(tcx: &ty::ctxt, e: &Expr) -> const_val {
     match eval_const_expr_partial(tcx, e, None) {
         Ok(r) => r,
-        Err(s) => tcx.sess.span_fatal(e.span, &s[])
+        Err(s) => tcx.sess.span_fatal(e.span, &s[..])
     }
 }
 
@@ -501,7 +501,7 @@ fn lit_to_const(lit: &ast::Lit, ty_hint: Option<Ty>) -> const_val {
     match lit.node {
         ast::LitStr(ref s, _) => const_str((*s).clone()),
         ast::LitBinary(ref data) => {
-            const_binary(Rc::new(data.iter().map(|x| *x).collect()))
+            const_binary(data.clone())
         }
         ast::LitByte(n) => const_uint(n as u64),
         ast::LitChar(n) => const_uint(n as u64),
@@ -552,14 +552,14 @@ pub fn compare_lit_exprs<'tcx>(tcx: &ty::ctxt<'tcx>,
     let a = match eval_const_expr_partial(tcx, a, ty_hint) {
         Ok(a) => a,
         Err(s) => {
-            tcx.sess.span_err(a.span, &s[]);
+            tcx.sess.span_err(a.span, &s[..]);
             return None;
         }
     };
     let b = match eval_const_expr_partial(tcx, b, ty_hint) {
         Ok(b) => b,
         Err(s) => {
-            tcx.sess.span_err(b.span, &s[]);
+            tcx.sess.span_err(b.span, &s[..]);
             return None;
         }
     };
diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs
index b792a44d4d8..085d5cbc347 100644
--- a/src/librustc/middle/dataflow.rs
+++ b/src/librustc/middle/dataflow.rs
@@ -89,7 +89,7 @@ struct PropagationContext<'a, 'b: 'a, 'tcx: 'b, O: 'a> {
 }
 
 fn to_cfgidx_or_die(id: ast::NodeId, index: &NodeMap<CFGIndex>) -> CFGIndex {
-    let opt_cfgindex = index.get(&id).map(|&i|i);
+    let opt_cfgindex = index.get(&id).cloned();
     opt_cfgindex.unwrap_or_else(|| {
         panic!("nodeid_to_index does not have entry for NodeId {}", id);
     })
@@ -312,7 +312,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
                 let mut t = on_entry.to_vec();
                 self.apply_gen_kill(cfgidx, &mut t);
                 temp_bits = t;
-                &temp_bits[]
+                &temp_bits[..]
             }
         };
         debug!("{} each_bit_for_node({:?}, cfgidx={:?}) bits={}",
@@ -400,7 +400,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
 
             let mut changed = false;
             for &node_id in &edge.data.exiting_scopes {
-                let opt_cfg_idx = self.nodeid_to_index.get(&node_id).map(|&i|i);
+                let opt_cfg_idx = self.nodeid_to_index.get(&node_id).cloned();
                 match opt_cfg_idx {
                     Some(cfg_idx) => {
                         let (start, end) = self.compute_id_range(cfg_idx);
@@ -421,7 +421,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
                 let bits = &mut self.kills[start.. end];
                 debug!("{} add_kills_from_flow_exits flow_exit={:?} bits={} [before]",
                        self.analysis_name, flow_exit, mut_bits_to_string(bits));
-                bits.clone_from_slice(&orig_kills[]);
+                bits.clone_from_slice(&orig_kills[..]);
                 debug!("{} add_kills_from_flow_exits flow_exit={:?} bits={} [after]",
                        self.analysis_name, flow_exit, mut_bits_to_string(bits));
             }
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index b2335f91ad9..ff78deb8d12 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -321,7 +321,7 @@ fn has_allow_dead_code_or_lang_attr(attrs: &[ast::Attribute]) -> bool {
     for attr in lint::gather_attrs(attrs) {
         match attr {
             Ok((ref name, lint::Allow, _))
-                if &name[] == dead_code => return true,
+                if &name[..] == dead_code => return true,
             _ => (),
         }
     }
diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs
index 6d35a82d153..ad9f4eade5c 100644
--- a/src/librustc/middle/dependency_format.rs
+++ b/src/librustc/middle/dependency_format.rs
@@ -158,7 +158,7 @@ fn calculate_type(sess: &session::Session,
 
     // Collect what we've got so far in the return vector.
     let mut ret = (1..sess.cstore.next_crate_num()).map(|i| {
-        match formats.get(&i).map(|v| *v) {
+        match formats.get(&i).cloned() {
             v @ Some(cstore::RequireDynamic) => v,
             _ => None,
         }
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index 8dbac7f515e..e99d214742a 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -29,7 +29,6 @@ use middle::ty::{MethodOrigin, MethodParam, MethodTypeParam};
 use middle::ty::{MethodStatic, MethodStaticClosure};
 use util::ppaux::Repr;
 
-use std::marker;
 use syntax::{ast, ast_util};
 use syntax::ptr::P;
 use syntax::codemap::Span;
@@ -128,16 +127,14 @@ pub enum MatchMode {
     MovingMatch,
 }
 
-#[derive(PartialEq,Debug)]
-enum TrackMatchMode<T> {
+#[derive(Copy, PartialEq, Debug)]
+enum TrackMatchMode {
     Unknown,
     Definite(MatchMode),
     Conflicting,
 }
 
-impl<T> marker::Copy for TrackMatchMode<T> {}
-
-impl<T> TrackMatchMode<T> {
+impl TrackMatchMode {
     // Builds up the whole match mode for a pattern from its constituent
     // parts.  The lattice looks like this:
     //
@@ -931,7 +928,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
         return true;
     }
 
-    fn arm_move_mode(&mut self, discr_cmt: mc::cmt<'tcx>, arm: &ast::Arm) -> TrackMatchMode<Span> {
+    fn arm_move_mode(&mut self, discr_cmt: mc::cmt<'tcx>, arm: &ast::Arm) -> TrackMatchMode {
         let mut mode = Unknown;
         for pat in &arm.pats {
             self.determine_pat_move_mode(discr_cmt.clone(), &**pat, &mut mode);
@@ -966,7 +963,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
     fn determine_pat_move_mode(&mut self,
                                cmt_discr: mc::cmt<'tcx>,
                                pat: &ast::Pat,
-                               mode: &mut TrackMatchMode<Span>) {
+                               mode: &mut TrackMatchMode) {
         debug!("determine_pat_move_mode cmt_discr={} pat={}", cmt_discr.repr(self.tcx()),
                pat.repr(self.tcx()));
         return_if_err!(self.mc.cat_pattern(cmt_discr, pat, |_mc, cmt_pat, pat| {
@@ -1166,7 +1163,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
                                 let msg = format!("Pattern has unexpected def: {:?} and type {}",
                                                   def,
                                                   cmt_pat.ty.repr(tcx));
-                                tcx.sess.span_bug(pat.span, &msg[])
+                                tcx.sess.span_bug(pat.span, &msg[..])
                             }
                         }
                     }
diff --git a/src/librustc/middle/graph.rs b/src/librustc/middle/graph.rs
index 4dd7a4a2266..436f04fc9e9 100644
--- a/src/librustc/middle/graph.rs
+++ b/src/librustc/middle/graph.rs
@@ -34,7 +34,7 @@
 
 use std::fmt::{Formatter, Error, Debug};
 use std::usize;
-use std::collections::BitvSet;
+use std::collections::BitSet;
 
 pub struct Graph<N,E> {
     nodes: Vec<Node<N>> ,
@@ -292,7 +292,7 @@ impl<N,E> Graph<N,E> {
         DepthFirstTraversal {
             graph: self,
             stack: vec![start],
-            visited: BitvSet::new()
+            visited: BitSet::new()
         }
     }
 }
@@ -300,7 +300,7 @@ impl<N,E> Graph<N,E> {
 pub struct DepthFirstTraversal<'g, N:'g, E:'g> {
     graph: &'g Graph<N, E>,
     stack: Vec<NodeIndex>,
-    visited: BitvSet
+    visited: BitSet
 }
 
 impl<'g, N, E> Iterator for DepthFirstTraversal<'g, N, E> {
diff --git a/src/librustc/middle/infer/bivariate.rs b/src/librustc/middle/infer/bivariate.rs
new file mode 100644
index 00000000000..93c80fb754f
--- /dev/null
+++ b/src/librustc/middle/infer/bivariate.rs
@@ -0,0 +1,145 @@
+// Copyright 2014 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.
+
+//! Applies the "bivariance relationship" to two types and/or regions.
+//! If (A,B) are bivariant then either A <: B or B <: A. It occurs
+//! when type/lifetime parameters are unconstrained. Usually this is
+//! an error, but we permit it in the specific case where a type
+//! parameter is constrained in a where-clause via an associated type.
+//!
+//! There are several ways one could implement bivariance. You could
+//! just do nothing at all, for example, or you could fully verify
+//! that one of the two subtyping relationships hold. We choose to
+//! thread a middle line: we relate types up to regions, but ignore
+//! all region relationships.
+//!
+//! At one point, handling bivariance in this fashion was necessary
+//! for inference, but I'm actually not sure if that is true anymore.
+//! In particular, it might be enough to say (A,B) are bivariant for
+//! all (A,B).
+
+use middle::ty::{BuiltinBounds};
+use middle::ty::{self, Ty};
+use middle::ty::TyVar;
+use middle::infer::combine::*;
+use middle::infer::{cres};
+use middle::infer::type_variable::{BiTo};
+use util::ppaux::{Repr};
+
+use syntax::ast::{Unsafety};
+
+pub struct Bivariate<'f, 'tcx: 'f> {
+    fields: CombineFields<'f, 'tcx>
+}
+
+#[allow(non_snake_case)]
+pub fn Bivariate<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Bivariate<'f, 'tcx> {
+    Bivariate { fields: cf }
+}
+
+impl<'f, 'tcx> Combine<'tcx> for Bivariate<'f, 'tcx> {
+    fn tag(&self) -> String { "Bivariate".to_string() }
+    fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields }
+
+    fn tys_with_variance(&self, v: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>)
+                         -> cres<'tcx, Ty<'tcx>>
+    {
+        match v {
+            ty::Invariant => self.equate().tys(a, b),
+            ty::Covariant => self.tys(a, b),
+            ty::Contravariant => self.tys(a, b),
+            ty::Bivariant => self.tys(a, b),
+        }
+    }
+
+    fn regions_with_variance(&self, v: ty::Variance, a: ty::Region, b: ty::Region)
+                             -> cres<'tcx, ty::Region>
+    {
+        match v {
+            ty::Invariant => self.equate().regions(a, b),
+            ty::Covariant => self.regions(a, b),
+            ty::Contravariant => self.regions(a, b),
+            ty::Bivariant => self.regions(a, b),
+        }
+    }
+
+    fn regions(&self, a: ty::Region, _: ty::Region) -> cres<'tcx, ty::Region> {
+        Ok(a)
+    }
+
+    fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>) -> cres<'tcx, ty::mt<'tcx>> {
+        debug!("mts({} <: {})",
+               a.repr(self.fields.infcx.tcx),
+               b.repr(self.fields.infcx.tcx));
+
+        if a.mutbl != b.mutbl { return Err(ty::terr_mutability); }
+        let t = try!(self.tys(a.ty, b.ty));
+        Ok(ty::mt { mutbl: a.mutbl, ty: t })
+    }
+
+    fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety> {
+        if a != b {
+            Err(ty::terr_unsafety_mismatch(expected_found(self, a, b)))
+        } else {
+            Ok(a)
+        }
+    }
+
+    fn builtin_bounds(&self,
+                      a: BuiltinBounds,
+                      b: BuiltinBounds)
+                      -> cres<'tcx, BuiltinBounds>
+    {
+        if a != b {
+            Err(ty::terr_builtin_bounds(expected_found(self, a, b)))
+        } else {
+            Ok(a)
+        }
+    }
+
+    fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> {
+        debug!("{}.tys({}, {})", self.tag(),
+               a.repr(self.fields.infcx.tcx), b.repr(self.fields.infcx.tcx));
+        if a == b { return Ok(a); }
+
+        let infcx = self.fields.infcx;
+        let a = infcx.type_variables.borrow().replace_if_possible(a);
+        let b = infcx.type_variables.borrow().replace_if_possible(b);
+        match (&a.sty, &b.sty) {
+            (&ty::ty_infer(TyVar(a_id)), &ty::ty_infer(TyVar(b_id))) => {
+                infcx.type_variables.borrow_mut().relate_vars(a_id, BiTo, b_id);
+                Ok(a)
+            }
+
+            (&ty::ty_infer(TyVar(a_id)), _) => {
+                try!(self.fields.instantiate(b, BiTo, a_id));
+                Ok(a)
+            }
+
+            (_, &ty::ty_infer(TyVar(b_id))) => {
+                try!(self.fields.instantiate(a, BiTo, b_id));
+                Ok(a)
+            }
+
+            _ => {
+                super_tys(self, a, b)
+            }
+        }
+    }
+
+    fn binders<T>(&self, a: &ty::Binder<T>, b: &ty::Binder<T>) -> cres<'tcx, ty::Binder<T>>
+        where T : Combineable<'tcx>
+    {
+        let a1 = ty::erase_late_bound_regions(self.tcx(), a);
+        let b1 = ty::erase_late_bound_regions(self.tcx(), b);
+        let c = try!(Combineable::combine(self, &a1, &b1));
+        Ok(ty::Binder(c))
+    }
+}
diff --git a/src/librustc/middle/infer/combine.rs b/src/librustc/middle/infer/combine.rs
index daa820f43b5..0eeafb767d8 100644
--- a/src/librustc/middle/infer/combine.rs
+++ b/src/librustc/middle/infer/combine.rs
@@ -32,6 +32,7 @@
 // is also useful to track which value is the "expected" value in
 // terms of error reporting.
 
+use super::bivariate::Bivariate;
 use super::equate::Equate;
 use super::glb::Glb;
 use super::lub::Lub;
@@ -39,7 +40,7 @@ use super::sub::Sub;
 use super::unify::InferCtxtMethodsForSimplyUnifiableTypes;
 use super::{InferCtxt, cres};
 use super::{MiscVariable, TypeTrace};
-use super::type_variable::{RelationDir, EqTo, SubtypeOf, SupertypeOf};
+use super::type_variable::{RelationDir, BiTo, EqTo, SubtypeOf, SupertypeOf};
 
 use middle::subst;
 use middle::subst::{ErasedRegions, NonerasedRegions, Substs};
@@ -48,7 +49,7 @@ use middle::ty::{IntType, UintType};
 use middle::ty::{BuiltinBounds};
 use middle::ty::{self, Ty};
 use middle::ty_fold;
-use middle::ty_fold::{TypeFoldable};
+use middle::ty_fold::{TypeFolder, TypeFoldable};
 use util::ppaux::Repr;
 
 use std::rc::Rc;
@@ -58,41 +59,32 @@ use syntax::abi;
 use syntax::codemap::Span;
 
 pub trait Combine<'tcx> : Sized {
-    fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx>;
     fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx> { self.infcx().tcx }
     fn tag(&self) -> String;
-    fn a_is_expected(&self) -> bool;
-    fn trace(&self) -> TypeTrace<'tcx>;
 
-    fn equate<'a>(&'a self) -> Equate<'a, 'tcx>;
-    fn sub<'a>(&'a self) -> Sub<'a, 'tcx>;
-    fn lub<'a>(&'a self) -> Lub<'a, 'tcx>;
-    fn glb<'a>(&'a self) -> Glb<'a, 'tcx>;
+    fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx>;
+
+    fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx> { self.fields().infcx }
+    fn a_is_expected(&self) -> bool { self.fields().a_is_expected }
+    fn trace(&self) -> TypeTrace<'tcx> { self.fields().trace.clone() }
+    fn equate<'a>(&'a self) -> Equate<'a, 'tcx> { self.fields().equate() }
+    fn bivariate<'a>(&'a self) -> Bivariate<'a, 'tcx> { self.fields().bivariate() }
+
+    fn sub<'a>(&'a self) -> Sub<'a, 'tcx> { self.fields().sub() }
+    fn lub<'a>(&'a self) -> Lub<'a, 'tcx> { Lub(self.fields().clone()) }
+    fn glb<'a>(&'a self) -> Glb<'a, 'tcx> { Glb(self.fields().clone()) }
 
     fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>) -> cres<'tcx, ty::mt<'tcx>>;
-    fn contratys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>>;
+
+    fn tys_with_variance(&self, variance: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>)
+                         -> cres<'tcx, Ty<'tcx>>;
+
     fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>>;
 
-    fn tps(&self,
-           _: subst::ParamSpace,
-           as_: &[Ty<'tcx>],
-           bs: &[Ty<'tcx>])
-           -> cres<'tcx, Vec<Ty<'tcx>>> {
-        // FIXME -- In general, we treat variance a bit wrong
-        // here. For historical reasons, we treat tps and Self
-        // as invariant. This is overly conservative.
-
-        if as_.len() != bs.len() {
-            return Err(ty::terr_ty_param_size(expected_found(self,
-                                                             as_.len(),
-                                                             bs.len())));
-        }
+    fn regions_with_variance(&self, variance: ty::Variance, a: ty::Region, b: ty::Region)
+                             -> cres<'tcx, ty::Region>;
 
-        try!(as_.iter().zip(bs.iter())
-                .map(|(a, b)| self.equate().tys(*a, *b))
-                .collect::<cres<Vec<Ty>>>());
-        Ok(as_.to_vec())
-    }
+    fn regions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region>;
 
     fn substs(&self,
               item_def_id: ast::DefId,
@@ -100,6 +92,11 @@ pub trait Combine<'tcx> : Sized {
               b_subst: &subst::Substs<'tcx>)
               -> cres<'tcx, subst::Substs<'tcx>>
     {
+        debug!("substs: item_def_id={} a_subst={} b_subst={}",
+               item_def_id.repr(self.infcx().tcx),
+               a_subst.repr(self.infcx().tcx),
+               b_subst.repr(self.infcx().tcx));
+
         let variances = if self.infcx().tcx.variance_computed.get() {
             Some(ty::item_variances(self.infcx().tcx, item_def_id))
         } else {
@@ -119,7 +116,8 @@ pub trait Combine<'tcx> : Sized {
         for &space in &subst::ParamSpace::all() {
             let a_tps = a_subst.types.get_slice(space);
             let b_tps = b_subst.types.get_slice(space);
-            let tps = try!(self.tps(space, a_tps, b_tps));
+            let t_variances = variances.map(|v| v.types.get_slice(space));
+            let tps = try!(relate_type_params(self, t_variances, a_tps, b_tps));
             substs.types.replace(space, tps);
         }
 
@@ -132,20 +130,7 @@ pub trait Combine<'tcx> : Sized {
                 for &space in &subst::ParamSpace::all() {
                     let a_regions = a.get_slice(space);
                     let b_regions = b.get_slice(space);
-
-                    let mut invariance = Vec::new();
-                    let r_variances = match variances {
-                        Some(variances) => {
-                            variances.regions.get_slice(space)
-                        }
-                        None => {
-                            for _ in a_regions {
-                                invariance.push(ty::Invariant);
-                            }
-                            &invariance[]
-                        }
-                    };
-
+                    let r_variances = variances.map(|v| v.regions.get_slice(space));
                     let regions = try!(relate_region_params(self,
                                                             r_variances,
                                                             a_regions,
@@ -157,13 +142,34 @@ pub trait Combine<'tcx> : Sized {
 
         return Ok(substs);
 
+        fn relate_type_params<'tcx, C: Combine<'tcx>>(this: &C,
+                                                      variances: Option<&[ty::Variance]>,
+                                                      a_tys: &[Ty<'tcx>],
+                                                      b_tys: &[Ty<'tcx>])
+                                                      -> cres<'tcx, Vec<Ty<'tcx>>>
+        {
+            if a_tys.len() != b_tys.len() {
+                return Err(ty::terr_ty_param_size(expected_found(this,
+                                                                 a_tys.len(),
+                                                                 b_tys.len())));
+            }
+
+            range(0, a_tys.len()).map(|i| {
+                let a_ty = a_tys[i];
+                let b_ty = b_tys[i];
+                let v = variances.map_or(ty::Invariant, |v| v[i]);
+                this.tys_with_variance(v, a_ty, b_ty)
+            }).collect()
+        }
+
         fn relate_region_params<'tcx, C: Combine<'tcx>>(this: &C,
-                                                        variances: &[ty::Variance],
+                                                        variances: Option<&[ty::Variance]>,
                                                         a_rs: &[ty::Region],
                                                         b_rs: &[ty::Region])
-                                                        -> cres<'tcx, Vec<ty::Region>> {
+                                                        -> cres<'tcx, Vec<ty::Region>>
+        {
             let tcx = this.infcx().tcx;
-            let num_region_params = variances.len();
+            let num_region_params = a_rs.len();
 
             debug!("relate_region_params(\
                    a_rs={}, \
@@ -173,22 +179,18 @@ pub trait Combine<'tcx> : Sized {
                    b_rs.repr(tcx),
                    variances.repr(tcx));
 
-            assert_eq!(num_region_params, a_rs.len());
+            assert_eq!(num_region_params,
+                       variances.map_or(num_region_params,
+                                        |v| v.len()));
+
             assert_eq!(num_region_params, b_rs.len());
-            let mut rs = vec!();
-            for i in 0..num_region_params {
+
+            (0..a_rs.len()).map(|i| {
                 let a_r = a_rs[i];
                 let b_r = b_rs[i];
-                let variance = variances[i];
-                let r = match variance {
-                    ty::Invariant => this.equate().regions(a_r, b_r),
-                    ty::Covariant => this.regions(a_r, b_r),
-                    ty::Contravariant => this.contraregions(a_r, b_r),
-                    ty::Bivariant => Ok(a_r),
-                };
-                rs.push(try!(r));
-            }
-            Ok(rs)
+                let variance = variances.map_or(ty::Invariant, |v| v[i]);
+                this.regions_with_variance(variance, a_r, b_r)
+            }).collect()
         }
     }
 
@@ -241,7 +243,7 @@ pub trait Combine<'tcx> : Sized {
     }
 
     fn args(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> {
-        self.contratys(a, b).and_then(|t| Ok(t))
+        self.tys_with_variance(ty::Contravariant, a, b).and_then(|t| Ok(t))
     }
 
     fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety>;
@@ -309,7 +311,7 @@ pub trait Combine<'tcx> : Sized {
                           b: &ty::ExistentialBounds<'tcx>)
                           -> cres<'tcx, ty::ExistentialBounds<'tcx>>
     {
-        let r = try!(self.contraregions(a.region_bound, b.region_bound));
+        let r = try!(self.regions_with_variance(ty::Contravariant, a.region_bound, b.region_bound));
         let nb = try!(self.builtin_bounds(a.builtin_bounds, b.builtin_bounds));
         let pb = try!(self.projection_bounds(&a.projection_bounds, &b.projection_bounds));
         Ok(ty::ExistentialBounds { region_bound: r,
@@ -322,11 +324,6 @@ pub trait Combine<'tcx> : Sized {
                       b: ty::BuiltinBounds)
                       -> cres<'tcx, ty::BuiltinBounds>;
 
-    fn contraregions(&self, a: ty::Region, b: ty::Region)
-                  -> cres<'tcx, ty::Region>;
-
-    fn regions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region>;
-
     fn trait_refs(&self,
                   a: &ty::TraitRef<'tcx>,
                   b: &ty::TraitRef<'tcx>)
@@ -540,7 +537,8 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C,
       }
 
       (&ty::ty_rptr(a_r, ref a_mt), &ty::ty_rptr(b_r, ref b_mt)) => {
-            let r = try!(this.contraregions(*a_r, *b_r));
+            let r = try!(this.regions_with_variance(ty::Contravariant, *a_r, *b_r));
+
             // FIXME(14985)  If we have mutable references to trait objects, we
             // used to use covariant subtyping. I have preserved this behaviour,
             // even though it is probably incorrect. So don't go down the usual
@@ -644,6 +642,10 @@ impl<'f, 'tcx> CombineFields<'f, 'tcx> {
         Equate((*self).clone())
     }
 
+    fn bivariate(&self) -> Bivariate<'f, 'tcx> {
+        Bivariate((*self).clone())
+    }
+
     fn sub(&self) -> Sub<'f, 'tcx> {
         Sub((*self).clone())
     }
@@ -697,7 +699,7 @@ impl<'f, 'tcx> CombineFields<'f, 'tcx> {
                         EqTo => {
                             self.generalize(a_ty, b_vid, false)
                         }
-                        SupertypeOf | SubtypeOf => {
+                        BiTo | SupertypeOf | SubtypeOf => {
                             self.generalize(a_ty, b_vid, true)
                         }
                     });
@@ -721,6 +723,10 @@ impl<'f, 'tcx> CombineFields<'f, 'tcx> {
             // to associate causes/spans with each of the relations in
             // the stack to get this right.
             match dir {
+                BiTo => {
+                    try!(self.bivariate().tys(a_ty, b_ty));
+                }
+
                 EqTo => {
                     try!(self.equate().tys(a_ty, b_ty));
                 }
@@ -730,7 +736,7 @@ impl<'f, 'tcx> CombineFields<'f, 'tcx> {
                 }
 
                 SupertypeOf => {
-                    try!(self.sub().contratys(a_ty, b_ty));
+                    try!(self.sub().tys_with_variance(ty::Contravariant, a_ty, b_ty));
                 }
             }
         }
diff --git a/src/librustc/middle/infer/equate.rs b/src/librustc/middle/infer/equate.rs
index f0bde222864..7194e20b0cf 100644
--- a/src/librustc/middle/infer/equate.rs
+++ b/src/librustc/middle/infer/equate.rs
@@ -13,11 +13,7 @@ use middle::ty::{self, Ty};
 use middle::ty::TyVar;
 use middle::infer::combine::*;
 use middle::infer::{cres};
-use middle::infer::glb::Glb;
-use middle::infer::InferCtxt;
-use middle::infer::lub::Lub;
-use middle::infer::sub::Sub;
-use middle::infer::{TypeTrace, Subtype};
+use middle::infer::{Subtype};
 use middle::infer::type_variable::{EqTo};
 use util::ppaux::{Repr};
 
@@ -33,21 +29,20 @@ pub fn Equate<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Equate<'f, 'tcx> {
 }
 
 impl<'f, 'tcx> Combine<'tcx> for Equate<'f, 'tcx> {
-    fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx> { self.fields.infcx }
-    fn tag(&self) -> String { "eq".to_string() }
-    fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
-    fn trace(&self) -> TypeTrace<'tcx> { self.fields.trace.clone() }
+    fn tag(&self) -> String { "Equate".to_string() }
+    fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields }
 
-    fn equate<'a>(&'a self) -> Equate<'a, 'tcx> { Equate(self.fields.clone()) }
-    fn sub<'a>(&'a self) -> Sub<'a, 'tcx> { Sub(self.fields.clone()) }
-    fn lub<'a>(&'a self) -> Lub<'a, 'tcx> { Lub(self.fields.clone()) }
-    fn glb<'a>(&'a self) -> Glb<'a, 'tcx> { Glb(self.fields.clone()) }
-
-    fn contratys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> {
+    fn tys_with_variance(&self, _: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>)
+                         -> cres<'tcx, Ty<'tcx>>
+    {
+        // Once we're equating, it doesn't matter what the variance is.
         self.tys(a, b)
     }
 
-    fn contraregions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region> {
+    fn regions_with_variance(&self, _: ty::Variance, a: ty::Region, b: ty::Region)
+                             -> cres<'tcx, ty::Region>
+    {
+        // Once we're equating, it doesn't matter what the variance is.
         self.regions(a, b)
     }
 
diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs
index 72b33613c66..53032f9b9ac 100644
--- a/src/librustc/middle/infer/error_reporting.rs
+++ b/src/librustc/middle/infer/error_reporting.rs
@@ -200,9 +200,9 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
                                 ref trace_origins,
                                 ref same_regions) => {
                     if !same_regions.is_empty() {
-                        self.report_processed_errors(&var_origins[],
-                                                     &trace_origins[],
-                                                     &same_regions[]);
+                        self.report_processed_errors(&var_origins[..],
+                                                     &trace_origins[..],
+                                                     &same_regions[..]);
                     }
                 }
             }
@@ -675,6 +675,17 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
                     sup,
                     "");
             }
+            infer::Operand(span) => {
+                self.tcx.sess.span_err(
+                    span,
+                    "lifetime of operand does not outlive \
+                     the operation");
+                note_and_explain_region(
+                    self.tcx,
+                    "the operand is only valid for ",
+                    sup,
+                    "");
+            }
             infer::AddrOf(span) => {
                 self.tcx.sess.span_err(
                     span,
@@ -824,7 +835,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
         let parent = self.tcx.map.get_parent(scope_id);
         let parent_node = self.tcx.map.find(parent);
         let taken = lifetimes_in_scope(self.tcx, scope_id);
-        let life_giver = LifeGiver::with_taken(&taken[]);
+        let life_giver = LifeGiver::with_taken(&taken[..]);
         let node_inner = match parent_node {
             Some(ref node) => match *node {
                 ast_map::NodeItem(ref item) => {
@@ -924,7 +935,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
 
     fn rebuild(&self)
                -> (ast::FnDecl, Option<ast::ExplicitSelf_>, ast::Generics) {
-        let mut expl_self_opt = self.expl_self_opt.map(|x| x.clone());
+        let mut expl_self_opt = self.expl_self_opt.cloned();
         let mut inputs = self.fn_decl.inputs.clone();
         let mut output = self.fn_decl.output.clone();
         let mut ty_params = self.generics.ty_params.clone();
@@ -942,7 +953,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
             }
             expl_self_opt = self.rebuild_expl_self(expl_self_opt, lifetime,
                                                    &anon_nums, &region_names);
-            inputs = self.rebuild_args_ty(&inputs[], lifetime,
+            inputs = self.rebuild_args_ty(&inputs[..], lifetime,
                                           &anon_nums, &region_names);
             output = self.rebuild_output(&output, lifetime, &anon_nums, &region_names);
             ty_params = self.rebuild_ty_params(ty_params, lifetime,
@@ -1426,7 +1437,7 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> {
                                               opt_explicit_self, generics);
         let msg = format!("consider using an explicit lifetime \
                            parameter as shown: {}", suggested_fn);
-        self.tcx.sess.span_help(span, &msg[]);
+        self.tcx.sess.span_help(span, &msg[..]);
     }
 
     fn report_inference_failure(&self,
@@ -1593,6 +1604,11 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> {
                     span,
                     "...so that return value is valid for the call");
             }
+            infer::Operand(span) => {
+                self.tcx.sess.span_err(
+                    span,
+                    "...so that operand is valid for operation");
+            }
             infer::AddrOf(span) => {
                 self.tcx.sess.span_note(
                     span,
@@ -1771,7 +1787,7 @@ impl LifeGiver {
             s.push_str(&num_to_string(self.counter.get())[]);
             if !self.taken.contains(&s) {
                 lifetime = name_to_dummy_lifetime(
-                                    token::str_to_ident(&s[]).name);
+                                    token::str_to_ident(&s[..]).name);
                 self.generated.borrow_mut().push(lifetime);
                 break;
             }
diff --git a/src/librustc/middle/infer/glb.rs b/src/librustc/middle/infer/glb.rs
index ff0c2d92f45..33303808e84 100644
--- a/src/librustc/middle/infer/glb.rs
+++ b/src/librustc/middle/infer/glb.rs
@@ -10,12 +10,9 @@
 
 use super::combine::*;
 use super::lattice::*;
-use super::equate::Equate;
 use super::higher_ranked::HigherRankedRelations;
-use super::lub::Lub;
-use super::sub::Sub;
-use super::{cres, InferCtxt};
-use super::{TypeTrace, Subtype};
+use super::{cres};
+use super::Subtype;
 
 use middle::ty::{BuiltinBounds};
 use middle::ty::{self, Ty};
@@ -34,15 +31,30 @@ pub fn Glb<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Glb<'f, 'tcx> {
 }
 
 impl<'f, 'tcx> Combine<'tcx> for Glb<'f, 'tcx> {
-    fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx> { self.fields.infcx }
-    fn tag(&self) -> String { "glb".to_string() }
-    fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
-    fn trace(&self) -> TypeTrace<'tcx> { self.fields.trace.clone() }
+    fn tag(&self) -> String { "Glb".to_string() }
+    fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields }
 
-    fn equate<'a>(&'a self) -> Equate<'a, 'tcx> { Equate(self.fields.clone()) }
-    fn sub<'a>(&'a self) -> Sub<'a, 'tcx> { Sub(self.fields.clone()) }
-    fn lub<'a>(&'a self) -> Lub<'a, 'tcx> { Lub(self.fields.clone()) }
-    fn glb<'a>(&'a self) -> Glb<'a, 'tcx> { Glb(self.fields.clone()) }
+    fn tys_with_variance(&self, v: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>)
+                         -> cres<'tcx, Ty<'tcx>>
+    {
+        match v {
+            ty::Invariant => self.equate().tys(a, b),
+            ty::Covariant => self.tys(a, b),
+            ty::Bivariant => self.bivariate().tys(a, b),
+            ty::Contravariant => self.lub().tys(a, b),
+        }
+    }
+
+    fn regions_with_variance(&self, v: ty::Variance, a: ty::Region, b: ty::Region)
+                             -> cres<'tcx, ty::Region>
+    {
+        match v {
+            ty::Invariant => self.equate().regions(a, b),
+            ty::Covariant => self.regions(a, b),
+            ty::Bivariant => self.bivariate().regions(a, b),
+            ty::Contravariant => self.lub().regions(a, b),
+        }
+    }
 
     fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>) -> cres<'tcx, ty::mt<'tcx>> {
         let tcx = self.fields.infcx.tcx;
@@ -75,10 +87,6 @@ impl<'f, 'tcx> Combine<'tcx> for Glb<'f, 'tcx> {
         }
     }
 
-    fn contratys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> {
-        self.lub().tys(a, b)
-    }
-
     fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety> {
         match (a, b) {
           (Unsafety::Normal, _) | (_, Unsafety::Normal) => Ok(Unsafety::Normal),
@@ -104,11 +112,6 @@ impl<'f, 'tcx> Combine<'tcx> for Glb<'f, 'tcx> {
         Ok(self.fields.infcx.region_vars.glb_regions(Subtype(self.trace()), a, b))
     }
 
-    fn contraregions(&self, a: ty::Region, b: ty::Region)
-                    -> cres<'tcx, ty::Region> {
-        self.lub().regions(a, b)
-    }
-
     fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> {
         super_lattice_tys(self, a, b)
     }
diff --git a/src/librustc/middle/infer/higher_ranked/mod.rs b/src/librustc/middle/infer/higher_ranked/mod.rs
index 4469e27a5b0..a729156c88b 100644
--- a/src/librustc/middle/infer/higher_ranked/mod.rs
+++ b/src/librustc/middle/infer/higher_ranked/mod.rs
@@ -31,7 +31,7 @@ pub trait HigherRankedRelations<'tcx> {
         where T : Combineable<'tcx>;
 }
 
-trait InferCtxtExt<'tcx> {
+trait InferCtxtExt {
     fn tainted_regions(&self, snapshot: &CombinedSnapshot, r: ty::Region) -> Vec<ty::Region>;
 
     fn region_vars_confined_to_snapshot(&self,
@@ -371,7 +371,7 @@ fn fold_regions_in<'tcx, T, F>(tcx: &ty::ctxt<'tcx>,
     }))
 }
 
-impl<'a,'tcx> InferCtxtExt<'tcx> for InferCtxt<'a,'tcx> {
+impl<'a,'tcx> InferCtxtExt for InferCtxt<'a,'tcx> {
     fn tainted_regions(&self, snapshot: &CombinedSnapshot, r: ty::Region) -> Vec<ty::Region> {
         self.region_vars.tainted(&snapshot.region_vars_snapshot, r)
     }
diff --git a/src/librustc/middle/infer/lub.rs b/src/librustc/middle/infer/lub.rs
index 204560e87ee..3570effa9fa 100644
--- a/src/librustc/middle/infer/lub.rs
+++ b/src/librustc/middle/infer/lub.rs
@@ -9,13 +9,10 @@
 // except according to those terms.
 
 use super::combine::*;
-use super::equate::Equate;
-use super::glb::Glb;
 use super::higher_ranked::HigherRankedRelations;
 use super::lattice::*;
-use super::sub::Sub;
-use super::{cres, InferCtxt};
-use super::{TypeTrace, Subtype};
+use super::{cres};
+use super::{Subtype};
 
 use middle::ty::{BuiltinBounds};
 use middle::ty::{self, Ty};
@@ -34,15 +31,30 @@ pub fn Lub<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Lub<'f, 'tcx> {
 }
 
 impl<'f, 'tcx> Combine<'tcx> for Lub<'f, 'tcx> {
-    fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx> { self.fields.infcx }
-    fn tag(&self) -> String { "lub".to_string() }
-    fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
-    fn trace(&self) -> TypeTrace<'tcx> { self.fields.trace.clone() }
+    fn tag(&self) -> String { "Lub".to_string() }
+    fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields }
 
-    fn equate<'a>(&'a self) -> Equate<'a, 'tcx> { Equate(self.fields.clone()) }
-    fn sub<'a>(&'a self) -> Sub<'a, 'tcx> { Sub(self.fields.clone()) }
-    fn lub<'a>(&'a self) -> Lub<'a, 'tcx> { Lub(self.fields.clone()) }
-    fn glb<'a>(&'a self) -> Glb<'a, 'tcx> { Glb(self.fields.clone()) }
+    fn tys_with_variance(&self, v: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>)
+                         -> cres<'tcx, Ty<'tcx>>
+    {
+        match v {
+            ty::Invariant => self.equate().tys(a, b),
+            ty::Covariant => self.tys(a, b),
+            ty::Bivariant => self.bivariate().tys(a, b),
+            ty::Contravariant => self.glb().tys(a, b),
+        }
+    }
+
+    fn regions_with_variance(&self, v: ty::Variance, a: ty::Region, b: ty::Region)
+                             -> cres<'tcx, ty::Region>
+    {
+        match v {
+            ty::Invariant => self.equate().regions(a, b),
+            ty::Covariant => self.regions(a, b),
+            ty::Bivariant => self.bivariate().regions(a, b),
+            ty::Contravariant => self.glb().regions(a, b),
+        }
+    }
 
     fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>) -> cres<'tcx, ty::mt<'tcx>> {
         let tcx = self.tcx();
@@ -70,10 +82,6 @@ impl<'f, 'tcx> Combine<'tcx> for Lub<'f, 'tcx> {
         }
     }
 
-    fn contratys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> {
-        self.glb().tys(a, b)
-    }
-
     fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety> {
         match (a, b) {
           (Unsafety::Unsafe, _) | (_, Unsafety::Unsafe) => Ok(Unsafety::Unsafe),
@@ -90,11 +98,6 @@ impl<'f, 'tcx> Combine<'tcx> for Lub<'f, 'tcx> {
         Ok(a.intersection(b))
     }
 
-    fn contraregions(&self, a: ty::Region, b: ty::Region)
-                    -> cres<'tcx, ty::Region> {
-        self.glb().regions(a, b)
-    }
-
     fn regions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region> {
         debug!("{}.regions({}, {})",
                self.tag(),
diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs
index 00e377d65fe..b0576ff55ff 100644
--- a/src/librustc/middle/infer/mod.rs
+++ b/src/librustc/middle/infer/mod.rs
@@ -45,6 +45,7 @@ use self::lub::Lub;
 use self::unify::{UnificationTable, InferCtxtMethodsForSimplyUnifiableTypes};
 use self::error_reporting::ErrorReporting;
 
+pub mod bivariate;
 pub mod combine;
 pub mod equate;
 pub mod error_reporting;
@@ -209,6 +210,9 @@ pub enum SubregionOrigin<'tcx> {
     // Region in return type of invoked fn must enclose call
     CallReturn(Span),
 
+    // Operands must be in scope
+    Operand(Span),
+
     // Region resulting from a `&` expr must enclose the `&` expr
     AddrOf(Span),
 
@@ -1194,6 +1198,7 @@ impl<'tcx> SubregionOrigin<'tcx> {
             CallRcvr(a) => a,
             CallArg(a) => a,
             CallReturn(a) => a,
+            Operand(a) => a,
             AddrOf(a) => a,
             AutoBorrow(a) => a,
             SafeDestructor(a) => a,
@@ -1257,6 +1262,7 @@ impl<'tcx> Repr<'tcx> for SubregionOrigin<'tcx> {
             CallRcvr(a) => format!("CallRcvr({})", a.repr(tcx)),
             CallArg(a) => format!("CallArg({})", a.repr(tcx)),
             CallReturn(a) => format!("CallReturn({})", a.repr(tcx)),
+            Operand(a) => format!("Operand({})", a.repr(tcx)),
             AddrOf(a) => format!("AddrOf({})", a.repr(tcx)),
             AutoBorrow(a) => format!("AutoBorrow({})", a.repr(tcx)),
             SafeDestructor(a) => format!("SafeDestructor({})", a.repr(tcx)),
diff --git a/src/librustc/middle/infer/region_inference/mod.rs b/src/librustc/middle/infer/region_inference/mod.rs
index 5cdfdcc7c9b..b4fd34f206f 100644
--- a/src/librustc/middle/infer/region_inference/mod.rs
+++ b/src/librustc/middle/infer/region_inference/mod.rs
@@ -977,7 +977,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
         self.expansion(&mut var_data);
         self.contraction(&mut var_data);
         let values =
-            self.extract_values_and_collect_conflicts(&var_data[],
+            self.extract_values_and_collect_conflicts(&var_data[..],
                                                       errors);
         self.collect_concrete_region_errors(&values, errors);
         values
diff --git a/src/librustc/middle/infer/sub.rs b/src/librustc/middle/infer/sub.rs
index 1e0d14544ff..33da3092b2a 100644
--- a/src/librustc/middle/infer/sub.rs
+++ b/src/librustc/middle/infer/sub.rs
@@ -10,12 +10,8 @@
 
 use super::combine::*;
 use super::{cres, CresCompare};
-use super::equate::Equate;
-use super::glb::Glb;
 use super::higher_ranked::HigherRankedRelations;
-use super::InferCtxt;
-use super::lub::Lub;
-use super::{TypeTrace, Subtype};
+use super::{Subtype};
 use super::type_variable::{SubtypeOf, SupertypeOf};
 
 use middle::ty::{BuiltinBounds};
@@ -37,28 +33,30 @@ pub fn Sub<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Sub<'f, 'tcx> {
 }
 
 impl<'f, 'tcx> Combine<'tcx> for Sub<'f, 'tcx> {
-    fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx> { self.fields.infcx }
-    fn tag(&self) -> String { "sub".to_string() }
-    fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
-    fn trace(&self) -> TypeTrace<'tcx> { self.fields.trace.clone() }
-
-    fn equate<'a>(&'a self) -> Equate<'a, 'tcx> { Equate(self.fields.clone()) }
-    fn sub<'a>(&'a self) -> Sub<'a, 'tcx> { Sub(self.fields.clone()) }
-    fn lub<'a>(&'a self) -> Lub<'a, 'tcx> { Lub(self.fields.clone()) }
-    fn glb<'a>(&'a self) -> Glb<'a, 'tcx> { Glb(self.fields.clone()) }
-
-    fn contratys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> {
-        Sub(self.fields.switch_expected()).tys(b, a)
+    fn tag(&self) -> String { "Sub".to_string() }
+    fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields }
+
+    fn tys_with_variance(&self, v: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>)
+                         -> cres<'tcx, Ty<'tcx>>
+    {
+        match v {
+            ty::Invariant => self.equate().tys(a, b),
+            ty::Covariant => self.tys(a, b),
+            ty::Bivariant => self.bivariate().tys(a, b),
+            ty::Contravariant => Sub(self.fields.switch_expected()).tys(b, a),
+        }
     }
 
-    fn contraregions(&self, a: ty::Region, b: ty::Region)
-                     -> cres<'tcx, ty::Region> {
-                         let opp = CombineFields {
-                             a_is_expected: !self.fields.a_is_expected,
-                             ..self.fields.clone()
-                         };
-                         Sub(opp).regions(b, a)
-                     }
+    fn regions_with_variance(&self, v: ty::Variance, a: ty::Region, b: ty::Region)
+                             -> cres<'tcx, ty::Region>
+    {
+        match v {
+            ty::Invariant => self.equate().regions(a, b),
+            ty::Covariant => self.regions(a, b),
+            ty::Bivariant => self.bivariate().regions(a, b),
+            ty::Contravariant => Sub(self.fields.switch_expected()).regions(b, a),
+        }
+    }
 
     fn regions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region> {
         debug!("{}.regions({}, {})",
diff --git a/src/librustc/middle/infer/type_variable.rs b/src/librustc/middle/infer/type_variable.rs
index 9b8a4a84412..a856137af09 100644
--- a/src/librustc/middle/infer/type_variable.rs
+++ b/src/librustc/middle/infer/type_variable.rs
@@ -14,6 +14,7 @@ use self::UndoEntry::*;
 
 use middle::ty::{self, Ty};
 use std::cmp::min;
+use std::marker::PhantomData;
 use std::mem;
 use std::u32;
 use util::snapshot_vec as sv;
@@ -42,13 +43,13 @@ enum UndoEntry {
     Relate(ty::TyVid, ty::TyVid),
 }
 
-struct Delegate<'tcx>;
+struct Delegate<'tcx>(PhantomData<&'tcx ()>);
 
 type Relation = (RelationDir, ty::TyVid);
 
 #[derive(Copy, PartialEq, Debug)]
 pub enum RelationDir {
-    SubtypeOf, SupertypeOf, EqTo
+    SubtypeOf, SupertypeOf, EqTo, BiTo
 }
 
 impl RelationDir {
@@ -56,14 +57,15 @@ impl RelationDir {
         match self {
             SubtypeOf => SupertypeOf,
             SupertypeOf => SubtypeOf,
-            EqTo => EqTo
+            EqTo => EqTo,
+            BiTo => BiTo,
         }
     }
 }
 
 impl<'tcx> TypeVariableTable<'tcx> {
     pub fn new() -> TypeVariableTable<'tcx> {
-        TypeVariableTable { values: sv::SnapshotVec::new(Delegate) }
+        TypeVariableTable { values: sv::SnapshotVec::new(Delegate(PhantomData)) }
     }
 
     fn relations<'a>(&'a mut self, a: ty::TyVid) -> &'a mut Vec<Relation> {
diff --git a/src/librustc/middle/infer/unify.rs b/src/librustc/middle/infer/unify.rs
index 235f3f994c6..0675cec6f69 100644
--- a/src/librustc/middle/infer/unify.rs
+++ b/src/librustc/middle/infer/unify.rs
@@ -18,6 +18,7 @@ use middle::infer::{uok, ures};
 use middle::infer::InferCtxt;
 use std::cell::RefCell;
 use std::fmt::Debug;
+use std::marker::PhantomData;
 use syntax::ast;
 use util::snapshot_vec as sv;
 
@@ -79,7 +80,7 @@ pub struct UnificationTable<K:UnifyKey> {
 /// made during the snapshot may either be *committed* or *rolled back*.
 pub struct Snapshot<K:UnifyKey> {
     // Link snapshot to the key type `K` of the table.
-    marker: marker::CovariantType<K>,
+    marker: marker::PhantomData<K>,
     snapshot: sv::Snapshot,
 }
 
@@ -92,7 +93,7 @@ pub struct Node<K:UnifyKey> {
 }
 
 #[derive(Copy)]
-pub struct Delegate<K>;
+pub struct Delegate<K>(PhantomData<K>);
 
 // We can't use V:LatticeValue, much as I would like to,
 // because frequently the pattern is that V=Option<U> for some
@@ -102,14 +103,14 @@ pub struct Delegate<K>;
 impl<K:UnifyKey> UnificationTable<K> {
     pub fn new() -> UnificationTable<K> {
         UnificationTable {
-            values: sv::SnapshotVec::new(Delegate),
+            values: sv::SnapshotVec::new(Delegate(PhantomData)),
         }
     }
 
     /// Starts a new snapshot. Each snapshot must be either
     /// rolled back or committed in a "LIFO" (stack) order.
     pub fn snapshot(&mut self) -> Snapshot<K> {
-        Snapshot { marker: marker::CovariantType::<K>,
+        Snapshot { marker: marker::PhantomData::<K>,
                    snapshot: self.values.start_snapshot() }
     }
 
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index e13a5672778..56c5928a132 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -147,18 +147,12 @@ struct LanguageItemCollector<'a> {
 
 impl<'a, 'v> Visitor<'v> for LanguageItemCollector<'a> {
     fn visit_item(&mut self, item: &ast::Item) {
-        match extract(&item.attrs) {
-            Some(value) => {
-                let item_index = self.item_refs.get(&value[]).map(|x| *x);
-
-                match item_index {
-                    Some(item_index) => {
-                        self.collect_item(item_index, local_def(item.id), item.span)
-                    }
-                    None => {}
-                }
+        if let Some(value) = extract(&item.attrs) {
+            let item_index = self.item_refs.get(&value[..]).cloned();
+
+            if let Some(item_index) = item_index {
+                self.collect_item(item_index, local_def(item.id), item.span)
             }
-            None => {}
         }
 
         visit::walk_item(self, item);
@@ -312,12 +306,13 @@ lets_do_this! {
     ExchangeHeapLangItem,            "exchange_heap",           exchange_heap;
     OwnedBoxLangItem,                "owned_box",               owned_box;
 
+    PhantomFnItem,                   "phantom_fn",              phantom_fn;
     PhantomDataItem,                 "phantom_data",            phantom_data;
 
+    // Deprecated:
     CovariantTypeItem,               "covariant_type",          covariant_type;
     ContravariantTypeItem,           "contravariant_type",      contravariant_type;
     InvariantTypeItem,               "invariant_type",          invariant_type;
-
     CovariantLifetimeItem,           "covariant_lifetime",      covariant_lifetime;
     ContravariantLifetimeItem,       "contravariant_lifetime",  contravariant_lifetime;
     InvariantLifetimeItem,           "invariant_lifetime",      invariant_lifetime;
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index d4fe0979313..e58136fb3f4 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -1119,7 +1119,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
           // Uninteresting cases: just propagate in rev exec order
 
           ast::ExprVec(ref exprs) => {
-            self.propagate_through_exprs(&exprs[], succ)
+            self.propagate_through_exprs(&exprs[..], succ)
           }
 
           ast::ExprRepeat(ref element, ref count) => {
@@ -1143,7 +1143,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
             } else {
                 succ
             };
-            let succ = self.propagate_through_exprs(&args[], succ);
+            let succ = self.propagate_through_exprs(&args[..], succ);
             self.propagate_through_expr(&**f, succ)
           }
 
@@ -1156,11 +1156,11 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
             } else {
                 succ
             };
-            self.propagate_through_exprs(&args[], succ)
+            self.propagate_through_exprs(&args[..], succ)
           }
 
           ast::ExprTup(ref exprs) => {
-            self.propagate_through_exprs(&exprs[], succ)
+            self.propagate_through_exprs(&exprs[..], succ)
           }
 
           ast::ExprBinary(op, ref l, ref r) if ast_util::lazy_binop(op.node) => {
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index 2f0462ab8c3..e539f6ae6cb 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -407,7 +407,7 @@ impl RegionMaps {
 
     pub fn opt_encl_scope(&self, id: CodeExtent) -> Option<CodeExtent> {
         //! Returns the narrowest scope that encloses `id`, if any.
-        self.scope_map.borrow().get(&id).map(|x| *x)
+        self.scope_map.borrow().get(&id).cloned()
     }
 
     #[allow(dead_code)] // used in middle::cfg
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index e91d7d8c52c..3ba08c10320 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -562,7 +562,7 @@ pub fn early_bound_lifetimes<'a>(generics: &'a ast::Generics) -> Vec<ast::Lifeti
 
     generics.lifetimes.iter()
         .filter(|l| referenced_idents.iter().any(|&i| i == l.lifetime.name))
-        .map(|l| (*l).clone())
+        .cloned()
         .collect()
 }
 
diff --git a/src/librustc/middle/subst.rs b/src/librustc/middle/subst.rs
index 9bf35bd4284..04fd03ab342 100644
--- a/src/librustc/middle/subst.rs
+++ b/src/librustc/middle/subst.rs
@@ -113,7 +113,7 @@ impl<'tcx> Substs<'tcx> {
     }
 
     pub fn self_ty(&self) -> Option<Ty<'tcx>> {
-        self.types.get_self().map(|&t| t)
+        self.types.get_self().cloned()
     }
 
     pub fn with_self_ty(&self, self_ty: Ty<'tcx>) -> Substs<'tcx> {
diff --git a/src/librustc/middle/traits/coherence.rs b/src/librustc/middle/traits/coherence.rs
index 3a7522cafee..e199a60c370 100644
--- a/src/librustc/middle/traits/coherence.rs
+++ b/src/librustc/middle/traits/coherence.rs
@@ -10,24 +10,27 @@
 
 //! See `doc.rs` for high-level documentation
 
+use super::Normalized;
 use super::SelectionContext;
-use super::{Obligation, ObligationCause};
+use super::{ObligationCause};
+use super::PredicateObligation;
 use super::project;
 use super::util;
 
 use middle::subst::{Subst, TypeSpace};
-use middle::ty::{self, Ty};
-use middle::infer::InferCtxt;
+use middle::ty::{self, ToPolyTraitRef, Ty};
+use middle::infer::{self, InferCtxt};
 use std::collections::HashSet;
 use std::rc::Rc;
 use syntax::ast;
 use syntax::codemap::DUMMY_SP;
 use util::ppaux::Repr;
 
-pub fn impl_can_satisfy(infcx: &InferCtxt,
-                        impl1_def_id: ast::DefId,
-                        impl2_def_id: ast::DefId)
-                        -> bool
+/// True if there exist types that satisfy both of the two given impls.
+pub fn overlapping_impls(infcx: &InferCtxt,
+                         impl1_def_id: ast::DefId,
+                         impl2_def_id: ast::DefId)
+                         -> bool
 {
     debug!("impl_can_satisfy(\
            impl1_def_id={}, \
@@ -35,28 +38,68 @@ pub fn impl_can_satisfy(infcx: &InferCtxt,
            impl1_def_id.repr(infcx.tcx),
            impl2_def_id.repr(infcx.tcx));
 
-    let param_env = ty::empty_parameter_environment(infcx.tcx);
-    let mut selcx = SelectionContext::intercrate(infcx, &param_env);
-    let cause = ObligationCause::dummy();
-
-    // `impl1` provides an implementation of `Foo<X,Y> for Z`.
-    let impl1_substs =
-        util::fresh_substs_for_impl(infcx, DUMMY_SP, impl1_def_id);
-    let impl1_trait_ref =
-        (*ty::impl_trait_ref(infcx.tcx, impl1_def_id).unwrap()).subst(infcx.tcx, &impl1_substs);
-    let impl1_trait_ref =
-        project::normalize(&mut selcx, cause.clone(), &impl1_trait_ref);
-
-    // Determine whether `impl2` can provide an implementation for those
-    // same types.
-    let obligation = Obligation::new(cause,
-                                     ty::Binder(ty::TraitPredicate {
-                                         trait_ref: Rc::new(impl1_trait_ref.value),
-                                     }));
-    debug!("impl_can_satisfy(obligation={})", obligation.repr(infcx.tcx));
-    selcx.evaluate_impl(impl2_def_id, &obligation) &&
-        impl1_trait_ref.obligations.iter().all(
-            |o| selcx.evaluate_obligation(o))
+    let param_env = &ty::empty_parameter_environment(infcx.tcx);
+    let selcx = &mut SelectionContext::intercrate(infcx, param_env);
+    infcx.probe(|_| {
+        overlap(selcx, impl1_def_id, impl2_def_id) || overlap(selcx, impl2_def_id, impl1_def_id)
+    })
+}
+
+/// Can the types from impl `a` be used to satisfy impl `b`?
+/// (Including all conditions)
+fn overlap(selcx: &mut SelectionContext,
+           a_def_id: ast::DefId,
+           b_def_id: ast::DefId)
+           -> bool
+{
+    let (a_trait_ref, a_obligations) = impl_trait_ref_and_oblig(selcx, a_def_id);
+    let (b_trait_ref, b_obligations) = impl_trait_ref_and_oblig(selcx, b_def_id);
+
+    // Does `a <: b` hold? If not, no overlap.
+    if let Err(_) = infer::mk_sub_poly_trait_refs(selcx.infcx(),
+                                                  true,
+                                                  infer::Misc(DUMMY_SP),
+                                                  a_trait_ref.to_poly_trait_ref(),
+                                                  b_trait_ref.to_poly_trait_ref()) {
+        return false;
+    }
+
+    // Are any of the obligations unsatisfiable? If so, no overlap.
+    a_obligations.iter()
+                 .chain(b_obligations.iter())
+                 .all(|o| selcx.evaluate_obligation(o))
+}
+
+/// Instantiate fresh variables for all bound parameters of the impl
+/// and return the impl trait ref with those variables substituted.
+fn impl_trait_ref_and_oblig<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
+                                     impl_def_id: ast::DefId)
+                                     -> (Rc<ty::TraitRef<'tcx>>,
+                                         Vec<PredicateObligation<'tcx>>)
+{
+    let impl_substs =
+        &util::fresh_substs_for_impl(selcx.infcx(), DUMMY_SP, impl_def_id);
+    let impl_trait_ref =
+        ty::impl_trait_ref(selcx.tcx(), impl_def_id).unwrap();
+    let impl_trait_ref =
+        impl_trait_ref.subst(selcx.tcx(), impl_substs);
+    let Normalized { value: impl_trait_ref, obligations: normalization_obligations1 } =
+        project::normalize(selcx, ObligationCause::dummy(), &impl_trait_ref);
+
+    let predicates = ty::lookup_predicates(selcx.tcx(), impl_def_id);
+    let predicates = predicates.instantiate(selcx.tcx(), impl_substs);
+    let Normalized { value: predicates, obligations: normalization_obligations2 } =
+        project::normalize(selcx, ObligationCause::dummy(), &predicates);
+    let impl_obligations =
+        util::predicates_for_generics(selcx.tcx(), ObligationCause::dummy(), 0, &predicates);
+
+    let impl_obligations: Vec<_> =
+        impl_obligations.into_iter()
+        .chain(normalization_obligations1.into_iter())
+        .chain(normalization_obligations2.into_iter())
+        .collect();
+
+    (impl_trait_ref, impl_obligations)
 }
 
 pub enum OrphanCheckErr<'tcx> {
diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs
index 57c9fa7a4d9..a63dcfc24a1 100644
--- a/src/librustc/middle/traits/mod.rs
+++ b/src/librustc/middle/traits/mod.rs
@@ -28,6 +28,7 @@ use util::ppaux::{Repr, UserString};
 pub use self::error_reporting::report_fulfillment_errors;
 pub use self::error_reporting::suggest_new_overflow_limit;
 pub use self::coherence::orphan_check;
+pub use self::coherence::overlapping_impls;
 pub use self::coherence::OrphanCheckErr;
 pub use self::fulfill::{FulfillmentContext, RegionObligation};
 pub use self::project::MismatchedProjectionTypes;
@@ -270,16 +271,6 @@ pub struct VtableObjectData<'tcx> {
     pub object_ty: Ty<'tcx>,
 }
 
-/// True if there exist types that satisfy both of the two given impls.
-pub fn overlapping_impls(infcx: &InferCtxt,
-                         impl1_def_id: ast::DefId,
-                         impl2_def_id: ast::DefId)
-                         -> bool
-{
-    coherence::impl_can_satisfy(infcx, impl1_def_id, impl2_def_id) &&
-    coherence::impl_can_satisfy(infcx, impl2_def_id, impl1_def_id)
-}
-
 /// Creates predicate obligations from the generic bounds.
 pub fn predicates_for_generics<'tcx>(tcx: &ty::ctxt<'tcx>,
                                      cause: ObligationCause<'tcx>,
diff --git a/src/librustc/middle/traits/object_safety.rs b/src/librustc/middle/traits/object_safety.rs
index b2701ae875c..f10f7eb3951 100644
--- a/src/librustc/middle/traits/object_safety.rs
+++ b/src/librustc/middle/traits/object_safety.rs
@@ -20,7 +20,7 @@
 use super::supertraits;
 use super::elaborate_predicates;
 
-use middle::subst::{self, SelfSpace};
+use middle::subst::{self, SelfSpace, TypeSpace};
 use middle::traits;
 use middle::ty::{self, Ty};
 use std::rc::Rc;
@@ -31,6 +31,10 @@ pub enum ObjectSafetyViolation<'tcx> {
     /// Self : Sized declared on the trait
     SizedSelf,
 
+    /// Supertrait reference references `Self` an in illegal location
+    /// (e.g. `trait Foo : Bar<Self>`)
+    SupertraitSelf,
+
     /// Method has something illegal
     Method(Rc<ty::Method<'tcx>>, MethodViolationCode),
 }
@@ -57,7 +61,7 @@ pub fn is_object_safe<'tcx>(tcx: &ty::ctxt<'tcx>,
 {
     // Because we query yes/no results frequently, we keep a cache:
     let cached_result =
-        tcx.object_safety_cache.borrow().get(&trait_ref.def_id()).map(|&r| r);
+        tcx.object_safety_cache.borrow().get(&trait_ref.def_id()).cloned();
 
     let result =
         cached_result.unwrap_or_else(|| {
@@ -110,6 +114,9 @@ fn object_safety_violations_for_trait<'tcx>(tcx: &ty::ctxt<'tcx>,
     if trait_has_sized_self(tcx, trait_def_id) {
         violations.push(ObjectSafetyViolation::SizedSelf);
     }
+    if supertraits_reference_self(tcx, trait_def_id) {
+        violations.push(ObjectSafetyViolation::SupertraitSelf);
+    }
 
     debug!("object_safety_violations_for_trait(trait_def_id={}) = {}",
            trait_def_id.repr(tcx),
@@ -118,6 +125,35 @@ fn object_safety_violations_for_trait<'tcx>(tcx: &ty::ctxt<'tcx>,
     violations
 }
 
+fn supertraits_reference_self<'tcx>(tcx: &ty::ctxt<'tcx>,
+                                    trait_def_id: ast::DefId)
+                                    -> bool
+{
+    let trait_def = ty::lookup_trait_def(tcx, trait_def_id);
+    let trait_ref = trait_def.trait_ref.clone();
+    let predicates = ty::predicates_for_trait_ref(tcx, &ty::Binder(trait_ref));
+    predicates
+        .into_iter()
+        .any(|predicate| {
+            match predicate {
+                ty::Predicate::Trait(ref data) => {
+                    // In the case of a trait predicate, we can skip the "self" type.
+                    Some(data.def_id()) != tcx.lang_items.phantom_fn() &&
+                        data.0.trait_ref.substs.types.get_slice(TypeSpace)
+                                                     .iter()
+                                                     .cloned()
+                                                     .any(is_self)
+                }
+                ty::Predicate::Projection(..) |
+                ty::Predicate::TypeOutlives(..) |
+                ty::Predicate::RegionOutlives(..) |
+                ty::Predicate::Equate(..) => {
+                    false
+                }
+            }
+        })
+}
+
 fn trait_has_sized_self<'tcx>(tcx: &ty::ctxt<'tcx>,
                               trait_def_id: ast::DefId)
                               -> bool
@@ -138,11 +174,7 @@ fn trait_has_sized_self<'tcx>(tcx: &ty::ctxt<'tcx>,
         .any(|predicate| {
             match predicate {
                 ty::Predicate::Trait(ref trait_pred) if trait_pred.def_id() == sized_def_id => {
-                    let self_ty = trait_pred.0.self_ty();
-                    match self_ty.sty {
-                        ty::ty_param(ref data) => data.space == subst::SelfSpace,
-                        _ => false,
-                    }
+                    is_self(trait_pred.0.self_ty())
                 }
                 ty::Predicate::Projection(..) |
                 ty::Predicate::Trait(..) |
@@ -295,8 +327,17 @@ impl<'tcx> Repr<'tcx> for ObjectSafetyViolation<'tcx> {
         match *self {
             ObjectSafetyViolation::SizedSelf =>
                 format!("SizedSelf"),
+            ObjectSafetyViolation::SupertraitSelf =>
+                format!("SupertraitSelf"),
             ObjectSafetyViolation::Method(ref m, code) =>
                 format!("Method({},{:?})", m.repr(tcx), code),
         }
     }
 }
+
+fn is_self<'tcx>(ty: Ty<'tcx>) -> bool {
+    match ty.sty {
+        ty::ty_param(ref data) => data.space == subst::SelfSpace,
+        _ => false,
+    }
+}
diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs
index 027415de998..0e298920841 100644
--- a/src/librustc/middle/traits/select.rs
+++ b/src/librustc/middle/traits/select.rs
@@ -132,6 +132,7 @@ pub enum MethodMatchedData {
 /// parameters) that would have to be inferred from the impl.
 #[derive(PartialEq,Eq,Debug,Clone)]
 enum SelectionCandidate<'tcx> {
+    PhantomFnCandidate,
     BuiltinCandidate(ty::BuiltinBound),
     ParamCandidate(ty::PolyTraitRef<'tcx>),
     ImplCandidate(ast::DefId),
@@ -736,7 +737,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     {
         let cache = self.pick_candidate_cache();
         let hashmap = cache.hashmap.borrow();
-        hashmap.get(&cache_fresh_trait_pred.0.trait_ref).map(|c| (*c).clone())
+        hashmap.get(&cache_fresh_trait_pred.0.trait_ref).cloned()
     }
 
     fn insert_candidate_cache(&mut self,
@@ -793,8 +794,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                                stack: &TraitObligationStack<'o, 'tcx>)
                                -> Result<SelectionCandidateSet<'tcx>, SelectionError<'tcx>>
     {
-        // Check for overflow.
-
         let TraitObligationStack { obligation, .. } = *stack;
 
         let mut candidates = SelectionCandidateSet {
@@ -802,6 +801,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             ambiguous: false
         };
 
+        // Check for the `PhantomFn` trait. This is really just a
+        // special annotation that is *always* considered to match, no
+        // matter what the type parameters are etc.
+        if self.tcx().lang_items.phantom_fn() == Some(obligation.predicate.def_id()) {
+            candidates.vec.push(PhantomFnCandidate);
+            return Ok(candidates);
+        }
+
         // Other bounds. Consider both in-scope bounds from fn decl
         // and applicable impls. There is a certain set of precedence rules here.
 
@@ -996,7 +1003,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
         let all_bounds =
             util::transitive_bounds(
-                self.tcx(), &caller_trait_refs[]);
+                self.tcx(), &caller_trait_refs[..]);
 
         let matching_bounds =
             all_bounds.filter(
@@ -1521,7 +1528,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     ty::substd_enum_variants(self.tcx(), def_id, substs)
                     .iter()
                     .flat_map(|variant| variant.args.iter())
-                    .map(|&ty| ty)
+                    .cloned()
                     .collect();
                 nominal(self, bound, def_id, types)
             }
@@ -1629,6 +1636,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     try!(self.confirm_builtin_candidate(obligation, builtin_bound))))
             }
 
+            PhantomFnCandidate |
             ErrorCandidate => {
                 Ok(VtableBuiltin(VtableBuiltinData { nested: VecPerParamSpace::empty() }))
             }
@@ -2295,6 +2303,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 impl<'tcx> Repr<'tcx> for SelectionCandidate<'tcx> {
     fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
         match *self {
+            PhantomFnCandidate => format!("PhantomFnCandidate"),
             ErrorCandidate => format!("ErrorCandidate"),
             BuiltinCandidate(b) => format!("BuiltinCandidate({:?})", b),
             ParamCandidate(ref a) => format!("ParamCandidate({})", a.repr(tcx)),
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index e3eda02b0a8..e9908397f97 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -68,15 +68,16 @@ use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet};
 use util::nodemap::{FnvHashMap};
 
 use arena::TypedArena;
-use std::borrow::{BorrowFrom, Cow};
+use std::borrow::{Borrow, Cow};
 use std::cell::{Cell, RefCell};
 use std::cmp;
 use std::fmt;
-use std::hash::{Hash, Writer, SipHasher, Hasher};
+use std::hash::{Hash, SipHasher, Hasher};
+#[cfg(stage0)] use std::hash::Writer;
 use std::mem;
 use std::ops;
 use std::rc::Rc;
-use std::vec::CowVec;
+use std::vec::{CowVec, IntoIter};
 use collections::enum_set::{EnumSet, CLike};
 use std::collections::{HashMap, HashSet};
 use syntax::abi;
@@ -958,11 +959,18 @@ impl<'tcx> PartialEq for TyS<'tcx> {
 }
 impl<'tcx> Eq for TyS<'tcx> {}
 
+#[cfg(stage0)]
 impl<'tcx, S: Writer + Hasher> Hash<S> for TyS<'tcx> {
     fn hash(&self, s: &mut S) {
         (self as *const _).hash(s)
     }
 }
+#[cfg(not(stage0))]
+impl<'tcx> Hash for TyS<'tcx> {
+    fn hash<H: Hasher>(&self, s: &mut H) {
+        (self as *const _).hash(s)
+    }
+}
 
 pub type Ty<'tcx> = &'tcx TyS<'tcx>;
 
@@ -980,15 +988,22 @@ impl<'tcx> PartialEq for InternedTy<'tcx> {
 
 impl<'tcx> Eq for InternedTy<'tcx> {}
 
+#[cfg(stage0)]
 impl<'tcx, S: Writer + Hasher> Hash<S> for InternedTy<'tcx> {
     fn hash(&self, s: &mut S) {
         self.ty.sty.hash(s)
     }
 }
+#[cfg(not(stage0))]
+impl<'tcx> Hash for InternedTy<'tcx> {
+    fn hash<H: Hasher>(&self, s: &mut H) {
+        self.ty.sty.hash(s)
+    }
+}
 
-impl<'tcx> BorrowFrom<InternedTy<'tcx>> for sty<'tcx> {
-    fn borrow_from<'a>(ty: &'a InternedTy<'tcx>) -> &'a sty<'tcx> {
-        &ty.ty.sty
+impl<'tcx> Borrow<sty<'tcx>> for InternedTy<'tcx> {
+    fn borrow<'a>(&'a self) -> &'a sty<'tcx> {
+        &self.ty.sty
     }
 }
 
@@ -2004,6 +2019,40 @@ impl<'tcx> AsPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
 }
 
 impl<'tcx> Predicate<'tcx> {
+    /// Iterates over the types in this predicate. Note that in all
+    /// cases this is skipping over a binder, so late-bound regions
+    /// with depth 0 are bound by the predicate.
+    pub fn walk_tys(&self) -> IntoIter<Ty<'tcx>> {
+        let vec: Vec<_> = match *self {
+            ty::Predicate::Trait(ref data) => {
+                data.0.trait_ref.substs.types.as_slice().to_vec()
+            }
+            ty::Predicate::Equate(ty::Binder(ref data)) => {
+                vec![data.0, data.1]
+            }
+            ty::Predicate::TypeOutlives(ty::Binder(ref data)) => {
+                vec![data.0]
+            }
+            ty::Predicate::RegionOutlives(..) => {
+                vec![]
+            }
+            ty::Predicate::Projection(ref data) => {
+                let trait_inputs = data.0.projection_ty.trait_ref.substs.types.as_slice();
+                trait_inputs.iter()
+                            .cloned()
+                            .chain(Some(data.0.ty).into_iter())
+                            .collect()
+            }
+        };
+
+        // The only reason to collect into a vector here is that I was
+        // too lazy to make the full (somewhat complicated) iterator
+        // type that would be needed here. But I wanted this fn to
+        // return an iterator conceptually, rather than a `Vec`, so as
+        // to be closer to `Ty::walk`.
+        vec.into_iter()
+    }
+
     pub fn has_escaping_regions(&self) -> bool {
         match *self {
             Predicate::Trait(ref trait_ref) => trait_ref.has_escaping_regions(),
@@ -2331,7 +2380,7 @@ impl ClosureKind {
         };
         match result {
             Ok(trait_did) => trait_did,
-            Err(err) => cx.sess.fatal(&err[]),
+            Err(err) => cx.sess.fatal(&err[..]),
         }
     }
 }
@@ -2665,7 +2714,7 @@ impl FlagComputation {
             }
 
             &ty_tup(ref ts) => {
-                self.add_tys(&ts[]);
+                self.add_tys(&ts[..]);
             }
 
             &ty_bare_fn(_, ref f) => {
@@ -2836,7 +2885,7 @@ pub fn mk_ctor_fn<'tcx>(cx: &ctxt<'tcx>,
                         def_id: ast::DefId,
                         input_tys: &[Ty<'tcx>],
                         output: Ty<'tcx>) -> Ty<'tcx> {
-    let input_args = input_tys.iter().map(|ty| *ty).collect();
+    let input_args = input_tys.iter().cloned().collect();
     mk_bare_fn(cx,
                Some(def_id),
                cx.mk_bare_fn(BareFnTy {
@@ -2959,6 +3008,13 @@ impl<'tcx> TyS<'tcx> {
         assert_eq!(r, Some(self));
         walker
     }
+
+    pub fn as_opt_param_ty(&self) -> Option<ty::ParamTy> {
+        match self.sty {
+            ty::ty_param(ref d) => Some(d.clone()),
+            _ => None,
+        }
+    }
 }
 
 pub fn walk_ty<'tcx, F>(ty_root: Ty<'tcx>, mut f: F)
@@ -3451,7 +3507,7 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
             ty_struct(did, substs) => {
                 let flds = struct_fields(cx, did, substs);
                 let mut res =
-                    TypeContents::union(&flds[],
+                    TypeContents::union(&flds[..],
                                         |f| tc_mt(cx, f.mt, cache));
 
                 if !lookup_repr_hints(cx, did).contains(&attr::ReprExtern) {
@@ -3474,14 +3530,14 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
             }
 
             ty_tup(ref tys) => {
-                TypeContents::union(&tys[],
+                TypeContents::union(&tys[..],
                                     |ty| tc_ty(cx, *ty, cache))
             }
 
             ty_enum(did, substs) => {
                 let variants = substd_enum_variants(cx, did, substs);
                 let mut res =
-                    TypeContents::union(&variants[], |variant| {
+                    TypeContents::union(&variants[..], |variant| {
                         TypeContents::union(&variant.args[],
                                             |arg_ty| {
                             tc_ty(cx, *arg_ty, cache)
@@ -3805,7 +3861,7 @@ pub fn is_type_representable<'tcx>(cx: &ctxt<'tcx>, sp: Span, ty: Ty<'tcx>)
                                        -> Representability {
         match ty.sty {
             ty_tup(ref ts) => {
-                find_nonrepresentable(cx, sp, seen, ts.iter().map(|ty| *ty))
+                find_nonrepresentable(cx, sp, seen, ts.iter().cloned())
             }
             // Fixed-length vectors.
             // FIXME(#11924) Behavior undecided for zero-length vectors.
@@ -4112,7 +4168,7 @@ pub fn positional_element_ty<'tcx>(cx: &ctxt<'tcx>,
                                    variant: Option<ast::DefId>) -> Option<Ty<'tcx>> {
 
     match (&ty.sty, variant) {
-        (&ty_tup(ref v), None) => v.get(i).map(|&t| t),
+        (&ty_tup(ref v), None) => v.get(i).cloned(),
 
 
         (&ty_struct(def_id, substs), None) => lookup_struct_fields(cx, def_id)
@@ -4933,7 +4989,7 @@ pub fn note_and_explain_type_err(cx: &ctxt, err: &type_err) {
 }
 
 pub fn provided_source(cx: &ctxt, id: ast::DefId) -> Option<ast::DefId> {
-    cx.provided_method_sources.borrow().get(&id).map(|x| *x)
+    cx.provided_method_sources.borrow().get(&id).cloned()
 }
 
 pub fn provided_trait_methods<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
@@ -4944,7 +5000,7 @@ pub fn provided_trait_methods<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
                 match item.node {
                     ItemTrait(_, _, _, ref ms) => {
                         let (_, p) =
-                            ast_util::split_trait_methods(&ms[]);
+                            ast_util::split_trait_methods(&ms[..]);
                         p.iter()
                          .map(|m| {
                             match impl_or_trait_item(
@@ -6600,7 +6656,7 @@ pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec<ty::Region>,
 }
 
 /// A free variable referred to in a function.
-#[derive(Copy, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
 pub struct Freevar {
     /// The variable being accessed free.
     pub def: def::Def,
@@ -6625,7 +6681,7 @@ pub fn with_freevars<T, F>(tcx: &ty::ctxt, fid: ast::NodeId, f: F) -> T where
 {
     match tcx.freevars.borrow().get(&fid) {
         None => f(&[]),
-        Some(d) => f(&d[])
+        Some(d) => f(&d[..])
     }
 }
 
diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs
index ee3fd681a00..60a9ffc7d2e 100644
--- a/src/librustc/middle/weak_lang_items.rs
+++ b/src/librustc/middle/weak_lang_items.rs
@@ -55,7 +55,7 @@ pub fn check_crate(krate: &ast::Crate,
 
 pub fn link_name(attrs: &[ast::Attribute]) -> Option<InternedString> {
     lang_items::extract(attrs).and_then(|name| {
-        $(if &name[] == stringify!($name) {
+        $(if &name[..] == stringify!($name) {
             Some(InternedString::new(stringify!($sym)))
         } else)* {
             None
diff --git a/src/librustc/plugin/load.rs b/src/librustc/plugin/load.rs
index 1895cbcb542..b3bc898748f 100644
--- a/src/librustc/plugin/load.rs
+++ b/src/librustc/plugin/load.rs
@@ -111,19 +111,19 @@ impl<'a> PluginLoader<'a> {
             // inside this crate, so continue would spew "macro undefined"
             // errors
             Err(err) => {
-                self.sess.span_fatal(span, &err[])
+                self.sess.span_fatal(span, &err[..])
             }
         };
 
         unsafe {
             let registrar =
-                match lib.symbol(&symbol[]) {
+                match lib.symbol(&symbol[..]) {
                     Ok(registrar) => {
                         mem::transmute::<*mut u8,PluginRegistrarFun>(registrar)
                     }
                     // again fatal if we can't register macros
                     Err(err) => {
-                        self.sess.span_fatal(span, &err[])
+                        self.sess.span_fatal(span, &err[..])
                     }
                 };
 
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 5768539b2cd..93a25de0491 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -629,7 +629,7 @@ pub fn build_configuration(sess: &Session) -> ast::CrateConfig {
         append_configuration(&mut user_cfg, InternedString::new("test"))
     }
     let mut v = user_cfg.into_iter().collect::<Vec<_>>();
-    v.push_all(&default_cfg[]);
+    v.push_all(&default_cfg[..]);
     v
 }
 
@@ -824,7 +824,7 @@ pub fn parse_cfgspecs(cfgspecs: Vec<String> ) -> ast::CrateConfig {
 pub fn build_session_options(matches: &getopts::Matches) -> Options {
     let unparsed_crate_types = matches.opt_strs("crate-type");
     let crate_types = parse_crate_types_from_list(unparsed_crate_types)
-        .unwrap_or_else(|e| early_error(&e[]));
+        .unwrap_or_else(|e| early_error(&e[..]));
 
     let mut lint_opts = vec!();
     let mut describe_lints = false;
@@ -923,7 +923,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
 
     let mut search_paths = SearchPaths::new();
     for s in &matches.opt_strs("L") {
-        search_paths.add_path(&s[]);
+        search_paths.add_path(&s[..]);
     }
 
     let libs = matches.opt_strs("l").into_iter().map(|s| {
@@ -981,7 +981,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
                     --debuginfo");
     }
 
-    let color = match matches.opt_str("color").as_ref().map(|s| &s[]) {
+    let color = match matches.opt_str("color").as_ref().map(|s| &s[..]) {
         Some("auto")   => Auto,
         Some("always") => Always,
         Some("never")  => Never,
@@ -1119,7 +1119,7 @@ mod test {
         let sessopts = build_session_options(matches);
         let sess = build_session(sessopts, None, registry);
         let cfg = build_configuration(&sess);
-        assert!((attr::contains_name(&cfg[], "test")));
+        assert!((attr::contains_name(&cfg[..], "test")));
     }
 
     // When the user supplies --test and --cfg test, don't implicitly add
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index bd44dbe78f5..c1c55188875 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -75,13 +75,13 @@ impl Session {
     }
     pub fn span_err(&self, sp: Span, msg: &str) {
         match split_msg_into_multilines(msg) {
-            Some(msg) => self.diagnostic().span_err(sp, &msg[]),
+            Some(msg) => self.diagnostic().span_err(sp, &msg[..]),
             None => self.diagnostic().span_err(sp, msg)
         }
     }
     pub fn span_err_with_code(&self, sp: Span, msg: &str, code: &str) {
         match split_msg_into_multilines(msg) {
-            Some(msg) => self.diagnostic().span_err_with_code(sp, &msg[], code),
+            Some(msg) => self.diagnostic().span_err_with_code(sp, &msg[..], code),
             None => self.diagnostic().span_err_with_code(sp, msg, code)
         }
     }
diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs
index d3d0f56c3ce..c9d50b9cecf 100644
--- a/src/librustc/util/common.rs
+++ b/src/librustc/util/common.rs
@@ -13,7 +13,8 @@
 use std::cell::{RefCell, Cell};
 use std::collections::HashMap;
 use std::fmt::Debug;
-use std::hash::{Hash, Hasher};
+use std::hash::Hash;
+#[cfg(stage0)] use std::hash::Hasher;
 use std::iter::repeat;
 use std::time::Duration;
 use std::collections::hash_state::HashState;
@@ -144,11 +145,54 @@ pub fn block_query<P>(b: &ast::Block, p: P) -> bool where P: FnMut(&ast::Expr) -
 /// Efficiency note: This is implemented in an inefficient way because it is typically invoked on
 /// very small graphs. If the graphs become larger, a more efficient graph representation and
 /// algorithm would probably be advised.
+#[cfg(stage0)]
 pub fn can_reach<T, S>(edges_map: &HashMap<T, Vec<T>, S>, source: T,
                        destination: T) -> bool
     where S: HashState,
           <S as HashState>::Hasher: Hasher<Output=u64>,
-          T: Hash< <S as HashState>::Hasher> + Eq + Clone,
+          T: Hash<<S as HashState>::Hasher> + Eq + Clone,
+{
+    if source == destination {
+        return true;
+    }
+
+    // Do a little breadth-first-search here.  The `queue` list
+    // doubles as a way to detect if we've seen a particular FR
+    // before.  Note that we expect this graph to be an *extremely
+    // shallow* tree.
+    let mut queue = vec!(source);
+    let mut i = 0;
+    while i < queue.len() {
+        match edges_map.get(&queue[i]) {
+            Some(edges) => {
+                for target in edges {
+                    if *target == destination {
+                        return true;
+                    }
+
+                    if !queue.iter().any(|x| x == target) {
+                        queue.push((*target).clone());
+                    }
+                }
+            }
+            None => {}
+        }
+        i += 1;
+    }
+    return false;
+}
+/// K: Eq + Hash<S>, V, S, H: Hasher<S>
+///
+/// Determines whether there exists a path from `source` to `destination`.  The graph is defined by
+/// the `edges_map`, which maps from a node `S` to a list of its adjacent nodes `T`.
+///
+/// Efficiency note: This is implemented in an inefficient way because it is typically invoked on
+/// very small graphs. If the graphs become larger, a more efficient graph representation and
+/// algorithm would probably be advised.
+#[cfg(not(stage0))]
+pub fn can_reach<T, S>(edges_map: &HashMap<T, Vec<T>, S>, source: T,
+                       destination: T) -> bool
+    where S: HashState, T: Hash + Eq + Clone,
 {
     if source == destination {
         return true;
@@ -206,6 +250,7 @@ pub fn can_reach<T, S>(edges_map: &HashMap<T, Vec<T>, S>, source: T,
 /// }
 /// ```
 #[inline(always)]
+#[cfg(stage0)]
 pub fn memoized<T, U, S, F>(cache: &RefCell<HashMap<T, U, S>>, arg: T, f: F) -> U
     where T: Clone + Hash<<S as HashState>::Hasher> + Eq,
           U: Clone,
@@ -214,6 +259,50 @@ pub fn memoized<T, U, S, F>(cache: &RefCell<HashMap<T, U, S>>, arg: T, f: F) ->
           F: FnOnce(T) -> U,
 {
     let key = arg.clone();
+    let result = cache.borrow().get(&key).cloned();
+    match result {
+        Some(result) => result,
+        None => {
+            let result = f(arg);
+            cache.borrow_mut().insert(key, result.clone());
+            result
+        }
+    }
+}
+/// Memoizes a one-argument closure using the given RefCell containing
+/// a type implementing MutableMap to serve as a cache.
+///
+/// In the future the signature of this function is expected to be:
+/// ```
+/// pub fn memoized<T: Clone, U: Clone, M: MutableMap<T, U>>(
+///    cache: &RefCell<M>,
+///    f: &|T| -> U
+/// ) -> impl |T| -> U {
+/// ```
+/// but currently it is not possible.
+///
+/// # Example
+/// ```
+/// struct Context {
+///    cache: RefCell<HashMap<uint, uint>>
+/// }
+///
+/// fn factorial(ctxt: &Context, n: uint) -> uint {
+///     memoized(&ctxt.cache, n, |n| match n {
+///         0 | 1 => n,
+///         _ => factorial(ctxt, n - 2) + factorial(ctxt, n - 1)
+///     })
+/// }
+/// ```
+#[inline(always)]
+#[cfg(not(stage0))]
+pub fn memoized<T, U, S, F>(cache: &RefCell<HashMap<T, U, S>>, arg: T, f: F) -> U
+    where T: Clone + Hash + Eq,
+          U: Clone,
+          S: HashState,
+          F: FnOnce(T) -> U,
+{
+    let key = arg.clone();
     let result = cache.borrow().get(&key).map(|result| result.clone());
     match result {
         Some(result) => result,
diff --git a/src/librustc/util/lev_distance.rs b/src/librustc/util/lev_distance.rs
index ca1bb7d7a94..10a7b2abea8 100644
--- a/src/librustc/util/lev_distance.rs
+++ b/src/librustc/util/lev_distance.rs
@@ -48,7 +48,7 @@ fn test_lev_distance() {
     for c in (0u32..MAX as u32)
              .filter_map(|i| from_u32(i))
              .map(|i| i.to_string()) {
-        assert_eq!(lev_distance(&c[], &c[]), 0);
+        assert_eq!(lev_distance(&c[..], &c[..]), 0);
     }
 
     let a = "\nMäry häd ä little lämb\n\nLittle lämb\n";
diff --git a/src/librustc/util/nodemap.rs b/src/librustc/util/nodemap.rs
index f8e3defe19d..1b07ce789e7 100644
--- a/src/librustc/util/nodemap.rs
+++ b/src/librustc/util/nodemap.rs
@@ -15,7 +15,8 @@
 use std::collections::hash_state::{DefaultState};
 use std::collections::{HashMap, HashSet};
 use std::default::Default;
-use std::hash::{Hasher, Writer, Hash};
+use std::hash::{Hasher, Hash};
+#[cfg(stage0)] use std::hash::Writer;
 use syntax::ast;
 
 pub type FnvHashMap<K, V> = HashMap<K, V, DefaultState<FnvHasher>>;
@@ -27,12 +28,22 @@ pub type DefIdMap<T> = FnvHashMap<ast::DefId, T>;
 pub type NodeSet = FnvHashSet<ast::NodeId>;
 pub type DefIdSet = FnvHashSet<ast::DefId>;
 
+#[cfg(stage0)]
 pub fn FnvHashMap<K: Hash<FnvHasher> + Eq, V>() -> FnvHashMap<K, V> {
     Default::default()
 }
+#[cfg(stage0)]
 pub fn FnvHashSet<V: Hash<FnvHasher> + Eq>() -> FnvHashSet<V> {
     Default::default()
 }
+#[cfg(not(stage0))]
+pub fn FnvHashMap<K: Hash + Eq, V>() -> FnvHashMap<K, V> {
+    Default::default()
+}
+#[cfg(not(stage0))]
+pub fn FnvHashSet<V: Hash + Eq>() -> FnvHashSet<V> {
+    Default::default()
+}
 
 pub fn NodeMap<T>() -> NodeMap<T> { FnvHashMap() }
 pub fn DefIdMap<T>() -> DefIdMap<T> { FnvHashMap() }
@@ -52,12 +63,14 @@ impl Default for FnvHasher {
     fn default() -> FnvHasher { FnvHasher(0xcbf29ce484222325) }
 }
 
+#[cfg(stage0)]
 impl Hasher for FnvHasher {
     type Output = u64;
     fn reset(&mut self) { *self = Default::default(); }
     fn finish(&self) -> u64 { self.0 }
 }
 
+#[cfg(stage0)]
 impl Writer for FnvHasher {
     fn write(&mut self, bytes: &[u8]) {
         let FnvHasher(mut hash) = *self;
@@ -68,3 +81,16 @@ impl Writer for FnvHasher {
         *self = FnvHasher(hash);
     }
 }
+
+#[cfg(not(stage0))]
+impl Hasher for FnvHasher {
+    fn write(&mut self, bytes: &[u8]) {
+        let FnvHasher(mut hash) = *self;
+        for byte in bytes {
+            hash = hash ^ (*byte as u64);
+            hash = hash * 0x100000001b3;
+        }
+        *self = FnvHasher(hash);
+    }
+    fn finish(&self) -> u64 { self.0 }
+}
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index d54199a679a..1d46c011bb3 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -28,7 +28,8 @@ use middle::ty_fold::TypeFoldable;
 
 use std::collections::HashMap;
 use std::collections::hash_state::HashState;
-use std::hash::{Hash, Hasher};
+use std::hash::Hash;
+#[cfg(stage0)] use std::hash::Hasher;
 use std::rc::Rc;
 use syntax::abi;
 use syntax::ast_map;
@@ -292,7 +293,7 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String {
             Some(def_id) => {
                 s.push_str(" {");
                 let path_str = ty::item_path_str(cx, def_id);
-                s.push_str(&path_str[]);
+                s.push_str(&path_str[..]);
                 s.push_str("}");
             }
             None => { }
@@ -376,7 +377,7 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String {
                 .iter()
                 .map(|elem| ty_to_string(cx, *elem))
                 .collect::<Vec<_>>();
-            match &strs[] {
+            match &strs[..] {
                 [ref string] => format!("({},)", string),
                 strs => format!("({})", strs.connect(", "))
             }
@@ -508,13 +509,26 @@ pub fn parameterized<'tcx,GG>(cx: &ctxt<'tcx>,
     // avoid those ICEs.
     let generics = get_generics();
 
+    let has_self = substs.self_ty().is_some();
     let tps = substs.types.get_slice(subst::TypeSpace);
     let ty_params = generics.types.get_slice(subst::TypeSpace);
     let has_defaults = ty_params.last().map_or(false, |def| def.default.is_some());
     let num_defaults = if has_defaults {
         ty_params.iter().zip(tps.iter()).rev().take_while(|&(def, &actual)| {
             match def.default {
-                Some(default) => default.subst(cx, substs) == actual,
+                Some(default) => {
+                    if !has_self && ty::type_has_self(default) {
+                        // In an object type, there is no `Self`, and
+                        // thus if the default value references Self,
+                        // the user will be required to give an
+                        // explicit value. We can't even do the
+                        // substitution below to check without causing
+                        // an ICE. (#18956).
+                        false
+                    } else {
+                        default.subst(cx, substs) == actual
+                    }
+                }
                 None => false
             }
         }).count()
@@ -625,7 +639,7 @@ impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for [T] {
 
 impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for OwnedSlice<T> {
     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
-        repr_vec(tcx, &self[])
+        repr_vec(tcx, &self[..])
     }
 }
 
@@ -633,7 +647,7 @@ impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for OwnedSlice<T> {
 // autoderef cannot convert the &[T] handler
 impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for Vec<T> {
     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
-        repr_vec(tcx, &self[])
+        repr_vec(tcx, &self[..])
     }
 }
 
@@ -673,7 +687,7 @@ impl<'tcx> UserString<'tcx> for TraitAndProjections<'tcx> {
                       &base,
                       trait_ref.substs,
                       trait_ref.def_id,
-                      &projection_bounds[],
+                      &projection_bounds[..],
                       || ty::lookup_trait_def(tcx, trait_ref.def_id).generics.clone())
     }
 }
@@ -1259,7 +1273,7 @@ impl<'tcx, T> UserString<'tcx> for ty::Binder<T>
                 }
             })
         });
-        let names: Vec<_> = names.iter().map(|s| &s[]).collect();
+        let names: Vec<_> = names.iter().map(|s| &s[..]).collect();
 
         let value_str = unbound_value.user_string(tcx);
         if names.len() == 0 {
@@ -1420,6 +1434,7 @@ impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for ty::Binder<T> {
     }
 }
 
+#[cfg(stage0)]
 impl<'tcx, S, K, V> Repr<'tcx> for HashMap<K, V, S>
     where K: Hash<<S as HashState>::Hasher> + Eq + Repr<'tcx>,
           V: Repr<'tcx>,
@@ -1435,6 +1450,21 @@ impl<'tcx, S, K, V> Repr<'tcx> for HashMap<K, V, S>
     }
 }
 
+#[cfg(not(stage0))]
+impl<'tcx, S, K, V> Repr<'tcx> for HashMap<K, V, S>
+    where K: Hash + Eq + Repr<'tcx>,
+          V: Repr<'tcx>,
+          S: HashState,
+{
+    fn repr(&self, tcx: &ctxt<'tcx>) -> String {
+        format!("HashMap({})",
+                self.iter()
+                    .map(|(k,v)| format!("{} => {}", k.repr(tcx), v.repr(tcx)))
+                    .collect::<Vec<String>>()
+                    .connect(", "))
+    }
+}
+
 impl<'tcx, T, U> Repr<'tcx> for ty::OutlivesPredicate<T,U>
     where T : Repr<'tcx> + TypeFoldable<'tcx>,
           U : Repr<'tcx> + TypeFoldable<'tcx>,
diff --git a/src/librustc_back/archive.rs b/src/librustc_back/archive.rs
index b779963a219..c45ee258342 100644
--- a/src/librustc_back/archive.rs
+++ b/src/librustc_back/archive.rs
@@ -53,7 +53,7 @@ fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option<String>,
           args: &str, cwd: Option<&Path>,
           paths: &[&Path]) -> ProcessOutput {
     let ar = match *maybe_ar_prog {
-        Some(ref ar) => &ar[],
+        Some(ref ar) => &ar[..],
         None => "ar"
     };
     let mut cmd = Command::new(ar);
@@ -84,7 +84,7 @@ fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option<String>,
             o
         },
         Err(e) => {
-            handler.err(&format!("could not exec `{}`: {}", &ar[],
+            handler.err(&format!("could not exec `{}`: {}", &ar[..],
                              e)[]);
             handler.abort_if_errors();
             panic!("rustc::back::archive::run_ar() should not reach this point");
@@ -101,10 +101,10 @@ pub fn find_library(name: &str, osprefix: &str, ossuffix: &str,
 
     for path in search_paths {
         debug!("looking for {} inside {:?}", name, path.display());
-        let test = path.join(&oslibname[]);
+        let test = path.join(&oslibname[..]);
         if test.exists() { return test }
         if oslibname != unixlibname {
-            let test = path.join(&unixlibname[]);
+            let test = path.join(&unixlibname[..]);
             if test.exists() { return test }
         }
     }
@@ -192,12 +192,12 @@ impl<'a> ArchiveBuilder<'a> {
         // as simple comparison is not enough - there
         // might be also an extra name suffix
         let obj_start = format!("{}", name);
-        let obj_start = &obj_start[];
+        let obj_start = &obj_start[..];
         // Ignoring all bytecode files, no matter of
         // name
         let bc_ext = ".bytecode.deflate";
 
-        self.add_archive(rlib, &name[], |fname: &str| {
+        self.add_archive(rlib, &name[..], |fname: &str| {
             let skip_obj = lto && fname.starts_with(obj_start)
                 && fname.ends_with(".o");
             skip_obj || fname.ends_with(bc_ext) || fname == METADATA_FILENAME
@@ -234,7 +234,7 @@ impl<'a> ArchiveBuilder<'a> {
             // allow running `ar s file.a` to update symbols only.
             if self.should_update_symbols {
                 run_ar(self.archive.handler, &self.archive.maybe_ar_prog,
-                       "s", Some(self.work_dir.path()), &args[]);
+                       "s", Some(self.work_dir.path()), &args[..]);
             }
             return self.archive;
         }
@@ -254,7 +254,7 @@ impl<'a> ArchiveBuilder<'a> {
                 // Add the archive members seen so far, without updating the
                 // symbol table (`S`).
                 run_ar(self.archive.handler, &self.archive.maybe_ar_prog,
-                       "cruS", Some(self.work_dir.path()), &args[]);
+                       "cruS", Some(self.work_dir.path()), &args[..]);
 
                 args.clear();
                 args.push(&abs_dst);
@@ -269,7 +269,7 @@ impl<'a> ArchiveBuilder<'a> {
         // necessary.
         let flags = if self.should_update_symbols { "crus" } else { "cruS" };
         run_ar(self.archive.handler, &self.archive.maybe_ar_prog,
-               flags, Some(self.work_dir.path()), &args[]);
+               flags, Some(self.work_dir.path()), &args[..]);
 
         self.archive
     }
@@ -312,7 +312,7 @@ impl<'a> ArchiveBuilder<'a> {
             } else {
                 filename
             };
-            let new_filename = self.work_dir.path().join(&filename[]);
+            let new_filename = self.work_dir.path().join(&filename[..]);
             try!(fs::rename(file, &new_filename));
             self.members.push(Path::new(filename));
         }
diff --git a/src/librustc_back/rpath.rs b/src/librustc_back/rpath.rs
index 36bbd4b9872..e7419d4bec3 100644
--- a/src/librustc_back/rpath.rs
+++ b/src/librustc_back/rpath.rs
@@ -40,12 +40,9 @@ pub fn get_rpath_flags<F, G>(config: RPathConfig<F, G>) -> Vec<String> where
     debug!("preparing the RPATH!");
 
     let libs = config.used_crates.clone();
-    let libs = libs.into_iter().filter_map(|(_, l)| {
-        l.map(|p| p.clone())
-    }).collect::<Vec<_>>();
-
-    let rpaths = get_rpaths(config, &libs[]);
-    flags.push_all(&rpaths_to_flags(&rpaths[])[]);
+    let libs = libs.into_iter().filter_map(|(_, l)| l).collect::<Vec<_>>();
+    let rpaths = get_rpaths(config, &libs[..]);
+    flags.push_all(&rpaths_to_flags(&rpaths[..]));
     flags
 }
 
@@ -82,14 +79,14 @@ fn get_rpaths<F, G>(mut config: RPathConfig<F, G>, libs: &[Path]) -> Vec<String>
         }
     }
 
-    log_rpaths("relative", &rel_rpaths[]);
-    log_rpaths("fallback", &fallback_rpaths[]);
+    log_rpaths("relative", &rel_rpaths[..]);
+    log_rpaths("fallback", &fallback_rpaths[..]);
 
     let mut rpaths = rel_rpaths;
-    rpaths.push_all(&fallback_rpaths[]);
+    rpaths.push_all(&fallback_rpaths[..]);
 
     // Remove duplicates
-    let rpaths = minimize_rpaths(&rpaths[]);
+    let rpaths = minimize_rpaths(&rpaths[..]);
     return rpaths;
 }
 
@@ -139,7 +136,7 @@ fn minimize_rpaths(rpaths: &[String]) -> Vec<String> {
     let mut set = HashSet::new();
     let mut minimized = Vec::new();
     for rpath in rpaths {
-        if set.insert(&rpath[]) {
+        if set.insert(&rpath[..]) {
             minimized.push(rpath.clone());
         }
     }
diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs
index 692e6b474fd..01a5f0d6e20 100644
--- a/src/librustc_back/target/mod.rs
+++ b/src/librustc_back/target/mod.rs
@@ -254,18 +254,18 @@ impl Target {
         macro_rules! key {
             ($key_name:ident) => ( {
                 let name = (stringify!($key_name)).replace("_", "-");
-                obj.find(&name[]).map(|o| o.as_string()
+                obj.find(&name[..]).map(|o| o.as_string()
                                     .map(|s| base.options.$key_name = s.to_string()));
             } );
             ($key_name:ident, bool) => ( {
                 let name = (stringify!($key_name)).replace("_", "-");
-                obj.find(&name[])
+                obj.find(&name[..])
                     .map(|o| o.as_boolean()
                          .map(|s| base.options.$key_name = s));
             } );
             ($key_name:ident, list) => ( {
                 let name = (stringify!($key_name)).replace("_", "-");
-                obj.find(&name[]).map(|o| o.as_array()
+                obj.find(&name[..]).map(|o| o.as_array()
                     .map(|v| base.options.$key_name = v.iter()
                         .map(|a| a.as_string().unwrap().to_string()).collect()
                         )
diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs
index a18e8b16e8b..abe01d193b4 100644
--- a/src/librustc_borrowck/borrowck/check_loans.rs
+++ b/src/librustc_borrowck/borrowck/check_loans.rs
@@ -656,7 +656,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
                                 &self.bccx.loan_path_to_string(move_path)[])
                 };
 
-                self.bccx.span_err(span, &err_message[]);
+                self.bccx.span_err(span, &err_message[..]);
                 self.bccx.span_note(
                     loan_span,
                     &format!("borrow of `{}` occurs here",
diff --git a/src/librustc_borrowck/borrowck/fragments.rs b/src/librustc_borrowck/borrowck/fragments.rs
index bee1ada28e3..c873831cb0f 100644
--- a/src/librustc_borrowck/borrowck/fragments.rs
+++ b/src/librustc_borrowck/borrowck/fragments.rs
@@ -38,7 +38,7 @@ enum Fragment {
     // This represents the collection of all but one of the elements
     // from an array at the path described by the move path index.
     // Note that attached MovePathIndex should have mem_categorization
-    // of InteriorElement (i.e. array dereference `&foo[]`).
+    // of InteriorElement (i.e. array dereference `&foo[..]`).
     AllButOneFrom(MovePathIndex),
 }
 
@@ -198,11 +198,11 @@ pub fn fixup_fragment_sets<'tcx>(this: &MoveData<'tcx>, tcx: &ty::ctxt<'tcx>) {
     // First, filter out duplicates
     moved.sort();
     moved.dedup();
-    debug!("fragments 1 moved: {:?}", path_lps(&moved[]));
+    debug!("fragments 1 moved: {:?}", path_lps(&moved[..]));
 
     assigned.sort();
     assigned.dedup();
-    debug!("fragments 1 assigned: {:?}", path_lps(&assigned[]));
+    debug!("fragments 1 assigned: {:?}", path_lps(&assigned[..]));
 
     // Second, build parents from the moved and assigned.
     for m in &moved {
@@ -222,14 +222,14 @@ pub fn fixup_fragment_sets<'tcx>(this: &MoveData<'tcx>, tcx: &ty::ctxt<'tcx>) {
 
     parents.sort();
     parents.dedup();
-    debug!("fragments 2 parents: {:?}", path_lps(&parents[]));
+    debug!("fragments 2 parents: {:?}", path_lps(&parents[..]));
 
     // Third, filter the moved and assigned fragments down to just the non-parents
-    moved.retain(|f| non_member(*f, &parents[]));
-    debug!("fragments 3 moved: {:?}", path_lps(&moved[]));
+    moved.retain(|f| non_member(*f, &parents[..]));
+    debug!("fragments 3 moved: {:?}", path_lps(&moved[..]));
 
-    assigned.retain(|f| non_member(*f, &parents[]));
-    debug!("fragments 3 assigned: {:?}", path_lps(&assigned[]));
+    assigned.retain(|f| non_member(*f, &parents[..]));
+    debug!("fragments 3 assigned: {:?}", path_lps(&assigned[..]));
 
     // Fourth, build the leftover from the moved, assigned, and parents.
     for m in &moved {
@@ -247,16 +247,16 @@ pub fn fixup_fragment_sets<'tcx>(this: &MoveData<'tcx>, tcx: &ty::ctxt<'tcx>) {
 
     unmoved.sort();
     unmoved.dedup();
-    debug!("fragments 4 unmoved: {:?}", frag_lps(&unmoved[]));
+    debug!("fragments 4 unmoved: {:?}", frag_lps(&unmoved[..]));
 
     // Fifth, filter the leftover fragments down to its core.
     unmoved.retain(|f| match *f {
         AllButOneFrom(_) => true,
-        Just(mpi) => non_member(mpi, &parents[]) &&
-            non_member(mpi, &moved[]) &&
-            non_member(mpi, &assigned[])
+        Just(mpi) => non_member(mpi, &parents[..]) &&
+            non_member(mpi, &moved[..]) &&
+            non_member(mpi, &assigned[..])
     });
-    debug!("fragments 5 unmoved: {:?}", frag_lps(&unmoved[]));
+    debug!("fragments 5 unmoved: {:?}", frag_lps(&unmoved[..]));
 
     // Swap contents back in.
     fragments.unmoved_fragments = unmoved;
@@ -437,7 +437,7 @@ fn add_fragment_siblings_for_extension<'tcx>(this: &MoveData<'tcx>,
             let msg = format!("type {} ({:?}) is not fragmentable",
                               parent_ty.repr(tcx), sty_and_variant_info);
             let opt_span = origin_id.and_then(|id|tcx.map.opt_span(id));
-            tcx.sess.opt_span_bug(opt_span, &msg[])
+            tcx.sess.opt_span_bug(opt_span, &msg[..])
         }
     }
 }
diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs
index 93d97a054a4..518e4bc472c 100644
--- a/src/librustc_borrowck/borrowck/mod.rs
+++ b/src/librustc_borrowck/borrowck/mod.rs
@@ -137,7 +137,7 @@ fn borrowck_fn(this: &mut BorrowckCtxt,
     check_loans::check_loans(this,
                              &loan_dfcx,
                              flowed_moves,
-                             &all_loans[],
+                             &all_loans[..],
                              id,
                              decl,
                              body);
diff --git a/src/librustc_borrowck/graphviz.rs b/src/librustc_borrowck/graphviz.rs
index 56bf3ae7fd5..39c9d9ba6ad 100644
--- a/src/librustc_borrowck/graphviz.rs
+++ b/src/librustc_borrowck/graphviz.rs
@@ -89,7 +89,7 @@ impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> {
                 set.push_str(", ");
             }
             let loan_str = self.borrowck_ctxt.loan_path_to_string(&*lp);
-            set.push_str(&loan_str[]);
+            set.push_str(&loan_str[..]);
             saw_some = true;
             true
         });
diff --git a/src/librustc_borrowck/lib.rs b/src/librustc_borrowck/lib.rs
index c2677cc3fd0..b7cfda28092 100644
--- a/src/librustc_borrowck/lib.rs
+++ b/src/librustc_borrowck/lib.rs
@@ -20,7 +20,6 @@
 #![allow(non_camel_case_types)]
 
 #![feature(core)]
-#![feature(hash)]
 #![feature(int_uint)]
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 728ff647599..a260997f605 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -85,7 +85,7 @@ pub fn compile_input(sess: Session,
             let expanded_crate
                 = match phase_2_configure_and_expand(&sess,
                                                      krate,
-                                                     &id[],
+                                                     &id[..],
                                                      addl_plugins) {
                     None => return,
                     Some(k) => k
@@ -99,20 +99,20 @@ pub fn compile_input(sess: Session,
                                                                  &sess,
                                                                  outdir,
                                                                  &expanded_crate,
-                                                                 &id[]));
+                                                                 &id[..]));
 
         let mut forest = ast_map::Forest::new(expanded_crate);
         let arenas = ty::CtxtArenas::new();
         let ast_map = assign_node_ids_and_map(&sess, &mut forest);
 
-        write_out_deps(&sess, input, &outputs, &id[]);
+        write_out_deps(&sess, input, &outputs, &id[..]);
 
         controller_entry_point!(after_write_deps,
                                 CompileState::state_after_write_deps(input,
                                                                      &sess,
                                                                      outdir,
                                                                      &ast_map,
-                                                                     &id[]));
+                                                                     &id[..]));
 
         let analysis = phase_3_run_analysis_passes(sess,
                                                    ast_map,
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index ac91a0098ea..2550432c810 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -272,7 +272,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
                       -> Compilation {
         match matches.opt_str("explain") {
             Some(ref code) => {
-                match descriptions.find_description(&code[]) {
+                match descriptions.find_description(&code[..]) {
                     Some(ref description) => {
                         println!("{}", description);
                     }
@@ -582,7 +582,7 @@ Available lint options:
         for lint in lints {
             let name = lint.name_lower().replace("_", "-");
             println!("    {}  {:7.7}  {}",
-                     padded(&name[]), lint.default_level.as_str(), lint.desc);
+                     padded(&name[..]), lint.default_level.as_str(), lint.desc);
         }
         println!("\n");
     };
@@ -612,7 +612,7 @@ Available lint options:
             let desc = to.into_iter().map(|x| x.as_str().replace("_", "-"))
                          .collect::<Vec<String>>().connect(", ");
             println!("    {}  {}",
-                     padded(&name[]), desc);
+                     padded(&name[..]), desc);
         }
         println!("\n");
     };
@@ -678,7 +678,7 @@ pub fn handle_options(mut args: Vec<String>) -> Option<getopts::Matches> {
     }
 
     let matches =
-        match getopts::getopts(&args[], &config::optgroups()[]) {
+        match getopts::getopts(&args[..], &config::optgroups()[]) {
             Ok(m) => m,
             Err(f_stable_attempt) => {
                 // redo option parsing, including unstable options this time,
@@ -803,7 +803,7 @@ pub fn monitor<F:FnOnce()+Send+'static>(f: F) {
                     "run with `RUST_BACKTRACE=1` for a backtrace".to_string(),
                 ];
                 for note in &xs {
-                    emitter.emit(None, &note[], None, diagnostic::Note)
+                    emitter.emit(None, &note[..], None, diagnostic::Note)
                 }
 
                 match r.read_to_string() {
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index 5dfef6c775e..0fbfa5fd89d 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -383,7 +383,7 @@ impl UserIdentifiedItem {
             ItemViaNode(node_id) =>
                 NodesMatchingDirect(Some(node_id).into_iter()),
             ItemViaPath(ref parts) =>
-                NodesMatchingSuffix(map.nodes_matching_suffix(&parts[])),
+                NodesMatchingSuffix(map.nodes_matching_suffix(&parts[..])),
         }
     }
 
@@ -395,7 +395,7 @@ impl UserIdentifiedItem {
                         user_option,
                         self.reconstructed_input(),
                         is_wrong_because);
-            sess.fatal(&message[])
+            sess.fatal(&message[..])
         };
 
         let mut saw_node = ast::DUMMY_NODE_ID;
@@ -522,7 +522,7 @@ pub fn pretty_print_input(sess: Session,
     let is_expanded = needs_expansion(&ppm);
     let compute_ast_map = needs_ast_map(&ppm, &opt_uii);
     let krate = if compute_ast_map {
-        match driver::phase_2_configure_and_expand(&sess, krate, &id[], None) {
+        match driver::phase_2_configure_and_expand(&sess, krate, &id[..], None) {
             None => return,
             Some(k) => k
         }
@@ -541,7 +541,7 @@ pub fn pretty_print_input(sess: Session,
     };
 
     let src_name = driver::source_name(input);
-    let src = sess.codemap().get_filemap(&src_name[])
+    let src = sess.codemap().get_filemap(&src_name[..])
                             .src.as_bytes().to_vec();
     let mut rdr = MemReader::new(src);
 
@@ -632,8 +632,8 @@ pub fn pretty_print_input(sess: Session,
                     // point to what was found, if there's an
                     // accessible span.
                     match ast_map.opt_span(nodeid) {
-                        Some(sp) => sess.span_fatal(sp, &message[]),
-                        None => sess.fatal(&message[])
+                        Some(sp) => sess.span_fatal(sp, &message[..]),
+                        None => sess.fatal(&message[..])
                     }
                 }
             }
diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs
index 7105a6cc488..fbbd72e2c76 100644
--- a/src/librustc_driver/test.rs
+++ b/src/librustc_driver/test.rs
@@ -254,7 +254,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
                 output_ty: Ty<'tcx>)
                 -> Ty<'tcx>
     {
-        let input_args = input_tys.iter().map(|ty| *ty).collect();
+        let input_args = input_tys.iter().cloned().collect();
         ty::mk_bare_fn(self.infcx.tcx,
                        None,
                        self.infcx.tcx.mk_bare_fn(ty::BareFnTy {
@@ -278,7 +278,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
 
     pub fn t_param(&self, space: subst::ParamSpace, index: u32) -> Ty<'tcx> {
         let name = format!("T{}", index);
-        ty::mk_param(self.infcx.tcx, space, index, token::intern(&name[]))
+        ty::mk_param(self.infcx.tcx, space, index, token::intern(&name[..]))
     }
 
     pub fn re_early_bound(&self,
diff --git a/src/librustc_llvm/archive_ro.rs b/src/librustc_llvm/archive_ro.rs
index d3555e4c043..14a99026aac 100644
--- a/src/librustc_llvm/archive_ro.rs
+++ b/src/librustc_llvm/archive_ro.rs
@@ -30,7 +30,7 @@ impl ArchiveRO {
     /// raised.
     pub fn open(dst: &Path) -> Option<ArchiveRO> {
         unsafe {
-            let s = CString::from_slice(dst.as_vec());
+            let s = CString::new(dst.as_vec()).unwrap();
             let ar = ::LLVMRustOpenArchive(s.as_ptr());
             if ar.is_null() {
                 None
@@ -44,7 +44,7 @@ impl ArchiveRO {
     pub fn read<'a>(&'a self, file: &str) -> Option<&'a [u8]> {
         unsafe {
             let mut size = 0 as libc::size_t;
-            let file = CString::from_slice(file.as_bytes());
+            let file = CString::new(file).unwrap();
             let ptr = ::LLVMRustArchiveReadSection(self.ptr, file.as_ptr(),
                                                    &mut size);
             if ptr.is_null() {
diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs
index aa90d7c851b..09a187befb2 100644
--- a/src/librustc_llvm/lib.rs
+++ b/src/librustc_llvm/lib.rs
@@ -25,7 +25,6 @@
 #![feature(box_syntax)]
 #![feature(collections)]
 #![feature(core)]
-#![feature(hash)]
 #![feature(int_uint)]
 #![feature(libc)]
 #![feature(link_args)]
@@ -2149,7 +2148,7 @@ impl Drop for TargetData {
 }
 
 pub fn mk_target_data(string_rep: &str) -> TargetData {
-    let string_rep = CString::from_slice(string_rep.as_bytes());
+    let string_rep = CString::new(string_rep).unwrap();
     TargetData {
         lltd: unsafe { LLVMCreateTargetData(string_rep.as_ptr()) }
     }
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 96e146fc894..5662a74a53d 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -585,10 +585,10 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
         match result {
             None => true,
             Some((span, msg, note)) => {
-                self.tcx.sess.span_err(span, &msg[]);
+                self.tcx.sess.span_err(span, &msg[..]);
                 match note {
                     Some((span, msg)) => {
-                        self.tcx.sess.span_note(span, &msg[])
+                        self.tcx.sess.span_note(span, &msg[..])
                     }
                     None => {},
                 }
@@ -690,7 +690,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
             UnnamedField(idx) => format!("field #{} of {} is private",
                                          idx + 1, struct_desc),
         };
-        self.tcx.sess.span_err(span, &msg[]);
+        self.tcx.sess.span_err(span, &msg[..]);
     }
 
     // Given the ID of a method, checks to ensure it's in scope.
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 874c8f2a940..333d32d76b6 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -20,7 +20,6 @@
 #![feature(alloc)]
 #![feature(collections)]
 #![feature(core)]
-#![feature(hash)]
 #![feature(int_uint)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(rustc_private)]
@@ -1072,7 +1071,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                           &import_directive.module_path[],
                                           import_directive.subclass),
                                       help);
-                    self.resolve_error(span, &msg[]);
+                    self.resolve_error(span, &msg[..]);
                 }
                 Indeterminate => break, // Bail out. We'll come around next time.
                 Success(()) => () // Good. Continue.
@@ -1102,7 +1101,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                         .iter()
                                         .map(|seg| seg.identifier.name)
                                         .collect();
-        self.names_to_string(&names[])
+        self.names_to_string(&names[..])
     }
 
     fn import_directive_subclass_to_string(&mut self,
@@ -1166,7 +1165,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         let module_path = &import_directive.module_path;
 
         debug!("(resolving import for module) resolving import `{}::...` in `{}`",
-               self.names_to_string(&module_path[]),
+               self.names_to_string(&module_path[..]),
                self.module_to_string(&*module_));
 
         // First, resolve the module path for the directive, if necessary.
@@ -1175,7 +1174,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             Some((self.graph_root.get_module(), LastMod(AllPublic)))
         } else {
             match self.resolve_module_path(module_.clone(),
-                                           &module_path[],
+                                           &module_path[..],
                                            DontUseLexicalScope,
                                            import_directive.span,
                                            ImportSearch) {
@@ -1768,7 +1767,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                     ValueNS => "value",
                                   },
                                   &token::get_name(name));
-                span_err!(self.session, import_span, E0252, "{}", &msg[]);
+                span_err!(self.session, import_span, E0252, "{}", &msg[..]);
             }
             Some(_) | None => {}
         }
@@ -1783,7 +1782,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         if !name_bindings.defined_in_namespace_with(namespace, IMPORTABLE) {
             let msg = format!("`{}` is not directly importable",
                               token::get_name(name));
-            span_err!(self.session, import_span, E0253, "{}", &msg[]);
+            span_err!(self.session, import_span, E0253, "{}", &msg[..]);
         }
     }
 
@@ -1804,7 +1803,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                        crate in this module \
                                        (maybe you meant `use {0}::*`?)",
                                       &token::get_name(name));
-                    span_err!(self.session, import_span, E0254, "{}", &msg[]);
+                    span_err!(self.session, import_span, E0254, "{}", &msg[..]);
                 }
                 Some(_) | None => {}
             }
@@ -1826,7 +1825,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     let msg = format!("import `{}` conflicts with value \
                                        in this module",
                                       &token::get_name(name));
-                    span_err!(self.session, import_span, E0255, "{}", &msg[]);
+                    span_err!(self.session, import_span, E0255, "{}", &msg[..]);
                     if let Some(span) = value.value_span {
                         self.session.span_note(span,
                                                "conflicting value here");
@@ -1844,7 +1843,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             let msg = format!("import `{}` conflicts with type in \
                                                this module",
                                               &token::get_name(name));
-                            span_err!(self.session, import_span, E0256, "{}", &msg[]);
+                            span_err!(self.session, import_span, E0256, "{}", &msg[..]);
                             if let Some(span) = ty.type_span {
                                 self.session.span_note(span,
                                                        "note conflicting type here")
@@ -1857,7 +1856,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                         let msg = format!("inherent implementations \
                                                            are only allowed on types \
                                                            defined in the current module");
-                                        span_err!(self.session, span, E0257, "{}", &msg[]);
+                                        span_err!(self.session, span, E0257, "{}", &msg[..]);
                                         self.session.span_note(import_span,
                                                                "import from other module here")
                                     }
@@ -1866,7 +1865,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                     let msg = format!("import `{}` conflicts with existing \
                                                        submodule",
                                                       &token::get_name(name));
-                                    span_err!(self.session, import_span, E0258, "{}", &msg[]);
+                                    span_err!(self.session, import_span, E0258, "{}", &msg[..]);
                                     if let Some(span) = ty.type_span {
                                         self.session.span_note(span,
                                                                "note conflicting module here")
@@ -1920,18 +1919,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                 -> ResolveResult<(Rc<Module>, LastPrivate)> {
         fn search_parent_externals(needle: Name, module: &Rc<Module>)
                                 -> Option<Rc<Module>> {
-            module.external_module_children.borrow()
-                                            .get(&needle).cloned()
-                                            .map(|_| module.clone())
-                                            .or_else(|| {
-                match module.parent_link.clone() {
-                    ModuleParentLink(parent, _) => {
-                        search_parent_externals(needle,
-                                                &parent.upgrade().unwrap())
+            match module.external_module_children.borrow().get(&needle) {
+                Some(_) => Some(module.clone()),
+                None => match module.parent_link {
+                    ModuleParentLink(ref parent, _) => {
+                        search_parent_externals(needle, &parent.upgrade().unwrap())
                     }
                    _ => None
                 }
-            })
+            }
         }
 
         let mut search_module = module_;
@@ -1953,7 +1949,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     let segment_name = token::get_name(name);
                     let module_name = self.module_to_string(&*search_module);
                     let mut span = span;
-                    let msg = if "???" == &module_name[] {
+                    let msg = if "???" == &module_name[..] {
                         span.hi = span.lo + Pos::from_usize(segment_name.len());
 
                         match search_parent_externals(name,
@@ -2066,7 +2062,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         match module_prefix_result {
             Failed(None) => {
                 let mpath = self.names_to_string(module_path);
-                let mpath = &mpath[];
+                let mpath = &mpath[..];
                 match mpath.rfind(':') {
                     Some(idx) => {
                         let msg = format!("Could not find `{}` in `{}`",
@@ -2369,11 +2365,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         let mut containing_module;
         let mut i;
         let first_module_path_string = token::get_name(module_path[0]);
-        if "self" == &first_module_path_string[] {
+        if "self" == &first_module_path_string[..] {
             containing_module =
                 self.get_nearest_normal_module_parent_or_self(module_);
             i = 1;
-        } else if "super" == &first_module_path_string[] {
+        } else if "super" == &first_module_path_string[..] {
             containing_module =
                 self.get_nearest_normal_module_parent_or_self(module_);
             i = 0;  // We'll handle `super` below.
@@ -2384,7 +2380,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         // Now loop through all the `super`s we find.
         while i < module_path.len() {
             let string = token::get_name(module_path[i]);
-            if "super" != &string[] {
+            if "super" != &string[..] {
                 break
             }
             debug!("(resolving module prefix) resolving `super` at {}",
@@ -2515,7 +2511,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             } else {
                 let err = format!("unresolved import (maybe you meant `{}::*`?)",
                                   sn);
-                self.resolve_error((*imports)[index].span, &err[]);
+                self.resolve_error((*imports)[index].span, &err[..]);
             }
         }
 
@@ -2853,7 +2849,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                             generics,
                                             implemented_traits,
                                             &**self_type,
-                                            &impl_items[]);
+                                            &impl_items[..]);
             }
 
             ItemTrait(_, ref generics, ref bounds, ref trait_items) => {
@@ -3196,7 +3192,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 };
 
                 let msg = format!("attempt to {} a nonexistent trait `{}`", usage_str, path_str);
-                self.resolve_error(trait_reference.path.span, &msg[]);
+                self.resolve_error(trait_reference.path.span, &msg[..]);
             }
             Some(def) => {
                 match def {
@@ -3624,7 +3620,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     None => {
                         let msg = format!("use of undeclared type name `{}`",
                                           self.path_names_to_string(path));
-                        self.resolve_error(ty.span, &msg[]);
+                        self.resolve_error(ty.span, &msg[..]);
                     }
                 }
             }
@@ -3825,7 +3821,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                     def: {:?}", result);
                             let msg = format!("`{}` does not name a structure",
                                               self.path_names_to_string(path));
-                            self.resolve_error(path.span, &msg[]);
+                            self.resolve_error(path.span, &msg[..]);
                         }
                     }
                 }
@@ -4082,7 +4078,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         let last_private;
         let module = self.current_module.clone();
         match self.resolve_module_path(module,
-                                       &module_path[],
+                                       &module_path[..],
                                        UseLexicalScope,
                                        path.span,
                                        PathSearch) {
@@ -4140,7 +4136,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         let containing_module;
         let last_private;
         match self.resolve_module_path_from_root(root_module,
-                                                 &module_path[],
+                                                 &module_path[..],
                                                  0,
                                                  path.span,
                                                  PathSearch,
@@ -4150,7 +4146,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     Some((span, msg)) => (span, msg),
                     None => {
                         let msg = format!("Use of undeclared module `::{}`",
-                                          self.names_to_string(&module_path[]));
+                                          self.names_to_string(&module_path[..]));
                         (path.span, msg)
                     }
                 };
@@ -4309,7 +4305,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 }
             } else {
                 match this.resolve_module_path(root,
-                                                &name_path[],
+                                                &name_path[..],
                                                 UseLexicalScope,
                                                 span,
                                                 PathSearch) {
@@ -4347,7 +4343,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         let name_path = path.segments.iter().map(|seg| seg.identifier.name).collect::<Vec<_>>();
 
         // Look for a method in the current self type's impl module.
-        match get_module(self, path.span, &name_path[]) {
+        match get_module(self, path.span, &name_path[..]) {
             Some(module) => match module.children.borrow().get(&name) {
                 Some(binding) => {
                     let p_str = self.path_names_to_string(&path);
@@ -4568,7 +4564,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                 def: {:?}", result);
                         let msg = format!("`{}` does not name a structure",
                                           self.path_names_to_string(path));
-                        self.resolve_error(path.span, &msg[]);
+                        self.resolve_error(path.span, &msg[..]);
                     }
                 }
 
diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs
index 9f26e9182ab..ef849bb3dca 100644
--- a/src/librustc_trans/back/link.rs
+++ b/src/librustc_trans/back/link.rs
@@ -127,7 +127,7 @@ pub fn find_crate_name(sess: Option<&Session>,
                        attrs: &[ast::Attribute],
                        input: &Input) -> String {
     let validate = |s: String, span: Option<Span>| {
-        creader::validate_crate_name(sess, &s[], span);
+        creader::validate_crate_name(sess, &s[..], span);
         s
     };
 
@@ -141,11 +141,11 @@ pub fn find_crate_name(sess: Option<&Session>,
     if let Some(sess) = sess {
         if let Some(ref s) = sess.opts.crate_name {
             if let Some((attr, ref name)) = attr_crate_name {
-                if *s != &name[] {
+                if *s != &name[..] {
                     let msg = format!("--crate-name and #[crate_name] are \
                                        required to match, but `{}` != `{}`",
                                       s, name);
-                    sess.span_err(attr.span, &msg[]);
+                    sess.span_err(attr.span, &msg[..]);
                 }
             }
             return validate(s.clone(), None);
@@ -195,7 +195,7 @@ fn symbol_hash<'tcx>(tcx: &ty::ctxt<'tcx>,
     symbol_hasher.input_str("-");
     symbol_hasher.input_str(link_meta.crate_hash.as_str());
     for meta in &*tcx.sess.crate_metadata.borrow() {
-        symbol_hasher.input_str(&meta[]);
+        symbol_hasher.input_str(&meta[..]);
     }
     symbol_hasher.input_str("-");
     symbol_hasher.input_str(&encoder::encoded_ty(tcx, t)[]);
@@ -262,7 +262,7 @@ pub fn sanitize(s: &str) -> String {
     if result.len() > 0 &&
         result.as_bytes()[0] != '_' as u8 &&
         ! (result.as_bytes()[0] as char).is_xid_start() {
-        return format!("_{}", &result[]);
+        return format!("_{}", &result[..]);
     }
 
     return result;
@@ -331,17 +331,17 @@ pub fn mangle_exported_name<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, path: PathEl
     hash.push(EXTRA_CHARS.as_bytes()[extra2] as char);
     hash.push(EXTRA_CHARS.as_bytes()[extra3] as char);
 
-    exported_name(path, &hash[])
+    exported_name(path, &hash[..])
 }
 
 pub fn mangle_internal_name_by_type_and_seq<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                                       t: Ty<'tcx>,
                                                       name: &str) -> String {
     let s = ppaux::ty_to_string(ccx.tcx(), t);
-    let path = [PathName(token::intern(&s[])),
+    let path = [PathName(token::intern(&s[..])),
                 gensym_name(name)];
     let hash = get_symbol_hash(ccx, t);
-    mangle(path.iter().cloned(), Some(&hash[]))
+    mangle(path.iter().cloned(), Some(&hash[..]))
 }
 
 pub fn mangle_internal_name_by_path_and_seq(path: PathElems, flav: &str) -> String {
@@ -541,7 +541,7 @@ fn link_rlib<'a>(sess: &'a Session,
     for &(ref l, kind) in &*sess.cstore.get_used_libraries().borrow() {
         match kind {
             cstore::NativeStatic => {
-                ab.add_native_library(&l[]).unwrap();
+                ab.add_native_library(&l[..]).unwrap();
             }
             cstore::NativeFramework | cstore::NativeUnknown => {}
         }
@@ -619,7 +619,7 @@ fn link_rlib<'a>(sess: &'a Session,
                                                  e)[])
                 };
 
-                let bc_data_deflated = match flate::deflate_bytes(&bc_data[]) {
+                let bc_data_deflated = match flate::deflate_bytes(&bc_data[..]) {
                     Some(compressed) => compressed,
                     None => sess.fatal(&format!("failed to compress bytecode from {}",
                                                bc_filename.display())[])
@@ -678,7 +678,7 @@ fn write_rlib_bytecode_object_v1<T: Writer>(writer: &mut T,
     try! { writer.write_all(RLIB_BYTECODE_OBJECT_MAGIC) };
     try! { writer.write_le_u32(1) };
     try! { writer.write_le_u64(bc_data_deflated_size) };
-    try! { writer.write_all(&bc_data_deflated[]) };
+    try! { writer.write_all(&bc_data_deflated[..]) };
 
     let number_of_bytes_written_so_far =
         RLIB_BYTECODE_OBJECT_MAGIC.len() +                // magic id
@@ -733,7 +733,7 @@ fn link_staticlib(sess: &Session, obj_filename: &Path, out_filename: &Path) {
                 continue
             }
         };
-        ab.add_rlib(&p, &name[], sess.lto()).unwrap();
+        ab.add_rlib(&p, &name[..], sess.lto()).unwrap();
 
         let native_libs = csearch::get_native_libraries(&sess.cstore, cnum);
         all_native_libs.extend(native_libs.into_iter());
@@ -769,7 +769,7 @@ fn link_natively(sess: &Session, trans: &CrateTranslation, dylib: bool,
 
     // The invocations of cc share some flags across platforms
     let pname = get_cc_prog(sess);
-    let mut cmd = Command::new(&pname[]);
+    let mut cmd = Command::new(&pname[..]);
 
     cmd.args(&sess.target.target.options.pre_link_args[]);
     link_args(&mut cmd, sess, dylib, tmpdir.path(),
@@ -798,7 +798,7 @@ fn link_natively(sess: &Session, trans: &CrateTranslation, dylib: bool,
                 sess.note(&format!("{:?}", &cmd)[]);
                 let mut output = prog.error.clone();
                 output.push_all(&prog.output[]);
-                sess.note(str::from_utf8(&output[]).unwrap());
+                sess.note(str::from_utf8(&output[..]).unwrap());
                 sess.abort_if_errors();
             }
             debug!("linker stderr:\n{}", String::from_utf8(prog.error).unwrap());
@@ -868,7 +868,7 @@ fn link_args(cmd: &mut Command,
 
             let mut v = b"-Wl,-force_load,".to_vec();
             v.push_all(morestack.as_vec());
-            cmd.arg(&v[]);
+            cmd.arg(&v[..]);
         } else {
             cmd.args(&["-Wl,--whole-archive", "-lmorestack", "-Wl,--no-whole-archive"]);
         }
@@ -993,7 +993,7 @@ fn link_args(cmd: &mut Command,
             if sess.opts.cg.rpath {
                 let mut v = "-Wl,-install_name,@rpath/".as_bytes().to_vec();
                 v.push_all(out_filename.filename().unwrap());
-                cmd.arg(&v[]);
+                cmd.arg(&v[..]);
             }
         } else {
             cmd.arg("-shared");
@@ -1029,7 +1029,7 @@ fn link_args(cmd: &mut Command,
     // with any #[link_args] attributes found inside the crate
     let empty = Vec::new();
     cmd.args(&sess.opts.cg.link_args.as_ref().unwrap_or(&empty)[]);
-    cmd.args(&used_link_args[]);
+    cmd.args(&used_link_args[..]);
 }
 
 // # Native library linking
@@ -1086,14 +1086,14 @@ fn add_local_native_libraries(cmd: &mut Command, sess: &Session) {
         } else {
             // -force_load is the OSX equivalent of --whole-archive, but it
             // involves passing the full path to the library to link.
-            let lib = archive::find_library(&l[],
+            let lib = archive::find_library(&l[..],
                                             &sess.target.target.options.staticlib_prefix,
                                             &sess.target.target.options.staticlib_suffix,
-                                            &search_path[],
+                                            &search_path[..],
                                             &sess.diagnostic().handler);
             let mut v = b"-Wl,-force_load,".to_vec();
             v.push_all(lib.as_vec());
-            cmd.arg(&v[]);
+            cmd.arg(&v[..]);
         }
     }
     if takes_hints {
@@ -1106,7 +1106,7 @@ fn add_local_native_libraries(cmd: &mut Command, sess: &Session) {
                 cmd.arg(format!("-l{}", l));
             }
             cstore::NativeFramework => {
-                cmd.arg("-framework").arg(&l[]);
+                cmd.arg("-framework").arg(&l[..]);
             }
             cstore::NativeStatic => unreachable!(),
         }
@@ -1248,7 +1248,7 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session,
 
         let mut v = "-l".as_bytes().to_vec();
         v.push_all(unlib(&sess.target, cratepath.filestem().unwrap()));
-        cmd.arg(&v[]);
+        cmd.arg(&v[..]);
     }
 }
 
@@ -1290,7 +1290,7 @@ fn add_upstream_native_libraries(cmd: &mut Command, sess: &Session) {
                 }
                 cstore::NativeFramework => {
                     cmd.arg("-framework");
-                    cmd.arg(&lib[]);
+                    cmd.arg(&lib[..]);
                 }
                 cstore::NativeStatic => {
                     sess.bug("statics shouldn't be propagated");
diff --git a/src/librustc_trans/back/lto.rs b/src/librustc_trans/back/lto.rs
index 0331b6171f3..0a0f2a9c186 100644
--- a/src/librustc_trans/back/lto.rs
+++ b/src/librustc_trans/back/lto.rs
@@ -132,7 +132,7 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
                                                         bc_decoded.len() as libc::size_t) {
                     write::llvm_err(sess.diagnostic().handler(),
                                     format!("failed to load bc of `{}`",
-                                            &name[]));
+                                            &name[..]));
                 }
             });
         }
@@ -140,7 +140,7 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
 
     // Internalize everything but the reachable symbols of the current module
     let cstrs: Vec<CString> = reachable.iter().map(|s| {
-        CString::from_slice(s.as_bytes())
+        CString::new(s.clone()).unwrap()
     }).collect();
     let arr: Vec<*const libc::c_char> = cstrs.iter().map(|c| c.as_ptr()).collect();
     let ptr = arr.as_ptr();
diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs
index 9934d9993d6..86b720d3fc1 100644
--- a/src/librustc_trans/back/write.rs
+++ b/src/librustc_trans/back/write.rs
@@ -22,7 +22,7 @@ use syntax::codemap;
 use syntax::diagnostic;
 use syntax::diagnostic::{Emitter, Handler, Level, mk_handler};
 
-use std::ffi::{self, CString};
+use std::ffi::{CStr, CString};
 use std::old_io::Command;
 use std::old_io::fs;
 use std::iter::Unfold;
@@ -47,14 +47,14 @@ pub fn llvm_err(handler: &diagnostic::Handler, msg: String) -> ! {
     unsafe {
         let cstr = llvm::LLVMRustGetLastError();
         if cstr == ptr::null() {
-            handler.fatal(&msg[]);
+            handler.fatal(&msg[..]);
         } else {
-            let err = ffi::c_str_to_bytes(&cstr);
+            let err = CStr::from_ptr(cstr).to_bytes();
             let err = String::from_utf8_lossy(err).to_string();
             libc::free(cstr as *mut _);
             handler.fatal(&format!("{}: {}",
-                                  &msg[],
-                                  &err[])[]);
+                                  &msg[..],
+                                  &err[..])[]);
         }
     }
 }
@@ -67,7 +67,7 @@ pub fn write_output_file(
         output: &Path,
         file_type: llvm::FileType) {
     unsafe {
-        let output_c = CString::from_slice(output.as_vec());
+        let output_c = CString::new(output.as_vec()).unwrap();
         let result = llvm::LLVMRustWriteOutputFile(
                 target, pm, m, output_c.as_ptr(), file_type);
         if !result {
@@ -105,7 +105,7 @@ impl SharedEmitter {
                 Some(ref code) => {
                     handler.emit_with_code(None,
                                            &diag.msg[],
-                                           &code[],
+                                           &code[..],
                                            diag.lvl);
                 },
                 None => {
@@ -165,7 +165,7 @@ fn get_llvm_opt_level(optimize: config::OptLevel) -> llvm::CodeGenOptLevel {
 
 fn create_target_machine(sess: &Session) -> TargetMachineRef {
     let reloc_model_arg = match sess.opts.cg.relocation_model {
-        Some(ref s) => &s[],
+        Some(ref s) => &s[..],
         None => &sess.target.target.options.relocation_model[]
     };
     let reloc_model = match reloc_model_arg {
@@ -198,7 +198,7 @@ fn create_target_machine(sess: &Session) -> TargetMachineRef {
     let fdata_sections = ffunction_sections;
 
     let code_model_arg = match sess.opts.cg.code_model {
-        Some(ref s) => &s[],
+        Some(ref s) => &s[..],
         None => &sess.target.target.options.code_model[]
     };
 
@@ -221,13 +221,13 @@ fn create_target_machine(sess: &Session) -> TargetMachineRef {
     let triple = &sess.target.target.llvm_target[];
 
     let tm = unsafe {
-        let triple = CString::from_slice(triple.as_bytes());
+        let triple = CString::new(triple.as_bytes()).unwrap();
         let cpu = match sess.opts.cg.target_cpu {
             Some(ref s) => &**s,
             None => &*sess.target.target.options.cpu
         };
-        let cpu = CString::from_slice(cpu.as_bytes());
-        let features = CString::from_slice(target_feature(sess).as_bytes());
+        let cpu = CString::new(cpu.as_bytes()).unwrap();
+        let features = CString::new(target_feature(sess).as_bytes()).unwrap();
         llvm::LLVMRustCreateTargetMachine(
             triple.as_ptr(), cpu.as_ptr(), features.as_ptr(),
             code_model,
@@ -365,7 +365,7 @@ unsafe extern "C" fn inline_asm_handler(diag: SMDiagnosticRef,
     let msg = llvm::build_string(|s| llvm::LLVMWriteSMDiagnosticToString(diag, s))
         .expect("non-UTF8 SMDiagnostic");
 
-    report_inline_asm(cgcx, &msg[], cookie);
+    report_inline_asm(cgcx, &msg[..], cookie);
 }
 
 unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_void) {
@@ -380,7 +380,7 @@ unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_vo
         }
 
         llvm::diagnostic::Optimization(opt) => {
-            let pass_name = str::from_utf8(ffi::c_str_to_bytes(&opt.pass_name))
+            let pass_name = str::from_utf8(CStr::from_ptr(opt.pass_name).to_bytes())
                                 .ok()
                                 .expect("got a non-UTF8 pass name from LLVM");
             let enabled = match cgcx.remark {
@@ -424,7 +424,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
     if config.emit_no_opt_bc {
         let ext = format!("{}.no-opt.bc", name_extra);
         let out = output_names.with_extension(&ext);
-        let out = CString::from_slice(out.as_vec());
+        let out = CString::new(out.as_vec()).unwrap();
         llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
     }
 
@@ -440,7 +440,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
             // If we're verifying or linting, add them to the function pass
             // manager.
             let addpass = |pass: &str| {
-                let pass = CString::from_slice(pass.as_bytes());
+                let pass = CString::new(pass).unwrap();
                 llvm::LLVMRustAddPass(fpm, pass.as_ptr())
             };
             if !config.no_verify { assert!(addpass("verify")); }
@@ -453,7 +453,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
             }
 
             for pass in &config.passes {
-                let pass = CString::from_slice(pass.as_bytes());
+                let pass = CString::new(pass.clone()).unwrap();
                 if !llvm::LLVMRustAddPass(mpm, pass.as_ptr()) {
                     cgcx.handler.warn(&format!("unknown pass {:?}, ignoring", pass));
                 }
@@ -477,7 +477,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
                     if config.emit_lto_bc {
                         let name = format!("{}.lto.bc", name_extra);
                         let out = output_names.with_extension(&name);
-                        let out = CString::from_slice(out.as_vec());
+                        let out = CString::new(out.as_vec()).unwrap();
                         llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
                     }
                 },
@@ -511,7 +511,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
     if config.emit_bc {
         let ext = format!("{}.bc", name_extra);
         let out = output_names.with_extension(&ext);
-        let out = CString::from_slice(out.as_vec());
+        let out = CString::new(out.as_vec()).unwrap();
         llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
     }
 
@@ -519,7 +519,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
         if config.emit_ir {
             let ext = format!("{}.ll", name_extra);
             let out = output_names.with_extension(&ext);
-            let out = CString::from_slice(out.as_vec());
+            let out = CString::new(out.as_vec()).unwrap();
             with_codegen(tm, llmod, config.no_builtins, |cpm| {
                 llvm::LLVMRustPrintModule(cpm, llmod, out.as_ptr());
             })
@@ -711,7 +711,7 @@ pub fn run_passes(sess: &Session,
             };
 
         let pname = get_cc_prog(sess);
-        let mut cmd = Command::new(&pname[]);
+        let mut cmd = Command::new(&pname[..]);
 
         cmd.args(&sess.target.target.options.pre_link_args[]);
         cmd.arg("-nostdlib");
@@ -829,12 +829,12 @@ pub fn run_passes(sess: &Session,
         for i in 0..trans.modules.len() {
             if modules_config.emit_obj {
                 let ext = format!("{}.o", i);
-                remove(sess, &crate_output.with_extension(&ext[]));
+                remove(sess, &crate_output.with_extension(&ext[..]));
             }
 
             if modules_config.emit_bc && !keep_numbered_bitcode {
                 let ext = format!("{}.bc", i);
-                remove(sess, &crate_output.with_extension(&ext[]));
+                remove(sess, &crate_output.with_extension(&ext[..]));
             }
         }
 
@@ -960,7 +960,7 @@ fn run_work_multithreaded(sess: &Session,
 
 pub fn run_assembler(sess: &Session, outputs: &OutputFilenames) {
     let pname = get_cc_prog(sess);
-    let mut cmd = Command::new(&pname[]);
+    let mut cmd = Command::new(&pname[..]);
 
     cmd.arg("-c").arg("-o").arg(outputs.path(config::OutputTypeObject))
                            .arg(outputs.temp_path(config::OutputTypeAssembly));
@@ -975,7 +975,7 @@ pub fn run_assembler(sess: &Session, outputs: &OutputFilenames) {
                 sess.note(&format!("{:?}", &cmd)[]);
                 let mut note = prog.error.clone();
                 note.push_all(&prog.output[]);
-                sess.note(str::from_utf8(&note[]).unwrap());
+                sess.note(str::from_utf8(&note[..]).unwrap());
                 sess.abort_if_errors();
             }
         },
@@ -1004,7 +1004,7 @@ unsafe fn configure_llvm(sess: &Session) {
     let mut llvm_args = Vec::new();
     {
         let mut add = |arg: &str| {
-            let s = CString::from_slice(arg.as_bytes());
+            let s = CString::new(arg).unwrap();
             llvm_args.push(s.as_ptr());
             llvm_c_strs.push(s);
         };
diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs
index 4606200d058..3deca436a1f 100644
--- a/src/librustc_trans/lib.rs
+++ b/src/librustc_trans/lib.rs
@@ -28,7 +28,6 @@
 #![feature(box_syntax)]
 #![feature(collections)]
 #![feature(core)]
-#![feature(hash)]
 #![feature(int_uint)]
 #![feature(old_io)]
 #![feature(env)]
diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs
index cdcd917ee5e..8d2a2d51ee4 100644
--- a/src/librustc_trans/save/mod.rs
+++ b/src/librustc_trans/save/mod.rs
@@ -155,7 +155,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
             };
             self.fmt.sub_mod_ref_str(path.span,
                                      *span,
-                                     &qualname[],
+                                     &qualname[..],
                                      self.cur_scope);
         }
     }
@@ -178,7 +178,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
             };
             self.fmt.sub_mod_ref_str(path.span,
                                      *span,
-                                     &qualname[],
+                                     &qualname[..],
                                      self.cur_scope);
         }
     }
@@ -197,7 +197,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
         let (ref span, ref qualname) = sub_paths[len-2];
         self.fmt.sub_type_ref_str(path.span,
                                   *span,
-                                  &qualname[]);
+                                  &qualname[..]);
 
         // write the other sub-paths
         if len <= 2 {
@@ -207,7 +207,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
         for &(ref span, ref qualname) in sub_paths {
             self.fmt.sub_mod_ref_str(path.span,
                                      *span,
-                                     &qualname[],
+                                     &qualname[..],
                                      self.cur_scope);
         }
     }
@@ -280,7 +280,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                                     id,
                                     qualname,
                                     &path_to_string(p)[],
-                                    &typ[]);
+                                    &typ[..]);
             }
             self.collected_paths.clear();
         }
@@ -356,7 +356,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
         };
 
         let qualname = format!("{}::{}", qualname, &get_ident(method.pe_ident()));
-        let qualname = &qualname[];
+        let qualname = &qualname[..];
 
         // record the decl for this def (if it has one)
         let decl_id = ty::trait_item_of_item(&self.analysis.ty_cx,
@@ -436,9 +436,9 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                     Some(sub_span) => self.fmt.field_str(field.span,
                                                          Some(sub_span),
                                                          field.node.id,
-                                                         &name[],
-                                                         &qualname[],
-                                                         &typ[],
+                                                         &name[..],
+                                                         &qualname[..],
+                                                         &typ[..],
                                                          scope_id),
                     None => self.sess.span_bug(field.span,
                                                &format!("Could not find sub-span for field {}",
@@ -470,7 +470,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
             self.fmt.typedef_str(full_span,
                                  Some(*param_ss),
                                  param.id,
-                                 &name[],
+                                 &name[..],
                                  "");
         }
         self.visit_generics(generics);
@@ -487,10 +487,10 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
         self.fmt.fn_str(item.span,
                         sub_span,
                         item.id,
-                        &qualname[],
+                        &qualname[..],
                         self.cur_scope);
 
-        self.process_formals(&decl.inputs, &qualname[]);
+        self.process_formals(&decl.inputs, &qualname[..]);
 
         // walk arg and return types
         for arg in &decl.inputs {
@@ -504,7 +504,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
         // walk the body
         self.nest(item.id, |v| v.visit_block(&*body));
 
-        self.process_generic_params(ty_params, item.span, &qualname[], item.id);
+        self.process_generic_params(ty_params, item.span, &qualname[..], item.id);
     }
 
     fn process_static(&mut self,
@@ -526,8 +526,8 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                             sub_span,
                             item.id,
                             &get_ident(item.ident),
-                            &qualname[],
-                            &value[],
+                            &qualname[..],
+                            &value[..],
                             &ty_to_string(&*typ)[],
                             self.cur_scope);
 
@@ -549,7 +549,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                             sub_span,
                             item.id,
                             &get_ident(item.ident),
-                            &qualname[],
+                            &qualname[..],
                             "",
                             &ty_to_string(&*typ)[],
                             self.cur_scope);
@@ -575,17 +575,17 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                             sub_span,
                             item.id,
                             ctor_id,
-                            &qualname[],
+                            &qualname[..],
                             self.cur_scope,
-                            &val[]);
+                            &val[..]);
 
         // fields
         for field in &def.fields {
-            self.process_struct_field_def(field, &qualname[], item.id);
+            self.process_struct_field_def(field, &qualname[..], item.id);
             self.visit_ty(&*field.node.ty);
         }
 
-        self.process_generic_params(ty_params, item.span, &qualname[], item.id);
+        self.process_generic_params(ty_params, item.span, &qualname[..], item.id);
     }
 
     fn process_enum(&mut self,
@@ -598,9 +598,9 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
             Some(sub_span) => self.fmt.enum_str(item.span,
                                                 Some(sub_span),
                                                 item.id,
-                                                &enum_name[],
+                                                &enum_name[..],
                                                 self.cur_scope,
-                                                &val[]),
+                                                &val[..]),
             None => self.sess.span_bug(item.span,
                                        &format!("Could not find subspan for enum {}",
                                                enum_name)[]),
@@ -619,9 +619,9 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                                                self.span.span_for_first_ident(variant.span),
                                                variant.node.id,
                                                name,
-                                               &qualname[],
-                                               &enum_name[],
-                                               &val[],
+                                               &qualname[..],
+                                               &enum_name[..],
+                                               &val[..],
                                                item.id);
                     for arg in args {
                         self.visit_ty(&*arg.ty);
@@ -637,9 +637,9 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                         self.span.span_for_first_ident(variant.span),
                         variant.node.id,
                         ctor_id,
-                        &qualname[],
-                        &enum_name[],
-                        &val[],
+                        &qualname[..],
+                        &enum_name[..],
+                        &val[..],
                         item.id);
 
                     for field in &struct_def.fields {
@@ -650,7 +650,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
             }
         }
 
-        self.process_generic_params(ty_params, item.span, &enum_name[], item.id);
+        self.process_generic_params(ty_params, item.span, &enum_name[..], item.id);
     }
 
     fn process_impl(&mut self,
@@ -724,9 +724,9 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
         self.fmt.trait_str(item.span,
                            sub_span,
                            item.id,
-                           &qualname[],
+                           &qualname[..],
                            self.cur_scope,
-                           &val[]);
+                           &val[..]);
 
         // super-traits
         for super_bound in &**trait_refs {
@@ -758,7 +758,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
         }
 
         // walk generics and methods
-        self.process_generic_params(generics, item.span, &qualname[], item.id);
+        self.process_generic_params(generics, item.span, &qualname[..], item.id);
         for method in methods {
             self.visit_trait_item(method)
         }
@@ -776,9 +776,9 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
         self.fmt.mod_str(item.span,
                          sub_span,
                          item.id,
-                         &qualname[],
+                         &qualname[..],
                          self.cur_scope,
-                         &filename[]);
+                         &filename[..]);
 
         self.nest(item.id, |v| visit::walk_mod(v, m));
     }
@@ -990,7 +990,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                                self.cur_scope);
 
         // walk receiver and args
-        visit::walk_exprs(self, &args[]);
+        visit::walk_exprs(self, &args[..]);
     }
 
     fn process_pat(&mut self, p:&ast::Pat) {
@@ -1164,7 +1164,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
                                           item.id,
                                           cnum,
                                           name,
-                                          &location[],
+                                          &location[..],
                                           self.cur_scope);
             }
             ast::ItemFn(ref decl, _, _, ref ty_params, ref body) =>
@@ -1196,8 +1196,8 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
                 self.fmt.typedef_str(item.span,
                                      sub_span,
                                      item.id,
-                                     &qualname[],
-                                     &value[]);
+                                     &qualname[..],
+                                     &value[..]);
 
                 self.visit_ty(&**ty);
                 self.process_generic_params(ty_params, item.span, &qualname, item.id);
@@ -1260,7 +1260,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
                 };
 
                 qualname.push_str(&get_ident(method_type.ident));
-                let qualname = &qualname[];
+                let qualname = &qualname[..];
 
                 let sub_span = self.span.sub_span_after_keyword(method_type.span, keywords::Fn);
                 self.fmt.method_decl_str(method_type.span,
@@ -1401,7 +1401,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
 
                 let mut id = String::from_str("$");
                 id.push_str(&ex.id.to_string()[]);
-                self.process_formals(&decl.inputs, &id[]);
+                self.process_formals(&decl.inputs, &id[..]);
 
                 // walk arg and return types
                 for arg in &decl.inputs {
@@ -1464,7 +1464,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
                                           Some(p.span),
                                           id,
                                           &path_to_string(p)[],
-                                          &value[],
+                                          &value[..],
                                           "")
                 }
                 def::DefVariant(..) | def::DefTy(..) | def::DefStruct(..) => {
@@ -1520,8 +1520,8 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
                                   sub_span,
                                   id,
                                   &path_to_string(p)[],
-                                  &value[],
-                                  &typ[]);
+                                  &value[..],
+                                  &typ[..]);
         }
         self.collected_paths.clear();
 
@@ -1603,7 +1603,7 @@ pub fn process_crate(sess: &Session,
         cur_scope: 0
     };
 
-    visitor.dump_crate_info(&cratename[], krate);
+    visitor.dump_crate_info(&cratename[..], krate);
 
     visit::walk_crate(&mut visitor, krate);
 }
diff --git a/src/librustc_trans/save/recorder.rs b/src/librustc_trans/save/recorder.rs
index 3bd04ed29d4..08e36bb1d85 100644
--- a/src/librustc_trans/save/recorder.rs
+++ b/src/librustc_trans/save/recorder.rs
@@ -43,7 +43,7 @@ impl Recorder {
         assert!(self.dump_spans);
         let result = format!("span,kind,{},{},text,\"{}\"\n",
                              kind, su.extent_str(span), escape(su.snippet(span)));
-        self.record(&result[]);
+        self.record(&result[..]);
     }
 }
 
@@ -170,14 +170,14 @@ impl<'a> FmtStrs<'a> {
             if s.len() > 1020 {
                 &s[..1020]
             } else {
-                &s[]
+                &s[..]
             }
         });
 
         let pairs = fields.iter().zip(values);
         let strs = pairs.map(|(f, v)| format!(",{},\"{}\"", f, escape(String::from_str(v))));
         Some(strs.fold(String::new(), |mut s, ss| {
-            s.push_str(&ss[]);
+            s.push_str(&ss[..]);
             s
         }))
     }
@@ -205,9 +205,9 @@ impl<'a> FmtStrs<'a> {
         };
 
         let mut result = String::from_str(label);
-        result.push_str(&values_str[]);
+        result.push_str(&values_str[..]);
         result.push_str("\n");
-        self.recorder.record(&result[]);
+        self.recorder.record(&result[..]);
     }
 
     pub fn record_with_span(&mut self,
@@ -238,7 +238,7 @@ impl<'a> FmtStrs<'a> {
             None => return,
         };
         let result = format!("{},{}{}\n", label, self.span.extent_str(sub_span), values_str);
-        self.recorder.record(&result[]);
+        self.recorder.record(&result[..]);
     }
 
     pub fn check_and_record(&mut self,
diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs
index b0ed6f9e727..2826afb71a2 100644
--- a/src/librustc_trans/trans/_match.rs
+++ b/src/librustc_trans/trans/_match.rs
@@ -566,7 +566,7 @@ fn enter_opt<'a, 'p, 'blk, 'tcx>(
         param_env: param_env,
     };
     enter_match(bcx, dm, m, col, val, |pats|
-        check_match::specialize(&mcx, &pats[], &ctor, col, variant_size)
+        check_match::specialize(&mcx, &pats[..], &ctor, col, variant_size)
     )
 }
 
@@ -987,7 +987,7 @@ fn compile_submatch<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             if has_nested_bindings(m, col) {
                 let expanded = expand_nested_bindings(bcx, m, col, val);
                 compile_submatch_continue(bcx,
-                                          &expanded[],
+                                          &expanded[..],
                                           vals,
                                           chk,
                                           col,
@@ -1233,10 +1233,10 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
         }
         let opt_ms = enter_opt(opt_cx, pat_id, dm, m, opt, col, size, val);
         let mut opt_vals = unpacked;
-        opt_vals.push_all(&vals_left[]);
+        opt_vals.push_all(&vals_left[..]);
         compile_submatch(opt_cx,
-                         &opt_ms[],
-                         &opt_vals[],
+                         &opt_ms[..],
+                         &opt_vals[..],
                          branch_chk.as_ref().unwrap_or(chk),
                          has_genuine_default);
     }
@@ -1255,8 +1255,8 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
             }
             _ => {
                 compile_submatch(else_cx,
-                                 &defaults[],
-                                 &vals_left[],
+                                 &defaults[..],
+                                 &vals_left[..],
                                  chk,
                                  has_genuine_default);
             }
@@ -1468,7 +1468,7 @@ fn trans_match_inner<'blk, 'tcx>(scope_cx: Block<'blk, 'tcx>,
         && arm.pats.last().unwrap().node == ast::PatWild(ast::PatWildSingle)
     });
 
-    compile_submatch(bcx, &matches[], &[discr_datum.val], &chk, has_default);
+    compile_submatch(bcx, &matches[..], &[discr_datum.val], &chk, has_default);
 
     let mut arm_cxs = Vec::new();
     for arm_data in &arm_datas {
@@ -1482,7 +1482,7 @@ fn trans_match_inner<'blk, 'tcx>(scope_cx: Block<'blk, 'tcx>,
         arm_cxs.push(bcx);
     }
 
-    bcx = scope_cx.fcx.join_blocks(match_id, &arm_cxs[]);
+    bcx = scope_cx.fcx.join_blocks(match_id, &arm_cxs[..]);
     return bcx;
 }
 
diff --git a/src/librustc_trans/trans/adt.rs b/src/librustc_trans/trans/adt.rs
index ddd720f1e84..eaf6eaa2f08 100644
--- a/src/librustc_trans/trans/adt.rs
+++ b/src/librustc_trans/trans/adt.rs
@@ -155,7 +155,7 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                                      t: Ty<'tcx>) -> Repr<'tcx> {
     match t.sty {
         ty::ty_tup(ref elems) => {
-            Univariant(mk_struct(cx, &elems[], false, t), false)
+            Univariant(mk_struct(cx, &elems[..], false, t), false)
         }
         ty::ty_struct(def_id, substs) => {
             let fields = ty::lookup_struct_fields(cx.tcx(), def_id);
@@ -167,13 +167,13 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             let dtor = ty::ty_dtor(cx.tcx(), def_id).has_drop_flag();
             if dtor { ftys.push(cx.tcx().types.bool); }
 
-            Univariant(mk_struct(cx, &ftys[], packed, t), dtor)
+            Univariant(mk_struct(cx, &ftys[..], packed, t), dtor)
         }
         ty::ty_closure(def_id, _, substs) => {
             let typer = NormalizingClosureTyper::new(cx.tcx());
             let upvars = typer.closure_upvars(def_id, substs).unwrap();
             let upvar_types = upvars.iter().map(|u| u.ty).collect::<Vec<_>>();
-            Univariant(mk_struct(cx, &upvar_types[], false, t), false)
+            Univariant(mk_struct(cx, &upvar_types[..], false, t), false)
         }
         ty::ty_enum(def_id, substs) => {
             let cases = get_cases(cx.tcx(), def_id, substs);
@@ -187,7 +187,7 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 // (Typechecking will reject discriminant-sizing attrs.)
                 assert_eq!(hint, attr::ReprAny);
                 let ftys = if dtor { vec!(cx.tcx().types.bool) } else { vec!() };
-                return Univariant(mk_struct(cx, &ftys[], false, t),
+                return Univariant(mk_struct(cx, &ftys[..], false, t),
                                   dtor);
             }
 
@@ -219,7 +219,7 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 assert_eq!(hint, attr::ReprAny);
                 let mut ftys = cases[0].tys.clone();
                 if dtor { ftys.push(cx.tcx().types.bool); }
-                return Univariant(mk_struct(cx, &ftys[], false, t),
+                return Univariant(mk_struct(cx, &ftys[..], false, t),
                                   dtor);
             }
 
@@ -320,10 +320,10 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 let mut ftys = vec!(ty_of_inttype(cx.tcx(), ity));
                 ftys.push_all(&c.tys[]);
                 if dtor { ftys.push(cx.tcx().types.bool); }
-                mk_struct(cx, &ftys[], false, t)
+                mk_struct(cx, &ftys[..], false, t)
             }).collect();
 
-            ensure_enum_fits_in_address_space(cx, &fields[], t);
+            ensure_enum_fits_in_address_space(cx, &fields[..], t);
 
             General(ity, fields, dtor)
         }
@@ -453,9 +453,9 @@ fn mk_struct<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
            .map(|&ty| type_of::sizing_type_of(cx, ty)).collect()
     };
 
-    ensure_struct_fits_in_address_space(cx, &lltys[], packed, scapegoat);
+    ensure_struct_fits_in_address_space(cx, &lltys[..], packed, scapegoat);
 
-    let llty_rec = Type::struct_(cx, &lltys[], packed);
+    let llty_rec = Type::struct_(cx, &lltys[..], packed);
     Struct {
         size: machine::llsize_of_alloc(cx, llty_rec),
         align: machine::llalign_of_min(cx, llty_rec),
@@ -659,7 +659,7 @@ fn generic_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             // of the size.
             //
             // FIXME #10604: this breaks when vector types are present.
-            let (size, align) = union_size_and_align(&sts[]);
+            let (size, align) = union_size_and_align(&sts[..]);
             let align_s = align as u64;
             assert_eq!(size % align_s, 0);
             let align_units = size / align_s - 1;
@@ -682,10 +682,10 @@ fn generic_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                           Type::array(&discr_ty, align_s / discr_size - 1),
                           fill_ty];
             match name {
-                None => Type::struct_(cx, &fields[], false),
+                None => Type::struct_(cx, &fields[..], false),
                 Some(name) => {
                     let mut llty = Type::named_struct(cx, name);
-                    llty.set_struct_body(&fields[], false);
+                    llty.set_struct_body(&fields[..], false);
                     llty
                 }
             }
@@ -763,7 +763,7 @@ pub fn trans_get_discr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>,
 
 fn struct_wrapped_nullable_bitdiscr(bcx: Block, nndiscr: Disr, discrfield: &DiscrField,
                                     scrutinee: ValueRef) -> ValueRef {
-    let llptrptr = GEPi(bcx, scrutinee, &discrfield[]);
+    let llptrptr = GEPi(bcx, scrutinee, &discrfield[..]);
     let llptr = Load(bcx, llptrptr);
     let cmp = if nndiscr == 0 { IntEQ } else { IntNE };
     ICmp(bcx, cmp, llptr, C_null(val_ty(llptr)), DebugLoc::None)
@@ -851,7 +851,7 @@ pub fn trans_set_discr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>,
         }
         StructWrappedNullablePointer { nndiscr, ref discrfield, .. } => {
             if discr != nndiscr {
-                let llptrptr = GEPi(bcx, val, &discrfield[]);
+                let llptrptr = GEPi(bcx, val, &discrfield[..]);
                 let llptrty = val_ty(llptrptr).element_type();
                 Store(bcx, C_null(llptrty), llptrptr)
             }
@@ -933,7 +933,7 @@ pub fn struct_field_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, st: &Struct<'tcx>, v
     let val = if needs_cast {
         let ccx = bcx.ccx();
         let fields = st.fields.iter().map(|&ty| type_of::type_of(ccx, ty)).collect::<Vec<_>>();
-        let real_ty = Type::struct_(ccx, &fields[], st.packed);
+        let real_ty = Type::struct_(ccx, &fields[..], st.packed);
         PointerCast(bcx, val, real_ty.ptr_to())
     } else {
         val
@@ -972,7 +972,7 @@ pub fn fold_variants<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
 
                 let fields = case.fields.iter().map(|&ty|
                     type_of::type_of(bcx.ccx(), ty)).collect::<Vec<_>>();
-                let real_ty = Type::struct_(ccx, &fields[], case.packed);
+                let real_ty = Type::struct_(ccx, &fields[..], case.packed);
                 let variant_value = PointerCast(variant_cx, value, real_ty.ptr_to());
 
                 variant_cx = f(variant_cx, case, variant_value);
@@ -1045,18 +1045,18 @@ pub fn trans_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, r: &Repr<'tcx>, discr
         }
         General(ity, ref cases, _) => {
             let case = &cases[discr as uint];
-            let (max_sz, _) = union_size_and_align(&cases[]);
+            let (max_sz, _) = union_size_and_align(&cases[..]);
             let lldiscr = C_integral(ll_inttype(ccx, ity), discr as u64, true);
             let mut f = vec![lldiscr];
             f.push_all(vals);
-            let mut contents = build_const_struct(ccx, case, &f[]);
+            let mut contents = build_const_struct(ccx, case, &f[..]);
             contents.push_all(&[padding(ccx, max_sz - case.size)]);
-            C_struct(ccx, &contents[], false)
+            C_struct(ccx, &contents[..], false)
         }
         Univariant(ref st, _dro) => {
             assert!(discr == 0);
             let contents = build_const_struct(ccx, st, vals);
-            C_struct(ccx, &contents[], st.packed)
+            C_struct(ccx, &contents[..], st.packed)
         }
         RawNullablePointer { nndiscr, nnty, .. } => {
             if discr == nndiscr {
@@ -1080,7 +1080,7 @@ pub fn trans_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, r: &Repr<'tcx>, discr
                 }).collect::<Vec<ValueRef>>();
                 C_struct(ccx, &build_const_struct(ccx,
                                                  nonnull,
-                                                 &vals[])[],
+                                                 &vals[..])[],
                          false)
             }
         }
diff --git a/src/librustc_trans/trans/asm.rs b/src/librustc_trans/trans/asm.rs
index e419be65fc4..a3bd0cf6b1a 100644
--- a/src/librustc_trans/trans/asm.rs
+++ b/src/librustc_trans/trans/asm.rs
@@ -71,7 +71,7 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm)
                                     callee::DontAutorefArg)
         })
     }).collect::<Vec<_>>();
-    inputs.push_all(&ext_inputs[]);
+    inputs.push_all(&ext_inputs[..]);
 
     // no failure occurred preparing operands, no need to cleanup
     fcx.pop_custom_cleanup_scope(temp_scope);
@@ -91,18 +91,18 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm)
         if !clobbers.is_empty() {
             clobbers.push(',');
         }
-        clobbers.push_str(&more_clobbers[]);
+        clobbers.push_str(&more_clobbers[..]);
     }
 
     // Add the clobbers to our constraints list
     if clobbers.len() != 0 && constraints.len() != 0 {
         constraints.push(',');
-        constraints.push_str(&clobbers[]);
+        constraints.push_str(&clobbers[..]);
     } else {
-        constraints.push_str(&clobbers[]);
+        constraints.push_str(&clobbers[..]);
     }
 
-    debug!("Asm Constraints: {}", &constraints[]);
+    debug!("Asm Constraints: {}", &constraints[..]);
 
     let num_outputs = outputs.len();
 
@@ -112,7 +112,7 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm)
     } else if num_outputs == 1 {
         output_types[0]
     } else {
-        Type::struct_(bcx.ccx(), &output_types[], false)
+        Type::struct_(bcx.ccx(), &output_types[..], false)
     };
 
     let dialect = match ia.dialect {
@@ -120,8 +120,8 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm)
         ast::AsmIntel => llvm::AD_Intel
     };
 
-    let asm = CString::from_slice(ia.asm.as_bytes());
-    let constraints = CString::from_slice(constraints.as_bytes());
+    let asm = CString::new(ia.asm.as_bytes()).unwrap();
+    let constraints = CString::new(constraints).unwrap();
     let r = InlineAsmCall(bcx,
                           asm.as_ptr(),
                           constraints.as_ptr(),
diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs
index 7f7b5cd8006..3091c852f55 100644
--- a/src/librustc_trans/trans/base.rs
+++ b/src/librustc_trans/trans/base.rs
@@ -86,7 +86,7 @@ use util::nodemap::NodeMap;
 
 use arena::TypedArena;
 use libc::{c_uint, uint64_t};
-use std::ffi::{self, CString};
+use std::ffi::{CStr, CString};
 use std::cell::{Cell, RefCell};
 use std::collections::HashSet;
 use std::mem;
@@ -186,7 +186,7 @@ impl<'a, 'tcx> Drop for StatRecorder<'a, 'tcx> {
 pub fn decl_fn(ccx: &CrateContext, name: &str, cc: llvm::CallConv,
                ty: Type, output: ty::FnOutput) -> ValueRef {
 
-    let buf = CString::from_slice(name.as_bytes());
+    let buf = CString::new(name).unwrap();
     let llfn: ValueRef = unsafe {
         llvm::LLVMGetOrInsertFunction(ccx.llmod(), buf.as_ptr(), ty.to_ref())
     };
@@ -247,7 +247,7 @@ fn get_extern_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<'tcx>,
     let f = decl_rust_fn(ccx, fn_ty, name);
 
     let attrs = csearch::get_item_attrs(&ccx.sess().cstore, did);
-    set_llvm_fn_attrs(ccx, &attrs[], f);
+    set_llvm_fn_attrs(ccx, &attrs[..], f);
 
     ccx.externs().borrow_mut().insert(name.to_string(), f);
     f
@@ -340,7 +340,7 @@ pub fn get_extern_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, did: ast::DefId,
         None => ()
     }
     unsafe {
-        let buf = CString::from_slice(name.as_bytes());
+        let buf = CString::new(name.clone()).unwrap();
         let c = llvm::LLVMAddGlobal(ccx.llmod(), ty.to_ref(), buf.as_ptr());
         // Thread-local statics in some other crate need to *always* be linked
         // against in a thread-local fashion, so we need to be sure to apply the
@@ -523,7 +523,7 @@ pub fn get_res_dtor<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                      ty::mk_nil(ccx.tcx()));
         get_extern_fn(ccx,
                       &mut *ccx.externs().borrow_mut(),
-                      &name[],
+                      &name[..],
                       llvm::CCallConv,
                       llty,
                       dtor_ty)
@@ -898,14 +898,14 @@ pub fn trans_external_path<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         ty::ty_bare_fn(_, ref fn_ty) => {
             match ccx.sess().target.target.adjust_abi(fn_ty.abi) {
                 Rust | RustCall => {
-                    get_extern_rust_fn(ccx, t, &name[], did)
+                    get_extern_rust_fn(ccx, t, &name[..], did)
                 }
                 RustIntrinsic => {
                     ccx.sess().bug("unexpected intrinsic in trans_external_path")
                 }
                 _ => {
                     foreign::register_foreign_item_fn(ccx, fn_ty.abi, t,
-                                                      &name[])
+                                                      &name[..])
                 }
             }
         }
@@ -947,7 +947,7 @@ pub fn invoke<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
         let llresult = Invoke(bcx,
                               llfn,
-                              &llargs[],
+                              &llargs[..],
                               normal_bcx.llbb,
                               landing_pad,
                               Some(attributes),
@@ -961,7 +961,7 @@ pub fn invoke<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
         let llresult = Call(bcx,
                             llfn,
-                            &llargs[],
+                            &llargs[..],
                             Some(attributes),
                             debug_loc);
         return (llresult, bcx);
@@ -1219,19 +1219,6 @@ pub fn alloca_zeroed<'blk, 'tcx>(cx: Block<'blk, 'tcx>, ty: Ty<'tcx>,
     p
 }
 
-pub fn arrayalloca(cx: Block, ty: Type, v: ValueRef) -> ValueRef {
-    let _icx = push_ctxt("arrayalloca");
-    if cx.unreachable.get() {
-        unsafe {
-            return llvm::LLVMGetUndef(ty.to_ref());
-        }
-    }
-    debuginfo::clear_source_location(cx.fcx);
-    let p = ArrayAlloca(cx, ty, v);
-    call_lifetime_start(cx, p);
-    p
-}
-
 // Creates the alloca slot which holds the pointer to the slot for the final return value
 pub fn make_return_slot_pointer<'a, 'tcx>(fcx: &FunctionContext<'a, 'tcx>,
                                           output_type: Ty<'tcx>) -> ValueRef {
@@ -1646,7 +1633,7 @@ fn copy_closure_args_to_allocas<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                                                          "argtuple",
                                                          arg_scope_id));
     let untupled_arg_types = match monomorphized_arg_types[0].sty {
-        ty::ty_tup(ref types) => &types[],
+        ty::ty_tup(ref types) => &types[..],
         _ => {
             bcx.tcx().sess.span_bug(args[0].pat.span,
                                     "first arg to `rust-call` ABI function \
@@ -1834,12 +1821,12 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
 
     let arg_datums = if abi != RustCall {
         create_datums_for_fn_args(&fcx,
-                                  &monomorphized_arg_types[])
+                                  &monomorphized_arg_types[..])
     } else {
         create_datums_for_fn_args_under_call_abi(
             bcx,
             arg_scope,
-            &monomorphized_arg_types[])
+            &monomorphized_arg_types[..])
     };
 
     bcx = match closure_env {
@@ -1855,7 +1842,7 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                 arg_scope,
                 &decl.inputs[],
                 arg_datums,
-                &monomorphized_arg_types[])
+                &monomorphized_arg_types[..])
         }
     };
 
@@ -2000,7 +1987,7 @@ pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                 bcx = expr::trans_adt(bcx,
                                       result_ty,
                                       disr,
-                                      &fields[],
+                                      &fields[..],
                                       None,
                                       expr::SaveIn(llresult),
                                       debug_loc);
@@ -2070,7 +2057,7 @@ fn trans_enum_variant_or_tuple_like_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx
         ty::erase_late_bound_regions(
             ccx.tcx(), &ty::ty_fn_args(ctor_ty));
 
-    let arg_datums = create_datums_for_fn_args(&fcx, &arg_tys[]);
+    let arg_datums = create_datums_for_fn_args(&fcx, &arg_tys[..]);
 
     if !type_is_zero_size(fcx.ccx, result_ty.unwrap()) {
         let dest = fcx.get_ret_slot(bcx, result_ty, "eret_slot");
@@ -2315,7 +2302,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
       ast::ItemImpl(_, _, ref generics, _, _, ref impl_items) => {
         meth::trans_impl(ccx,
                          item.ident,
-                         &impl_items[],
+                         &impl_items[..],
                          generics,
                          item.id);
       }
@@ -2430,7 +2417,7 @@ fn register_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         _ => panic!("expected bare rust fn")
     };
 
-    let llfn = decl_rust_fn(ccx, node_type, &sym[]);
+    let llfn = decl_rust_fn(ccx, node_type, &sym[..]);
     finish_register_fn(ccx, sp, sym, node_id, llfn);
     llfn
 }
@@ -2475,7 +2462,7 @@ pub fn get_fn_llvm_attributes<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<
 
             match fn_sig.inputs[1].sty {
                 ty::ty_tup(ref t_in) => {
-                    inputs.push_all(&t_in[]);
+                    inputs.push_all(&t_in[..]);
                     inputs
                 }
                 _ => ccx.sess().bug("expected tuple'd inputs")
@@ -2611,7 +2598,7 @@ pub fn register_fn_llvmty(ccx: &CrateContext,
     debug!("register_fn_llvmty id={} sym={}", node_id, sym);
 
     let llfn = decl_fn(ccx,
-                       &sym[],
+                       &sym[..],
                        cc,
                        llfty,
                        ty::FnConverging(ty::mk_nil(ccx.tcx())));
@@ -2667,7 +2654,7 @@ pub fn create_entry_wrapper(ccx: &CrateContext,
             let (start_fn, args) = if use_start_lang_item {
                 let start_def_id = match ccx.tcx().lang_items.require(StartFnLangItem) {
                     Ok(id) => id,
-                    Err(s) => { ccx.sess().fatal(&s[]); }
+                    Err(s) => { ccx.sess().fatal(&s[..]); }
                 };
                 let start_fn = if start_def_id.krate == ast::LOCAL_CRATE {
                     get_item_val(ccx, start_def_id.node)
@@ -2783,12 +2770,12 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
                         } else {
                             llvm::LLVMTypeOf(v)
                         };
-                        if contains_null(&sym[]) {
+                        if contains_null(&sym[..]) {
                             ccx.sess().fatal(
                                 &format!("Illegal null byte in export_name \
                                          value: `{}`", sym)[]);
                         }
-                        let buf = CString::from_slice(sym.as_bytes());
+                        let buf = CString::new(sym.clone()).unwrap();
                         let g = llvm::LLVMAddGlobal(ccx.llmod(), llty,
                                                     buf.as_ptr());
 
@@ -2826,7 +2813,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
                                                  &sect)[]);
                     }
                     unsafe {
-                        let buf = CString::from_slice(sect.as_bytes());
+                        let buf = CString::new(sect.as_bytes()).unwrap();
                         llvm::LLVMSetSection(v, buf.as_ptr());
                     }
                 },
@@ -2988,12 +2975,12 @@ pub fn write_metadata(cx: &SharedCrateContext, krate: &ast::Crate) -> Vec<u8> {
         Some(compressed) => compressed,
         None => cx.sess().fatal("failed to compress metadata"),
     });
-    let llmeta = C_bytes_in_context(cx.metadata_llcx(), &compressed[]);
+    let llmeta = C_bytes_in_context(cx.metadata_llcx(), &compressed[..]);
     let llconst = C_struct_in_context(cx.metadata_llcx(), &[llmeta], false);
     let name = format!("rust_metadata_{}_{}",
                        cx.link_meta().crate_name,
                        cx.link_meta().crate_hash);
-    let buf = CString::from_vec(name.into_bytes());
+    let buf = CString::new(name).unwrap();
     let llglobal = unsafe {
         llvm::LLVMAddGlobal(cx.metadata_llmod(), val_ty(llconst).to_ref(),
                             buf.as_ptr())
@@ -3001,7 +2988,7 @@ pub fn write_metadata(cx: &SharedCrateContext, krate: &ast::Crate) -> Vec<u8> {
     unsafe {
         llvm::LLVMSetInitializer(llglobal, llconst);
         let name = loader::meta_section_name(cx.sess().target.target.options.is_like_osx);
-        let name = CString::from_slice(name.as_bytes());
+        let name = CString::new(name).unwrap();
         llvm::LLVMSetSection(llglobal, name.as_ptr())
     }
     return metadata;
@@ -3039,8 +3026,8 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<String>) {
                     continue
                 }
 
-                let name = ffi::c_str_to_bytes(&llvm::LLVMGetValueName(val))
-                               .to_vec();
+                let name = CStr::from_ptr(llvm::LLVMGetValueName(val))
+                                .to_bytes().to_vec();
                 declared.insert(name);
             }
         }
@@ -3056,8 +3043,8 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<String>) {
                     continue
                 }
 
-                let name = ffi::c_str_to_bytes(&llvm::LLVMGetValueName(val))
-                               .to_vec();
+                let name = CStr::from_ptr(llvm::LLVMGetValueName(val))
+                                .to_bytes().to_vec();
                 if !declared.contains(&name) &&
                    !reachable.contains(str::from_utf8(&name).unwrap()) {
                     llvm::SetLinkage(val, llvm::InternalLinkage);
@@ -3211,7 +3198,7 @@ pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>)
     reachable.push("rust_eh_personality_catch".to_string());
 
     if codegen_units > 1 {
-        internalize_symbols(&shared_ccx, &reachable.iter().map(|x| x.clone()).collect());
+        internalize_symbols(&shared_ccx, &reachable.iter().cloned().collect());
     }
 
     let metadata_module = ModuleTranslation {
diff --git a/src/librustc_trans/trans/builder.rs b/src/librustc_trans/trans/builder.rs
index e268c2f0d5c..8199e6189c9 100644
--- a/src/librustc_trans/trans/builder.rs
+++ b/src/librustc_trans/trans/builder.rs
@@ -431,7 +431,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             if name.is_empty() {
                 llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(), noname())
             } else {
-                let name = CString::from_slice(name.as_bytes());
+                let name = CString::new(name).unwrap();
                 llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(),
                                       name.as_ptr())
             }
@@ -567,7 +567,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         } else {
             let v = ixs.iter().map(|i| C_i32(self.ccx, *i as i32)).collect::<Vec<ValueRef>>();
             self.count_insn("gepi");
-            self.inbounds_gep(base, &v[])
+            self.inbounds_gep(base, &v[..])
         }
     }
 
@@ -775,8 +775,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             let s = format!("{} ({})",
                             text,
                             self.ccx.sess().codemap().span_to_string(sp));
-            debug!("{}", &s[]);
-            self.add_comment(&s[]);
+            debug!("{}", &s[..]);
+            self.add_comment(&s[..]);
         }
     }
 
@@ -786,7 +786,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             let comment_text = format!("{} {}", "#",
                                        sanitized.replace("\n", "\n\t# "));
             self.count_insn("inlineasm");
-            let comment_text = CString::from_vec(comment_text.into_bytes());
+            let comment_text = CString::new(comment_text).unwrap();
             let asm = unsafe {
                 llvm::LLVMConstInlineAsm(Type::func(&[], &Type::void(self.ccx)).to_ref(),
                                          comment_text.as_ptr(), noname(), False,
@@ -813,7 +813,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         }).collect::<Vec<_>>();
 
         debug!("Asm Output Type: {}", self.ccx.tn().type_to_string(output));
-        let fty = Type::func(&argtys[], &output);
+        let fty = Type::func(&argtys[..], &output);
         unsafe {
             let v = llvm::LLVMInlineAsm(
                 fty.to_ref(), asm, cons, volatile, alignstack, dia as c_uint);
diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs
index bda8b8938b7..3d3e35cd776 100644
--- a/src/librustc_trans/trans/callee.rs
+++ b/src/librustc_trans/trans/callee.rs
@@ -323,7 +323,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
     let llfn =
         decl_internal_rust_fn(ccx,
                               tuple_fn_ty,
-                              &function_name[]);
+                              &function_name[..]);
 
     //
     let empty_substs = tcx.mk_substs(Substs::trans_empty());
@@ -359,7 +359,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
                            DebugLoc::None,
                            bare_fn_ty,
                            |bcx, _| Callee { bcx: bcx, data: Fn(llfnpointer) },
-                           ArgVals(&llargs[]),
+                           ArgVals(&llargs[..]),
                            dest).bcx;
 
     finish_fn(&fcx, bcx, sig.output, DebugLoc::None);
@@ -792,7 +792,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
         // Invoke the actual rust fn and update bcx/llresult.
         let (llret, b) = base::invoke(bcx,
                                       llfn,
-                                      &llargs[],
+                                      &llargs[..],
                                       callee_ty,
                                       debug_loc);
         bcx = b;
@@ -833,7 +833,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
                                          callee_ty,
                                          llfn,
                                          opt_llretslot.unwrap(),
-                                         &llargs[],
+                                         &llargs[..],
                                          arg_tys,
                                          debug_loc);
     }
diff --git a/src/librustc_trans/trans/cleanup.rs b/src/librustc_trans/trans/cleanup.rs
index 1c831090e3e..85e53618f6d 100644
--- a/src/librustc_trans/trans/cleanup.rs
+++ b/src/librustc_trans/trans/cleanup.rs
@@ -764,7 +764,7 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx
                 let name = scope.block_name("clean");
                 debug!("generating cleanups for {}", name);
                 let bcx_in = self.new_block(label.is_unwind(),
-                                            &name[],
+                                            &name[..],
                                             None);
                 let mut bcx_out = bcx_in;
                 for cleanup in scope.cleanups.iter().rev() {
@@ -811,7 +811,7 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx
                 Some(llbb) => { return llbb; }
                 None => {
                     let name = last_scope.block_name("unwind");
-                    pad_bcx = self.new_block(true, &name[], None);
+                    pad_bcx = self.new_block(true, &name[..], None);
                     last_scope.cached_landing_pad = Some(pad_bcx.llbb);
                 }
             }
diff --git a/src/librustc_trans/trans/closure.rs b/src/librustc_trans/trans/closure.rs
index f92df999e60..1d4bbd79d71 100644
--- a/src/librustc_trans/trans/closure.rs
+++ b/src/librustc_trans/trans/closure.rs
@@ -158,7 +158,7 @@ pub fn get_or_create_declaration_if_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tc
         mangle_internal_name_by_path_and_seq(path, "closure")
     });
 
-    let llfn = decl_internal_rust_fn(ccx, function_type, &symbol[]);
+    let llfn = decl_internal_rust_fn(ccx, function_type, &symbol[..]);
 
     // set an inline hint for all closures
     set_inline_hint(llfn);
@@ -208,7 +208,7 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
     let function_type = typer.closure_type(closure_id, param_substs);
 
     let freevars: Vec<ty::Freevar> =
-        ty::with_freevars(tcx, id, |fv| fv.iter().map(|&fv| fv).collect());
+        ty::with_freevars(tcx, id, |fv| fv.iter().cloned().collect());
 
     let sig = ty::erase_late_bound_regions(tcx, &function_type.sig);
 
@@ -221,7 +221,7 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
                   &[],
                   sig.output,
                   function_type.abi,
-                  ClosureEnv::Closure(&freevars[]));
+                  ClosureEnv::Closure(&freevars[..]));
 
     // Don't hoist this to the top of the function. It's perfectly legitimate
     // to have a zero-size closure (in which case dest will be `Ignore`) and
diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs
index ac9a982f298..a9cda94beba 100644
--- a/src/librustc_trans/trans/common.rs
+++ b/src/librustc_trans/trans/common.rs
@@ -488,7 +488,7 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
                      opt_node_id: Option<ast::NodeId>)
                      -> Block<'a, 'tcx> {
         unsafe {
-            let name = CString::from_slice(name.as_bytes());
+            let name = CString::new(name).unwrap();
             let llbb = llvm::LLVMAppendBasicBlockInContext(self.ccx.llcx(),
                                                            self.llfn,
                                                            name.as_ptr());
@@ -757,7 +757,7 @@ pub fn C_integral(t: Type, u: u64, sign_extend: bool) -> ValueRef {
 
 pub fn C_floating(s: &str, t: Type) -> ValueRef {
     unsafe {
-        let s = CString::from_slice(s.as_bytes());
+        let s = CString::new(s).unwrap();
         llvm::LLVMConstRealOfString(t.to_ref(), s.as_ptr())
     }
 }
@@ -835,7 +835,8 @@ pub fn C_cstr(cx: &CrateContext, s: InternedString, null_terminated: bool) -> Va
                                                 !null_terminated as Bool);
 
         let gsym = token::gensym("str");
-        let buf = CString::from_vec(format!("str{}", gsym.usize()).into_bytes());
+        let buf = CString::new(format!("str{}", gsym.usize()));
+        let buf = buf.unwrap();
         let g = llvm::LLVMAddGlobal(cx.llmod(), val_ty(sc).to_ref(), buf.as_ptr());
         llvm::LLVMSetInitializer(g, sc);
         llvm::LLVMSetGlobalConstant(g, True);
@@ -1161,8 +1162,8 @@ pub fn langcall(bcx: Block,
         Err(s) => {
             let msg = format!("{} {}", msg, s);
             match span {
-                Some(span) => bcx.tcx().sess.span_fatal(span, &msg[]),
-                None => bcx.tcx().sess.fatal(&msg[]),
+                Some(span) => bcx.tcx().sess.span_fatal(span, &msg[..]),
+                None => bcx.tcx().sess.fatal(&msg[..]),
             }
         }
     }
diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs
index 86f5589556a..7705b53ee38 100644
--- a/src/librustc_trans/trans/consts.rs
+++ b/src/librustc_trans/trans/consts.rs
@@ -75,7 +75,7 @@ pub fn const_lit(cx: &CrateContext, e: &ast::Expr, lit: &ast::Lit)
         ast::LitBool(b) => C_bool(cx, b),
         ast::LitStr(ref s, _) => C_str_slice(cx, (*s).clone()),
         ast::LitBinary(ref data) => {
-            let g = addr_of(cx, C_bytes(cx, &data[]), "binary", e.id);
+            let g = addr_of(cx, C_bytes(cx, &data[..]), "binary", e.id);
             let base = ptrcast(g, Type::i8p(cx));
             let prev_const = cx.const_unsized().borrow_mut()
                                .insert(base, g);
@@ -611,8 +611,8 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
           }
           ast::ExprTup(ref es) => {
               let repr = adt::represent_type(cx, ety);
-              let vals = map_list(&es[]);
-              adt::trans_const(cx, &*repr, 0, &vals[])
+              let vals = map_list(&es[..]);
+              adt::trans_const(cx, &*repr, 0, &vals[..])
           }
           ast::ExprStruct(_, ref fs, ref base_opt) => {
               let repr = adt::represent_type(cx, ety);
@@ -642,9 +642,9 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                       }
                   }).collect::<Vec<_>>();
                   if ty::type_is_simd(cx.tcx(), ety) {
-                      C_vector(&cs[])
+                      C_vector(&cs[..])
                   } else {
-                      adt::trans_const(cx, &*repr, discr, &cs[])
+                      adt::trans_const(cx, &*repr, discr, &cs[..])
                   }
               })
           }
@@ -655,9 +655,9 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                               .collect::<Vec<_>>();
             // If the vector contains enums, an LLVM array won't work.
             if vs.iter().any(|vi| val_ty(*vi) != llunitty) {
-                C_struct(cx, &vs[], false)
+                C_struct(cx, &vs[..], false)
             } else {
-                C_array(llunitty, &vs[])
+                C_array(llunitty, &vs[..])
             }
           }
           ast::ExprRepeat(ref elem, ref count) => {
@@ -671,9 +671,9 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             let unit_val = const_expr(cx, &**elem, param_substs).0;
             let vs: Vec<_> = repeat(unit_val).take(n).collect();
             if val_ty(unit_val) != llunitty {
-                C_struct(cx, &vs[], false)
+                C_struct(cx, &vs[..], false)
             } else {
-                C_array(llunitty, &vs[])
+                C_array(llunitty, &vs[..])
             }
           }
           ast::ExprPath(_) | ast::ExprQPath(_) => {
@@ -715,14 +715,14 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
           }
           ast::ExprCall(ref callee, ref args) => {
               let opt_def = cx.tcx().def_map.borrow().get(&callee.id).cloned();
-              let arg_vals = map_list(&args[]);
+              let arg_vals = map_list(&args[..]);
               match opt_def {
                   Some(def::DefStruct(_)) => {
                       if ty::type_is_simd(cx.tcx(), ety) {
-                          C_vector(&arg_vals[])
+                          C_vector(&arg_vals[..])
                       } else {
                           let repr = adt::represent_type(cx, ety);
-                          adt::trans_const(cx, &*repr, 0, &arg_vals[])
+                          adt::trans_const(cx, &*repr, 0, &arg_vals[..])
                       }
                   }
                   Some(def::DefVariant(enum_did, variant_did, _)) => {
@@ -733,7 +733,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                       adt::trans_const(cx,
                                        &*repr,
                                        vinfo.disr_val,
-                                       &arg_vals[])
+                                       &arg_vals[..])
                   }
                   _ => cx.sess().span_bug(e.span, "expected a struct or variant def")
               }
diff --git a/src/librustc_trans/trans/context.rs b/src/librustc_trans/trans/context.rs
index 96506291b5a..eb07bdb7ba1 100644
--- a/src/librustc_trans/trans/context.rs
+++ b/src/librustc_trans/trans/context.rs
@@ -225,15 +225,15 @@ impl<'a, 'tcx> Iterator for CrateContextMaybeIterator<'a, 'tcx> {
 
 unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextRef, ModuleRef) {
     let llcx = llvm::LLVMContextCreate();
-    let mod_name = CString::from_slice(mod_name.as_bytes());
+    let mod_name = CString::new(mod_name).unwrap();
     let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx);
 
-    let data_layout = &*sess.target.target.data_layout;
-    let data_layout = CString::from_slice(data_layout.as_bytes());
+    let data_layout = sess.target.target.data_layout.as_bytes();
+    let data_layout = CString::new(data_layout).unwrap();
     llvm::LLVMSetDataLayout(llmod, data_layout.as_ptr());
 
-    let llvm_target = &*sess.target.target.llvm_target;
-    let llvm_target = CString::from_slice(llvm_target.as_bytes());
+    let llvm_target = sess.target.target.llvm_target.as_bytes();
+    let llvm_target = CString::new(llvm_target).unwrap();
     llvm::LLVMRustSetNormalizedTarget(llmod, llvm_target.as_ptr());
     (llcx, llmod)
 }
@@ -288,7 +288,7 @@ impl<'tcx> SharedCrateContext<'tcx> {
             // such as a function name in the module.
             // 1. http://llvm.org/bugs/show_bug.cgi?id=11479
             let llmod_id = format!("{}.{}.rs", crate_name, i);
-            let local_ccx = LocalCrateContext::new(&shared_ccx, &llmod_id[]);
+            let local_ccx = LocalCrateContext::new(&shared_ccx, &llmod_id[..]);
             shared_ccx.local_ccxs.push(local_ccx);
         }
 
diff --git a/src/librustc_trans/trans/controlflow.rs b/src/librustc_trans/trans/controlflow.rs
index e6cd44676ce..26e12a1af40 100644
--- a/src/librustc_trans/trans/controlflow.rs
+++ b/src/librustc_trans/trans/controlflow.rs
@@ -177,7 +177,7 @@ pub fn trans_if<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     }
 
     let name = format!("then-block-{}-", thn.id);
-    let then_bcx_in = bcx.fcx.new_id_block(&name[], thn.id);
+    let then_bcx_in = bcx.fcx.new_id_block(&name[..], thn.id);
     let then_bcx_out = trans_block(then_bcx_in, &*thn, dest);
     trans::debuginfo::clear_source_location(bcx.fcx);
 
@@ -378,7 +378,7 @@ pub fn trans_fail<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let did = langcall(bcx, Some(call_info.span), "", PanicFnLangItem);
     let bcx = callee::trans_lang_call(bcx,
                                       did,
-                                      &args[],
+                                      &args[..],
                                       Some(expr::Ignore),
                                       call_info.debug_loc()).bcx;
     Unreachable(bcx);
@@ -407,7 +407,7 @@ pub fn trans_fail_bounds_check<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let did = langcall(bcx, Some(call_info.span), "", PanicBoundsCheckFnLangItem);
     let bcx = callee::trans_lang_call(bcx,
                                       did,
-                                      &args[],
+                                      &args[..],
                                       Some(expr::Ignore),
                                       call_info.debug_loc()).bcx;
     Unreachable(bcx);
diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs
index 23498089c58..fc0129239aa 100644
--- a/src/librustc_trans/trans/debuginfo.rs
+++ b/src/librustc_trans/trans/debuginfo.rs
@@ -299,7 +299,7 @@ impl<'tcx> TypeMap<'tcx> {
         if self.unique_id_to_metadata.insert(unique_type_id, metadata).is_some() {
             let unique_type_id_str = self.get_unique_type_id_as_string(unique_type_id);
             cx.sess().bug(&format!("Type metadata for unique id '{}' is already in the TypeMap!",
-                                  &unique_type_id_str[])[]);
+                                  &unique_type_id_str[..])[]);
         }
     }
 
@@ -380,14 +380,14 @@ impl<'tcx> TypeMap<'tcx> {
                         self.get_unique_type_id_of_type(cx, component_type);
                     let component_type_id =
                         self.get_unique_type_id_as_string(component_type_id);
-                    unique_type_id.push_str(&component_type_id[]);
+                    unique_type_id.push_str(&component_type_id[..]);
                 }
             },
             ty::ty_uniq(inner_type) => {
                 unique_type_id.push('~');
                 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
                 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
-                unique_type_id.push_str(&inner_type_id[]);
+                unique_type_id.push_str(&inner_type_id[..]);
             },
             ty::ty_ptr(ty::mt { ty: inner_type, mutbl } ) => {
                 unique_type_id.push('*');
@@ -397,7 +397,7 @@ impl<'tcx> TypeMap<'tcx> {
 
                 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
                 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
-                unique_type_id.push_str(&inner_type_id[]);
+                unique_type_id.push_str(&inner_type_id[..]);
             },
             ty::ty_rptr(_, ty::mt { ty: inner_type, mutbl }) => {
                 unique_type_id.push('&');
@@ -407,7 +407,7 @@ impl<'tcx> TypeMap<'tcx> {
 
                 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
                 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
-                unique_type_id.push_str(&inner_type_id[]);
+                unique_type_id.push_str(&inner_type_id[..]);
             },
             ty::ty_vec(inner_type, optional_length) => {
                 match optional_length {
@@ -421,7 +421,7 @@ impl<'tcx> TypeMap<'tcx> {
 
                 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
                 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
-                unique_type_id.push_str(&inner_type_id[]);
+                unique_type_id.push_str(&inner_type_id[..]);
             },
             ty::ty_trait(ref trait_data) => {
                 unique_type_id.push_str("trait ");
@@ -452,7 +452,7 @@ impl<'tcx> TypeMap<'tcx> {
                         self.get_unique_type_id_of_type(cx, parameter_type);
                     let parameter_type_id =
                         self.get_unique_type_id_as_string(parameter_type_id);
-                    unique_type_id.push_str(&parameter_type_id[]);
+                    unique_type_id.push_str(&parameter_type_id[..]);
                     unique_type_id.push(',');
                 }
 
@@ -465,7 +465,7 @@ impl<'tcx> TypeMap<'tcx> {
                     ty::FnConverging(ret_ty) => {
                         let return_type_id = self.get_unique_type_id_of_type(cx, ret_ty);
                         let return_type_id = self.get_unique_type_id_as_string(return_type_id);
-                        unique_type_id.push_str(&return_type_id[]);
+                        unique_type_id.push_str(&return_type_id[..]);
                     }
                     ty::FnDiverging => {
                         unique_type_id.push_str("!");
@@ -538,7 +538,7 @@ impl<'tcx> TypeMap<'tcx> {
                         type_map.get_unique_type_id_of_type(cx, type_parameter);
                     let param_type_id =
                         type_map.get_unique_type_id_as_string(param_type_id);
-                    output.push_str(&param_type_id[]);
+                    output.push_str(&param_type_id[..]);
                     output.push(',');
                 }
 
@@ -568,7 +568,7 @@ impl<'tcx> TypeMap<'tcx> {
                 self.get_unique_type_id_of_type(cx, parameter_type);
             let parameter_type_id =
                 self.get_unique_type_id_as_string(parameter_type_id);
-            unique_type_id.push_str(&parameter_type_id[]);
+            unique_type_id.push_str(&parameter_type_id[..]);
             unique_type_id.push(',');
         }
 
@@ -582,7 +582,7 @@ impl<'tcx> TypeMap<'tcx> {
             ty::FnConverging(ret_ty) => {
                 let return_type_id = self.get_unique_type_id_of_type(cx, ret_ty);
                 let return_type_id = self.get_unique_type_id_as_string(return_type_id);
-                unique_type_id.push_str(&return_type_id[]);
+                unique_type_id.push_str(&return_type_id[..]);
             }
             ty::FnDiverging => {
                 unique_type_id.push_str("!");
@@ -806,11 +806,11 @@ pub fn create_global_var_metadata(cx: &CrateContext,
     let namespace_node = namespace_for_item(cx, ast_util::local_def(node_id));
     let var_name = token::get_ident(ident).to_string();
     let linkage_name =
-        namespace_node.mangled_name_of_contained_item(&var_name[]);
+        namespace_node.mangled_name_of_contained_item(&var_name[..]);
     let var_scope = namespace_node.scope;
 
-    let var_name = CString::from_slice(var_name.as_bytes());
-    let linkage_name = CString::from_slice(linkage_name.as_bytes());
+    let var_name = CString::new(var_name).unwrap();
+    let linkage_name = CString::new(linkage_name).unwrap();
     unsafe {
         llvm::LLVMDIBuilderCreateStaticVariable(DIB(cx),
                                                 var_scope,
@@ -1287,7 +1287,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             match expr.node {
                 ast::ExprClosure(_, ref fn_decl, ref top_level_block) => {
                     let name = format!("fn{}", token::gensym("fn"));
-                    let name = token::str_to_ident(&name[]);
+                    let name = token::str_to_ident(&name[..]);
                     (name, &**fn_decl,
                         // This is not quite right. It should actually inherit
                         // the generics of the enclosing function.
@@ -1366,7 +1366,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     let (linkage_name, containing_scope) = if has_path {
         let namespace_node = namespace_for_item(cx, ast_util::local_def(fn_ast_id));
         let linkage_name = namespace_node.mangled_name_of_contained_item(
-            &function_name[]);
+            &function_name[..]);
         let containing_scope = namespace_node.scope;
         (linkage_name, containing_scope)
     } else {
@@ -1379,8 +1379,8 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
     let is_local_to_unit = is_node_local_to_unit(cx, fn_ast_id);
 
-    let function_name = CString::from_slice(function_name.as_bytes());
-    let linkage_name = CString::from_slice(linkage_name.as_bytes());
+    let function_name = CString::new(function_name).unwrap();
+    let linkage_name = CString::new(linkage_name).unwrap();
     let fn_metadata = unsafe {
         llvm::LLVMDIBuilderCreateFunction(
             DIB(cx),
@@ -1451,7 +1451,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             signature.push(type_metadata(cx, arg_type, codemap::DUMMY_SP));
         }
 
-        return create_DIArray(DIB(cx), &signature[]);
+        return create_DIArray(DIB(cx), &signature[..]);
     }
 
     fn get_template_parameters<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
@@ -1486,7 +1486,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 actual_self_type,
                 true);
 
-            name_to_append_suffix_to.push_str(&actual_self_type_name[]);
+            name_to_append_suffix_to.push_str(&actual_self_type_name[..]);
 
             if generics.is_type_parameterized() {
                 name_to_append_suffix_to.push_str(",");
@@ -1501,7 +1501,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 let ident = special_idents::type_self;
 
                 let ident = token::get_ident(ident);
-                let name = CString::from_slice(ident.as_bytes());
+                let name = CString::new(ident.as_bytes()).unwrap();
                 let param_metadata = unsafe {
                     llvm::LLVMDIBuilderCreateTemplateTypeParameter(
                         DIB(cx),
@@ -1525,7 +1525,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             let actual_type_name = compute_debuginfo_type_name(cx,
                                                                actual_type,
                                                                true);
-            name_to_append_suffix_to.push_str(&actual_type_name[]);
+            name_to_append_suffix_to.push_str(&actual_type_name[..]);
 
             if index != generics.ty_params.len() - 1 {
                 name_to_append_suffix_to.push_str(",");
@@ -1535,7 +1535,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             if cx.sess().opts.debuginfo == FullDebugInfo {
                 let actual_type_metadata = type_metadata(cx, actual_type, codemap::DUMMY_SP);
                 let ident = token::get_ident(ident);
-                let name = CString::from_slice(ident.as_bytes());
+                let name = CString::new(ident.as_bytes()).unwrap();
                 let param_metadata = unsafe {
                     llvm::LLVMDIBuilderCreateTemplateTypeParameter(
                         DIB(cx),
@@ -1552,7 +1552,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
         name_to_append_suffix_to.push('>');
 
-        return create_DIArray(DIB(cx), &template_params[]);
+        return create_DIArray(DIB(cx), &template_params[..]);
     }
 }
 
@@ -1601,7 +1601,7 @@ fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor {
                             path_bytes.insert(1, prefix[1]);
                         }
 
-                        CString::from_vec(path_bytes)
+                        CString::new(path_bytes).unwrap()
                     }
                     _ => fallback_path(cx)
                 }
@@ -1614,8 +1614,8 @@ fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor {
                            (option_env!("CFG_VERSION")).expect("CFG_VERSION"));
 
     let compile_unit_name = compile_unit_name.as_ptr();
-    let work_dir = CString::from_slice(work_dir.as_vec());
-    let producer = CString::from_slice(producer.as_bytes());
+    let work_dir = CString::new(work_dir.as_vec()).unwrap();
+    let producer = CString::new(producer).unwrap();
     let flags = "\0";
     let split_name = "\0";
     return unsafe {
@@ -1632,7 +1632,7 @@ fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor {
     };
 
     fn fallback_path(cx: &CrateContext) -> CString {
-        CString::from_slice(cx.link_meta().crate_name.as_bytes())
+        CString::new(cx.link_meta().crate_name.clone()).unwrap()
     }
 }
 
@@ -1646,7 +1646,7 @@ fn declare_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let cx: &CrateContext = bcx.ccx();
 
     let filename = span_start(cx, span).file.name.clone();
-    let file_metadata = file_metadata(cx, &filename[]);
+    let file_metadata = file_metadata(cx, &filename[..]);
 
     let name = token::get_ident(variable_ident);
     let loc = span_start(cx, span);
@@ -1658,7 +1658,7 @@ fn declare_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         CapturedVariable => (0, DW_TAG_auto_variable)
     };
 
-    let name = CString::from_slice(name.as_bytes());
+    let name = CString::new(name.as_bytes()).unwrap();
     match (variable_access, [].as_slice()) {
         (DirectVariable { alloca }, address_operations) |
         (IndirectVariable {alloca, address_operations}, _) => {
@@ -1724,8 +1724,8 @@ fn file_metadata(cx: &CrateContext, full_path: &str) -> DIFile {
             full_path
         };
 
-    let file_name = CString::from_slice(file_name.as_bytes());
-    let work_dir = CString::from_slice(work_dir.as_bytes());
+    let file_name = CString::new(file_name).unwrap();
+    let work_dir = CString::new(work_dir).unwrap();
     let file_metadata = unsafe {
         llvm::LLVMDIBuilderCreateFile(DIB(cx), file_name.as_ptr(),
                                       work_dir.as_ptr())
@@ -1800,7 +1800,7 @@ fn basic_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
     let llvm_type = type_of::type_of(cx, t);
     let (size, align) = size_and_align_of(cx, llvm_type);
-    let name = CString::from_slice(name.as_bytes());
+    let name = CString::new(name).unwrap();
     let ty_metadata = unsafe {
         llvm::LLVMDIBuilderCreateBasicType(
             DIB(cx),
@@ -1820,7 +1820,7 @@ fn pointer_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     let pointer_llvm_type = type_of::type_of(cx, pointer_type);
     let (pointer_size, pointer_align) = size_and_align_of(cx, pointer_llvm_type);
     let name = compute_debuginfo_type_name(cx, pointer_type, false);
-    let name = CString::from_slice(name.as_bytes());
+    let name = CString::new(name).unwrap();
     let ptr_metadata = unsafe {
         llvm::LLVMDIBuilderCreatePointerType(
             DIB(cx),
@@ -1959,7 +1959,7 @@ impl<'tcx> RecursiveTypeDescription<'tcx> {
                 set_members_of_composite_type(cx,
                                               metadata_stub,
                                               llvm_type,
-                                              &member_descriptions[]);
+                                              &member_descriptions[..]);
                 return MetadataCreationResult::new(metadata_stub, true);
             }
         }
@@ -2031,7 +2031,7 @@ fn prepare_struct_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
     let struct_metadata_stub = create_struct_stub(cx,
                                                   struct_llvm_type,
-                                                  &struct_name[],
+                                                  &struct_name[..],
                                                   unique_type_id,
                                                   containing_scope);
 
@@ -2098,7 +2098,7 @@ fn prepare_tuple_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
         unique_type_id,
         create_struct_stub(cx,
                            tuple_llvm_type,
-                           &tuple_name[],
+                           &tuple_name[..],
                            unique_type_id,
                            UNKNOWN_SCOPE_METADATA),
         tuple_llvm_type,
@@ -2158,7 +2158,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
                         set_members_of_composite_type(cx,
                                                       variant_type_metadata,
                                                       variant_llvm_type,
-                                                      &member_descriptions[]);
+                                                      &member_descriptions[..]);
                         MemberDescription {
                             name: "".to_string(),
                             llvm_type: variant_llvm_type,
@@ -2191,7 +2191,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
                     set_members_of_composite_type(cx,
                                                   variant_type_metadata,
                                                   variant_llvm_type,
-                                                  &member_descriptions[]);
+                                                  &member_descriptions[..]);
                     vec![
                         MemberDescription {
                             name: "".to_string(),
@@ -2291,7 +2291,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
                 set_members_of_composite_type(cx,
                                               variant_type_metadata,
                                               variant_llvm_type,
-                                              &variant_member_descriptions[]);
+                                              &variant_member_descriptions[..]);
 
                 // Encode the information about the null variant in the union
                 // member's name.
@@ -2445,7 +2445,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
         .iter()
         .map(|v| {
             let token = token::get_name(v.name);
-            let name = CString::from_slice(token.as_bytes());
+            let name = CString::new(token.as_bytes()).unwrap();
             unsafe {
                 llvm::LLVMDIBuilderCreateEnumerator(
                     DIB(cx),
@@ -2475,7 +2475,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                                   codemap::DUMMY_SP);
                 let discriminant_name = get_enum_discriminant_name(cx, enum_def_id);
 
-                let name = CString::from_slice(discriminant_name.as_bytes());
+                let name = CString::new(discriminant_name.as_bytes()).unwrap();
                 let discriminant_type_metadata = unsafe {
                     llvm::LLVMDIBuilderCreateEnumerationType(
                         DIB(cx),
@@ -2518,8 +2518,8 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                              .borrow()
                              .get_unique_type_id_as_string(unique_type_id);
 
-    let enum_name = CString::from_slice(enum_name.as_bytes());
-    let unique_type_id_str = CString::from_slice(unique_type_id_str.as_bytes());
+    let enum_name = CString::new(enum_name).unwrap();
+    let unique_type_id_str = CString::new(unique_type_id_str.as_bytes()).unwrap();
     let enum_metadata = unsafe {
         llvm::LLVMDIBuilderCreateUnionType(
         DIB(cx),
@@ -2644,7 +2644,8 @@ fn set_members_of_composite_type(cx: &CrateContext,
                 ComputedMemberOffset => machine::llelement_offset(cx, composite_llvm_type, i)
             };
 
-            let member_name = CString::from_slice(member_description.name.as_bytes());
+            let member_name = member_description.name.as_bytes();
+            let member_name = CString::new(member_name).unwrap();
             unsafe {
                 llvm::LLVMDIBuilderCreateMemberType(
                     DIB(cx),
@@ -2662,7 +2663,7 @@ fn set_members_of_composite_type(cx: &CrateContext,
         .collect();
 
     unsafe {
-        let type_array = create_DIArray(DIB(cx), &member_metadata[]);
+        let type_array = create_DIArray(DIB(cx), &member_metadata[..]);
         llvm::LLVMDICompositeTypeSetTypeArray(DIB(cx), composite_type_metadata, type_array);
     }
 }
@@ -2681,8 +2682,8 @@ fn create_struct_stub(cx: &CrateContext,
     let unique_type_id_str = debug_context(cx).type_map
                                               .borrow()
                                               .get_unique_type_id_as_string(unique_type_id);
-    let name = CString::from_slice(struct_type_name.as_bytes());
-    let unique_type_id = CString::from_slice(unique_type_id_str.as_bytes());
+    let name = CString::new(struct_type_name).unwrap();
+    let unique_type_id = CString::new(unique_type_id_str.as_bytes()).unwrap();
     let metadata_stub = unsafe {
         // LLVMDIBuilderCreateStructType() wants an empty array. A null
         // pointer will lead to hard to trace and debug LLVM assertions
@@ -2763,7 +2764,7 @@ fn vec_slice_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
     let member_llvm_types = slice_llvm_type.field_types();
     assert!(slice_layout_is_correct(cx,
-                                    &member_llvm_types[],
+                                    &member_llvm_types[..],
                                     element_type));
     let member_descriptions = [
         MemberDescription {
@@ -2789,7 +2790,7 @@ fn vec_slice_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
     let metadata = composite_type_metadata(cx,
                                            slice_llvm_type,
-                                           &slice_type_name[],
+                                           &slice_type_name[..],
                                            unique_type_id,
                                            &member_descriptions,
                                            UNKNOWN_SCOPE_METADATA,
@@ -2838,7 +2839,7 @@ fn subroutine_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             llvm::LLVMDIBuilderCreateSubroutineType(
                 DIB(cx),
                 UNKNOWN_FILE_METADATA,
-                create_DIArray(DIB(cx), &signature_metadata[]))
+                create_DIArray(DIB(cx), &signature_metadata[..]))
         },
         false);
 }
@@ -2864,7 +2865,7 @@ fn trait_pointer_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             let pp_type_name = ppaux::ty_to_string(cx.tcx(), trait_type);
             cx.sess().bug(&format!("debuginfo: Unexpected trait-object type in \
                                    trait_pointer_metadata(): {}",
-                                   &pp_type_name[])[]);
+                                   &pp_type_name[..])[]);
         }
     };
 
@@ -2878,7 +2879,7 @@ fn trait_pointer_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
     composite_type_metadata(cx,
                             trait_llvm_type,
-                            &trait_type_name[],
+                            &trait_type_name[..],
                             unique_type_id,
                             &[],
                             containing_scope,
@@ -2998,7 +2999,7 @@ fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
         ty::ty_tup(ref elements) => {
             prepare_tuple_metadata(cx,
                                    t,
-                                   &elements[],
+                                   &elements[..],
                                    unique_type_id,
                                    usage_site_span).finalize(cx)
         }
@@ -3022,9 +3023,9 @@ fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                                                  type id '{}' to already be in \
                                                  the debuginfo::TypeMap but it \
                                                  was not. (Ty = {})",
-                                                &unique_type_id_str[],
+                                                &unique_type_id_str[..],
                                                 ppaux::ty_to_string(cx.tcx(), t));
-                    cx.sess().span_bug(usage_site_span, &error_message[]);
+                    cx.sess().span_bug(usage_site_span, &error_message[..]);
                 }
             };
 
@@ -3037,9 +3038,9 @@ fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                                                      UniqueTypeId maps in \
                                                      debuginfo::TypeMap. \
                                                      UniqueTypeId={}, Ty={}",
-                            &unique_type_id_str[],
+                            &unique_type_id_str[..],
                             ppaux::ty_to_string(cx.tcx(), t));
-                        cx.sess().span_bug(usage_site_span, &error_message[]);
+                        cx.sess().span_bug(usage_site_span, &error_message[..]);
                     }
                 }
                 None => {
@@ -3128,7 +3129,7 @@ fn contains_nodebug_attribute(attributes: &[ast::Attribute]) -> bool {
     attributes.iter().any(|attr| {
         let meta_item: &ast::MetaItem = &*attr.node.value;
         match meta_item.node {
-            ast::MetaWord(ref value) => &value[] == "no_debug",
+            ast::MetaWord(ref value) => &value[..] == "no_debug",
             _ => false
         }
     })
@@ -3971,8 +3972,7 @@ fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> Rc<NamespaceTree
                         None => ptr::null_mut()
                     };
                     let namespace_name = token::get_name(name);
-                    let namespace_name = CString::from_slice(namespace_name
-                                                                .as_bytes());
+                    let namespace_name = CString::new(namespace_name.as_bytes()).unwrap();
                     let scope = unsafe {
                         llvm::LLVMDIBuilderCreateNameSpace(
                             DIB(cx),
@@ -4020,7 +4020,7 @@ fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> Rc<NamespaceTree
 /// .debug_gdb_scripts global is referenced, so it isn't removed by the linker.
 pub fn insert_reference_to_gdb_debug_scripts_section_global(ccx: &CrateContext) {
     if needs_gdb_debug_scripts_section(ccx) {
-        let empty = CString::from_slice(b"");
+        let empty = CString::new(b"").unwrap();
         let gdb_debug_scripts_section_global =
             get_or_insert_gdb_debug_scripts_section_global(ccx);
         unsafe {
diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs
index 861a218e0f1..1af9fa87c6b 100644
--- a/src/librustc_trans/trans/expr.rs
+++ b/src/librustc_trans/trans/expr.rs
@@ -1046,14 +1046,14 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             controlflow::trans_if(bcx, expr.id, &**cond, &**thn, els.as_ref().map(|e| &**e), dest)
         }
         ast::ExprMatch(ref discr, ref arms, _) => {
-            _match::trans_match(bcx, expr, &**discr, &arms[], dest)
+            _match::trans_match(bcx, expr, &**discr, &arms[..], dest)
         }
         ast::ExprBlock(ref blk) => {
             controlflow::trans_block(bcx, &**blk, dest)
         }
         ast::ExprStruct(_, ref fields, ref base) => {
             trans_struct(bcx,
-                         &fields[],
+                         &fields[..],
                          base.as_ref().map(|e| &**e),
                          expr.span,
                          expr.id,
@@ -1118,7 +1118,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             trans_adt(bcx,
                       expr_ty(bcx, expr),
                       0,
-                      &numbered_fields[],
+                      &numbered_fields[..],
                       None,
                       dest,
                       expr.debug_loc())
@@ -1153,13 +1153,13 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 trans_overloaded_call(bcx,
                                       expr,
                                       &**f,
-                                      &args[],
+                                      &args[..],
                                       Some(dest))
             } else {
                 callee::trans_call(bcx,
                                    expr,
                                    &**f,
-                                   callee::ArgExprs(&args[]),
+                                   callee::ArgExprs(&args[..]),
                                    dest)
             }
         }
@@ -1167,7 +1167,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             callee::trans_method_call(bcx,
                                       expr,
                                       &*args[0],
-                                      callee::ArgExprs(&args[]),
+                                      callee::ArgExprs(&args[..]),
                                       dest)
         }
         ast::ExprBinary(op, ref lhs, ref rhs) => {
@@ -1197,7 +1197,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 let trait_ref =
                     bcx.tcx().object_cast_map.borrow()
                                              .get(&expr.id)
-                                             .map(|t| (*t).clone())
+                                             .cloned()
                                              .unwrap();
                 let trait_ref = bcx.monomorphize(&trait_ref);
                 let datum = unpack_datum!(bcx, trans(bcx, &**val));
@@ -1354,11 +1354,11 @@ pub fn with_field_tys<'tcx, R, F>(tcx: &ty::ctxt<'tcx>,
         ty::ty_struct(did, substs) => {
             let fields = struct_fields(tcx, did, substs);
             let fields = monomorphize::normalize_associated_type(tcx, &fields);
-            op(0, &fields[])
+            op(0, &fields[..])
         }
 
         ty::ty_tup(ref v) => {
-            op(0, &tup_fields(&v[])[])
+            op(0, &tup_fields(&v[..])[])
         }
 
         ty::ty_enum(_, substs) => {
@@ -1378,7 +1378,7 @@ pub fn with_field_tys<'tcx, R, F>(tcx: &ty::ctxt<'tcx>,
                                 tcx, enum_id, variant_id);
                             let fields = struct_fields(tcx, variant_id, substs);
                             let fields = monomorphize::normalize_associated_type(tcx, &fields);
-                            op(variant_info.disr_val, &fields[])
+                            op(variant_info.disr_val, &fields[..])
                         }
                         _ => {
                             tcx.sess.bug("resolve didn't map this expr to a \
diff --git a/src/librustc_trans/trans/foreign.rs b/src/librustc_trans/trans/foreign.rs
index 8f0e4e647b5..4508fe21a65 100644
--- a/src/librustc_trans/trans/foreign.rs
+++ b/src/librustc_trans/trans/foreign.rs
@@ -135,7 +135,7 @@ pub fn register_static(ccx: &CrateContext,
             };
             unsafe {
                 // Declare a symbol `foo` with the desired linkage.
-                let buf = CString::from_slice(ident.as_bytes());
+                let buf = CString::new(ident.as_bytes()).unwrap();
                 let g1 = llvm::LLVMAddGlobal(ccx.llmod(), llty2.to_ref(),
                                              buf.as_ptr());
                 llvm::SetLinkage(g1, linkage);
@@ -148,7 +148,7 @@ pub fn register_static(ccx: &CrateContext,
                 // zero.
                 let mut real_name = "_rust_extern_with_linkage_".to_string();
                 real_name.push_str(&ident);
-                let real_name = CString::from_vec(real_name.into_bytes());
+                let real_name = CString::new(real_name).unwrap();
                 let g2 = llvm::LLVMAddGlobal(ccx.llmod(), llty.to_ref(),
                                              real_name.as_ptr());
                 llvm::SetLinkage(g2, llvm::InternalLinkage);
@@ -158,7 +158,7 @@ pub fn register_static(ccx: &CrateContext,
         }
         None => unsafe {
             // Generate an external declaration.
-            let buf = CString::from_slice(ident.as_bytes());
+            let buf = CString::new(ident.as_bytes()).unwrap();
             llvm::LLVMAddGlobal(ccx.llmod(), llty.to_ref(), buf.as_ptr())
         }
     }
@@ -238,7 +238,7 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         _ => ccx.sess().bug("trans_native_call called on non-function type")
     };
     let fn_sig = ty::erase_late_bound_regions(ccx.tcx(), fn_sig);
-    let llsig = foreign_signature(ccx, &fn_sig, &passed_arg_tys[]);
+    let llsig = foreign_signature(ccx, &fn_sig, &passed_arg_tys[..]);
     let fn_type = cabi::compute_abi_info(ccx,
                                          &llsig.llarg_tys[],
                                          llsig.llret_ty,
@@ -370,7 +370,7 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
     let llforeign_retval = CallWithConv(bcx,
                                         llfn,
-                                        &llargs_foreign[],
+                                        &llargs_foreign[..],
                                         cc,
                                         Some(attrs),
                                         call_debug_loc);
@@ -611,7 +611,7 @@ pub fn trans_rust_fn_with_foreign_abi<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                ccx.tcx().map.path_to_string(id),
                id, t.repr(tcx));
 
-        let llfn = base::decl_internal_rust_fn(ccx, t, &ps[]);
+        let llfn = base::decl_internal_rust_fn(ccx, t, &ps[..]);
         base::set_llvm_fn_attrs(ccx, attrs, llfn);
         base::trans_fn(ccx, decl, body, llfn, param_substs, id, &[]);
         llfn
@@ -974,7 +974,7 @@ fn lltype_for_fn_from_foreign_types(ccx: &CrateContext, tys: &ForeignTypes) -> T
     if tys.fn_sig.variadic {
         Type::variadic_func(&llargument_tys, &llreturn_ty)
     } else {
-        Type::func(&llargument_tys[], &llreturn_ty)
+        Type::func(&llargument_tys[..], &llreturn_ty)
     }
 }
 
diff --git a/src/librustc_trans/trans/glue.rs b/src/librustc_trans/trans/glue.rs
index af90e1ec5c5..268b65c6ceb 100644
--- a/src/librustc_trans/trans/glue.rs
+++ b/src/librustc_trans/trans/glue.rs
@@ -170,7 +170,7 @@ pub fn get_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Val
 
     let (glue, new_sym) = match ccx.available_drop_glues().borrow().get(&t) {
         Some(old_sym) => {
-            let glue = decl_cdecl_fn(ccx, &old_sym[], llfnty, ty::mk_nil(ccx.tcx()));
+            let glue = decl_cdecl_fn(ccx, &old_sym[..], llfnty, ty::mk_nil(ccx.tcx()));
             (glue, None)
         },
         None => {
@@ -304,7 +304,7 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                      class_did,
                                      &[get_drop_glue_type(bcx.ccx(), t)],
                                      ty::mk_nil(bcx.tcx()));
-        let (_, variant_cx) = invoke(variant_cx, dtor_addr, &args[], dtor_ty, DebugLoc::None);
+        let (_, variant_cx) = invoke(variant_cx, dtor_addr, &args[..], dtor_ty, DebugLoc::None);
 
         variant_cx.fcx.pop_and_trans_custom_cleanup_scope(variant_cx, field_scope);
         variant_cx
@@ -513,7 +513,7 @@ pub fn declare_tydesc<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>)
     let llalign = llalign_of(ccx, llty);
     let name = mangle_internal_name_by_type_and_seq(ccx, t, "tydesc");
     debug!("+++ declare_tydesc {} {}", ppaux::ty_to_string(ccx.tcx(), t), name);
-    let buf = CString::from_slice(name.as_bytes());
+    let buf = CString::new(name.clone()).unwrap();
     let gvar = unsafe {
         llvm::LLVMAddGlobal(ccx.llmod(), ccx.tydesc_type().to_ref(),
                             buf.as_ptr())
@@ -541,7 +541,7 @@ fn declare_generic_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>,
         ccx,
         t,
         &format!("glue_{}", name)[]);
-    let llfn = decl_cdecl_fn(ccx, &fn_nm[], llfnty, ty::mk_nil(ccx.tcx()));
+    let llfn = decl_cdecl_fn(ccx, &fn_nm[..], llfnty, ty::mk_nil(ccx.tcx()));
     note_unique_llvm_symbol(ccx, fn_nm.clone());
     return (fn_nm, llfn);
 }
diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs
index 5687247561e..a1b66ed94f0 100644
--- a/src/librustc_trans/trans/intrinsic.rs
+++ b/src/librustc_trans/trans/intrinsic.rs
@@ -166,7 +166,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
     let name = token::get_ident(foreign_item.ident);
 
     // For `transmute` we can just trans the input expr directly into dest
-    if &name[] == "transmute" {
+    if &name[..] == "transmute" {
         let llret_ty = type_of::type_of(ccx, ret_ty.unwrap());
         match args {
             callee::ArgExprs(arg_exprs) => {
@@ -274,13 +274,13 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
     let call_debug_location = DebugLoc::At(call_info.id, call_info.span);
 
     // These are the only intrinsic functions that diverge.
-    if &name[] == "abort" {
+    if &name[..] == "abort" {
         let llfn = ccx.get_intrinsic(&("llvm.trap"));
         Call(bcx, llfn, &[], None, call_debug_location);
         fcx.pop_and_trans_custom_cleanup_scope(bcx, cleanup_scope);
         Unreachable(bcx);
         return Result::new(bcx, C_undef(Type::nil(ccx).ptr_to()));
-    } else if &name[] == "unreachable" {
+    } else if &name[..] == "unreachable" {
         fcx.pop_and_trans_custom_cleanup_scope(bcx, cleanup_scope);
         Unreachable(bcx);
         return Result::new(bcx, C_nil(ccx));
@@ -307,7 +307,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
     };
 
     let simple = get_simple_intrinsic(ccx, &*foreign_item);
-    let llval = match (simple, &name[]) {
+    let llval = match (simple, &name[..]) {
         (Some(llfn), _) => {
             Call(bcx, llfn, &llargs, None, call_debug_location)
         }
diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs
index 30797344da8..ec48ab0d34a 100644
--- a/src/librustc_trans/trans/monomorphize.rs
+++ b/src/librustc_trans/trans/monomorphize.rs
@@ -131,7 +131,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
 
         hash = format!("h{}", state.finish());
         ccx.tcx().map.with_path(fn_id.node, |path| {
-            exported_name(path, &hash[])
+            exported_name(path, &hash[..])
         })
     };
 
@@ -141,9 +141,9 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
     let mut hash_id = Some(hash_id);
     let mut mk_lldecl = |abi: abi::Abi| {
         let lldecl = if abi != abi::Rust {
-            foreign::decl_rust_fn_with_foreign_abi(ccx, mono_ty, &s[])
+            foreign::decl_rust_fn_with_foreign_abi(ccx, mono_ty, &s[..])
         } else {
-            decl_internal_rust_fn(ccx, mono_ty, &s[])
+            decl_internal_rust_fn(ccx, mono_ty, &s[..])
         };
 
         ccx.monomorphized().borrow_mut().insert(hash_id.take().unwrap(), lldecl);
@@ -182,7 +182,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                       if abi != abi::Rust {
                           foreign::trans_rust_fn_with_foreign_abi(
                               ccx, &**decl, &**body, &[], d, psubsts, fn_id.node,
-                              Some(&hash[]));
+                              Some(&hash[..]));
                       } else {
                           trans_fn(ccx, &**decl, &**body, d, psubsts, fn_id.node, &[]);
                       }
@@ -206,7 +206,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                     trans_enum_variant(ccx,
                                        parent,
                                        &*v,
-                                       &args[],
+                                       &args[..],
                                        this_tv.disr_val,
                                        psubsts,
                                        d);
diff --git a/src/librustc_trans/trans/tvec.rs b/src/librustc_trans/trans/tvec.rs
index 456e27967f5..7b59e0258ee 100644
--- a/src/librustc_trans/trans/tvec.rs
+++ b/src/librustc_trans/trans/tvec.rs
@@ -171,33 +171,27 @@ pub fn trans_slice_vec<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let vt = vec_types_from_expr(bcx, content_expr);
     let count = elements_required(bcx, content_expr);
     debug!("    vt={}, count={}", vt.to_string(ccx), count);
-    let llcount = C_uint(ccx, count);
 
     let fixed_ty = ty::mk_vec(bcx.tcx(),
                               vt.unit_ty,
                               Some(count));
-    let llfixed_ty = type_of::type_of(bcx.ccx(), fixed_ty).ptr_to();
+    let llfixed_ty = type_of::type_of(bcx.ccx(), fixed_ty);
 
-    let llfixed = if count == 0 {
-        // Just create a zero-sized alloca to preserve
-        // the non-null invariant of the inner slice ptr
-        let llfixed = base::arrayalloca(bcx, vt.llunit_ty, llcount);
-        BitCast(bcx, llfixed, llfixed_ty)
-    } else {
-        // Make a fixed-length backing array and allocate it on the stack.
-        let llfixed = base::arrayalloca(bcx, vt.llunit_ty, llcount);
+    // Always create an alloca even if zero-sized, to preserve
+    // the non-null invariant of the inner slice ptr
+    let llfixed = base::alloca(bcx, llfixed_ty, "");
 
+    if count > 0 {
         // Arrange for the backing array to be cleaned up.
-        let llfixed_casted = BitCast(bcx, llfixed, llfixed_ty);
         let cleanup_scope = cleanup::temporary_scope(bcx.tcx(), content_expr.id);
-        fcx.schedule_lifetime_end(cleanup_scope, llfixed_casted);
-        fcx.schedule_drop_mem(cleanup_scope, llfixed_casted, fixed_ty);
+        fcx.schedule_lifetime_end(cleanup_scope, llfixed);
+        fcx.schedule_drop_mem(cleanup_scope, llfixed, fixed_ty);
 
         // Generate the content into the backing array.
-        bcx = write_content(bcx, &vt, slice_expr,
-                            content_expr, SaveIn(llfixed));
-
-        llfixed_casted
+        // llfixed has type *[T x N], but we want the type *T,
+        // so use GEP to convert
+        bcx = write_content(bcx, &vt, slice_expr, content_expr,
+                            SaveIn(GEPi(bcx, llfixed, &[0, 0])));
     };
 
     immediate_rvalue_bcx(bcx, llfixed, vec_ty).to_expr_datumblock()
@@ -426,49 +420,27 @@ pub fn iter_vec_loop<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
     let _icx = push_ctxt("tvec::iter_vec_loop");
     let fcx = bcx.fcx;
 
-    let next_bcx = fcx.new_temp_block("expr_repeat: while next");
     let loop_bcx = fcx.new_temp_block("expr_repeat");
-    let cond_bcx = fcx.new_temp_block("expr_repeat: loop cond");
-    let body_bcx = fcx.new_temp_block("expr_repeat: body: set");
-    let inc_bcx = fcx.new_temp_block("expr_repeat: body: inc");
-    Br(bcx, loop_bcx.llbb, DebugLoc::None);
-
-    let loop_counter = {
-        // i = 0
-        let i = alloca(loop_bcx, bcx.ccx().int_type(), "__i");
-        Store(loop_bcx, C_uint(bcx.ccx(), 0_u32), i);
+    let next_bcx = fcx.new_temp_block("expr_repeat: next");
 
-        Br(loop_bcx, cond_bcx.llbb, DebugLoc::None);
-        i
-    };
-
-    { // i < count
-        let lhs = Load(cond_bcx, loop_counter);
-        let rhs = count;
-        let cond_val = ICmp(cond_bcx, llvm::IntULT, lhs, rhs, DebugLoc::None);
-
-        CondBr(cond_bcx, cond_val, body_bcx.llbb, next_bcx.llbb, DebugLoc::None);
-    }
+    Br(bcx, loop_bcx.llbb, DebugLoc::None);
 
-    { // loop body
-        let i = Load(body_bcx, loop_counter);
-        let lleltptr = if vt.llunit_alloc_size == 0 {
-            data_ptr
-        } else {
-            InBoundsGEP(body_bcx, data_ptr, &[i])
-        };
-        let body_bcx = f(body_bcx, lleltptr, vt.unit_ty);
+    let loop_counter = Phi(loop_bcx, bcx.ccx().int_type(),
+                           &[C_uint(bcx.ccx(), 0 as usize)], &[bcx.llbb]);
 
-        Br(body_bcx, inc_bcx.llbb, DebugLoc::None);
-    }
+    let bcx = loop_bcx;
 
-    { // i += 1
-        let i = Load(inc_bcx, loop_counter);
-        let plusone = Add(inc_bcx, i, C_uint(bcx.ccx(), 1_u32), DebugLoc::None);
-        Store(inc_bcx, plusone, loop_counter);
+    let lleltptr = if vt.llunit_alloc_size == 0 {
+        data_ptr
+    } else {
+        InBoundsGEP(bcx, data_ptr, &[loop_counter])
+    };
+    let bcx = f(bcx, lleltptr, vt.unit_ty);
+    let plusone = Add(bcx, loop_counter, C_uint(bcx.ccx(), 1us), DebugLoc::None);
+    AddIncomingToPhi(loop_counter, plusone, bcx.llbb);
 
-        Br(inc_bcx, cond_bcx.llbb, DebugLoc::None);
-    }
+    let cond_val = ICmp(bcx, llvm::IntULT, plusone, count, DebugLoc::None);
+    CondBr(bcx, cond_val, loop_bcx.llbb, next_bcx.llbb, DebugLoc::None);
 
     next_bcx
 }
diff --git a/src/librustc_trans/trans/type_.rs b/src/librustc_trans/trans/type_.rs
index e3e4ca62c26..ad83135a0d4 100644
--- a/src/librustc_trans/trans/type_.rs
+++ b/src/librustc_trans/trans/type_.rs
@@ -163,7 +163,7 @@ impl Type {
     }
 
     pub fn named_struct(ccx: &CrateContext, name: &str) -> Type {
-        let name = CString::from_slice(name.as_bytes());
+        let name = CString::new(name).unwrap();
         ty!(llvm::LLVMStructCreateNamed(ccx.llcx(), name.as_ptr()))
     }
 
diff --git a/src/librustc_trans/trans/type_of.rs b/src/librustc_trans/trans/type_of.rs
index 9d1c0fadefc..489b56bbe68 100644
--- a/src/librustc_trans/trans/type_of.rs
+++ b/src/librustc_trans/trans/type_of.rs
@@ -67,7 +67,7 @@ pub fn untuple_arguments_if_necessary<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                                 abi: abi::Abi)
                                                 -> Vec<Ty<'tcx>> {
     if abi != abi::RustCall {
-        return inputs.iter().map(|x| (*x).clone()).collect()
+        return inputs.iter().cloned().collect()
     }
 
     if inputs.len() == 0 {
@@ -144,7 +144,7 @@ pub fn type_of_rust_fn<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     let input_tys = inputs.iter().map(|&arg_ty| type_of_explicit_arg(cx, arg_ty));
     atys.extend(input_tys);
 
-    Type::func(&atys[], &lloutputtype)
+    Type::func(&atys[..], &lloutputtype)
 }
 
 // Given a function type and a count of ty params, construct an llvm type
@@ -332,7 +332,7 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
           let repr = adt::represent_type(cx, t);
           let tps = substs.types.get_slice(subst::TypeSpace);
           let name = llvm_type_name(cx, an_enum, did, tps);
-          adt::incomplete_type_of(cx, &*repr, &name[])
+          adt::incomplete_type_of(cx, &*repr, &name[..])
       }
       ty::ty_closure(did, _, ref substs) => {
           // Only create the named struct, but don't fill it in. We
@@ -343,7 +343,7 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
           // contents of the VecPerParamSpace to to construct the llvm
           // name
           let name = llvm_type_name(cx, a_closure, did, substs.types.as_slice());
-          adt::incomplete_type_of(cx, &*repr, &name[])
+          adt::incomplete_type_of(cx, &*repr, &name[..])
       }
 
       ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) | ty::ty_ptr(ty::mt{ty, ..}) => {
@@ -399,7 +399,7 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
               let repr = adt::represent_type(cx, t);
               let tps = substs.types.get_slice(subst::TypeSpace);
               let name = llvm_type_name(cx, a_struct, did, tps);
-              adt::incomplete_type_of(cx, &*repr, &name[])
+              adt::incomplete_type_of(cx, &*repr, &name[..])
           }
       }
 
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 0183b3474a5..e3c1c66f78c 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -404,17 +404,30 @@ fn create_substs_for_ast_path<'tcx>(
 
     let actual_supplied_ty_param_count = substs.types.len(TypeSpace);
     for param in &ty_param_defs[actual_supplied_ty_param_count..] {
-        match param.default {
-            Some(default) => {
+        if let Some(default) = param.default {
+            // If we are converting an object type, then the
+            // `Self` parameter is unknown. However, some of the
+            // other type parameters may reference `Self` in their
+            // defaults. This will lead to an ICE if we are not
+            // careful!
+            if self_ty.is_none() && ty::type_has_self(default) {
+                tcx.sess.span_err(
+                    span,
+                    &format!("the type parameter `{}` must be explicitly specified \
+                              in an object type because its default value `{}` references \
+                              the type `Self`",
+                             param.name.user_string(tcx),
+                             default.user_string(tcx)));
+                substs.types.push(TypeSpace, tcx.types.err);
+            } else {
                 // This is a default type parameter.
                 let default = default.subst_spanned(tcx,
                                                     &substs,
                                                     Some(span));
                 substs.types.push(TypeSpace, default);
             }
-            None => {
-                tcx.sess.span_bug(span, "extra parameter without default");
-            }
+        } else {
+            tcx.sess.span_bug(span, "extra parameter without default");
         }
     }
 
@@ -1139,14 +1152,14 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>,
                 ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, &**ty), None)
             }
             ast::TyObjectSum(ref ty, ref bounds) => {
-                match ast_ty_to_trait_ref(this, rscope, &**ty, &bounds[]) {
+                match ast_ty_to_trait_ref(this, rscope, &**ty, &bounds[..]) {
                     Ok((trait_ref, projection_bounds)) => {
                         trait_ref_to_object_type(this,
                                                  rscope,
                                                  ast_ty.span,
                                                  trait_ref,
                                                  projection_bounds,
-                                                 &bounds[])
+                                                 &bounds[..])
                     }
                     Err(ErrorReported) => {
                         this.tcx().types.err
@@ -1185,7 +1198,7 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>,
                 ty::mk_bare_fn(tcx, None, tcx.mk_bare_fn(bare_fn))
             }
             ast::TyPolyTraitRef(ref bounds) => {
-                conv_ty_poly_trait_ref(this, rscope, ast_ty.span, &bounds[])
+                conv_ty_poly_trait_ref(this, rscope, ast_ty.span, &bounds[..])
             }
             ast::TyPath(ref path, id) => {
                 let a_def = match tcx.def_map.borrow().get(&id) {
@@ -1424,7 +1437,7 @@ fn ty_of_method_or_bare_fn<'a, 'tcx>(this: &AstConv<'tcx>,
             // Skip the first argument if `self` is present.
             &self_and_input_tys[1..]
         } else {
-            &self_and_input_tys[]
+            &self_and_input_tys[..]
         };
 
         let (ior, lfp) = find_implied_output_region(input_tys, input_pats);
@@ -1623,7 +1636,7 @@ fn conv_ty_poly_trait_ref<'tcx>(
     ast_bounds: &[ast::TyParamBound])
     -> Ty<'tcx>
 {
-    let mut partitioned_bounds = partition_bounds(this.tcx(), span, &ast_bounds[]);
+    let mut partitioned_bounds = partition_bounds(this.tcx(), span, &ast_bounds[..]);
 
     let mut projection_bounds = Vec::new();
     let main_trait_bound = if !partitioned_bounds.trait_bounds.is_empty() {
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 0d30741978a..34c52981b79 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -162,7 +162,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
             check_pat_enum(pcx, pat, &path, Some(&[]), expected);
         }
         ast::PatEnum(ref path, ref subpats) => {
-            let subpats = subpats.as_ref().map(|v| &v[]);
+            let subpats = subpats.as_ref().map(|v| &v[..]);
             check_pat_enum(pcx, pat, path, subpats, expected);
         }
         ast::PatStruct(ref path, ref fields, etc) => {
diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs
index 7354ea7377c..0ad15456df9 100644
--- a/src/librustc_typeck/check/callee.rs
+++ b/src/librustc_typeck/check/callee.rs
@@ -256,7 +256,7 @@ fn confirm_builtin_call<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
     check_argument_types(fcx,
                          call_expr.span,
                          &fn_sig.inputs,
-                         &expected_arg_tys[],
+                         &expected_arg_tys[..],
                          arg_exprs,
                          AutorefArgs::No,
                          fn_sig.variadic,
diff --git a/src/librustc_typeck/check/implicator.rs b/src/librustc_typeck/check/implicator.rs
index da25719baaa..4aaaf4ffe5a 100644
--- a/src/librustc_typeck/check/implicator.rs
+++ b/src/librustc_typeck/check/implicator.rs
@@ -329,6 +329,9 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> {
     fn accumulate_from_assoc_types_transitive(&mut self,
                                               data: &ty::PolyTraitPredicate<'tcx>)
     {
+        debug!("accumulate_from_assoc_types_transitive({})",
+               data.repr(self.tcx()));
+
         for poly_trait_ref in traits::supertraits(self.tcx(), data.to_poly_trait_ref()) {
             match ty::no_late_bound_regions(self.tcx(), &poly_trait_ref) {
                 Some(trait_ref) => { self.accumulate_from_assoc_types(trait_ref); }
@@ -340,6 +343,9 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> {
     fn accumulate_from_assoc_types(&mut self,
                                    trait_ref: Rc<ty::TraitRef<'tcx>>)
     {
+        debug!("accumulate_from_assoc_types({})",
+               trait_ref.repr(self.tcx()));
+
         let trait_def_id = trait_ref.def_id;
         let trait_def = ty::lookup_trait_def(self.tcx(), trait_def_id);
         let assoc_type_projections: Vec<_> =
@@ -347,6 +353,8 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> {
                      .iter()
                      .map(|&name| ty::mk_projection(self.tcx(), trait_ref.clone(), name))
                      .collect();
+        debug!("accumulate_from_assoc_types: assoc_type_projections={}",
+               assoc_type_projections.repr(self.tcx()));
         let tys = match self.fully_normalize(&assoc_type_projections) {
             Ok(tys) => { tys }
             Err(ErrorReported) => { return; }
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index 82bd4ae87ff..978fbbbcffc 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -901,7 +901,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
         debug!("applicable_candidates: {}", applicable_candidates.repr(self.tcx()));
 
         if applicable_candidates.len() > 1 {
-            match self.collapse_candidates_to_trait_pick(&applicable_candidates[]) {
+            match self.collapse_candidates_to_trait_pick(&applicable_candidates[..]) {
                 Some(pick) => { return Some(Ok(pick)); }
                 None => { }
             }
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 063300a1d72..1639772103b 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -172,7 +172,7 @@ fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
             traits_are = if candidates.len() == 1 {"trait is"} else {"traits are"},
             one_of_them = if candidates.len() == 1 {"it"} else {"one of them"});
 
-        fcx.sess().fileline_help(span, &msg[]);
+        fcx.sess().fileline_help(span, &msg[..]);
 
         for (i, trait_did) in candidates.iter().enumerate() {
             fcx.sess().fileline_help(span,
@@ -218,7 +218,7 @@ fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
             one_of_them = if candidates.len() == 1 {"it"} else {"one of them"},
             name = method_ustring);
 
-        fcx.sess().fileline_help(span, &msg[]);
+        fcx.sess().fileline_help(span, &msg[..]);
 
         for (i, trait_info) in candidates.iter().enumerate() {
             fcx.sess().fileline_help(span,
@@ -306,10 +306,10 @@ pub fn all_traits<'a>(ccx: &'a CrateCtxt) -> AllTraits<'a> {
         // Crate-local:
         //
         // meh.
-        struct Visitor<'a, 'b: 'a, 'tcx: 'a + 'b> {
+        struct Visitor<'a> {
             traits: &'a mut AllTraitsVec,
         }
-        impl<'v,'a, 'b, 'tcx> visit::Visitor<'v> for Visitor<'a, 'b, 'tcx> {
+        impl<'v, 'a> visit::Visitor<'v> for Visitor<'a> {
             fn visit_item(&mut self, i: &'v ast::Item) {
                 match i.node {
                     ast::ItemTrait(..) => {
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 3c2888e2278..e443b4d0e60 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -638,7 +638,7 @@ fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
     // Remember return type so that regionck can access it later.
     let mut fn_sig_tys: Vec<Ty> =
         arg_tys.iter()
-        .map(|&ty| ty)
+        .cloned()
         .collect();
 
     if let ty::FnConverging(ret_ty) = ret_ty {
@@ -2208,7 +2208,7 @@ fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 
         check_argument_types(fcx,
                              sp,
-                             &err_inputs[],
+                             &err_inputs[..],
                              &[],
                              args_no_rcvr,
                              autoref_args,
@@ -2227,7 +2227,7 @@ fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                 check_argument_types(fcx,
                                      sp,
                                      &fty.sig.0.inputs[1..],
-                                     &expected_arg_tys[],
+                                     &expected_arg_tys[..],
                                      args_no_rcvr,
                                      autoref_args,
                                      fty.sig.0.variadic,
@@ -3054,7 +3054,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
                     ty::ty_struct(base_id, substs) => {
                         debug!("struct named {}", ppaux::ty_to_string(tcx, base_t));
                         let fields = ty::lookup_struct_fields(tcx, base_id);
-                        fcx.lookup_field_ty(expr.span, base_id, &fields[],
+                        fcx.lookup_field_ty(expr.span, base_id, &fields[..],
                                             field.node.name, &(*substs))
                     }
                     _ => None
@@ -3154,7 +3154,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
                         if tuple_like {
                             debug!("tuple struct named {}", ppaux::ty_to_string(tcx, base_t));
                             let fields = ty::lookup_struct_fields(tcx, base_id);
-                            fcx.lookup_tup_field_ty(expr.span, base_id, &fields[],
+                            fcx.lookup_tup_field_ty(expr.span, base_id, &fields[..],
                                                     idx.node, &(*substs))
                         } else {
                             None
@@ -3219,7 +3219,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
         for field in ast_fields {
             let mut expected_field_type = tcx.types.err;
 
-            let pair = class_field_map.get(&field.ident.node.name).map(|x| *x);
+            let pair = class_field_map.get(&field.ident.node.name).cloned();
             match pair {
                 None => {
                     fcx.type_error_message(
@@ -3327,7 +3327,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
                                        class_id,
                                        id,
                                        fcx.ccx.tcx.mk_substs(struct_substs),
-                                       &class_fields[],
+                                       &class_fields[..],
                                        fields,
                                        base_expr.is_none(),
                                        None);
@@ -3370,7 +3370,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
                                        variant_id,
                                        id,
                                        fcx.ccx.tcx.mk_substs(substitutions),
-                                       &variant_fields[],
+                                       &variant_fields[..],
                                        fields,
                                        true,
                                        Some(enum_id));
@@ -3731,10 +3731,10 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
         fcx.write_ty(id, fcx.node_ty(b.id));
       }
       ast::ExprCall(ref callee, ref args) => {
-          callee::check_call(fcx, expr, &**callee, &args[], expected);
+          callee::check_call(fcx, expr, &**callee, &args[..], expected);
       }
       ast::ExprMethodCall(ident, ref tps, ref args) => {
-        check_method_call(fcx, expr, ident, &args[], &tps[], expected, lvalue_pref);
+        check_method_call(fcx, expr, ident, &args[..], &tps[..], expected, lvalue_pref);
         let arg_tys = args.iter().map(|a| fcx.expr_ty(&**a));
         let  args_err = arg_tys.fold(false,
              |rest_err, a| {
@@ -3821,7 +3821,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
       ast::ExprTup(ref elts) => {
         let flds = expected.only_has_type(fcx).and_then(|ty| {
             match ty.sty {
-                ty::ty_tup(ref flds) => Some(&flds[]),
+                ty::ty_tup(ref flds) => Some(&flds[..]),
                 _ => None
             }
         });
@@ -3851,11 +3851,11 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
       }
       ast::ExprStruct(ref path, ref fields, ref base_expr) => {
         // Resolve the path.
-        let def = tcx.def_map.borrow().get(&id).map(|i| *i);
+        let def = tcx.def_map.borrow().get(&id).cloned();
         let struct_id = match def {
             Some(def::DefVariant(enum_id, variant_id, true)) => {
                 check_struct_enum_variant(fcx, id, expr.span, enum_id,
-                                          variant_id, &fields[]);
+                                          variant_id, &fields[..]);
                 enum_id
             }
             Some(def::DefTrait(def_id)) => {
@@ -3864,7 +3864,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
                     pprust::path_to_string(path));
                 check_struct_fields_on_error(fcx,
                                              id,
-                                             &fields[],
+                                             &fields[..],
                                              base_expr);
                 def_id
             },
@@ -3877,7 +3877,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
                                                  id,
                                                  expr.span,
                                                  struct_did,
-                                                 &fields[],
+                                                 &fields[..],
                                                  base_expr.as_ref().map(|e| &**e));
                     }
                     _ => {
@@ -3886,7 +3886,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
                             pprust::path_to_string(path));
                         check_struct_fields_on_error(fcx,
                                                      id,
-                                                     &fields[],
+                                                     &fields[..],
                                                      base_expr);
                     }
                 }
@@ -5231,10 +5231,10 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
             }
         };
         (n_tps, inputs, ty::FnConverging(output))
-    } else if &name[] == "abort" || &name[] == "unreachable" {
+    } else if &name[..] == "abort" || &name[..] == "unreachable" {
         (0, Vec::new(), ty::FnDiverging)
     } else {
-        let (n_tps, inputs, output) = match &name[] {
+        let (n_tps, inputs, output) = match &name[..] {
             "breakpoint" => (0, Vec::new(), ty::mk_nil(tcx)),
             "size_of" |
             "pref_align_of" | "min_align_of" => (1, Vec::new(), ccx.tcx.types.uint),
@@ -5259,7 +5259,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
             "get_tydesc" => {
               let tydesc_ty = match ty::get_tydesc_ty(ccx.tcx) {
                   Ok(t) => t,
-                  Err(s) => { span_fatal!(tcx.sess, it.span, E0240, "{}", &s[]); }
+                  Err(s) => { span_fatal!(tcx.sess, it.span, E0240, "{}", &s[..]); }
               };
               let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt {
                   ty: tydesc_ty,
diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs
index 4e5550a2106..82abff8c425 100644
--- a/src/librustc_typeck/check/regionck.rs
+++ b/src/librustc_typeck/check/regionck.rs
@@ -294,8 +294,8 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> {
 
         let len = self.region_bound_pairs.len();
         let old_body_id = self.set_body_id(body.id);
-        self.relate_free_regions(&fn_sig[], body.id, span);
-        link_fn_args(self, CodeExtent::from_node_id(body.id), &fn_decl.inputs[]);
+        self.relate_free_regions(&fn_sig[..], body.id, span);
+        link_fn_args(self, CodeExtent::from_node_id(body.id), &fn_decl.inputs[..]);
         self.visit_block(body);
         self.visit_region_obligations(body.id);
         self.region_bound_pairs.truncate(len);
@@ -626,6 +626,20 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
             visit::walk_expr(rcx, expr);
         }
 
+        ast::ExprBinary(_, ref lhs, ref rhs) => {
+            // If you do `x OP y`, then the types of `x` and `y` must
+            // outlive the operation you are performing.
+            let lhs_ty = rcx.resolve_expr_type_adjusted(&**lhs);
+            let rhs_ty = rcx.resolve_expr_type_adjusted(&**rhs);
+            for &ty in [lhs_ty, rhs_ty].iter() {
+                type_must_outlive(rcx,
+                                  infer::Operand(expr.span),
+                                  ty,
+                                  ty::ReScope(CodeExtent::from_node_id(expr.id)));
+            }
+            visit::walk_expr(rcx, expr);
+        }
+
         ast::ExprUnary(op, ref lhs) if has_method_map => {
             let implicitly_ref_args = !ast_util::is_by_value_unop(op);
 
@@ -690,7 +704,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
         }
 
         ast::ExprMatch(ref discr, ref arms, _) => {
-            link_match(rcx, &**discr, &arms[]);
+            link_match(rcx, &**discr, &arms[..]);
 
             visit::walk_expr(rcx, expr);
         }
diff --git a/src/librustc_typeck/check/vtable.rs b/src/librustc_typeck/check/vtable.rs
index 2e7eff68bd5..3666b69d1c6 100644
--- a/src/librustc_typeck/check/vtable.rs
+++ b/src/librustc_typeck/check/vtable.rs
@@ -126,6 +126,13 @@ pub fn check_object_safety<'tcx>(tcx: &ty::ctxt<'tcx>,
                     "the trait cannot require that `Self : Sized`");
             }
 
+            ObjectSafetyViolation::SupertraitSelf => {
+                tcx.sess.span_note(
+                    span,
+                    "the trait cannot use `Self` as a type parameter \
+                     in the supertrait listing");
+            }
+
             ObjectSafetyViolation::Method(method, MethodViolationCode::ByValueSelf) => {
                 tcx.sess.span_note(
                     span,
diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs
index d124282d391..2601c4d2752 100644
--- a/src/librustc_typeck/check/wf.rs
+++ b/src/librustc_typeck/check/wf.rs
@@ -10,21 +10,22 @@
 
 use astconv::AstConv;
 use check::{FnCtxt, Inherited, blank_fn_ctxt, vtable, regionck};
+use constrained_type_params::identify_constrained_type_params;
 use CrateCtxt;
 use middle::region;
-use middle::subst;
+use middle::subst::{self, TypeSpace, FnSpace, ParamSpace, SelfSpace};
 use middle::traits;
 use middle::ty::{self, Ty};
 use middle::ty::liberate_late_bound_regions;
 use middle::ty_fold::{TypeFolder, TypeFoldable, super_fold_ty};
-use util::ppaux::Repr;
+use util::ppaux::{Repr, UserString};
 
 use std::collections::HashSet;
 use syntax::ast;
 use syntax::ast_util::{local_def};
 use syntax::attr;
 use syntax::codemap::Span;
-use syntax::parse::token;
+use syntax::parse::token::{self, special_idents};
 use syntax::visit;
 use syntax::visit::Visitor;
 
@@ -38,6 +39,10 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
         CheckTypeWellFormedVisitor { ccx: ccx, cache: HashSet::new() }
     }
 
+    fn tcx(&self) -> &ty::ctxt<'tcx> {
+        self.ccx.tcx
+    }
+
     /// Checks that the field types (in a struct def'n) or argument types (in an enum def'n) are
     /// well-formed, meaning that they do not require any constraints not declared in the struct
     /// definition itself. For example, this definition would be illegal:
@@ -96,19 +101,29 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
             ast::ItemConst(..) => {
                 self.check_item_type(item);
             }
-            ast::ItemStruct(ref struct_def, _) => {
-                self.check_type_defn(item, |fcx| vec![struct_variant(fcx, &**struct_def)]);
+            ast::ItemStruct(ref struct_def, ref ast_generics) => {
+                self.check_type_defn(item, |fcx| {
+                    vec![struct_variant(fcx, &**struct_def)]
+                });
+
+                self.check_variances_for_type_defn(item, ast_generics);
             }
-            ast::ItemEnum(ref enum_def, _) => {
-                self.check_type_defn(item, |fcx| enum_variants(fcx, enum_def));
+            ast::ItemEnum(ref enum_def, ref ast_generics) => {
+                self.check_type_defn(item, |fcx| {
+                    enum_variants(fcx, enum_def)
+                });
+
+                self.check_variances_for_type_defn(item, ast_generics);
             }
-            ast::ItemTrait(..) => {
+            ast::ItemTrait(_, ref ast_generics, _, _) => {
                 let trait_predicates =
                     ty::lookup_predicates(ccx.tcx, local_def(item.id));
                 reject_non_type_param_bounds(
                     ccx.tcx,
                     item.span,
                     &trait_predicates);
+                self.check_variances(item, ast_generics, &trait_predicates,
+                                     self.tcx().lang_items.phantom_fn());
             }
             _ => {}
         }
@@ -276,6 +291,123 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
             }
         });
     }
+
+    fn check_variances_for_type_defn(&self,
+                                     item: &ast::Item,
+                                     ast_generics: &ast::Generics)
+    {
+        let item_def_id = local_def(item.id);
+        let predicates = ty::lookup_predicates(self.tcx(), item_def_id);
+        self.check_variances(item,
+                             ast_generics,
+                             &predicates,
+                             self.tcx().lang_items.phantom_data());
+    }
+
+    fn check_variances(&self,
+                       item: &ast::Item,
+                       ast_generics: &ast::Generics,
+                       ty_predicates: &ty::GenericPredicates<'tcx>,
+                       suggested_marker_id: Option<ast::DefId>)
+    {
+        let variance_lang_items = &[
+            self.tcx().lang_items.phantom_fn(),
+            self.tcx().lang_items.phantom_data(),
+        ];
+
+        let item_def_id = local_def(item.id);
+        let is_lang_item = variance_lang_items.iter().any(|n| *n == Some(item_def_id));
+        if is_lang_item {
+            return;
+        }
+
+        let variances = ty::item_variances(self.tcx(), item_def_id);
+
+        let mut constrained_parameters: HashSet<_> =
+            variances.types
+            .iter_enumerated()
+            .filter(|&(_, _, &variance)| variance != ty::Bivariant)
+            .map(|(space, index, _)| self.param_ty(ast_generics, space, index))
+            .collect();
+
+        identify_constrained_type_params(self.tcx(),
+                                         ty_predicates.predicates.as_slice(),
+                                         None,
+                                         &mut constrained_parameters);
+
+        for (space, index, _) in variances.types.iter_enumerated() {
+            let param_ty = self.param_ty(ast_generics, space, index);
+            if constrained_parameters.contains(&param_ty) {
+                continue;
+            }
+            let span = self.ty_param_span(ast_generics, item, space, index);
+            self.report_bivariance(span, param_ty.name, suggested_marker_id);
+        }
+
+        for (space, index, &variance) in variances.regions.iter_enumerated() {
+            if variance != ty::Bivariant {
+                continue;
+            }
+
+            assert_eq!(space, TypeSpace);
+            let span = ast_generics.lifetimes[index].lifetime.span;
+            let name = ast_generics.lifetimes[index].lifetime.name;
+            self.report_bivariance(span, name, suggested_marker_id);
+        }
+    }
+
+    fn param_ty(&self,
+                ast_generics: &ast::Generics,
+                space: ParamSpace,
+                index: usize)
+                -> ty::ParamTy
+    {
+        let name = match space {
+            TypeSpace => ast_generics.ty_params[index].ident.name,
+            SelfSpace => special_idents::type_self.name,
+            FnSpace => self.tcx().sess.bug("Fn space occupied?"),
+        };
+
+        ty::ParamTy { space: space, idx: index as u32, name: name }
+    }
+
+    fn ty_param_span(&self,
+                     ast_generics: &ast::Generics,
+                     item: &ast::Item,
+                     space: ParamSpace,
+                     index: usize)
+                     -> Span
+    {
+        match space {
+            TypeSpace => ast_generics.ty_params[index].span,
+            SelfSpace => item.span,
+            FnSpace => self.tcx().sess.span_bug(item.span, "Fn space occupied?"),
+        }
+    }
+
+    fn report_bivariance(&self,
+                         span: Span,
+                         param_name: ast::Name,
+                         suggested_marker_id: Option<ast::DefId>)
+    {
+        self.tcx().sess.span_err(
+            span,
+            &format!("parameter `{}` is never used",
+                     param_name.user_string(self.tcx()))[]);
+
+        match suggested_marker_id {
+            Some(def_id) => {
+                self.tcx().sess.span_help(
+                    span,
+                    format!("consider removing `{}` or using a marker such as `{}`",
+                            param_name.user_string(self.tcx()),
+                            ty::item_path_str(self.tcx(), def_id)).as_slice());
+            }
+            None => {
+                // no lang items, no help!
+            }
+        }
+    }
 }
 
 // Reject any predicates that do not involve a type parameter.
@@ -343,9 +475,9 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> {
         match fk {
             visit::FkFnBlock | visit::FkItemFn(..) => {}
             visit::FkMethod(..) => {
-                match ty::impl_or_trait_item(self.ccx.tcx, local_def(id)) {
+                match ty::impl_or_trait_item(self.tcx(), local_def(id)) {
                     ty::ImplOrTraitItem::MethodTraitItem(ty_method) => {
-                        reject_shadowing_type_parameters(self.ccx.tcx, span, &ty_method.generics)
+                        reject_shadowing_type_parameters(self.tcx(), span, &ty_method.generics)
                     }
                     _ => {}
                 }
@@ -359,14 +491,14 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> {
             &ast::TraitItem::ProvidedMethod(_) |
             &ast::TraitItem::TypeTraitItem(_) => {},
             &ast::TraitItem::RequiredMethod(ref method) => {
-                match ty::impl_or_trait_item(self.ccx.tcx, local_def(method.id)) {
+                match ty::impl_or_trait_item(self.tcx(), local_def(method.id)) {
                     ty::ImplOrTraitItem::MethodTraitItem(ty_method) => {
                         reject_non_type_param_bounds(
-                            self.ccx.tcx,
+                            self.tcx(),
                             method.span,
                             &ty_method.predicates);
                         reject_shadowing_type_parameters(
-                            self.ccx.tcx,
+                            self.tcx(),
                             method.span,
                             &ty_method.generics);
                     }
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 44e850a0738..0b78af18e26 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -87,6 +87,7 @@ There are some shortcomings in this design:
 
 use astconv::{self, AstConv, ty_of_arg, ast_ty_to_ty, ast_region_to_region};
 use middle::def;
+use constrained_type_params::identify_constrained_type_params;
 use middle::lang_items::SizedTraitLangItem;
 use middle::region;
 use middle::resolve_lifetime;
@@ -268,7 +269,7 @@ fn get_enum_variant_types<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
             ast::TupleVariantKind(ref args) if args.len() > 0 => {
                 let rs = ExplicitRscope;
                 let input_tys: Vec<_> = args.iter().map(|va| ccx.to_ty(&rs, &*va.ty)).collect();
-                ty::mk_ctor_fn(tcx, variant_def_id, &input_tys[], enum_scheme.ty)
+                ty::mk_ctor_fn(tcx, variant_def_id, &input_tys[..], enum_scheme.ty)
             }
 
             ast::TupleVariantKind(_) => {
@@ -313,7 +314,7 @@ fn collect_trait_methods<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
                                     trait_id,
                                     &trait_def.generics,
                                     &trait_predicates,
-                                    &trait_items[],
+                                    &trait_items[..],
                                     &m.id,
                                     &m.ident.name,
                                     &m.explicit_self,
@@ -328,7 +329,7 @@ fn collect_trait_methods<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
                                     trait_id,
                                     &trait_def.generics,
                                     &trait_predicates,
-                                    &trait_items[],
+                                    &trait_items[..],
                                     &m.id,
                                     &m.pe_ident().name,
                                     m.pe_explicit_self(),
@@ -871,7 +872,7 @@ fn convert_struct<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
                             local_def(field.node.id)].ty).collect();
                 let ctor_fn_ty = ty::mk_ctor_fn(tcx,
                                                 local_def(ctor_id),
-                                                &inputs[],
+                                                &inputs[..],
                                                 selfty);
                 write_ty_to_tcx(tcx, ctor_id, ctor_fn_ty);
                 tcx.tcache.borrow_mut().insert(local_def(ctor_id),
@@ -1358,7 +1359,7 @@ fn ty_generics_for_fn_or_method<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
     let early_lifetimes = resolve_lifetime::early_bound_lifetimes(generics);
     ty_generics(ccx,
                 subst::FnSpace,
-                &early_lifetimes[],
+                &early_lifetimes[..],
                 &generics.ty_params[],
                 &generics.where_clause,
                 base_generics)
@@ -1960,51 +1961,15 @@ fn enforce_impl_ty_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>,
     let mut input_parameters: HashSet<_> =
         impl_trait_ref.iter()
                       .flat_map(|t| t.input_types().iter()) // Types in trait ref, if any
-                      .chain(Some(impl_scheme.ty).iter())  // Self type, always
+                      .chain(Some(impl_scheme.ty).iter())   // Self type, always
                       .flat_map(|t| t.walk())
-                      .filter_map(to_opt_param_ty)
+                      .filter_map(|t| t.as_opt_param_ty())
                       .collect();
 
-    loop {
-        let num_inputs = input_parameters.len();
-
-        let projection_predicates =
-            impl_predicates.predicates
-                           .iter()
-                           .filter_map(|predicate| {
-                               match *predicate {
-                                   // Ignore higher-ranked binders. For the purposes
-                                   // of this check, they don't matter because they
-                                   // only affect named regions, and we're just
-                                   // concerned about type parameters here.
-                                   ty::Predicate::Projection(ref data) => Some(data.0.clone()),
-                                   _ => None,
-                               }
-                           });
-
-        for projection in projection_predicates {
-            // Special case: watch out for some kind of sneaky attempt
-            // to project out an associated type defined by this very trait.
-            if Some(projection.projection_ty.trait_ref.clone()) == impl_trait_ref {
-                continue;
-            }
-
-            let relies_only_on_inputs =
-                projection.projection_ty.trait_ref.input_types().iter()
-                .flat_map(|t| t.walk())
-                .filter_map(to_opt_param_ty)
-                .all(|t| input_parameters.contains(&t));
-
-            if relies_only_on_inputs {
-                input_parameters.extend(
-                    projection.ty.walk().filter_map(to_opt_param_ty));
-            }
-        }
-
-        if input_parameters.len() == num_inputs {
-            break;
-        }
-    }
+    identify_constrained_type_params(tcx,
+                                     impl_predicates.predicates.as_slice(),
+                                     impl_trait_ref,
+                                     &mut input_parameters);
 
     for (index, ty_param) in ast_generics.ty_params.iter().enumerate() {
         let param_ty = ty::ParamTy { space: TypeSpace,
@@ -2025,11 +1990,4 @@ fn enforce_impl_ty_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>,
             }
         }
     }
-
-    fn to_opt_param_ty<'tcx>(ty: Ty<'tcx>) -> Option<ty::ParamTy> {
-        match ty.sty {
-            ty::ty_param(ref d) => Some(d.clone()),
-            _ => None,
-        }
-    }
 }
diff --git a/src/librustc_typeck/constrained_type_params.rs b/src/librustc_typeck/constrained_type_params.rs
new file mode 100644
index 00000000000..83d7e985000
--- /dev/null
+++ b/src/librustc_typeck/constrained_type_params.rs
@@ -0,0 +1,61 @@
+// Copyright 2015 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 middle::ty::{self};
+
+use std::collections::HashSet;
+use std::rc::Rc;
+
+pub fn identify_constrained_type_params<'tcx>(_tcx: &ty::ctxt<'tcx>,
+                                              predicates: &[ty::Predicate<'tcx>],
+                                              impl_trait_ref: Option<Rc<ty::TraitRef<'tcx>>>,
+                                              input_parameters: &mut HashSet<ty::ParamTy>)
+{
+    loop {
+        let num_inputs = input_parameters.len();
+
+        let projection_predicates =
+            predicates.iter()
+                      .filter_map(|predicate| {
+                          match *predicate {
+                              // Ignore higher-ranked binders. For the purposes
+                              // of this check, they don't matter because they
+                              // only affect named regions, and we're just
+                              // concerned about type parameters here.
+                              ty::Predicate::Projection(ref data) => Some(data.0.clone()),
+                              _ => None,
+                          }
+                      });
+
+        for projection in projection_predicates {
+            // Special case: watch out for some kind of sneaky attempt
+            // to project out an associated type defined by this very trait.
+            if Some(projection.projection_ty.trait_ref.clone()) == impl_trait_ref {
+                continue;
+            }
+
+            let relies_only_on_inputs =
+                projection.projection_ty.trait_ref.input_types()
+                                                  .iter()
+                                                  .flat_map(|t| t.walk())
+                                                  .filter_map(|t| t.as_opt_param_ty())
+                                                  .all(|t| input_parameters.contains(&t));
+
+            if relies_only_on_inputs {
+                input_parameters.extend(
+                    projection.ty.walk().filter_map(|t| t.as_opt_param_ty()));
+            }
+        }
+
+        if input_parameters.len() == num_inputs {
+            break;
+        }
+    }
+}
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 7498dc8179d..b5dca0bd4f6 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -123,6 +123,7 @@ mod check;
 mod rscope;
 mod astconv;
 mod collect;
+mod constrained_type_params;
 mod coherence;
 mod variance;
 
diff --git a/src/librustc_typeck/variance.rs b/src/librustc_typeck/variance.rs
index d5883d8bf86..1adcf133bf3 100644
--- a/src/librustc_typeck/variance.rs
+++ b/src/librustc_typeck/variance.rs
@@ -187,6 +187,22 @@
 //!   and the definition-site variance of the [corresponding] type parameter
 //!   of a class `C` is `V1`, then the variance of `X` in the type expression
 //!   `C<E>` is `V3 = V1.xform(V2)`.
+//!
+//! ### Constraints
+//!
+//! If I have a struct or enum with where clauses:
+//!
+//!     struct Foo<T:Bar> { ... }
+//!
+//! you might wonder whether the variance of `T` with respect to `Bar`
+//! affects the variance `T` with respect to `Foo`. I claim no.  The
+//! reason: assume that `T` is invariant w/r/t `Bar` but covariant w/r/t
+//! `Foo`. And then we have a `Foo<X>` that is upcast to `Foo<Y>`, where
+//! `X <: Y`. However, while `X : Bar`, `Y : Bar` does not hold.  In that
+//! case, the upcast will be illegal, but not because of a variance
+//! failure, but rather because the target type `Foo<Y>` is itself just
+//! not well-formed. Basically we get to assume well-formedness of all
+//! types involved before considering variance.
 
 use self::VarianceTerm::*;
 use self::ParamKind::*;
@@ -199,7 +215,6 @@ use middle::subst::{ParamSpace, FnSpace, TypeSpace, SelfSpace, VecPerParamSpace}
 use middle::ty::{self, Ty};
 use std::fmt;
 use std::rc::Rc;
-use std::iter::repeat;
 use syntax::ast;
 use syntax::ast_map;
 use syntax::ast_util;
@@ -258,6 +273,11 @@ struct TermsContext<'a, 'tcx: 'a> {
 
     empty_variances: Rc<ty::ItemVariances>,
 
+    // For marker types, UnsafeCell, and other lang items where
+    // variance is hardcoded, records the item-id and the hardcoded
+    // variance.
+    lang_items: Vec<(ast::NodeId, Vec<ty::Variance>)>,
+
     // Maps from the node id of a type/generic parameter to the
     // corresponding inferred index.
     inferred_map: NodeMap<InferredIndex>,
@@ -269,7 +289,7 @@ struct TermsContext<'a, 'tcx: 'a> {
 #[derive(Copy, Debug, PartialEq)]
 enum ParamKind {
     TypeParam,
-    RegionParam
+    RegionParam,
 }
 
 struct InferredInfo<'a> {
@@ -279,6 +299,11 @@ struct InferredInfo<'a> {
     index: uint,
     param_id: ast::NodeId,
     term: VarianceTermPtr<'a>,
+
+    // Initial value to use for this parameter when inferring
+    // variance. For most parameters, this is Bivariant. But for lang
+    // items and input type parameters on traits, it is different.
+    initial_variance: ty::Variance,
 }
 
 fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>,
@@ -291,6 +316,8 @@ fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>,
         inferred_map: NodeMap(),
         inferred_infos: Vec::new(),
 
+        lang_items: lang_items(tcx),
+
         // cache and share the variance struct used for items with
         // no type/region parameters
         empty_variances: Rc::new(ty::ItemVariances {
@@ -304,7 +331,78 @@ fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>,
     terms_cx
 }
 
+fn lang_items(tcx: &ty::ctxt) -> Vec<(ast::NodeId,Vec<ty::Variance>)> {
+    let all = vec![
+        (tcx.lang_items.phantom_fn(), vec![ty::Contravariant, ty::Covariant]),
+        (tcx.lang_items.phantom_data(), vec![ty::Covariant]),
+        (tcx.lang_items.unsafe_cell_type(), vec![ty::Invariant]),
+
+        // Deprecated:
+        (tcx.lang_items.covariant_type(), vec![ty::Covariant]),
+        (tcx.lang_items.contravariant_type(), vec![ty::Contravariant]),
+        (tcx.lang_items.invariant_type(), vec![ty::Invariant]),
+        (tcx.lang_items.covariant_lifetime(), vec![ty::Covariant]),
+        (tcx.lang_items.contravariant_lifetime(), vec![ty::Contravariant]),
+        (tcx.lang_items.invariant_lifetime(), vec![ty::Invariant]),
+
+        ];
+
+    all.into_iter()
+       .filter(|&(ref d,_)| d.is_some())
+       .filter(|&(ref d,_)| d.as_ref().unwrap().krate == ast::LOCAL_CRATE)
+       .map(|(d, v)| (d.unwrap().node, v))
+       .collect()
+}
+
 impl<'a, 'tcx> TermsContext<'a, 'tcx> {
+    fn add_inferreds_for_item(&mut self,
+                              item_id: ast::NodeId,
+                              has_self: bool,
+                              generics: &ast::Generics)
+    {
+        /*!
+         * Add "inferreds" for the generic parameters declared on this
+         * item. This has a lot of annoying parameters because we are
+         * trying to drive this from the AST, rather than the
+         * ty::Generics, so that we can get span info -- but this
+         * means we must accommodate syntactic distinctions.
+         */
+
+        // NB: In the code below for writing the results back into the
+        // tcx, we rely on the fact that all inferreds for a particular
+        // item are assigned continuous indices.
+
+        let inferreds_on_entry = self.num_inferred();
+
+        if has_self {
+            self.add_inferred(item_id, TypeParam, SelfSpace, 0, item_id);
+        }
+
+        for (i, p) in generics.lifetimes.iter().enumerate() {
+            let id = p.lifetime.id;
+            self.add_inferred(item_id, RegionParam, TypeSpace, i, id);
+        }
+
+        for (i, p) in generics.ty_params.iter().enumerate() {
+            self.add_inferred(item_id, TypeParam, TypeSpace, i, p.id);
+        }
+
+        // If this item has no type or lifetime parameters,
+        // then there are no variances to infer, so just
+        // insert an empty entry into the variance map.
+        // Arguably we could just leave the map empty in this
+        // case but it seems cleaner to be able to distinguish
+        // "invalid item id" from "item id with no
+        // parameters".
+        if self.num_inferred() == inferreds_on_entry {
+            let newly_added =
+                self.tcx.item_variance_map.borrow_mut().insert(
+                    ast_util::local_def(item_id),
+                    self.empty_variances.clone()).is_none();
+            assert!(newly_added);
+        }
+    }
+
     fn add_inferred(&mut self,
                     item_id: ast::NodeId,
                     kind: ParamKind,
@@ -313,21 +411,48 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> {
                     param_id: ast::NodeId) {
         let inf_index = InferredIndex(self.inferred_infos.len());
         let term = self.arena.alloc(InferredTerm(inf_index));
+        let initial_variance = self.pick_initial_variance(item_id, space, index);
         self.inferred_infos.push(InferredInfo { item_id: item_id,
                                                 kind: kind,
                                                 space: space,
                                                 index: index,
                                                 param_id: param_id,
-                                                term: term });
+                                                term: term,
+                                                initial_variance: initial_variance });
         let newly_added = self.inferred_map.insert(param_id, inf_index).is_none();
         assert!(newly_added);
 
-        debug!("add_inferred(item_id={}, \
+        debug!("add_inferred(item_path={}, \
+                item_id={}, \
                 kind={:?}, \
+                space={:?}, \
                 index={}, \
-                param_id={},
-                inf_index={:?})",
-                item_id, kind, index, param_id, inf_index);
+                param_id={}, \
+                inf_index={:?}, \
+                initial_variance={:?})",
+               ty::item_path_str(self.tcx, ast_util::local_def(item_id)),
+               item_id, kind, space, index, param_id, inf_index,
+               initial_variance);
+    }
+
+    fn pick_initial_variance(&self,
+                             item_id: ast::NodeId,
+                             space: ParamSpace,
+                             index: uint)
+                             -> ty::Variance
+    {
+        match space {
+            SelfSpace | FnSpace => {
+                ty::Bivariant
+            }
+
+            TypeSpace => {
+                match self.lang_items.iter().find(|&&(n, _)| n == item_id) {
+                    Some(&(_, ref variances)) => variances[index],
+                    None => ty::Bivariant
+                }
+            }
+        }
     }
 
     fn num_inferred(&self) -> uint {
@@ -339,44 +464,13 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TermsContext<'a, 'tcx> {
     fn visit_item(&mut self, item: &ast::Item) {
         debug!("add_inferreds for item {}", item.repr(self.tcx));
 
-        let inferreds_on_entry = self.num_inferred();
-
-        // NB: In the code below for writing the results back into the
-        // tcx, we rely on the fact that all inferreds for a particular
-        // item are assigned continuous indices.
-        match item.node {
-            ast::ItemTrait(..) => {
-                self.add_inferred(item.id, TypeParam, SelfSpace, 0, item.id);
-            }
-            _ => { }
-        }
-
         match item.node {
             ast::ItemEnum(_, ref generics) |
-            ast::ItemStruct(_, ref generics) |
+            ast::ItemStruct(_, ref generics) => {
+                self.add_inferreds_for_item(item.id, false, generics);
+            }
             ast::ItemTrait(_, ref generics, _, _) => {
-                for (i, p) in generics.lifetimes.iter().enumerate() {
-                    let id = p.lifetime.id;
-                    self.add_inferred(item.id, RegionParam, TypeSpace, i, id);
-                }
-                for (i, p) in generics.ty_params.iter().enumerate() {
-                    self.add_inferred(item.id, TypeParam, TypeSpace, i, p.id);
-                }
-
-                // If this item has no type or lifetime parameters,
-                // then there are no variances to infer, so just
-                // insert an empty entry into the variance map.
-                // Arguably we could just leave the map empty in this
-                // case but it seems cleaner to be able to distinguish
-                // "invalid item id" from "item id with no
-                // parameters".
-                if self.num_inferred() == inferreds_on_entry {
-                    let newly_added = self.tcx.item_variance_map.borrow_mut().insert(
-                        ast_util::local_def(item.id),
-                        self.empty_variances.clone()).is_none();
-                    assert!(newly_added);
-                }
-
+                self.add_inferreds_for_item(item.id, true, generics);
                 visit::walk_item(self, item);
             }
 
@@ -404,16 +498,6 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TermsContext<'a, 'tcx> {
 struct ConstraintContext<'a, 'tcx: 'a> {
     terms_cx: TermsContext<'a, 'tcx>,
 
-    // These are the def-id of the std::marker::InvariantType,
-    // std::marker::InvariantLifetime, and so on. The arrays
-    // are indexed by the `ParamKind` (type, lifetime, self). Note
-    // that there are no marker types for self, so the entries for
-    // self are always None.
-    invariant_lang_items: [Option<ast::DefId>; 2],
-    covariant_lang_items: [Option<ast::DefId>; 2],
-    contravariant_lang_items: [Option<ast::DefId>; 2],
-    unsafe_cell_lang_item: Option<ast::DefId>,
-
     // These are pointers to common `ConstantTerm` instances
     covariant: VarianceTermPtr<'a>,
     contravariant: VarianceTermPtr<'a>,
@@ -433,40 +517,14 @@ struct Constraint<'a> {
 
 fn add_constraints_from_crate<'a, 'tcx>(terms_cx: TermsContext<'a, 'tcx>,
                                         krate: &ast::Crate)
-                                        -> ConstraintContext<'a, 'tcx> {
-    let mut invariant_lang_items = [None; 2];
-    let mut covariant_lang_items = [None; 2];
-    let mut contravariant_lang_items = [None; 2];
-
-    covariant_lang_items[TypeParam as uint] =
-        terms_cx.tcx.lang_items.covariant_type();
-    covariant_lang_items[RegionParam as uint] =
-        terms_cx.tcx.lang_items.covariant_lifetime();
-
-    contravariant_lang_items[TypeParam as uint] =
-        terms_cx.tcx.lang_items.contravariant_type();
-    contravariant_lang_items[RegionParam as uint] =
-        terms_cx.tcx.lang_items.contravariant_lifetime();
-
-    invariant_lang_items[TypeParam as uint] =
-        terms_cx.tcx.lang_items.invariant_type();
-    invariant_lang_items[RegionParam as uint] =
-        terms_cx.tcx.lang_items.invariant_lifetime();
-
-    let unsafe_cell_lang_item = terms_cx.tcx.lang_items.unsafe_cell_type();
-
+                                        -> ConstraintContext<'a, 'tcx>
+{
     let covariant = terms_cx.arena.alloc(ConstantTerm(ty::Covariant));
     let contravariant = terms_cx.arena.alloc(ConstantTerm(ty::Contravariant));
     let invariant = terms_cx.arena.alloc(ConstantTerm(ty::Invariant));
     let bivariant = terms_cx.arena.alloc(ConstantTerm(ty::Bivariant));
     let mut constraint_cx = ConstraintContext {
         terms_cx: terms_cx,
-
-        invariant_lang_items: invariant_lang_items,
-        covariant_lang_items: covariant_lang_items,
-        contravariant_lang_items: contravariant_lang_items,
-        unsafe_cell_lang_item: unsafe_cell_lang_item,
-
         covariant: covariant,
         contravariant: contravariant,
         invariant: invariant,
@@ -487,7 +545,13 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> {
 
         match item.node {
             ast::ItemEnum(ref enum_definition, _) => {
-                let generics = &ty::lookup_item_type(tcx, did).generics;
+                let scheme = ty::lookup_item_type(tcx, did);
+
+                // Not entirely obvious: constraints on structs/enums do not
+                // affect the variance of their type parameters. See discussion
+                // in comment at top of module.
+                //
+                // self.add_constraints_from_generics(&scheme.generics);
 
                 // Hack: If we directly call `ty::enum_variants`, it
                 // annoyingly takes it upon itself to run off and
@@ -505,29 +569,48 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> {
                                                           &**ast_variant,
                                                           /*discriminant*/ 0);
                     for arg_ty in &variant.args {
-                        self.add_constraints_from_ty(generics, *arg_ty, self.covariant);
+                        self.add_constraints_from_ty(&scheme.generics, *arg_ty, self.covariant);
                     }
                 }
             }
 
             ast::ItemStruct(..) => {
-                let generics = &ty::lookup_item_type(tcx, did).generics;
+                let scheme = ty::lookup_item_type(tcx, did);
+
+                // Not entirely obvious: constraints on structs/enums do not
+                // affect the variance of their type parameters. See discussion
+                // in comment at top of module.
+                //
+                // self.add_constraints_from_generics(&scheme.generics);
+
                 let struct_fields = ty::lookup_struct_fields(tcx, did);
                 for field_info in &struct_fields {
                     assert_eq!(field_info.id.krate, ast::LOCAL_CRATE);
                     let field_ty = ty::node_id_to_type(tcx, field_info.id.node);
-                    self.add_constraints_from_ty(generics, field_ty, self.covariant);
+                    self.add_constraints_from_ty(&scheme.generics, field_ty, self.covariant);
                 }
             }
 
             ast::ItemTrait(..) => {
+                let trait_def = ty::lookup_trait_def(tcx, did);
+                let predicates = ty::predicates(tcx, ty::mk_self_type(tcx), &trait_def.bounds);
+                self.add_constraints_from_predicates(&trait_def.generics,
+                                                     &predicates[],
+                                                     self.covariant);
+
                 let trait_items = ty::trait_items(tcx, did);
                 for trait_item in &*trait_items {
                     match *trait_item {
                         ty::MethodTraitItem(ref method) => {
-                            self.add_constraints_from_sig(&method.generics,
-                                                          &method.fty.sig,
-                                                          self.covariant);
+                            self.add_constraints_from_predicates(
+                                &method.generics,
+                                method.predicates.predicates.get_slice(FnSpace),
+                                self.contravariant);
+
+                            self.add_constraints_from_sig(
+                                &method.generics,
+                                &method.fty.sig,
+                                self.covariant);
                         }
                         ty::TypeTraitItem(_) => {}
                     }
@@ -544,9 +627,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> {
             ast::ItemTy(..) |
             ast::ItemImpl(..) |
             ast::ItemMac(..) => {
-                visit::walk_item(self, item);
             }
         }
+
+        visit::walk_item(self, item);
     }
 }
 
@@ -648,15 +732,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
                          -> VarianceTermPtr<'a> {
         assert_eq!(param_def_id.krate, item_def_id.krate);
 
-        if self.invariant_lang_items[kind as uint] == Some(item_def_id) {
-            self.invariant
-        } else if self.covariant_lang_items[kind as uint] == Some(item_def_id) {
-            self.covariant
-        } else if self.contravariant_lang_items[kind as uint] == Some(item_def_id) {
-            self.contravariant
-        } else if kind == TypeParam && Some(item_def_id) == self.unsafe_cell_lang_item {
-            self.invariant
-        } else if param_def_id.krate == ast::LOCAL_CRATE {
+        if param_def_id.krate == ast::LOCAL_CRATE {
             // Parameter on an item defined within current crate:
             // variance not yet inferred, so return a symbolic
             // variance.
@@ -724,6 +800,25 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
         }
     }
 
+    fn add_constraints_from_trait_ref(&mut self,
+                                      generics: &ty::Generics<'tcx>,
+                                      trait_ref: &ty::TraitRef<'tcx>,
+                                      variance: VarianceTermPtr<'a>) {
+        debug!("add_constraints_from_trait_ref: trait_ref={} variance={:?}",
+               trait_ref.repr(self.tcx()),
+               variance);
+
+        let trait_def = ty::lookup_trait_def(self.tcx(), trait_ref.def_id);
+
+        self.add_constraints_from_substs(
+            generics,
+            trait_ref.def_id,
+            trait_def.generics.types.as_slice(),
+            trait_def.generics.regions.as_slice(),
+            trait_ref.substs,
+            variance);
+    }
+
     /// Adds constraints appropriate for an instance of `ty` appearing
     /// in a context with the generics defined in `generics` and
     /// ambient variance `variance`
@@ -731,7 +826,9 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
                                generics: &ty::Generics<'tcx>,
                                ty: Ty<'tcx>,
                                variance: VarianceTermPtr<'a>) {
-        debug!("add_constraints_from_ty(ty={})", ty.repr(self.tcx()));
+        debug!("add_constraints_from_ty(ty={}, variance={:?})",
+               ty.repr(self.tcx()),
+               variance);
 
         match ty.sty {
             ty::ty_bool |
@@ -754,6 +851,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
                 self.add_constraints_from_ty(generics, typ, variance);
             }
 
+
             ty::ty_ptr(ref mt) => {
                 self.add_constraints_from_mt(generics, mt, variance);
             }
@@ -797,27 +895,16 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
             }
 
             ty::ty_trait(ref data) => {
-                let trait_ref = data.principal_trait_ref_with_self_ty(self.tcx(),
-                                                                      self.tcx().types.err);
-                let trait_def = ty::lookup_trait_def(self.tcx(), trait_ref.def_id());
-
-                // Traits never declare region parameters in the self
-                // space nor anything in the fn space.
-                assert!(trait_def.generics.regions.is_empty_in(subst::SelfSpace));
-                assert!(trait_def.generics.types.is_empty_in(subst::FnSpace));
-                assert!(trait_def.generics.regions.is_empty_in(subst::FnSpace));
+                let poly_trait_ref =
+                    data.principal_trait_ref_with_self_ty(self.tcx(),
+                                                          self.tcx().types.err);
 
                 // The type `Foo<T+'a>` is contravariant w/r/t `'a`:
                 let contra = self.contravariant(variance);
                 self.add_constraints_from_region(generics, data.bounds.region_bound, contra);
 
-                self.add_constraints_from_substs(
-                    generics,
-                    trait_ref.def_id(),
-                    trait_def.generics.types.get_slice(subst::TypeSpace),
-                    trait_def.generics.regions.get_slice(subst::TypeSpace),
-                    trait_ref.substs(),
-                    variance);
+                // Ignore the SelfSpace, it is erased.
+                self.add_constraints_from_trait_ref(generics, &*poly_trait_ref.0, variance);
 
                 let projections = data.projection_bounds_with_self_ty(self.tcx(),
                                                                       self.tcx().types.err);
@@ -845,7 +932,12 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
                 self.add_constraints_from_sig(generics, sig, variance);
             }
 
-            ty::ty_infer(..) | ty::ty_err => {
+            ty::ty_err => {
+                // we encounter this when walking the trait references for object
+                // types, where we use ty_err as the Self type
+            }
+
+            ty::ty_infer(..) => {
                 self.tcx().sess.bug(
                     &format!("unexpected type encountered in \
                             variance inference: {}",
@@ -864,7 +956,10 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
                                    region_param_defs: &[ty::RegionParameterDef],
                                    substs: &subst::Substs<'tcx>,
                                    variance: VarianceTermPtr<'a>) {
-        debug!("add_constraints_from_substs(def_id={:?})", def_id);
+        debug!("add_constraints_from_substs(def_id={}, substs={}, variance={:?})",
+               def_id.repr(self.tcx()),
+               substs.repr(self.tcx()),
+               variance);
 
         for p in type_param_defs {
             let variance_decl =
@@ -872,6 +967,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
                                        p.space, p.index as uint);
             let variance_i = self.xform(variance, variance_decl);
             let substs_ty = *substs.types.get(p.space, p.index as uint);
+            debug!("add_constraints_from_substs: variance_decl={:?} variance_i={:?}",
+                   variance_decl, variance_i);
             self.add_constraints_from_ty(generics, substs_ty, variance_i);
         }
 
@@ -885,6 +982,51 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
         }
     }
 
+    fn add_constraints_from_predicates(&mut self,
+                                       generics: &ty::Generics<'tcx>,
+                                       predicates: &[ty::Predicate<'tcx>],
+                                       variance: VarianceTermPtr<'a>) {
+        debug!("add_constraints_from_generics({})",
+               generics.repr(self.tcx()));
+
+        for predicate in predicates.iter() {
+            match *predicate {
+                ty::Predicate::Trait(ty::Binder(ref data)) => {
+                    self.add_constraints_from_trait_ref(generics, &*data.trait_ref, variance);
+                }
+
+                ty::Predicate::Equate(ty::Binder(ref data)) => {
+                    self.add_constraints_from_ty(generics, data.0, variance);
+                    self.add_constraints_from_ty(generics, data.1, variance);
+                }
+
+                ty::Predicate::TypeOutlives(ty::Binder(ref data)) => {
+                    self.add_constraints_from_ty(generics, data.0, variance);
+
+                    let variance_r = self.xform(variance, self.contravariant);
+                    self.add_constraints_from_region(generics, data.1, variance_r);
+                }
+
+                ty::Predicate::RegionOutlives(ty::Binder(ref data)) => {
+                    // `'a : 'b` is still true if 'a gets bigger
+                    self.add_constraints_from_region(generics, data.0, variance);
+
+                    // `'a : 'b` is still true if 'b gets smaller
+                    let variance_r = self.xform(variance, self.contravariant);
+                    self.add_constraints_from_region(generics, data.1, variance_r);
+                }
+
+                ty::Predicate::Projection(ty::Binder(ref data)) => {
+                    self.add_constraints_from_trait_ref(generics,
+                                                        &*data.projection_ty.trait_ref,
+                                                        variance);
+
+                    self.add_constraints_from_ty(generics, data.ty, self.invariant);
+                }
+            }
+        }
+    }
+
     /// Adds constraints appropriate for a function with signature
     /// `sig` appearing in a context with ambient variance `variance`
     fn add_constraints_from_sig(&mut self,
@@ -969,7 +1111,12 @@ struct SolveContext<'a, 'tcx: 'a> {
 
 fn solve_constraints(constraints_cx: ConstraintContext) {
     let ConstraintContext { terms_cx, constraints, .. } = constraints_cx;
-    let solutions: Vec<_> = repeat(ty::Bivariant).take(terms_cx.num_inferred()).collect();
+
+    let solutions =
+        terms_cx.inferred_infos.iter()
+                               .map(|ii| ii.initial_variance)
+                               .collect();
+
     let mut solutions_cx = SolveContext {
         terms_cx: terms_cx,
         constraints: constraints,
@@ -1034,20 +1181,16 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
             let mut types = VecPerParamSpace::empty();
             let mut regions = VecPerParamSpace::empty();
 
-            while index < num_inferred &&
-                  inferred_infos[index].item_id == item_id {
+            while index < num_inferred && inferred_infos[index].item_id == item_id {
                 let info = &inferred_infos[index];
                 let variance = solutions[index];
                 debug!("Index {} Info {} / {:?} / {:?} Variance {:?}",
                        index, info.index, info.kind, info.space, variance);
                 match info.kind {
-                    TypeParam => {
-                        types.push(info.space, variance);
-                    }
-                    RegionParam => {
-                        regions.push(info.space, variance);
-                    }
+                    TypeParam => { types.push(info.space, variance); }
+                    RegionParam => { regions.push(info.space, variance); }
                 }
+
                 index += 1;
             }
 
@@ -1065,7 +1208,7 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
             // attribute and report an error with various results if found.
             if ty::has_attr(tcx, item_def_id, "rustc_variance") {
                 let found = item_variances.repr(tcx);
-                span_err!(tcx.sess, tcx.map.span(item_id), E0208, "{}", &found[]);
+                span_err!(tcx.sess, tcx.map.span(item_id), E0208, "{}", &found[..]);
             }
 
             let newly_added = tcx.item_variance_map.borrow_mut()
@@ -1144,3 +1287,4 @@ fn glb(v1: ty::Variance, v2: ty::Variance) -> ty::Variance {
         (x, ty::Bivariant) | (ty::Bivariant, x) => x,
     }
 }
+
diff --git a/src/librustdoc/flock.rs b/src/librustdoc/flock.rs
index a7cf5eb8918..ad91c3cb2c3 100644
--- a/src/librustdoc/flock.rs
+++ b/src/librustdoc/flock.rs
@@ -112,7 +112,7 @@ mod imp {
 
     impl Lock {
         pub fn new(p: &Path) -> Lock {
-            let buf = CString::from_slice(p.as_vec());
+            let buf = CString::new(p.as_vec()).unwrap();
             let fd = unsafe {
                 libc::open(buf.as_ptr(), libc::O_RDWR | libc::O_CREAT,
                            libc::S_IRWXU)
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index 6acd1537946..44c0acda66f 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -34,7 +34,7 @@ pub fn highlight(src: &str, class: Option<&str>, id: Option<&str>) -> String {
          class,
          id,
          &mut out).unwrap();
-    String::from_utf8_lossy(&out[]).into_owned()
+    String::from_utf8_lossy(&out[..]).into_owned()
 }
 
 /// Exhausts the `lexer` writing the output into `out`.
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index c513fe2e8eb..7ea5bd569e1 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -236,7 +236,7 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
                 s.push_str(&highlight::highlight(&text,
                                                  None,
                                                  Some("rust-example-rendered")));
-                let output = CString::from_vec(s.into_bytes());
+                let output = CString::new(s).unwrap();
                 hoedown_buffer_puts(ob, output.as_ptr());
             })
         }
@@ -293,7 +293,7 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
                                format!("{} ", sec)
                            });
 
-        let text = CString::from_vec(text.into_bytes());
+        let text = CString::new(text).unwrap();
         unsafe { hoedown_buffer_puts(ob, text.as_ptr()) }
     }
 
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 95994af7dc8..fc3c8738991 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -1404,8 +1404,7 @@ impl<'a> fmt::Display for Item<'a> {
 
         try!(write!(fmt,
         r##"<span id='render-detail'>
-            <a id="collapse-all" href="#">[-]
-            </a>&nbsp;<a id="expand-all" href="#">[+]</a>
+            <a id="collapse-all" href="#">[-]</a>&nbsp;<a id="expand-all" href="#">[+]</a>
         </span>"##));
 
         // Write `src` tag
diff --git a/src/librustdoc/html/static/main.css b/src/librustdoc/html/static/main.css
index a4263badb01..2f0755ecb89 100644
--- a/src/librustdoc/html/static/main.css
+++ b/src/librustdoc/html/static/main.css
@@ -374,8 +374,8 @@ a {
     color: #000;
     background: transparent;
 }
-p a { color: #4e8bca; }
-p a:hover { text-decoration: underline; }
+.docblock a { color: #4e8bca; }
+.docblock a:hover { text-decoration: underline; }
 
 .content span.trait, .content a.trait, .block a.current.trait { color: #ed9603; }
 .content span.mod, .content a.mod, block a.current.mod { color: #4d76ae; }
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index bab734db126..f9e0948d7bc 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -23,7 +23,6 @@
 #![feature(collections)]
 #![feature(core)]
 #![feature(env)]
-#![feature(hash)]
 #![feature(int_uint)]
 #![feature(old_io)]
 #![feature(libc)]
diff --git a/src/librustdoc/passes.rs b/src/librustdoc/passes.rs
index abd73fcfb70..722f14fa6d4 100644
--- a/src/librustdoc/passes.rs
+++ b/src/librustdoc/passes.rs
@@ -293,7 +293,7 @@ pub fn collapse_docs(krate: clean::Crate) -> plugins::PluginResult {
             let mut a: Vec<clean::Attribute> = i.attrs.iter().filter(|&a| match a {
                 &clean::NameValue(ref x, _) if "doc" == *x => false,
                 _ => true
-            }).map(|x| x.clone()).collect();
+            }).cloned().collect();
             if docstr.len() > 0 {
                 a.push(clean::NameValue("doc".to_string(), docstr));
             }
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index ac1a0285412..c52b0bab1fa 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -333,7 +333,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                     name: name,
                     items: items.clone(),
                     generics: gen.clone(),
-                    bounds: b.iter().map(|x| (*x).clone()).collect(),
+                    bounds: b.iter().cloned().collect(),
                     id: item.id,
                     attrs: item.attrs.clone(),
                     whence: item.span,
diff --git a/src/libserialize/collection_impls.rs b/src/libserialize/collection_impls.rs
index f81edca8371..10cf02f85e8 100644
--- a/src/libserialize/collection_impls.rs
+++ b/src/libserialize/collection_impls.rs
@@ -12,16 +12,17 @@
 
 use std::usize;
 use std::default::Default;
-use std::hash::{Hash, Hasher};
+use std::hash::Hash;
+#[cfg(stage0)] use std::hash::Hasher;
 use std::collections::hash_state::HashState;
 
 use {Decodable, Encodable, Decoder, Encoder};
-use std::collections::{DList, RingBuf, BTreeMap, BTreeSet, HashMap, HashSet, VecMap};
+use std::collections::{LinkedList, VecDeque, BTreeMap, BTreeSet, HashMap, HashSet, VecMap};
 use collections::enum_set::{EnumSet, CLike};
 
 impl<
     T: Encodable
-> Encodable for DList<T> {
+> Encodable for LinkedList<T> {
     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_seq(self.len(), |s| {
             for (i, e) in self.iter().enumerate() {
@@ -32,10 +33,10 @@ impl<
     }
 }
 
-impl<T:Decodable> Decodable for DList<T> {
-    fn decode<D: Decoder>(d: &mut D) -> Result<DList<T>, D::Error> {
+impl<T:Decodable> Decodable for LinkedList<T> {
+    fn decode<D: Decoder>(d: &mut D) -> Result<LinkedList<T>, D::Error> {
         d.read_seq(|d, len| {
-            let mut list = DList::new();
+            let mut list = LinkedList::new();
             for i in 0..len {
                 list.push_back(try!(d.read_seq_elt(i, |d| Decodable::decode(d))));
             }
@@ -44,7 +45,7 @@ impl<T:Decodable> Decodable for DList<T> {
     }
 }
 
-impl<T: Encodable> Encodable for RingBuf<T> {
+impl<T: Encodable> Encodable for VecDeque<T> {
     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_seq(self.len(), |s| {
             for (i, e) in self.iter().enumerate() {
@@ -55,10 +56,10 @@ impl<T: Encodable> Encodable for RingBuf<T> {
     }
 }
 
-impl<T:Decodable> Decodable for RingBuf<T> {
-    fn decode<D: Decoder>(d: &mut D) -> Result<RingBuf<T>, D::Error> {
+impl<T:Decodable> Decodable for VecDeque<T> {
+    fn decode<D: Decoder>(d: &mut D) -> Result<VecDeque<T>, D::Error> {
         d.read_seq(|d, len| {
-            let mut deque: RingBuf<T> = RingBuf::new();
+            let mut deque: VecDeque<T> = VecDeque::new();
             for i in 0..len {
                 deque.push_back(try!(d.read_seq_elt(i, |d| Decodable::decode(d))));
             }
@@ -157,6 +158,7 @@ impl<
     }
 }
 
+#[cfg(stage0)]
 impl<K, V, S> Encodable for HashMap<K, V, S>
     where K: Encodable + Hash< <S as HashState>::Hasher> + Eq,
           V: Encodable,
@@ -175,7 +177,26 @@ impl<K, V, S> Encodable for HashMap<K, V, S>
         })
     }
 }
+#[cfg(not(stage0))]
+impl<K, V, S> Encodable for HashMap<K, V, S>
+    where K: Encodable + Hash + Eq,
+          V: Encodable,
+          S: HashState,
+{
+    fn encode<E: Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
+        e.emit_map(self.len(), |e| {
+            let mut i = 0;
+            for (key, val) in self {
+                try!(e.emit_map_elt_key(i, |e| key.encode(e)));
+                try!(e.emit_map_elt_val(i, |e| val.encode(e)));
+                i += 1;
+            }
+            Ok(())
+        })
+    }
+}
 
+#[cfg(stage0)]
 impl<K, V, S> Decodable for HashMap<K, V, S>
     where K: Decodable + Hash< <S as HashState>::Hasher> + Eq,
           V: Decodable,
@@ -195,7 +216,27 @@ impl<K, V, S> Decodable for HashMap<K, V, S>
         })
     }
 }
+#[cfg(not(stage0))]
+impl<K, V, S> Decodable for HashMap<K, V, S>
+    where K: Decodable + Hash + Eq,
+          V: Decodable,
+          S: HashState + Default,
+{
+    fn decode<D: Decoder>(d: &mut D) -> Result<HashMap<K, V, S>, D::Error> {
+        d.read_map(|d, len| {
+            let state = Default::default();
+            let mut map = HashMap::with_capacity_and_hash_state(len, state);
+            for i in 0..len {
+                let key = try!(d.read_map_elt_key(i, |d| Decodable::decode(d)));
+                let val = try!(d.read_map_elt_val(i, |d| Decodable::decode(d)));
+                map.insert(key, val);
+            }
+            Ok(map)
+        })
+    }
+}
 
+#[cfg(stage0)]
 impl<T, S> Encodable for HashSet<T, S>
     where T: Encodable + Hash< <S as HashState>::Hasher> + Eq,
           S: HashState,
@@ -212,7 +253,24 @@ impl<T, S> Encodable for HashSet<T, S>
         })
     }
 }
+#[cfg(not(stage0))]
+impl<T, S> Encodable for HashSet<T, S>
+    where T: Encodable + Hash + Eq,
+          S: HashState,
+{
+    fn encode<E: Encoder>(&self, s: &mut E) -> Result<(), E::Error> {
+        s.emit_seq(self.len(), |s| {
+            let mut i = 0;
+            for e in self {
+                try!(s.emit_seq_elt(i, |s| e.encode(s)));
+                i += 1;
+            }
+            Ok(())
+        })
+    }
+}
 
+#[cfg(stage0)]
 impl<T, S> Decodable for HashSet<T, S>
     where T: Decodable + Hash< <S as HashState>::Hasher> + Eq,
           S: HashState + Default,
@@ -229,6 +287,22 @@ impl<T, S> Decodable for HashSet<T, S>
         })
     }
 }
+#[cfg(not(stage0))]
+impl<T, S> Decodable for HashSet<T, S>
+    where T: Decodable + Hash + Eq,
+          S: HashState + Default,
+{
+    fn decode<D: Decoder>(d: &mut D) -> Result<HashSet<T, S>, D::Error> {
+        d.read_seq(|d, len| {
+            let state = Default::default();
+            let mut set = HashSet::with_capacity_and_hash_state(len, state);
+            for i in 0..len {
+                set.insert(try!(d.read_seq_elt(i, |d| Decodable::decode(d))));
+            }
+            Ok(set)
+        })
+    }
+}
 
 impl<V: Encodable> Encodable for VecMap<V> {
     fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs
index 68b28784b42..a0f42815b43 100644
--- a/src/libserialize/json.rs
+++ b/src/libserialize/json.rs
@@ -1120,7 +1120,7 @@ impl Json {
     /// Returns None otherwise.
     pub fn as_string<'a>(&'a self) -> Option<&'a str> {
         match *self {
-            Json::String(ref s) => Some(&s[]),
+            Json::String(ref s) => Some(&s[..]),
             _ => None
         }
     }
@@ -2237,7 +2237,7 @@ impl ::Decoder for Decoder {
                 return Err(ExpectedError("String or Object".to_string(), format!("{}", json)))
             }
         };
-        let idx = match names.iter().position(|n| *n == &name[]) {
+        let idx = match names.iter().position(|n| *n == &name[..]) {
             Some(idx) => idx,
             None => return Err(UnknownVariantError(name))
         };
@@ -3461,7 +3461,7 @@ mod tests {
         hm.insert(1, true);
         let mut mem_buf = Vec::new();
         write!(&mut mem_buf, "{}", super::as_pretty_json(&hm)).unwrap();
-        let json_str = from_utf8(&mem_buf[]).unwrap();
+        let json_str = from_utf8(&mem_buf[..]).unwrap();
         match from_str(json_str) {
             Err(_) => panic!("Unable to parse json_str: {:?}", json_str),
             _ => {} // it parsed and we are good to go
@@ -3477,7 +3477,7 @@ mod tests {
         hm.insert(1, true);
         let mut mem_buf = Vec::new();
         write!(&mut mem_buf, "{}", super::as_pretty_json(&hm)).unwrap();
-        let json_str = from_utf8(&mem_buf[]).unwrap();
+        let json_str = from_utf8(&mem_buf[..]).unwrap();
         match from_str(json_str) {
             Err(_) => panic!("Unable to parse json_str: {:?}", json_str),
             _ => {} // it parsed and we are good to go
@@ -3517,7 +3517,7 @@ mod tests {
             write!(&mut writer, "{}",
                    super::as_pretty_json(&json).indent(i)).unwrap();
 
-            let printed = from_utf8(&writer[]).unwrap();
+            let printed = from_utf8(&writer[..]).unwrap();
 
             // Check for indents at each line
             let lines: Vec<&str> = printed.lines().collect();
@@ -3549,7 +3549,7 @@ mod tests {
         let mut map = HashMap::new();
         map.insert(Enum::Foo, 0);
         let result = json::encode(&map).unwrap();
-        assert_eq!(&result[], r#"{"Foo":0}"#);
+        assert_eq!(&result[..], r#"{"Foo":0}"#);
         let decoded: HashMap<Enum, _> = json::decode(&result).unwrap();
         assert_eq!(map, decoded);
     }
diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs
index 853da598ab5..d476fd72abc 100644
--- a/src/libserialize/lib.rs
+++ b/src/libserialize/lib.rs
@@ -31,7 +31,6 @@ Core encoding and decoding interfaces.
 #![feature(int_uint)]
 #![feature(old_io)]
 #![feature(old_path)]
-#![feature(hash)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
 #![feature(std_misc)]
diff --git a/src/libserialize/serialize.rs b/src/libserialize/serialize.rs
index 517907bcf58..70f0ba4bb23 100644
--- a/src/libserialize/serialize.rs
+++ b/src/libserialize/serialize.rs
@@ -326,7 +326,7 @@ impl Encodable for str {
 
 impl Encodable for String {
     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        s.emit_str(&self[])
+        s.emit_str(&self[..])
     }
 }
 
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index 1b9f8b99017..ade4f1f0533 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -14,12 +14,12 @@ use self::Entry::*;
 use self::SearchResult::*;
 use self::VacantEntryState::*;
 
-use borrow::BorrowFrom;
+use borrow::Borrow;
 use clone::Clone;
 use cmp::{max, Eq, PartialEq};
 use default::Default;
 use fmt::{self, Debug};
-use hash::{self, Hash, SipHasher};
+use hash::{Hash, SipHasher};
 use iter::{self, Iterator, ExactSizeIterator, IntoIterator, IteratorExt, FromIterator, Extend, Map};
 use marker::Sized;
 use mem::{self, replace};
@@ -440,12 +440,10 @@ impl<K, V, M> SearchResult<K, V, M> {
     }
 }
 
-impl<K, V, S, H> HashMap<K, V, S>
-    where K: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
+impl<K, V, S> HashMap<K, V, S>
+    where K: Eq + Hash, S: HashState
 {
-    fn make_hash<X: ?Sized>(&self, x: &X) -> SafeHash where X: Hash<H> {
+    fn make_hash<X: ?Sized>(&self, x: &X) -> SafeHash where X: Hash {
         table::make_hash(&self.hash_state, x)
     }
 
@@ -453,18 +451,18 @@ impl<K, V, S, H> HashMap<K, V, S>
     /// If you already have the hash for the key lying around, use
     /// search_hashed.
     fn search<'a, Q: ?Sized>(&'a self, q: &Q) -> Option<FullBucketImm<'a, K, V>>
-        where Q: BorrowFrom<K> + Eq + Hash<H>
+        where K: Borrow<Q>, Q: Eq + Hash
     {
         let hash = self.make_hash(q);
-        search_hashed(&self.table, hash, |k| q.eq(BorrowFrom::borrow_from(k)))
+        search_hashed(&self.table, hash, |k| q.eq(k.borrow()))
             .into_option()
     }
 
     fn search_mut<'a, Q: ?Sized>(&'a mut self, q: &Q) -> Option<FullBucketMut<'a, K, V>>
-        where Q: BorrowFrom<K> + Eq + Hash<H>
+        where K: Borrow<Q>, Q: Eq + Hash
     {
         let hash = self.make_hash(q);
-        search_hashed(&mut self.table, hash, |k| q.eq(BorrowFrom::borrow_from(k)))
+        search_hashed(&mut self.table, hash, |k| q.eq(k.borrow()))
             .into_option()
     }
 
@@ -490,7 +488,7 @@ impl<K, V, S, H> HashMap<K, V, S>
     }
 }
 
-impl<K: Hash<Hasher> + Eq, V> HashMap<K, V, RandomState> {
+impl<K: Hash + Eq, V> HashMap<K, V, RandomState> {
     /// Create an empty HashMap.
     ///
     /// # Example
@@ -520,10 +518,8 @@ impl<K: Hash<Hasher> + Eq, V> HashMap<K, V, RandomState> {
     }
 }
 
-impl<K, V, S, H> HashMap<K, V, S>
-    where K: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
+impl<K, V, S> HashMap<K, V, S>
+    where K: Eq + Hash, S: HashState
 {
     /// Creates an empty hashmap which will use the given hasher to hash keys.
     ///
@@ -1037,7 +1033,7 @@ impl<K, V, S, H> HashMap<K, V, S>
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
-        where Q: Hash<H> + Eq + BorrowFrom<K>
+        where K: Borrow<Q>, Q: Hash + Eq
     {
         self.search(k).map(|bucket| bucket.into_refs().1)
     }
@@ -1060,7 +1056,7 @@ impl<K, V, S, H> HashMap<K, V, S>
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool
-        where Q: Hash<H> + Eq + BorrowFrom<K>
+        where K: Borrow<Q>, Q: Hash + Eq
     {
         self.search(k).is_some()
     }
@@ -1086,7 +1082,7 @@ impl<K, V, S, H> HashMap<K, V, S>
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V>
-        where Q: Hash<H> + Eq + BorrowFrom<K>
+        where K: Borrow<Q>, Q: Hash + Eq
     {
         self.search_mut(k).map(|bucket| bucket.into_mut_refs().1)
     }
@@ -1138,7 +1134,7 @@ impl<K, V, S, H> HashMap<K, V, S>
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V>
-        where Q: Hash<H> + Eq + BorrowFrom<K>
+        where K: Borrow<Q>, Q: Hash + Eq
     {
         if self.table.size() == 0 {
             return None
@@ -1195,10 +1191,8 @@ fn search_entry_hashed<'a, K: Eq, V>(table: &'a mut RawTable<K,V>, hash: SafeHas
     }
 }
 
-impl<K, V, S, H> PartialEq for HashMap<K, V, S>
-    where K: Eq + Hash<H>, V: PartialEq,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
+impl<K, V, S> PartialEq for HashMap<K, V, S>
+    where K: Eq + Hash, V: PartialEq, S: HashState
 {
     fn eq(&self, other: &HashMap<K, V, S>) -> bool {
         if self.len() != other.len() { return false; }
@@ -1210,17 +1204,13 @@ impl<K, V, S, H> PartialEq for HashMap<K, V, S>
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<K, V, S, H> Eq for HashMap<K, V, S>
-    where K: Eq + Hash<H>, V: Eq,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
+impl<K, V, S> Eq for HashMap<K, V, S>
+    where K: Eq + Hash, V: Eq, S: HashState
 {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<K, V, S, H> Debug for HashMap<K, V, S>
-    where K: Eq + Hash<H> + Debug, V: Debug,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
+impl<K, V, S> Debug for HashMap<K, V, S>
+    where K: Eq + Hash + Debug, V: Debug, S: HashState
 {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         try!(write!(f, "HashMap {{"));
@@ -1235,10 +1225,9 @@ impl<K, V, S, H> Debug for HashMap<K, V, S>
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<K, V, S, H> Default for HashMap<K, V, S>
-    where K: Eq + Hash<H>,
-          S: HashState<Hasher=H> + Default,
-          H: hash::Hasher<Output=u64>
+impl<K, V, S> Default for HashMap<K, V, S>
+    where K: Eq + Hash,
+          S: HashState + Default,
 {
     fn default() -> HashMap<K, V, S> {
         HashMap::with_hash_state(Default::default())
@@ -1246,11 +1235,10 @@ impl<K, V, S, H> Default for HashMap<K, V, S>
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<K, Q: ?Sized, V, S, H> Index<Q> for HashMap<K, V, S>
-    where K: Eq + Hash<H>,
-          Q: Eq + Hash<H> + BorrowFrom<K>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
+impl<K, Q: ?Sized, V, S> Index<Q> for HashMap<K, V, S>
+    where K: Eq + Hash + Borrow<Q>,
+          Q: Eq + Hash,
+          S: HashState,
 {
     type Output = V;
 
@@ -1261,11 +1249,10 @@ impl<K, Q: ?Sized, V, S, H> Index<Q> for HashMap<K, V, S>
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<K, V, S, H, Q: ?Sized> IndexMut<Q> for HashMap<K, V, S>
-    where K: Eq + Hash<H>,
-          Q: Eq + Hash<H> + BorrowFrom<K>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
+impl<K, V, S, Q: ?Sized> IndexMut<Q> for HashMap<K, V, S>
+    where K: Eq + Hash + Borrow<Q>,
+          Q: Eq + Hash,
+          S: HashState,
 {
     #[inline]
     fn index_mut<'a>(&'a mut self, index: &Q) -> &'a mut V {
@@ -1373,10 +1360,8 @@ enum VacantEntryState<K, V, M> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, K, V, S, H> IntoIterator for &'a HashMap<K, V, S>
-    where K: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
+impl<'a, K, V, S> IntoIterator for &'a HashMap<K, V, S>
+    where K: Eq + Hash, S: HashState
 {
     type Item = (&'a K, &'a V);
     type IntoIter = Iter<'a, K, V>;
@@ -1387,10 +1372,8 @@ impl<'a, K, V, S, H> IntoIterator for &'a HashMap<K, V, S>
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, K, V, S, H> IntoIterator for &'a mut HashMap<K, V, S>
-    where K: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
+impl<'a, K, V, S> IntoIterator for &'a mut HashMap<K, V, S>
+    where K: Eq + Hash, S: HashState
 {
     type Item = (&'a K, &'a mut V);
     type IntoIter = IterMut<'a, K, V>;
@@ -1401,10 +1384,8 @@ impl<'a, K, V, S, H> IntoIterator for &'a mut HashMap<K, V, S>
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<K, V, S, H> IntoIterator for HashMap<K, V, S>
-    where K: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
+impl<K, V, S> IntoIterator for HashMap<K, V, S>
+    where K: Eq + Hash, S: HashState
 {
     type Item = (K, V);
     type IntoIter = IntoIter<K, V>;
@@ -1550,12 +1531,11 @@ impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<K, V, S, H> FromIterator<(K, V)> for HashMap<K, V, S>
-    where K: Eq + Hash<H>,
-          S: HashState<Hasher=H> + Default,
-          H: hash::Hasher<Output=u64>
+impl<K, V, S> FromIterator<(K, V)> for HashMap<K, V, S>
+    where K: Eq + Hash, S: HashState + Default
 {
-    fn from_iter<T: Iterator<Item=(K, V)>>(iter: T) -> HashMap<K, V, S> {
+    fn from_iter<T: IntoIterator<Item=(K, V)>>(iterable: T) -> HashMap<K, V, S> {
+        let iter = iterable.into_iter();
         let lower = iter.size_hint().0;
         let mut map = HashMap::with_capacity_and_hash_state(lower,
                                                             Default::default());
@@ -1565,12 +1545,10 @@ impl<K, V, S, H> FromIterator<(K, V)> for HashMap<K, V, S>
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<K, V, S, H> Extend<(K, V)> for HashMap<K, V, S>
-    where K: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
+impl<K, V, S> Extend<(K, V)> for HashMap<K, V, S>
+    where K: Eq + Hash, S: HashState
 {
-    fn extend<T: Iterator<Item=(K, V)>>(&mut self, iter: T) {
+    fn extend<T: IntoIterator<Item=(K, V)>>(&mut self, iter: T) {
         for (k, v) in iter {
             self.insert(k, v);
         }
@@ -1606,9 +1584,9 @@ impl RandomState {
 #[unstable(feature = "std_misc",
            reason = "hashing an hash maps may be altered")]
 impl HashState for RandomState {
-    type Hasher = Hasher;
-    fn hasher(&self) -> Hasher {
-        Hasher { inner: SipHasher::new_with_keys(self.k0, self.k1) }
+    type Hasher = SipHasher;
+    fn hasher(&self) -> SipHasher {
+        SipHasher::new_with_keys(self.k0, self.k1)
     }
 }
 
@@ -1621,25 +1599,6 @@ impl Default for RandomState {
     }
 }
 
-/// A hasher implementation which is generated from `RandomState` instances.
-///
-/// This is the default hasher used in a `HashMap` to hash keys. Types do not
-/// typically declare an ability to explicitly hash into this particular type,
-/// but rather in a `H: hash::Writer` type parameter.
-#[unstable(feature = "std_misc",
-           reason = "hashing an hash maps may be altered")]
-pub struct Hasher { inner: SipHasher }
-
-impl hash::Writer for Hasher {
-    fn write(&mut self, data: &[u8]) { self.inner.write(data) }
-}
-
-impl hash::Hasher for Hasher {
-    type Output = u64;
-    fn reset(&mut self) { self.inner.reset() }
-    fn finish(&self) -> u64 { self.inner.finish() }
-}
-
 #[cfg(test)]
 mod test_map {
     use prelude::v1::*;
diff --git a/src/libstd/collections/hash/map_stage0.rs b/src/libstd/collections/hash/map_stage0.rs
new file mode 100644
index 00000000000..f9e5044c597
--- /dev/null
+++ b/src/libstd/collections/hash/map_stage0.rs
@@ -0,0 +1,2330 @@
+// Copyright 2014-2015 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.
+//
+// ignore-lexer-test FIXME #15883
+
+use self::Entry::*;
+use self::SearchResult::*;
+use self::VacantEntryState::*;
+
+use borrow::Borrow;
+use clone::Clone;
+use cmp::{max, Eq, PartialEq};
+use default::Default;
+use fmt::{self, Debug};
+use hash::{self, Hash, SipHasher};
+use iter::{self, Iterator, ExactSizeIterator, IntoIterator, IteratorExt, FromIterator, Extend, Map};
+use marker::Sized;
+use mem::{self, replace};
+use num::{Int, UnsignedInt};
+use ops::{Deref, FnMut, Index, IndexMut};
+use option::Option::{self, Some, None};
+use rand::{self, Rng};
+use result::Result::{self, Ok, Err};
+
+use super::table::{
+    self,
+    Bucket,
+    EmptyBucket,
+    FullBucket,
+    FullBucketImm,
+    FullBucketMut,
+    RawTable,
+    SafeHash
+};
+use super::table::BucketState::{
+    Empty,
+    Full,
+};
+use super::state::HashState;
+
+const INITIAL_LOG2_CAP: usize = 5;
+#[unstable(feature = "std_misc")]
+pub const INITIAL_CAPACITY: usize = 1 << INITIAL_LOG2_CAP; // 2^5
+
+/// The default behavior of HashMap implements a load factor of 90.9%.
+/// This behavior is characterized by the following condition:
+///
+/// - if size > 0.909 * capacity: grow the map
+#[derive(Clone)]
+struct DefaultResizePolicy;
+
+impl DefaultResizePolicy {
+    fn new() -> DefaultResizePolicy {
+        DefaultResizePolicy
+    }
+
+    #[inline]
+    fn min_capacity(&self, usable_size: usize) -> usize {
+        // Here, we are rephrasing the logic by specifying the lower limit
+        // on capacity:
+        //
+        // - if `cap < size * 1.1`: grow the map
+        usable_size * 11 / 10
+    }
+
+    /// An inverse of `min_capacity`, approximately.
+    #[inline]
+    fn usable_capacity(&self, cap: usize) -> usize {
+        // As the number of entries approaches usable capacity,
+        // min_capacity(size) must be smaller than the internal capacity,
+        // so that the map is not resized:
+        // `min_capacity(usable_capacity(x)) <= x`.
+        // The left-hand side can only be smaller due to flooring by integer
+        // division.
+        //
+        // This doesn't have to be checked for overflow since allocation size
+        // in bytes will overflow earlier than multiplication by 10.
+        cap * 10 / 11
+    }
+}
+
+#[test]
+fn test_resize_policy() {
+    use prelude::v1::*;
+    let rp = DefaultResizePolicy;
+    for n in 0..1000 {
+        assert!(rp.min_capacity(rp.usable_capacity(n)) <= n);
+        assert!(rp.usable_capacity(rp.min_capacity(n)) <= n);
+    }
+}
+
+// The main performance trick in this hashmap is called Robin Hood Hashing.
+// It gains its excellent performance from one essential operation:
+//
+//    If an insertion collides with an existing element, and that element's
+//    "probe distance" (how far away the element is from its ideal location)
+//    is higher than how far we've already probed, swap the elements.
+//
+// This massively lowers variance in probe distance, and allows us to get very
+// high load factors with good performance. The 90% load factor I use is rather
+// conservative.
+//
+// > Why a load factor of approximately 90%?
+//
+// In general, all the distances to initial buckets will converge on the mean.
+// At a load factor of α, the odds of finding the target bucket after k
+// probes is approximately 1-α^k. If we set this equal to 50% (since we converge
+// on the mean) and set k=8 (64-byte cache line / 8-byte hash), α=0.92. I round
+// this down to make the math easier on the CPU and avoid its FPU.
+// Since on average we start the probing in the middle of a cache line, this
+// strategy pulls in two cache lines of hashes on every lookup. I think that's
+// pretty good, but if you want to trade off some space, it could go down to one
+// cache line on average with an α of 0.84.
+//
+// > Wait, what? Where did you get 1-α^k from?
+//
+// On the first probe, your odds of a collision with an existing element is α.
+// The odds of doing this twice in a row is approximately α^2. For three times,
+// α^3, etc. Therefore, the odds of colliding k times is α^k. The odds of NOT
+// colliding after k tries is 1-α^k.
+//
+// The paper from 1986 cited below mentions an implementation which keeps track
+// of the distance-to-initial-bucket histogram. This approach is not suitable
+// for modern architectures because it requires maintaining an internal data
+// structure. This allows very good first guesses, but we are most concerned
+// with guessing entire cache lines, not individual indexes. Furthermore, array
+// accesses are no longer linear and in one direction, as we have now. There
+// is also memory and cache pressure that this would entail that would be very
+// difficult to properly see in a microbenchmark.
+//
+// ## Future Improvements (FIXME!)
+//
+// Allow the load factor to be changed dynamically and/or at initialization.
+//
+// Also, would it be possible for us to reuse storage when growing the
+// underlying table? This is exactly the use case for 'realloc', and may
+// be worth exploring.
+//
+// ## Future Optimizations (FIXME!)
+//
+// Another possible design choice that I made without any real reason is
+// parameterizing the raw table over keys and values. Technically, all we need
+// is the size and alignment of keys and values, and the code should be just as
+// efficient (well, we might need one for power-of-two size and one for not...).
+// This has the potential to reduce code bloat in rust executables, without
+// really losing anything except 4 words (key size, key alignment, val size,
+// val alignment) which can be passed in to every call of a `RawTable` function.
+// This would definitely be an avenue worth exploring if people start complaining
+// about the size of rust executables.
+//
+// Annotate exceedingly likely branches in `table::make_hash`
+// and `search_hashed` to reduce instruction cache pressure
+// and mispredictions once it becomes possible (blocked on issue #11092).
+//
+// Shrinking the table could simply reallocate in place after moving buckets
+// to the first half.
+//
+// The growth algorithm (fragment of the Proof of Correctness)
+// --------------------
+//
+// The growth algorithm is basically a fast path of the naive reinsertion-
+// during-resize algorithm. Other paths should never be taken.
+//
+// Consider growing a robin hood hashtable of capacity n. Normally, we do this
+// by allocating a new table of capacity `2n`, and then individually reinsert
+// each element in the old table into the new one. This guarantees that the
+// new table is a valid robin hood hashtable with all the desired statistical
+// properties. Remark that the order we reinsert the elements in should not
+// matter. For simplicity and efficiency, we will consider only linear
+// reinsertions, which consist of reinserting all elements in the old table
+// into the new one by increasing order of index. However we will not be
+// starting our reinsertions from index 0 in general. If we start from index
+// i, for the purpose of reinsertion we will consider all elements with real
+// index j < i to have virtual index n + j.
+//
+// Our hash generation scheme consists of generating a 64-bit hash and
+// truncating the most significant bits. When moving to the new table, we
+// simply introduce a new bit to the front of the hash. Therefore, if an
+// elements has ideal index i in the old table, it can have one of two ideal
+// locations in the new table. If the new bit is 0, then the new ideal index
+// is i. If the new bit is 1, then the new ideal index is n + i. Intuitively,
+// we are producing two independent tables of size n, and for each element we
+// independently choose which table to insert it into with equal probability.
+// However the rather than wrapping around themselves on overflowing their
+// indexes, the first table overflows into the first, and the first into the
+// second. Visually, our new table will look something like:
+//
+// [yy_xxx_xxxx_xxx|xx_yyy_yyyy_yyy]
+//
+// Where x's are elements inserted into the first table, y's are elements
+// inserted into the second, and _'s are empty sections. We now define a few
+// key concepts that we will use later. Note that this is a very abstract
+// perspective of the table. A real resized table would be at least half
+// empty.
+//
+// Theorem: A linear robin hood reinsertion from the first ideal element
+// produces identical results to a linear naive reinsertion from the same
+// element.
+//
+// FIXME(Gankro, pczarn): review the proof and put it all in a separate doc.rs
+
+/// A hash map implementation which uses linear probing with Robin
+/// Hood bucket stealing.
+///
+/// The hashes are all keyed by the task-local random number generator
+/// on creation by default. This means that the ordering of the keys is
+/// randomized, but makes the tables more resistant to
+/// denial-of-service attacks (Hash DoS). This behaviour can be
+/// overridden with one of the constructors.
+///
+/// It is required that the keys implement the `Eq` and `Hash` traits, although
+/// this can frequently be achieved by using `#[derive(Eq, Hash)]`.
+///
+/// Relevant papers/articles:
+///
+/// 1. Pedro Celis. ["Robin Hood Hashing"](https://cs.uwaterloo.ca/research/tr/1986/CS-86-14.pdf)
+/// 2. Emmanuel Goossaert. ["Robin Hood
+///    hashing"](http://codecapsule.com/2013/11/11/robin-hood-hashing/)
+/// 3. Emmanuel Goossaert. ["Robin Hood hashing: backward shift
+///    deletion"](http://codecapsule.com/2013/11/17/robin-hood-hashing-backward-shift-deletion/)
+///
+/// # Example
+///
+/// ```
+/// use std::collections::HashMap;
+///
+/// // type inference lets us omit an explicit type signature (which
+/// // would be `HashMap<&str, &str>` in this example).
+/// let mut book_reviews = HashMap::new();
+///
+/// // review some books.
+/// book_reviews.insert("Adventures of Huckleberry Finn",    "My favorite book.");
+/// book_reviews.insert("Grimms' Fairy Tales",               "Masterpiece.");
+/// book_reviews.insert("Pride and Prejudice",               "Very enjoyable.");
+/// book_reviews.insert("The Adventures of Sherlock Holmes", "Eye lyked it alot.");
+///
+/// // check for a specific one.
+/// if !book_reviews.contains_key(&("Les Misérables")) {
+///     println!("We've got {} reviews, but Les Misérables ain't one.",
+///              book_reviews.len());
+/// }
+///
+/// // oops, this review has a lot of spelling mistakes, let's delete it.
+/// book_reviews.remove(&("The Adventures of Sherlock Holmes"));
+///
+/// // look up the values associated with some keys.
+/// let to_find = ["Pride and Prejudice", "Alice's Adventure in Wonderland"];
+/// for book in to_find.iter() {
+///     match book_reviews.get(book) {
+///         Some(review) => println!("{}: {}", *book, *review),
+///         None => println!("{} is unreviewed.", *book)
+///     }
+/// }
+///
+/// // iterate over everything.
+/// for (book, review) in book_reviews.iter() {
+///     println!("{}: \"{}\"", *book, *review);
+/// }
+/// ```
+///
+/// The easiest way to use `HashMap` with a custom type as key is to derive `Eq` and `Hash`.
+/// We must also derive `PartialEq`.
+///
+/// ```
+/// use std::collections::HashMap;
+///
+/// #[derive(Hash, Eq, PartialEq, Debug)]
+/// struct Viking {
+///     name: String,
+///     country: String,
+/// }
+///
+/// impl Viking {
+///     /// Create a new Viking.
+///     fn new(name: &str, country: &str) -> Viking {
+///         Viking { name: name.to_string(), country: country.to_string() }
+///     }
+/// }
+///
+/// // Use a HashMap to store the vikings' health points.
+/// let mut vikings = HashMap::new();
+///
+/// vikings.insert(Viking::new("Einar", "Norway"), 25);
+/// vikings.insert(Viking::new("Olaf", "Denmark"), 24);
+/// vikings.insert(Viking::new("Harald", "Iceland"), 12);
+///
+/// // Use derived implementation to print the status of the vikings.
+/// for (viking, health) in vikings.iter() {
+///     println!("{:?} has {} hp", viking, health);
+/// }
+/// ```
+#[derive(Clone)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct HashMap<K, V, S = RandomState> {
+    // All hashes are keyed on these values, to prevent hash collision attacks.
+    hash_state: S,
+
+    table: RawTable<K, V>,
+
+    resize_policy: DefaultResizePolicy,
+}
+
+/// Search for a pre-hashed key.
+fn search_hashed<K, V, M, F>(table: M,
+                             hash: SafeHash,
+                             mut is_match: F)
+                             -> SearchResult<K, V, M> where
+    M: Deref<Target=RawTable<K, V>>,
+    F: FnMut(&K) -> bool,
+{
+    let size = table.size();
+    let mut probe = Bucket::new(table, hash);
+    let ib = probe.index();
+
+    while probe.index() != ib + size {
+        let full = match probe.peek() {
+            Empty(b) => return TableRef(b.into_table()), // hit an empty bucket
+            Full(b) => b
+        };
+
+        if full.distance() + ib < full.index() {
+            // We can finish the search early if we hit any bucket
+            // with a lower distance to initial bucket than we've probed.
+            return TableRef(full.into_table());
+        }
+
+        // If the hash doesn't match, it can't be this one..
+        if hash == full.hash() {
+            // If the key doesn't match, it can't be this one..
+            if is_match(full.read().0) {
+                return FoundExisting(full);
+            }
+        }
+
+        probe = full.next();
+    }
+
+    TableRef(probe.into_table())
+}
+
+fn pop_internal<K, V>(starting_bucket: FullBucketMut<K, V>) -> (K, V) {
+    let (empty, retkey, retval) = starting_bucket.take();
+    let mut gap = match empty.gap_peek() {
+        Some(b) => b,
+        None => return (retkey, retval)
+    };
+
+    while gap.full().distance() != 0 {
+        gap = match gap.shift() {
+            Some(b) => b,
+            None => break
+        };
+    }
+
+    // Now we've done all our shifting. Return the value we grabbed earlier.
+    (retkey, retval)
+}
+
+/// Perform robin hood bucket stealing at the given `bucket`. You must
+/// also pass the position of that bucket's initial bucket so we don't have
+/// to recalculate it.
+///
+/// `hash`, `k`, and `v` are the elements to "robin hood" into the hashtable.
+fn robin_hood<'a, K: 'a, V: 'a>(mut bucket: FullBucketMut<'a, K, V>,
+                        mut ib: usize,
+                        mut hash: SafeHash,
+                        mut k: K,
+                        mut v: V)
+                        -> &'a mut V {
+    let starting_index = bucket.index();
+    let size = {
+        let table = bucket.table(); // FIXME "lifetime too short".
+        table.size()
+    };
+    // There can be at most `size - dib` buckets to displace, because
+    // in the worst case, there are `size` elements and we already are
+    // `distance` buckets away from the initial one.
+    let idx_end = starting_index + size - bucket.distance();
+
+    loop {
+        let (old_hash, old_key, old_val) = bucket.replace(hash, k, v);
+        loop {
+            let probe = bucket.next();
+            assert!(probe.index() != idx_end);
+
+            let full_bucket = match probe.peek() {
+                Empty(bucket) => {
+                    // Found a hole!
+                    let b = bucket.put(old_hash, old_key, old_val);
+                    // Now that it's stolen, just read the value's pointer
+                    // right out of the table!
+                    return Bucket::at_index(b.into_table(), starting_index)
+                               .peek()
+                               .expect_full()
+                               .into_mut_refs()
+                               .1;
+                },
+                Full(bucket) => bucket
+            };
+
+            let probe_ib = full_bucket.index() - full_bucket.distance();
+
+            bucket = full_bucket;
+
+            // Robin hood! Steal the spot.
+            if ib < probe_ib {
+                ib = probe_ib;
+                hash = old_hash;
+                k = old_key;
+                v = old_val;
+                break;
+            }
+        }
+    }
+}
+
+/// A result that works like Option<FullBucket<..>> but preserves
+/// the reference that grants us access to the table in any case.
+enum SearchResult<K, V, M> {
+    // This is an entry that holds the given key:
+    FoundExisting(FullBucket<K, V, M>),
+
+    // There was no such entry. The reference is given back:
+    TableRef(M)
+}
+
+impl<K, V, M> SearchResult<K, V, M> {
+    fn into_option(self) -> Option<FullBucket<K, V, M>> {
+        match self {
+            FoundExisting(bucket) => Some(bucket),
+            TableRef(_) => None
+        }
+    }
+}
+
+impl<K, V, S, H> HashMap<K, V, S>
+    where K: Eq + Hash<H>,
+          S: HashState<Hasher=H>,
+          H: hash::Hasher<Output=u64>
+{
+    fn make_hash<X: ?Sized>(&self, x: &X) -> SafeHash where X: Hash<H> {
+        table::make_hash(&self.hash_state, x)
+    }
+
+    /// Search for a key, yielding the index if it's found in the hashtable.
+    /// If you already have the hash for the key lying around, use
+    /// search_hashed.
+    fn search<'a, Q: ?Sized>(&'a self, q: &Q) -> Option<FullBucketImm<'a, K, V>>
+        where K: Borrow<Q>, Q: Eq + Hash<H>
+    {
+        let hash = self.make_hash(q);
+        search_hashed(&self.table, hash, |k| q.eq(k.borrow()))
+            .into_option()
+    }
+
+    fn search_mut<'a, Q: ?Sized>(&'a mut self, q: &Q) -> Option<FullBucketMut<'a, K, V>>
+        where K: Borrow<Q>, Q: Eq + Hash<H>
+    {
+        let hash = self.make_hash(q);
+        search_hashed(&mut self.table, hash, |k| q.eq(k.borrow()))
+            .into_option()
+    }
+
+    // The caller should ensure that invariants by Robin Hood Hashing hold.
+    fn insert_hashed_ordered(&mut self, hash: SafeHash, k: K, v: V) {
+        let cap = self.table.capacity();
+        let mut buckets = Bucket::new(&mut self.table, hash);
+        let ib = buckets.index();
+
+        while buckets.index() != ib + cap {
+            // We don't need to compare hashes for value swap.
+            // Not even DIBs for Robin Hood.
+            buckets = match buckets.peek() {
+                Empty(empty) => {
+                    empty.put(hash, k, v);
+                    return;
+                }
+                Full(b) => b.into_bucket()
+            };
+            buckets.next();
+        }
+        panic!("Internal HashMap error: Out of space.");
+    }
+}
+
+impl<K: Hash<Hasher> + Eq, V> HashMap<K, V, RandomState> {
+    /// Create an empty HashMap.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    /// let mut map: HashMap<&str, int> = HashMap::new();
+    /// ```
+    #[inline]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn new() -> HashMap<K, V, RandomState> {
+        Default::default()
+    }
+
+    /// Creates an empty hash map with the given initial capacity.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    /// let mut map: HashMap<&str, int> = HashMap::with_capacity(10);
+    /// ```
+    #[inline]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn with_capacity(capacity: usize) -> HashMap<K, V, RandomState> {
+        HashMap::with_capacity_and_hash_state(capacity, Default::default())
+    }
+}
+
+impl<K, V, S, H> HashMap<K, V, S>
+    where K: Eq + Hash<H>,
+          S: HashState<Hasher=H>,
+          H: hash::Hasher<Output=u64>
+{
+    /// Creates an empty hashmap which will use the given hasher to hash keys.
+    ///
+    /// The creates map has the default initial capacity.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    /// use std::collections::hash_map::RandomState;
+    ///
+    /// let s = RandomState::new();
+    /// let mut map = HashMap::with_hash_state(s);
+    /// map.insert(1, 2);
+    /// ```
+    #[inline]
+    #[unstable(feature = "std_misc", reason = "hasher stuff is unclear")]
+    pub fn with_hash_state(hash_state: S) -> HashMap<K, V, S> {
+        HashMap {
+            hash_state:    hash_state,
+            resize_policy: DefaultResizePolicy::new(),
+            table:         RawTable::new(0),
+        }
+    }
+
+    /// Create an empty HashMap with space for at least `capacity`
+    /// elements, using `hasher` to hash the keys.
+    ///
+    /// Warning: `hasher` is normally randomly generated, and
+    /// is designed to allow HashMaps to be resistant to attacks that
+    /// cause many collisions and very poor performance. Setting it
+    /// manually using this function can expose a DoS attack vector.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    /// use std::collections::hash_map::RandomState;
+    ///
+    /// let s = RandomState::new();
+    /// let mut map = HashMap::with_capacity_and_hash_state(10, s);
+    /// map.insert(1, 2);
+    /// ```
+    #[inline]
+    #[unstable(feature = "std_misc", reason = "hasher stuff is unclear")]
+    pub fn with_capacity_and_hash_state(capacity: usize, hash_state: S)
+                                        -> HashMap<K, V, S> {
+        let resize_policy = DefaultResizePolicy::new();
+        let min_cap = max(INITIAL_CAPACITY, resize_policy.min_capacity(capacity));
+        let internal_cap = min_cap.checked_next_power_of_two().expect("capacity overflow");
+        assert!(internal_cap >= capacity, "capacity overflow");
+        HashMap {
+            hash_state:    hash_state,
+            resize_policy: resize_policy,
+            table:         RawTable::new(internal_cap),
+        }
+    }
+
+    /// Returns the number of elements the map can hold without reallocating.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    /// let map: HashMap<int, int> = HashMap::with_capacity(100);
+    /// assert!(map.capacity() >= 100);
+    /// ```
+    #[inline]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn capacity(&self) -> usize {
+        self.resize_policy.usable_capacity(self.table.capacity())
+    }
+
+    /// Reserves capacity for at least `additional` more elements to be inserted
+    /// in the `HashMap`. The collection may reserve more space to avoid
+    /// frequent reallocations.
+    ///
+    /// # Panics
+    ///
+    /// Panics if the new allocation size overflows `usize`.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    /// let mut map: HashMap<&str, int> = HashMap::new();
+    /// map.reserve(10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn reserve(&mut self, additional: usize) {
+        let new_size = self.len().checked_add(additional).expect("capacity overflow");
+        let min_cap = self.resize_policy.min_capacity(new_size);
+
+        // An invalid value shouldn't make us run out of space. This includes
+        // an overflow check.
+        assert!(new_size <= min_cap);
+
+        if self.table.capacity() < min_cap {
+            let new_capacity = max(min_cap.next_power_of_two(), INITIAL_CAPACITY);
+            self.resize(new_capacity);
+        }
+    }
+
+    /// Resizes the internal vectors to a new capacity. It's your responsibility to:
+    ///   1) Make sure the new capacity is enough for all the elements, accounting
+    ///      for the load factor.
+    ///   2) Ensure new_capacity is a power of two or zero.
+    fn resize(&mut self, new_capacity: usize) {
+        assert!(self.table.size() <= new_capacity);
+        assert!(new_capacity.is_power_of_two() || new_capacity == 0);
+
+        let mut old_table = replace(&mut self.table, RawTable::new(new_capacity));
+        let old_size = old_table.size();
+
+        if old_table.capacity() == 0 || old_table.size() == 0 {
+            return;
+        }
+
+        // Grow the table.
+        // Specialization of the other branch.
+        let mut bucket = Bucket::first(&mut old_table);
+
+        // "So a few of the first shall be last: for many be called,
+        // but few chosen."
+        //
+        // We'll most likely encounter a few buckets at the beginning that
+        // have their initial buckets near the end of the table. They were
+        // placed at the beginning as the probe wrapped around the table
+        // during insertion. We must skip forward to a bucket that won't
+        // get reinserted too early and won't unfairly steal others spot.
+        // This eliminates the need for robin hood.
+        loop {
+            bucket = match bucket.peek() {
+                Full(full) => {
+                    if full.distance() == 0 {
+                        // This bucket occupies its ideal spot.
+                        // It indicates the start of another "cluster".
+                        bucket = full.into_bucket();
+                        break;
+                    }
+                    // Leaving this bucket in the last cluster for later.
+                    full.into_bucket()
+                }
+                Empty(b) => {
+                    // Encountered a hole between clusters.
+                    b.into_bucket()
+                }
+            };
+            bucket.next();
+        }
+
+        // This is how the buckets might be laid out in memory:
+        // ($ marks an initialized bucket)
+        //  ________________
+        // |$$$_$$$$$$_$$$$$|
+        //
+        // But we've skipped the entire initial cluster of buckets
+        // and will continue iteration in this order:
+        //  ________________
+        //     |$$$$$$_$$$$$
+        //                  ^ wrap around once end is reached
+        //  ________________
+        //  $$$_____________|
+        //    ^ exit once table.size == 0
+        loop {
+            bucket = match bucket.peek() {
+                Full(bucket) => {
+                    let h = bucket.hash();
+                    let (b, k, v) = bucket.take();
+                    self.insert_hashed_ordered(h, k, v);
+                    {
+                        let t = b.table(); // FIXME "lifetime too short".
+                        if t.size() == 0 { break }
+                    };
+                    b.into_bucket()
+                }
+                Empty(b) => b.into_bucket()
+            };
+            bucket.next();
+        }
+
+        assert_eq!(self.table.size(), old_size);
+    }
+
+    /// Shrinks the capacity of the map as much as possible. It will drop
+    /// down as much as possible while maintaining the internal rules
+    /// and possibly leaving some space in accordance with the resize policy.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut map: HashMap<int, int> = HashMap::with_capacity(100);
+    /// map.insert(1, 2);
+    /// map.insert(3, 4);
+    /// assert!(map.capacity() >= 100);
+    /// map.shrink_to_fit();
+    /// assert!(map.capacity() >= 2);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn shrink_to_fit(&mut self) {
+        let min_capacity = self.resize_policy.min_capacity(self.len());
+        let min_capacity = max(min_capacity.next_power_of_two(), INITIAL_CAPACITY);
+
+        // An invalid value shouldn't make us run out of space.
+        debug_assert!(self.len() <= min_capacity);
+
+        if self.table.capacity() != min_capacity {
+            let old_table = replace(&mut self.table, RawTable::new(min_capacity));
+            let old_size = old_table.size();
+
+            // Shrink the table. Naive algorithm for resizing:
+            for (h, k, v) in old_table.into_iter() {
+                self.insert_hashed_nocheck(h, k, v);
+            }
+
+            debug_assert_eq!(self.table.size(), old_size);
+        }
+    }
+
+    /// Insert a pre-hashed key-value pair, without first checking
+    /// that there's enough room in the buckets. Returns a reference to the
+    /// newly insert value.
+    ///
+    /// If the key already exists, the hashtable will be returned untouched
+    /// and a reference to the existing element will be returned.
+    fn insert_hashed_nocheck(&mut self, hash: SafeHash, k: K, v: V) -> &mut V {
+        self.insert_or_replace_with(hash, k, v, |_, _, _| ())
+    }
+
+    fn insert_or_replace_with<'a, F>(&'a mut self,
+                                     hash: SafeHash,
+                                     k: K,
+                                     v: V,
+                                     mut found_existing: F)
+                                     -> &'a mut V where
+        F: FnMut(&mut K, &mut V, V),
+    {
+        // Worst case, we'll find one empty bucket among `size + 1` buckets.
+        let size = self.table.size();
+        let mut probe = Bucket::new(&mut self.table, hash);
+        let ib = probe.index();
+
+        loop {
+            let mut bucket = match probe.peek() {
+                Empty(bucket) => {
+                    // Found a hole!
+                    return bucket.put(hash, k, v).into_mut_refs().1;
+                }
+                Full(bucket) => bucket
+            };
+
+            // hash matches?
+            if bucket.hash() == hash {
+                // key matches?
+                if k == *bucket.read_mut().0 {
+                    let (bucket_k, bucket_v) = bucket.into_mut_refs();
+                    debug_assert!(k == *bucket_k);
+                    // Key already exists. Get its reference.
+                    found_existing(bucket_k, bucket_v, v);
+                    return bucket_v;
+                }
+            }
+
+            let robin_ib = bucket.index() as int - bucket.distance() as int;
+
+            if (ib as int) < robin_ib {
+                // Found a luckier bucket than me. Better steal his spot.
+                return robin_hood(bucket, robin_ib as usize, hash, k, v);
+            }
+
+            probe = bucket.next();
+            assert!(probe.index() != ib + size + 1);
+        }
+    }
+
+    /// An iterator visiting all keys in arbitrary order.
+    /// Iterator element type is `&'a K`.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut map = HashMap::new();
+    /// map.insert("a", 1);
+    /// map.insert("b", 2);
+    /// map.insert("c", 3);
+    ///
+    /// for key in map.keys() {
+    ///     println!("{}", key);
+    /// }
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn keys<'a>(&'a self) -> Keys<'a, K, V> {
+        fn first<A, B>((a, _): (A, B)) -> A { a }
+        let first: fn((&'a K,&'a V)) -> &'a K = first; // coerce to fn ptr
+
+        Keys { inner: self.iter().map(first) }
+    }
+
+    /// An iterator visiting all values in arbitrary order.
+    /// Iterator element type is `&'a V`.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut map = HashMap::new();
+    /// map.insert("a", 1);
+    /// map.insert("b", 2);
+    /// map.insert("c", 3);
+    ///
+    /// for val in map.values() {
+    ///     println!("{}", val);
+    /// }
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn values<'a>(&'a self) -> Values<'a, K, V> {
+        fn second<A, B>((_, b): (A, B)) -> B { b }
+        let second: fn((&'a K,&'a V)) -> &'a V = second; // coerce to fn ptr
+
+        Values { inner: self.iter().map(second) }
+    }
+
+    /// An iterator visiting all key-value pairs in arbitrary order.
+    /// Iterator element type is `(&'a K, &'a V)`.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut map = HashMap::new();
+    /// map.insert("a", 1);
+    /// map.insert("b", 2);
+    /// map.insert("c", 3);
+    ///
+    /// for (key, val) in map.iter() {
+    ///     println!("key: {} val: {}", key, val);
+    /// }
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn iter(&self) -> Iter<K, V> {
+        Iter { inner: self.table.iter() }
+    }
+
+    /// An iterator visiting all key-value pairs in arbitrary order,
+    /// with mutable references to the values.
+    /// Iterator element type is `(&'a K, &'a mut V)`.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut map = HashMap::new();
+    /// map.insert("a", 1);
+    /// map.insert("b", 2);
+    /// map.insert("c", 3);
+    ///
+    /// // Update all values
+    /// for (_, val) in map.iter_mut() {
+    ///     *val *= 2;
+    /// }
+    ///
+    /// for (key, val) in map.iter() {
+    ///     println!("key: {} val: {}", key, val);
+    /// }
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn iter_mut(&mut self) -> IterMut<K, V> {
+        IterMut { inner: self.table.iter_mut() }
+    }
+
+    /// Creates a consuming iterator, that is, one that moves each key-value
+    /// pair out of the map in arbitrary order. The map cannot be used after
+    /// calling this.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut map = HashMap::new();
+    /// map.insert("a", 1);
+    /// map.insert("b", 2);
+    /// map.insert("c", 3);
+    ///
+    /// // Not possible with .iter()
+    /// let vec: Vec<(&str, int)> = map.into_iter().collect();
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn into_iter(self) -> IntoIter<K, V> {
+        fn last_two<A, B, C>((_, b, c): (A, B, C)) -> (B, C) { (b, c) }
+        let last_two: fn((SafeHash, K, V)) -> (K, V) = last_two;
+
+        IntoIter {
+            inner: self.table.into_iter().map(last_two)
+        }
+    }
+
+    /// Gets the given key's corresponding entry in the map for in-place manipulation.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn entry(&mut self, key: K) -> Entry<K, V> {
+        // Gotta resize now.
+        self.reserve(1);
+
+        let hash = self.make_hash(&key);
+        search_entry_hashed(&mut self.table, hash, key)
+    }
+
+    /// Returns the number of elements in the map.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut a = HashMap::new();
+    /// assert_eq!(a.len(), 0);
+    /// a.insert(1, "a");
+    /// assert_eq!(a.len(), 1);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn len(&self) -> usize { self.table.size() }
+
+    /// Returns true if the map contains no elements.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut a = HashMap::new();
+    /// assert!(a.is_empty());
+    /// a.insert(1, "a");
+    /// assert!(!a.is_empty());
+    /// ```
+    #[inline]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn is_empty(&self) -> bool { self.len() == 0 }
+
+    /// Clears the map, returning all key-value pairs as an iterator. Keeps the
+    /// allocated memory for reuse.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut a = HashMap::new();
+    /// a.insert(1, "a");
+    /// a.insert(2, "b");
+    ///
+    /// for (k, v) in a.drain().take(1) {
+    ///     assert!(k == 1 || k == 2);
+    ///     assert!(v == "a" || v == "b");
+    /// }
+    ///
+    /// assert!(a.is_empty());
+    /// ```
+    #[inline]
+    #[unstable(feature = "std_misc",
+               reason = "matches collection reform specification, waiting for dust to settle")]
+    pub fn drain(&mut self) -> Drain<K, V> {
+        fn last_two<A, B, C>((_, b, c): (A, B, C)) -> (B, C) { (b, c) }
+        let last_two: fn((SafeHash, K, V)) -> (K, V) = last_two; // coerce to fn pointer
+
+        Drain {
+            inner: self.table.drain().map(last_two),
+        }
+    }
+
+    /// Clears the map, removing all key-value pairs. Keeps the allocated memory
+    /// for reuse.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut a = HashMap::new();
+    /// a.insert(1, "a");
+    /// a.clear();
+    /// assert!(a.is_empty());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn clear(&mut self) {
+        self.drain();
+    }
+
+    /// Returns a reference to the value corresponding to the key.
+    ///
+    /// The key may be any borrowed form of the map's key type, but
+    /// `Hash` and `Eq` on the borrowed form *must* match those for
+    /// the key type.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut map = HashMap::new();
+    /// map.insert(1, "a");
+    /// assert_eq!(map.get(&1), Some(&"a"));
+    /// assert_eq!(map.get(&2), None);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
+        where K: Borrow<Q>, Q: Hash<H> + Eq
+    {
+        self.search(k).map(|bucket| bucket.into_refs().1)
+    }
+
+    /// Returns true if the map contains a value for the specified key.
+    ///
+    /// The key may be any borrowed form of the map's key type, but
+    /// `Hash` and `Eq` on the borrowed form *must* match those for
+    /// the key type.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut map = HashMap::new();
+    /// map.insert(1, "a");
+    /// assert_eq!(map.contains_key(&1), true);
+    /// assert_eq!(map.contains_key(&2), false);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool
+        where K: Borrow<Q>, Q: Hash<H> + Eq
+    {
+        self.search(k).is_some()
+    }
+
+    /// Returns a mutable reference to the value corresponding to the key.
+    ///
+    /// The key may be any borrowed form of the map's key type, but
+    /// `Hash` and `Eq` on the borrowed form *must* match those for
+    /// the key type.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut map = HashMap::new();
+    /// map.insert(1, "a");
+    /// match map.get_mut(&1) {
+    ///     Some(x) => *x = "b",
+    ///     None => (),
+    /// }
+    /// assert_eq!(map[1], "b");
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V>
+        where K: Borrow<Q>, Q: Hash<H> + Eq
+    {
+        self.search_mut(k).map(|bucket| bucket.into_mut_refs().1)
+    }
+
+    /// Inserts a key-value pair from the map. If the key already had a value
+    /// present in the map, that value is returned. Otherwise, `None` is returned.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut map = HashMap::new();
+    /// assert_eq!(map.insert(37, "a"), None);
+    /// assert_eq!(map.is_empty(), false);
+    ///
+    /// map.insert(37, "b");
+    /// assert_eq!(map.insert(37, "c"), Some("b"));
+    /// assert_eq!(map[37], "c");
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn insert(&mut self, k: K, v: V) -> Option<V> {
+        let hash = self.make_hash(&k);
+        self.reserve(1);
+
+        let mut retval = None;
+        self.insert_or_replace_with(hash, k, v, |_, val_ref, val| {
+            retval = Some(replace(val_ref, val));
+        });
+        retval
+    }
+
+    /// Removes a key from the map, returning the value at the key if the key
+    /// was previously in the map.
+    ///
+    /// The key may be any borrowed form of the map's key type, but
+    /// `Hash` and `Eq` on the borrowed form *must* match those for
+    /// the key type.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut map = HashMap::new();
+    /// map.insert(1, "a");
+    /// assert_eq!(map.remove(&1), Some("a"));
+    /// assert_eq!(map.remove(&1), None);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V>
+        where K: Borrow<Q>, Q: Hash<H> + Eq
+    {
+        if self.table.size() == 0 {
+            return None
+        }
+
+        self.search_mut(k).map(|bucket| pop_internal(bucket).1)
+    }
+}
+
+fn search_entry_hashed<'a, K: Eq, V>(table: &'a mut RawTable<K,V>, hash: SafeHash, k: K)
+        -> Entry<'a, K, V>
+{
+    // Worst case, we'll find one empty bucket among `size + 1` buckets.
+    let size = table.size();
+    let mut probe = Bucket::new(table, hash);
+    let ib = probe.index();
+
+    loop {
+        let bucket = match probe.peek() {
+            Empty(bucket) => {
+                // Found a hole!
+                return Vacant(VacantEntry {
+                    hash: hash,
+                    key: k,
+                    elem: NoElem(bucket),
+                });
+            },
+            Full(bucket) => bucket
+        };
+
+        // hash matches?
+        if bucket.hash() == hash {
+            // key matches?
+            if k == *bucket.read().0 {
+                return Occupied(OccupiedEntry{
+                    elem: bucket,
+                });
+            }
+        }
+
+        let robin_ib = bucket.index() as int - bucket.distance() as int;
+
+        if (ib as int) < robin_ib {
+            // Found a luckier bucket than me. Better steal his spot.
+            return Vacant(VacantEntry {
+                hash: hash,
+                key: k,
+                elem: NeqElem(bucket, robin_ib as usize),
+            });
+        }
+
+        probe = bucket.next();
+        assert!(probe.index() != ib + size + 1);
+    }
+}
+
+impl<K, V, S, H> PartialEq for HashMap<K, V, S>
+    where K: Eq + Hash<H>, V: PartialEq,
+          S: HashState<Hasher=H>,
+          H: hash::Hasher<Output=u64>
+{
+    fn eq(&self, other: &HashMap<K, V, S>) -> bool {
+        if self.len() != other.len() { return false; }
+
+        self.iter().all(|(key, value)|
+            other.get(key).map_or(false, |v| *value == *v)
+        )
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<K, V, S, H> Eq for HashMap<K, V, S>
+    where K: Eq + Hash<H>, V: Eq,
+          S: HashState<Hasher=H>,
+          H: hash::Hasher<Output=u64>
+{}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<K, V, S, H> Debug for HashMap<K, V, S>
+    where K: Eq + Hash<H> + Debug, V: Debug,
+          S: HashState<Hasher=H>,
+          H: hash::Hasher<Output=u64>
+{
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        try!(write!(f, "HashMap {{"));
+
+        for (i, (k, v)) in self.iter().enumerate() {
+            if i != 0 { try!(write!(f, ", ")); }
+            try!(write!(f, "{:?}: {:?}", *k, *v));
+        }
+
+        write!(f, "}}")
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<K, V, S, H> Default for HashMap<K, V, S>
+    where K: Eq + Hash<H>,
+          S: HashState<Hasher=H> + Default,
+          H: hash::Hasher<Output=u64>
+{
+    fn default() -> HashMap<K, V, S> {
+        HashMap::with_hash_state(Default::default())
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<K, Q: ?Sized, V, S, H> Index<Q> for HashMap<K, V, S>
+    where K: Eq + Hash<H> + Borrow<Q>,
+          Q: Eq + Hash<H>,
+          S: HashState<Hasher=H>,
+          H: hash::Hasher<Output=u64>
+{
+    type Output = V;
+
+    #[inline]
+    fn index<'a>(&'a self, index: &Q) -> &'a V {
+        self.get(index).expect("no entry found for key")
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<K, V, S, H, Q: ?Sized> IndexMut<Q> for HashMap<K, V, S>
+    where K: Eq + Hash<H> + Borrow<Q>,
+          Q: Eq + Hash<H>,
+          S: HashState<Hasher=H>,
+          H: hash::Hasher<Output=u64>
+{
+    #[inline]
+    fn index_mut<'a>(&'a mut self, index: &Q) -> &'a mut V {
+        self.get_mut(index).expect("no entry found for key")
+    }
+}
+
+/// HashMap iterator.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Iter<'a, K: 'a, V: 'a> {
+    inner: table::Iter<'a, K, V>
+}
+
+// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
+impl<'a, K, V> Clone for Iter<'a, K, V> {
+    fn clone(&self) -> Iter<'a, K, V> {
+        Iter {
+            inner: self.inner.clone()
+        }
+    }
+}
+
+/// HashMap mutable values iterator.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct IterMut<'a, K: 'a, V: 'a> {
+    inner: table::IterMut<'a, K, V>
+}
+
+/// HashMap move iterator.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct IntoIter<K, V> {
+    inner: iter::Map<table::IntoIter<K, V>, fn((SafeHash, K, V)) -> (K, V)>
+}
+
+/// HashMap keys iterator.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Keys<'a, K: 'a, V: 'a> {
+    inner: Map<Iter<'a, K, V>, fn((&'a K, &'a V)) -> &'a K>
+}
+
+// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
+impl<'a, K, V> Clone for Keys<'a, K, V> {
+    fn clone(&self) -> Keys<'a, K, V> {
+        Keys {
+            inner: self.inner.clone()
+        }
+    }
+}
+
+/// HashMap values iterator.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Values<'a, K: 'a, V: 'a> {
+    inner: Map<Iter<'a, K, V>, fn((&'a K, &'a V)) -> &'a V>
+}
+
+// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
+impl<'a, K, V> Clone for Values<'a, K, V> {
+    fn clone(&self) -> Values<'a, K, V> {
+        Values {
+            inner: self.inner.clone()
+        }
+    }
+}
+
+/// HashMap drain iterator.
+#[unstable(feature = "std_misc",
+           reason = "matches collection reform specification, waiting for dust to settle")]
+pub struct Drain<'a, K: 'a, V: 'a> {
+    inner: iter::Map<table::Drain<'a, K, V>, fn((SafeHash, K, V)) -> (K, V)>
+}
+
+/// A view into a single occupied location in a HashMap.
+#[unstable(feature = "std_misc",
+           reason = "precise API still being fleshed out")]
+pub struct OccupiedEntry<'a, K: 'a, V: 'a> {
+    elem: FullBucket<K, V, &'a mut RawTable<K, V>>,
+}
+
+/// A view into a single empty location in a HashMap.
+#[unstable(feature = "std_misc",
+           reason = "precise API still being fleshed out")]
+pub struct VacantEntry<'a, K: 'a, V: 'a> {
+    hash: SafeHash,
+    key: K,
+    elem: VacantEntryState<K, V, &'a mut RawTable<K, V>>,
+}
+
+/// A view into a single location in a map, which may be vacant or occupied.
+#[unstable(feature = "std_misc",
+           reason = "precise API still being fleshed out")]
+pub enum Entry<'a, K: 'a, V: 'a> {
+    /// An occupied Entry.
+    Occupied(OccupiedEntry<'a, K, V>),
+    /// A vacant Entry.
+    Vacant(VacantEntry<'a, K, V>),
+}
+
+/// Possible states of a VacantEntry.
+enum VacantEntryState<K, V, M> {
+    /// The index is occupied, but the key to insert has precedence,
+    /// and will kick the current one out on insertion.
+    NeqElem(FullBucket<K, V, M>, usize),
+    /// The index is genuinely vacant.
+    NoElem(EmptyBucket<K, V, M>),
+}
+
+impl<'a, K, V, S, H> IntoIterator for &'a HashMap<K, V, S>
+    where K: Eq + Hash<H>,
+          S: HashState<Hasher=H>,
+          H: hash::Hasher<Output=u64>
+{
+    type Item = (&'a K, &'a V);
+    type IntoIter = Iter<'a, K, V>;
+
+    fn into_iter(self) -> Iter<'a, K, V> {
+        self.iter()
+    }
+}
+
+impl<'a, K, V, S, H> IntoIterator for &'a mut HashMap<K, V, S>
+    where K: Eq + Hash<H>,
+          S: HashState<Hasher=H>,
+          H: hash::Hasher<Output=u64>
+{
+    type Item = (&'a K, &'a mut V);
+    type IntoIter = IterMut<'a, K, V>;
+
+    fn into_iter(mut self) -> IterMut<'a, K, V> {
+        self.iter_mut()
+    }
+}
+
+impl<K, V, S, H> IntoIterator for HashMap<K, V, S>
+    where K: Eq + Hash<H>,
+          S: HashState<Hasher=H>,
+          H: hash::Hasher<Output=u64>
+{
+    type Item = (K, V);
+    type IntoIter = IntoIter<K, V>;
+
+    fn into_iter(self) -> IntoIter<K, V> {
+        self.into_iter()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, K, V> Iterator for Iter<'a, K, V> {
+    type Item = (&'a K, &'a V);
+
+    #[inline] fn next(&mut self) -> Option<(&'a K, &'a V)> { self.inner.next() }
+    #[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
+}
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {
+    #[inline] fn len(&self) -> usize { self.inner.len() }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, K, V> Iterator for IterMut<'a, K, V> {
+    type Item = (&'a K, &'a mut V);
+
+    #[inline] fn next(&mut self) -> Option<(&'a K, &'a mut V)> { self.inner.next() }
+    #[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
+}
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {
+    #[inline] fn len(&self) -> usize { self.inner.len() }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<K, V> Iterator for IntoIter<K, V> {
+    type Item = (K, V);
+
+    #[inline] fn next(&mut self) -> Option<(K, V)> { self.inner.next() }
+    #[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
+}
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<K, V> ExactSizeIterator for IntoIter<K, V> {
+    #[inline] fn len(&self) -> usize { self.inner.len() }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, K, V> Iterator for Keys<'a, K, V> {
+    type Item = &'a K;
+
+    #[inline] fn next(&mut self) -> Option<(&'a K)> { self.inner.next() }
+    #[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
+}
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, K, V> ExactSizeIterator for Keys<'a, K, V> {
+    #[inline] fn len(&self) -> usize { self.inner.len() }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, K, V> Iterator for Values<'a, K, V> {
+    type Item = &'a V;
+
+    #[inline] fn next(&mut self) -> Option<(&'a V)> { self.inner.next() }
+    #[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
+}
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> {
+    #[inline] fn len(&self) -> usize { self.inner.len() }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, K, V> Iterator for Drain<'a, K, V> {
+    type Item = (K, V);
+
+    #[inline] fn next(&mut self) -> Option<(K, V)> { self.inner.next() }
+    #[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
+}
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, K, V> ExactSizeIterator for Drain<'a, K, V> {
+    #[inline] fn len(&self) -> usize { self.inner.len() }
+}
+
+#[unstable(feature = "std_misc",
+           reason = "matches collection reform v2 specification, waiting for dust to settle")]
+impl<'a, K, V> Entry<'a, K, V> {
+    /// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant.
+    pub fn get(self) -> Result<&'a mut V, VacantEntry<'a, K, V>> {
+        match self {
+            Occupied(entry) => Ok(entry.into_mut()),
+            Vacant(entry) => Err(entry),
+        }
+    }
+}
+
+impl<'a, K, V> OccupiedEntry<'a, K, V> {
+    /// Gets a reference to the value in the entry.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn get(&self) -> &V {
+        self.elem.read().1
+    }
+
+    /// Gets a mutable reference to the value in the entry.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn get_mut(&mut self) -> &mut V {
+        self.elem.read_mut().1
+    }
+
+    /// Converts the OccupiedEntry into a mutable reference to the value in the entry
+    /// with a lifetime bound to the map itself
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn into_mut(self) -> &'a mut V {
+        self.elem.into_mut_refs().1
+    }
+
+    /// Sets the value of the entry, and returns the entry's old value
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn insert(&mut self, mut value: V) -> V {
+        let old_value = self.get_mut();
+        mem::swap(&mut value, old_value);
+        value
+    }
+
+    /// Takes the value out of the entry, and returns it
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn remove(self) -> V {
+        pop_internal(self.elem).1
+    }
+}
+
+impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> {
+    /// Sets the value of the entry with the VacantEntry's key,
+    /// and returns a mutable reference to it
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn insert(self, value: V) -> &'a mut V {
+        match self.elem {
+            NeqElem(bucket, ib) => {
+                robin_hood(bucket, ib, self.hash, self.key, value)
+            }
+            NoElem(bucket) => {
+                bucket.put(self.hash, self.key, value).into_mut_refs().1
+            }
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<K, V, S, H> FromIterator<(K, V)> for HashMap<K, V, S>
+    where K: Eq + Hash<H>,
+          S: HashState<Hasher=H> + Default,
+          H: hash::Hasher<Output=u64>
+{
+    fn from_iter<T: IntoIterator<Item=(K, V)>>(iter: T) -> HashMap<K, V, S> {
+        let iter = iter.into_iter();
+        let lower = iter.size_hint().0;
+        let mut map = HashMap::with_capacity_and_hash_state(lower,
+                                                            Default::default());
+        map.extend(iter);
+        map
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<K, V, S, H> Extend<(K, V)> for HashMap<K, V, S>
+    where K: Eq + Hash<H>,
+          S: HashState<Hasher=H>,
+          H: hash::Hasher<Output=u64>
+{
+    fn extend<T: IntoIterator<Item=(K, V)>>(&mut self, iter: T) {
+        for (k, v) in iter {
+            self.insert(k, v);
+        }
+    }
+}
+
+
+/// `RandomState` is the default state for `HashMap` types.
+///
+/// A particular instance `RandomState` will create the same instances of
+/// `Hasher`, but the hashers created by two different `RandomState`
+/// instances are unlikely to produce the same result for the same values.
+#[derive(Clone)]
+#[unstable(feature = "std_misc",
+           reason = "hashing an hash maps may be altered")]
+pub struct RandomState {
+    k0: u64,
+    k1: u64,
+}
+
+#[unstable(feature = "std_misc",
+           reason = "hashing an hash maps may be altered")]
+impl RandomState {
+    /// Construct a new `RandomState` that is initialized with random keys.
+    #[inline]
+    #[allow(deprecated)]
+    pub fn new() -> RandomState {
+        let mut r = rand::thread_rng();
+        RandomState { k0: r.gen(), k1: r.gen() }
+    }
+}
+
+#[unstable(feature = "std_misc",
+           reason = "hashing an hash maps may be altered")]
+impl HashState for RandomState {
+    type Hasher = Hasher;
+    fn hasher(&self) -> Hasher {
+        Hasher { inner: SipHasher::new_with_keys(self.k0, self.k1) }
+    }
+}
+
+#[unstable(feature = "std_misc",
+           reason = "hashing an hash maps may be altered")]
+impl Default for RandomState {
+    #[inline]
+    fn default() -> RandomState {
+        RandomState::new()
+    }
+}
+
+/// A hasher implementation which is generated from `RandomState` instances.
+///
+/// This is the default hasher used in a `HashMap` to hash keys. Types do not
+/// typically declare an ability to explicitly hash into this particular type,
+/// but rather in a `H: hash::Writer` type parameter.
+#[unstable(feature = "std_misc",
+           reason = "hashing an hash maps may be altered")]
+pub struct Hasher { inner: SipHasher }
+
+impl hash::Writer for Hasher {
+    fn write(&mut self, data: &[u8]) {
+        hash::Writer::write(&mut self.inner, data)
+    }
+}
+
+impl hash::Hasher for Hasher {
+    type Output = u64;
+    fn reset(&mut self) { hash::Hasher::reset(&mut self.inner) }
+    fn finish(&self) -> u64 { self.inner.finish() }
+}
+
+#[cfg(test)]
+mod test_map {
+    use prelude::v1::*;
+
+    use super::HashMap;
+    use super::Entry::{Occupied, Vacant};
+    use iter::{range_inclusive, range_step_inclusive, repeat};
+    use cell::RefCell;
+    use rand::{weak_rng, Rng};
+
+    #[test]
+    fn test_create_capacity_zero() {
+        let mut m = HashMap::with_capacity(0);
+
+        assert!(m.insert(1, 1).is_none());
+
+        assert!(m.contains_key(&1));
+        assert!(!m.contains_key(&0));
+    }
+
+    #[test]
+    fn test_insert() {
+        let mut m = HashMap::new();
+        assert_eq!(m.len(), 0);
+        assert!(m.insert(1, 2).is_none());
+        assert_eq!(m.len(), 1);
+        assert!(m.insert(2, 4).is_none());
+        assert_eq!(m.len(), 2);
+        assert_eq!(*m.get(&1).unwrap(), 2);
+        assert_eq!(*m.get(&2).unwrap(), 4);
+    }
+
+    thread_local! { static DROP_VECTOR: RefCell<Vec<int>> = RefCell::new(Vec::new()) }
+
+    #[derive(Hash, PartialEq, Eq)]
+    struct Dropable {
+        k: usize
+    }
+
+    impl Dropable {
+        fn new(k: usize) -> Dropable {
+            DROP_VECTOR.with(|slot| {
+                slot.borrow_mut()[k] += 1;
+            });
+
+            Dropable { k: k }
+        }
+    }
+
+    impl Drop for Dropable {
+        fn drop(&mut self) {
+            DROP_VECTOR.with(|slot| {
+                slot.borrow_mut()[self.k] -= 1;
+            });
+        }
+    }
+
+    impl Clone for Dropable {
+        fn clone(&self) -> Dropable {
+            Dropable::new(self.k)
+        }
+    }
+
+    #[test]
+    fn test_drops() {
+        DROP_VECTOR.with(|slot| {
+            *slot.borrow_mut() = repeat(0).take(200).collect();
+        });
+
+        {
+            let mut m = HashMap::new();
+
+            DROP_VECTOR.with(|v| {
+                for i in 0..200 {
+                    assert_eq!(v.borrow()[i], 0);
+                }
+            });
+
+            for i in 0..100 {
+                let d1 = Dropable::new(i);
+                let d2 = Dropable::new(i+100);
+                m.insert(d1, d2);
+            }
+
+            DROP_VECTOR.with(|v| {
+                for i in 0..200 {
+                    assert_eq!(v.borrow()[i], 1);
+                }
+            });
+
+            for i in 0..50 {
+                let k = Dropable::new(i);
+                let v = m.remove(&k);
+
+                assert!(v.is_some());
+
+                DROP_VECTOR.with(|v| {
+                    assert_eq!(v.borrow()[i], 1);
+                    assert_eq!(v.borrow()[i+100], 1);
+                });
+            }
+
+            DROP_VECTOR.with(|v| {
+                for i in 0..50 {
+                    assert_eq!(v.borrow()[i], 0);
+                    assert_eq!(v.borrow()[i+100], 0);
+                }
+
+                for i in 50..100 {
+                    assert_eq!(v.borrow()[i], 1);
+                    assert_eq!(v.borrow()[i+100], 1);
+                }
+            });
+        }
+
+        DROP_VECTOR.with(|v| {
+            for i in 0..200 {
+                assert_eq!(v.borrow()[i], 0);
+            }
+        });
+    }
+
+    #[test]
+    fn test_move_iter_drops() {
+        DROP_VECTOR.with(|v| {
+            *v.borrow_mut() = repeat(0).take(200).collect();
+        });
+
+        let hm = {
+            let mut hm = HashMap::new();
+
+            DROP_VECTOR.with(|v| {
+                for i in 0..200 {
+                    assert_eq!(v.borrow()[i], 0);
+                }
+            });
+
+            for i in 0..100 {
+                let d1 = Dropable::new(i);
+                let d2 = Dropable::new(i+100);
+                hm.insert(d1, d2);
+            }
+
+            DROP_VECTOR.with(|v| {
+                for i in 0..200 {
+                    assert_eq!(v.borrow()[i], 1);
+                }
+            });
+
+            hm
+        };
+
+        // By the way, ensure that cloning doesn't screw up the dropping.
+        drop(hm.clone());
+
+        {
+            let mut half = hm.into_iter().take(50);
+
+            DROP_VECTOR.with(|v| {
+                for i in 0..200 {
+                    assert_eq!(v.borrow()[i], 1);
+                }
+            });
+
+            for _ in half.by_ref() {}
+
+            DROP_VECTOR.with(|v| {
+                let nk = (0..100).filter(|&i| {
+                    v.borrow()[i] == 1
+                }).count();
+
+                let nv = (0..100).filter(|&i| {
+                    v.borrow()[i+100] == 1
+                }).count();
+
+                assert_eq!(nk, 50);
+                assert_eq!(nv, 50);
+            });
+        };
+
+        DROP_VECTOR.with(|v| {
+            for i in 0..200 {
+                assert_eq!(v.borrow()[i], 0);
+            }
+        });
+    }
+
+    #[test]
+    fn test_empty_pop() {
+        let mut m: HashMap<int, bool> = HashMap::new();
+        assert_eq!(m.remove(&0), None);
+    }
+
+    #[test]
+    fn test_lots_of_insertions() {
+        let mut m = HashMap::new();
+
+        // Try this a few times to make sure we never screw up the hashmap's
+        // internal state.
+        for _ in 0..10 {
+            assert!(m.is_empty());
+
+            for i in range_inclusive(1, 1000) {
+                assert!(m.insert(i, i).is_none());
+
+                for j in range_inclusive(1, i) {
+                    let r = m.get(&j);
+                    assert_eq!(r, Some(&j));
+                }
+
+                for j in range_inclusive(i+1, 1000) {
+                    let r = m.get(&j);
+                    assert_eq!(r, None);
+                }
+            }
+
+            for i in range_inclusive(1001, 2000) {
+                assert!(!m.contains_key(&i));
+            }
+
+            // remove forwards
+            for i in range_inclusive(1, 1000) {
+                assert!(m.remove(&i).is_some());
+
+                for j in range_inclusive(1, i) {
+                    assert!(!m.contains_key(&j));
+                }
+
+                for j in range_inclusive(i+1, 1000) {
+                    assert!(m.contains_key(&j));
+                }
+            }
+
+            for i in range_inclusive(1, 1000) {
+                assert!(!m.contains_key(&i));
+            }
+
+            for i in range_inclusive(1, 1000) {
+                assert!(m.insert(i, i).is_none());
+            }
+
+            // remove backwards
+            for i in range_step_inclusive(1000, 1, -1) {
+                assert!(m.remove(&i).is_some());
+
+                for j in range_inclusive(i, 1000) {
+                    assert!(!m.contains_key(&j));
+                }
+
+                for j in range_inclusive(1, i-1) {
+                    assert!(m.contains_key(&j));
+                }
+            }
+        }
+    }
+
+    #[test]
+    fn test_find_mut() {
+        let mut m = HashMap::new();
+        assert!(m.insert(1, 12).is_none());
+        assert!(m.insert(2, 8).is_none());
+        assert!(m.insert(5, 14).is_none());
+        let new = 100;
+        match m.get_mut(&5) {
+            None => panic!(), Some(x) => *x = new
+        }
+        assert_eq!(m.get(&5), Some(&new));
+    }
+
+    #[test]
+    fn test_insert_overwrite() {
+        let mut m = HashMap::new();
+        assert!(m.insert(1, 2).is_none());
+        assert_eq!(*m.get(&1).unwrap(), 2);
+        assert!(!m.insert(1, 3).is_none());
+        assert_eq!(*m.get(&1).unwrap(), 3);
+    }
+
+    #[test]
+    fn test_insert_conflicts() {
+        let mut m = HashMap::with_capacity(4);
+        assert!(m.insert(1, 2).is_none());
+        assert!(m.insert(5, 3).is_none());
+        assert!(m.insert(9, 4).is_none());
+        assert_eq!(*m.get(&9).unwrap(), 4);
+        assert_eq!(*m.get(&5).unwrap(), 3);
+        assert_eq!(*m.get(&1).unwrap(), 2);
+    }
+
+    #[test]
+    fn test_conflict_remove() {
+        let mut m = HashMap::with_capacity(4);
+        assert!(m.insert(1, 2).is_none());
+        assert_eq!(*m.get(&1).unwrap(), 2);
+        assert!(m.insert(5, 3).is_none());
+        assert_eq!(*m.get(&1).unwrap(), 2);
+        assert_eq!(*m.get(&5).unwrap(), 3);
+        assert!(m.insert(9, 4).is_none());
+        assert_eq!(*m.get(&1).unwrap(), 2);
+        assert_eq!(*m.get(&5).unwrap(), 3);
+        assert_eq!(*m.get(&9).unwrap(), 4);
+        assert!(m.remove(&1).is_some());
+        assert_eq!(*m.get(&9).unwrap(), 4);
+        assert_eq!(*m.get(&5).unwrap(), 3);
+    }
+
+    #[test]
+    fn test_is_empty() {
+        let mut m = HashMap::with_capacity(4);
+        assert!(m.insert(1, 2).is_none());
+        assert!(!m.is_empty());
+        assert!(m.remove(&1).is_some());
+        assert!(m.is_empty());
+    }
+
+    #[test]
+    fn test_pop() {
+        let mut m = HashMap::new();
+        m.insert(1, 2);
+        assert_eq!(m.remove(&1), Some(2));
+        assert_eq!(m.remove(&1), None);
+    }
+
+    #[test]
+    fn test_iterate() {
+        let mut m = HashMap::with_capacity(4);
+        for i in 0..32 {
+            assert!(m.insert(i, i*2).is_none());
+        }
+        assert_eq!(m.len(), 32);
+
+        let mut observed: u32 = 0;
+
+        for (k, v) in &m {
+            assert_eq!(*v, *k * 2);
+            observed |= 1 << *k;
+        }
+        assert_eq!(observed, 0xFFFF_FFFF);
+    }
+
+    #[test]
+    fn test_keys() {
+        let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
+        let map: HashMap<_, _> = vec.into_iter().collect();
+        let keys: Vec<_> = map.keys().cloned().collect();
+        assert_eq!(keys.len(), 3);
+        assert!(keys.contains(&1));
+        assert!(keys.contains(&2));
+        assert!(keys.contains(&3));
+    }
+
+    #[test]
+    fn test_values() {
+        let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
+        let map: HashMap<_, _> = vec.into_iter().collect();
+        let values: Vec<_> = map.values().cloned().collect();
+        assert_eq!(values.len(), 3);
+        assert!(values.contains(&'a'));
+        assert!(values.contains(&'b'));
+        assert!(values.contains(&'c'));
+    }
+
+    #[test]
+    fn test_find() {
+        let mut m = HashMap::new();
+        assert!(m.get(&1).is_none());
+        m.insert(1, 2);
+        match m.get(&1) {
+            None => panic!(),
+            Some(v) => assert_eq!(*v, 2)
+        }
+    }
+
+    #[test]
+    fn test_eq() {
+        let mut m1 = HashMap::new();
+        m1.insert(1, 2);
+        m1.insert(2, 3);
+        m1.insert(3, 4);
+
+        let mut m2 = HashMap::new();
+        m2.insert(1, 2);
+        m2.insert(2, 3);
+
+        assert!(m1 != m2);
+
+        m2.insert(3, 4);
+
+        assert_eq!(m1, m2);
+    }
+
+    #[test]
+    fn test_show() {
+        let mut map = HashMap::new();
+        let empty: HashMap<i32, i32> = HashMap::new();
+
+        map.insert(1, 2);
+        map.insert(3, 4);
+
+        let map_str = format!("{:?}", map);
+
+        assert!(map_str == "HashMap {1: 2, 3: 4}" ||
+                map_str == "HashMap {3: 4, 1: 2}");
+        assert_eq!(format!("{:?}", empty), "HashMap {}");
+    }
+
+    #[test]
+    fn test_expand() {
+        let mut m = HashMap::new();
+
+        assert_eq!(m.len(), 0);
+        assert!(m.is_empty());
+
+        let mut i = 0;
+        let old_cap = m.table.capacity();
+        while old_cap == m.table.capacity() {
+            m.insert(i, i);
+            i += 1;
+        }
+
+        assert_eq!(m.len(), i);
+        assert!(!m.is_empty());
+    }
+
+    #[test]
+    fn test_behavior_resize_policy() {
+        let mut m = HashMap::new();
+
+        assert_eq!(m.len(), 0);
+        assert_eq!(m.table.capacity(), 0);
+        assert!(m.is_empty());
+
+        m.insert(0, 0);
+        m.remove(&0);
+        assert!(m.is_empty());
+        let initial_cap = m.table.capacity();
+        m.reserve(initial_cap);
+        let cap = m.table.capacity();
+
+        assert_eq!(cap, initial_cap * 2);
+
+        let mut i = 0;
+        for _ in 0..cap * 3 / 4 {
+            m.insert(i, i);
+            i += 1;
+        }
+        // three quarters full
+
+        assert_eq!(m.len(), i);
+        assert_eq!(m.table.capacity(), cap);
+
+        for _ in 0..cap / 4 {
+            m.insert(i, i);
+            i += 1;
+        }
+        // half full
+
+        let new_cap = m.table.capacity();
+        assert_eq!(new_cap, cap * 2);
+
+        for _ in 0..cap / 2 - 1 {
+            i -= 1;
+            m.remove(&i);
+            assert_eq!(m.table.capacity(), new_cap);
+        }
+        // A little more than one quarter full.
+        m.shrink_to_fit();
+        assert_eq!(m.table.capacity(), cap);
+        // again, a little more than half full
+        for _ in 0..cap / 2 - 1 {
+            i -= 1;
+            m.remove(&i);
+        }
+        m.shrink_to_fit();
+
+        assert_eq!(m.len(), i);
+        assert!(!m.is_empty());
+        assert_eq!(m.table.capacity(), initial_cap);
+    }
+
+    #[test]
+    fn test_reserve_shrink_to_fit() {
+        let mut m = HashMap::new();
+        m.insert(0, 0);
+        m.remove(&0);
+        assert!(m.capacity() >= m.len());
+        for i in 0..128 {
+            m.insert(i, i);
+        }
+        m.reserve(256);
+
+        let usable_cap = m.capacity();
+        for i in 128..(128 + 256) {
+            m.insert(i, i);
+            assert_eq!(m.capacity(), usable_cap);
+        }
+
+        for i in 100..(128 + 256) {
+            assert_eq!(m.remove(&i), Some(i));
+        }
+        m.shrink_to_fit();
+
+        assert_eq!(m.len(), 100);
+        assert!(!m.is_empty());
+        assert!(m.capacity() >= m.len());
+
+        for i in 0..100 {
+            assert_eq!(m.remove(&i), Some(i));
+        }
+        m.shrink_to_fit();
+        m.insert(0, 0);
+
+        assert_eq!(m.len(), 1);
+        assert!(m.capacity() >= m.len());
+        assert_eq!(m.remove(&0), Some(0));
+    }
+
+    #[test]
+    fn test_from_iter() {
+        let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
+
+        let map: HashMap<_, _> = xs.iter().cloned().collect();
+
+        for &(k, v) in &xs {
+            assert_eq!(map.get(&k), Some(&v));
+        }
+    }
+
+    #[test]
+    fn test_size_hint() {
+        let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
+
+        let map: HashMap<_, _>  = xs.iter().cloned().collect();
+
+        let mut iter = map.iter();
+
+        for _ in iter.by_ref().take(3) {}
+
+        assert_eq!(iter.size_hint(), (3, Some(3)));
+    }
+
+    #[test]
+    fn test_iter_len() {
+        let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
+
+        let map: HashMap<_, _>  = xs.iter().cloned().collect();
+
+        let mut iter = map.iter();
+
+        for _ in iter.by_ref().take(3) {}
+
+        assert_eq!(iter.len(), 3);
+    }
+
+    #[test]
+    fn test_mut_size_hint() {
+        let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
+
+        let mut map: HashMap<_, _>  = xs.iter().cloned().collect();
+
+        let mut iter = map.iter_mut();
+
+        for _ in iter.by_ref().take(3) {}
+
+        assert_eq!(iter.size_hint(), (3, Some(3)));
+    }
+
+    #[test]
+    fn test_iter_mut_len() {
+        let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
+
+        let mut map: HashMap<_, _>  = xs.iter().cloned().collect();
+
+        let mut iter = map.iter_mut();
+
+        for _ in iter.by_ref().take(3) {}
+
+        assert_eq!(iter.len(), 3);
+    }
+
+    #[test]
+    fn test_index() {
+        let mut map = HashMap::new();
+
+        map.insert(1, 2);
+        map.insert(2, 1);
+        map.insert(3, 4);
+
+        assert_eq!(map[2], 1);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_index_nonexistent() {
+        let mut map = HashMap::new();
+
+        map.insert(1, 2);
+        map.insert(2, 1);
+        map.insert(3, 4);
+
+        map[4];
+    }
+
+    #[test]
+    fn test_entry(){
+        let xs = [(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
+
+        let mut map: HashMap<_, _> = xs.iter().cloned().collect();
+
+        // Existing key (insert)
+        match map.entry(1) {
+            Vacant(_) => unreachable!(),
+            Occupied(mut view) => {
+                assert_eq!(view.get(), &10);
+                assert_eq!(view.insert(100), 10);
+            }
+        }
+        assert_eq!(map.get(&1).unwrap(), &100);
+        assert_eq!(map.len(), 6);
+
+
+        // Existing key (update)
+        match map.entry(2) {
+            Vacant(_) => unreachable!(),
+            Occupied(mut view) => {
+                let v = view.get_mut();
+                let new_v = (*v) * 10;
+                *v = new_v;
+            }
+        }
+        assert_eq!(map.get(&2).unwrap(), &200);
+        assert_eq!(map.len(), 6);
+
+        // Existing key (take)
+        match map.entry(3) {
+            Vacant(_) => unreachable!(),
+            Occupied(view) => {
+                assert_eq!(view.remove(), 30);
+            }
+        }
+        assert_eq!(map.get(&3), None);
+        assert_eq!(map.len(), 5);
+
+
+        // Inexistent key (insert)
+        match map.entry(10) {
+            Occupied(_) => unreachable!(),
+            Vacant(view) => {
+                assert_eq!(*view.insert(1000), 1000);
+            }
+        }
+        assert_eq!(map.get(&10).unwrap(), &1000);
+        assert_eq!(map.len(), 6);
+    }
+
+    #[test]
+    fn test_entry_take_doesnt_corrupt() {
+        // Test for #19292
+        fn check(m: &HashMap<isize, ()>) {
+            for k in m.keys() {
+                assert!(m.contains_key(k),
+                        "{} is in keys() but not in the map?", k);
+            }
+        }
+
+        let mut m = HashMap::new();
+        let mut rng = weak_rng();
+
+        // Populate the map with some items.
+        for _ in 0..50 {
+            let x = rng.gen_range(-10, 10);
+            m.insert(x, ());
+        }
+
+        for i in 0..1000 {
+            let x = rng.gen_range(-10, 10);
+            match m.entry(x) {
+                Vacant(_) => {},
+                Occupied(e) => {
+                    println!("{}: remove {}", i, x);
+                    e.remove();
+                },
+            }
+
+            check(&m);
+        }
+    }
+}
diff --git a/src/libstd/collections/hash/mod.rs b/src/libstd/collections/hash/mod.rs
index 47e300af269..39c1458b720 100644
--- a/src/libstd/collections/hash/mod.rs
+++ b/src/libstd/collections/hash/mod.rs
@@ -12,6 +12,14 @@
 
 mod bench;
 mod table;
+#[cfg(stage0)]
+#[path = "map_stage0.rs"]
 pub mod map;
+#[cfg(not(stage0))]
+pub mod map;
+#[cfg(stage0)]
+#[path = "set_stage0.rs"]
+pub mod set;
+#[cfg(not(stage0))]
 pub mod set;
 pub mod state;
diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs
index 5fbbcb3b347..e0631a64d44 100644
--- a/src/libstd/collections/hash/set.rs
+++ b/src/libstd/collections/hash/set.rs
@@ -10,21 +10,21 @@
 //
 // ignore-lexer-test FIXME #15883
 
-use borrow::BorrowFrom;
+use borrow::Borrow;
 use clone::Clone;
 use cmp::{Eq, PartialEq};
 use core::marker::Sized;
 use default::Default;
 use fmt::Debug;
 use fmt;
-use hash::{self, Hash};
+use hash::Hash;
 use iter::{
     Iterator, IntoIterator, ExactSizeIterator, IteratorExt, FromIterator, Map, Chain, Extend,
 };
 use ops::{BitOr, BitAnd, BitXor, Sub};
 use option::Option::{Some, None, self};
 
-use super::map::{self, HashMap, Keys, INITIAL_CAPACITY, RandomState, Hasher};
+use super::map::{self, HashMap, Keys, INITIAL_CAPACITY, RandomState};
 use super::state::HashState;
 
 // Future Optimization (FIXME!)
@@ -97,7 +97,7 @@ pub struct HashSet<T, S = RandomState> {
     map: HashMap<T, (), S>
 }
 
-impl<T: Hash<Hasher> + Eq> HashSet<T, RandomState> {
+impl<T: Hash + Eq> HashSet<T, RandomState> {
     /// Create an empty HashSet.
     ///
     /// # Example
@@ -128,10 +128,8 @@ impl<T: Hash<Hasher> + Eq> HashSet<T, RandomState> {
     }
 }
 
-impl<T, S, H> HashSet<T, S>
-    where T: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
+impl<T, S> HashSet<T, S>
+    where T: Eq + Hash, S: HashState
 {
     /// Creates a new empty hash set which will use the given hasher to hash
     /// keys.
@@ -462,7 +460,7 @@ impl<T, S, H> HashSet<T, S>
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool
-        where Q: BorrowFrom<T> + Hash<H> + Eq
+        where T: Borrow<Q>, Q: Hash + Eq
     {
         self.map.contains_key(value)
     }
@@ -572,17 +570,15 @@ impl<T, S, H> HashSet<T, S>
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool
-        where Q: BorrowFrom<T> + Hash<H> + Eq
+        where T: Borrow<Q>, Q: Hash + Eq
     {
         self.map.remove(value).is_some()
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, S, H> PartialEq for HashSet<T, S>
-    where T: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
+impl<T, S> PartialEq for HashSet<T, S>
+    where T: Eq + Hash, S: HashState
 {
     fn eq(&self, other: &HashSet<T, S>) -> bool {
         if self.len() != other.len() { return false; }
@@ -592,17 +588,14 @@ impl<T, S, H> PartialEq for HashSet<T, S>
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, S, H> Eq for HashSet<T, S>
-    where T: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
+impl<T, S> Eq for HashSet<T, S>
+    where T: Eq + Hash, S: HashState
 {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, S, H> fmt::Debug for HashSet<T, S>
-    where T: Eq + Hash<H> + fmt::Debug,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
+impl<T, S> fmt::Debug for HashSet<T, S>
+    where T: Eq + Hash + fmt::Debug,
+          S: HashState
 {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         try!(write!(f, "HashSet {{"));
@@ -617,12 +610,12 @@ impl<T, S, H> fmt::Debug for HashSet<T, S>
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, S, H> FromIterator<T> for HashSet<T, S>
-    where T: Eq + Hash<H>,
-          S: HashState<Hasher=H> + Default,
-          H: hash::Hasher<Output=u64>
+impl<T, S> FromIterator<T> for HashSet<T, S>
+    where T: Eq + Hash,
+          S: HashState + Default,
 {
-    fn from_iter<I: Iterator<Item=T>>(iter: I) -> HashSet<T, S> {
+    fn from_iter<I: IntoIterator<Item=T>>(iterable: I) -> HashSet<T, S> {
+        let iter = iterable.into_iter();
         let lower = iter.size_hint().0;
         let mut set = HashSet::with_capacity_and_hash_state(lower, Default::default());
         set.extend(iter);
@@ -631,12 +624,11 @@ impl<T, S, H> FromIterator<T> for HashSet<T, S>
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, S, H> Extend<T> for HashSet<T, S>
-    where T: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
+impl<T, S> Extend<T> for HashSet<T, S>
+    where T: Eq + Hash,
+          S: HashState,
 {
-    fn extend<I: Iterator<Item=T>>(&mut self, iter: I) {
+    fn extend<I: IntoIterator<Item=T>>(&mut self, iter: I) {
         for k in iter {
             self.insert(k);
         }
@@ -644,10 +636,9 @@ impl<T, S, H> Extend<T> for HashSet<T, S>
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, S, H> Default for HashSet<T, S>
-    where T: Eq + Hash<H>,
-          S: HashState<Hasher=H> + Default,
-          H: hash::Hasher<Output=u64>
+impl<T, S> Default for HashSet<T, S>
+    where T: Eq + Hash,
+          S: HashState + Default,
 {
     #[stable(feature = "rust1", since = "1.0.0")]
     fn default() -> HashSet<T, S> {
@@ -656,10 +647,9 @@ impl<T, S, H> Default for HashSet<T, S>
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, 'b, T, S, H> BitOr<&'b HashSet<T, S>> for &'a HashSet<T, S>
-    where T: Eq + Hash<H> + Clone,
-          S: HashState<Hasher=H> + Default,
-          H: hash::Hasher<Output=u64>
+impl<'a, 'b, T, S> BitOr<&'b HashSet<T, S>> for &'a HashSet<T, S>
+    where T: Eq + Hash + Clone,
+          S: HashState + Default,
 {
     type Output = HashSet<T, S>;
 
@@ -689,10 +679,9 @@ impl<'a, 'b, T, S, H> BitOr<&'b HashSet<T, S>> for &'a HashSet<T, S>
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, 'b, T, S, H> BitAnd<&'b HashSet<T, S>> for &'a HashSet<T, S>
-    where T: Eq + Hash<H> + Clone,
-          S: HashState<Hasher=H> + Default,
-          H: hash::Hasher<Output=u64>
+impl<'a, 'b, T, S> BitAnd<&'b HashSet<T, S>> for &'a HashSet<T, S>
+    where T: Eq + Hash + Clone,
+          S: HashState + Default,
 {
     type Output = HashSet<T, S>;
 
@@ -722,10 +711,9 @@ impl<'a, 'b, T, S, H> BitAnd<&'b HashSet<T, S>> for &'a HashSet<T, S>
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, 'b, T, S, H> BitXor<&'b HashSet<T, S>> for &'a HashSet<T, S>
-    where T: Eq + Hash<H> + Clone,
-          S: HashState<Hasher=H> + Default,
-          H: hash::Hasher<Output=u64>
+impl<'a, 'b, T, S> BitXor<&'b HashSet<T, S>> for &'a HashSet<T, S>
+    where T: Eq + Hash + Clone,
+          S: HashState + Default,
 {
     type Output = HashSet<T, S>;
 
@@ -755,10 +743,9 @@ impl<'a, 'b, T, S, H> BitXor<&'b HashSet<T, S>> for &'a HashSet<T, S>
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, 'b, T, S, H> Sub<&'b HashSet<T, S>> for &'a HashSet<T, S>
-    where T: Eq + Hash<H> + Clone,
-          S: HashState<Hasher=H> + Default,
-          H: hash::Hasher<Output=u64>
+impl<'a, 'b, T, S> Sub<&'b HashSet<T, S>> for &'a HashSet<T, S>
+    where T: Eq + Hash + Clone,
+          S: HashState + Default,
 {
     type Output = HashSet<T, S>;
 
@@ -836,10 +823,8 @@ pub struct Union<'a, T: 'a, S: 'a> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, S, H> IntoIterator for &'a HashSet<T, S>
-    where T: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
+impl<'a, T, S> IntoIterator for &'a HashSet<T, S>
+    where T: Eq + Hash, S: HashState
 {
     type Item = &'a T;
     type IntoIter = Iter<'a, T>;
@@ -850,10 +835,9 @@ impl<'a, T, S, H> IntoIterator for &'a HashSet<T, S>
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, S, H> IntoIterator for HashSet<T, S>
-    where T: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
+impl<T, S> IntoIterator for HashSet<T, S>
+    where T: Eq + Hash,
+          S: HashState
 {
     type Item = T;
     type IntoIter = IntoIter<T>;
@@ -900,10 +884,8 @@ impl<'a, K> ExactSizeIterator for Drain<'a, K> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, S, H> Iterator for Intersection<'a, T, S>
-    where T: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
+impl<'a, T, S> Iterator for Intersection<'a, T, S>
+    where T: Eq + Hash, S: HashState
 {
     type Item = &'a T;
 
@@ -925,10 +907,8 @@ impl<'a, T, S, H> Iterator for Intersection<'a, T, S>
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, S, H> Iterator for Difference<'a, T, S>
-    where T: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
+impl<'a, T, S> Iterator for Difference<'a, T, S>
+    where T: Eq + Hash, S: HashState
 {
     type Item = &'a T;
 
@@ -950,10 +930,8 @@ impl<'a, T, S, H> Iterator for Difference<'a, T, S>
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, S, H> Iterator for SymmetricDifference<'a, T, S>
-    where T: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
+impl<'a, T, S> Iterator for SymmetricDifference<'a, T, S>
+    where T: Eq + Hash, S: HashState
 {
     type Item = &'a T;
 
@@ -962,10 +940,8 @@ impl<'a, T, S, H> Iterator for SymmetricDifference<'a, T, S>
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, S, H> Iterator for Union<'a, T, S>
-    where T: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
+impl<'a, T, S> Iterator for Union<'a, T, S>
+    where T: Eq + Hash, S: HashState
 {
     type Item = &'a T;
 
diff --git a/src/libstd/collections/hash/set_stage0.rs b/src/libstd/collections/hash/set_stage0.rs
new file mode 100644
index 00000000000..68c9e02d8ad
--- /dev/null
+++ b/src/libstd/collections/hash/set_stage0.rs
@@ -0,0 +1,1252 @@
+// Copyright 2014 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.
+//
+// ignore-lexer-test FIXME #15883
+
+use borrow::Borrow;
+use clone::Clone;
+use cmp::{Eq, PartialEq};
+use core::marker::Sized;
+use default::Default;
+use fmt::Debug;
+use fmt;
+use hash::{self, Hash};
+use iter::{
+    Iterator, IntoIterator, ExactSizeIterator, IteratorExt, FromIterator, Map, Chain, Extend,
+};
+use ops::{BitOr, BitAnd, BitXor, Sub};
+use option::Option::{Some, None, self};
+
+use super::map::{self, HashMap, Keys, INITIAL_CAPACITY, RandomState, Hasher};
+use super::state::HashState;
+
+// Future Optimization (FIXME!)
+// =============================
+//
+// Iteration over zero sized values is a noop. There is no need
+// for `bucket.val` in the case of HashSet. I suppose we would need HKT
+// to get rid of it properly.
+
+/// An implementation of a hash set using the underlying representation of a
+/// HashMap where the value is (). As with the `HashMap` type, a `HashSet`
+/// requires that the elements implement the `Eq` and `Hash` traits.
+///
+/// # Example
+///
+/// ```
+/// use std::collections::HashSet;
+/// // Type inference lets us omit an explicit type signature (which
+/// // would be `HashSet<&str>` in this example).
+/// let mut books = HashSet::new();
+///
+/// // Add some books.
+/// books.insert("A Dance With Dragons");
+/// books.insert("To Kill a Mockingbird");
+/// books.insert("The Odyssey");
+/// books.insert("The Great Gatsby");
+///
+/// // Check for a specific one.
+/// if !books.contains(&("The Winds of Winter")) {
+///     println!("We have {} books, but The Winds of Winter ain't one.",
+///              books.len());
+/// }
+///
+/// // Remove a book.
+/// books.remove(&"The Odyssey");
+///
+/// // Iterate over everything.
+/// for book in books.iter() {
+///     println!("{}", *book);
+/// }
+/// ```
+///
+/// The easiest way to use `HashSet` with a custom type is to derive
+/// `Eq` and `Hash`. We must also derive `PartialEq`, this will in the
+/// future be implied by `Eq`.
+///
+/// ```
+/// use std::collections::HashSet;
+/// #[derive(Hash, Eq, PartialEq, Debug)]
+/// struct Viking<'a> {
+///     name: &'a str,
+///     power: usize,
+/// }
+///
+/// let mut vikings = HashSet::new();
+///
+/// vikings.insert(Viking { name: "Einar", power: 9 });
+/// vikings.insert(Viking { name: "Einar", power: 9 });
+/// vikings.insert(Viking { name: "Olaf", power: 4 });
+/// vikings.insert(Viking { name: "Harald", power: 8 });
+///
+/// // Use derived implementation to print the vikings.
+/// for x in vikings.iter() {
+///     println!("{:?}", x);
+/// }
+/// ```
+#[derive(Clone)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct HashSet<T, S = RandomState> {
+    map: HashMap<T, (), S>
+}
+
+impl<T: Hash<Hasher> + Eq> HashSet<T, RandomState> {
+    /// Create an empty HashSet.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    /// let mut set: HashSet<int> = HashSet::new();
+    /// ```
+    #[inline]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn new() -> HashSet<T, RandomState> {
+        HashSet::with_capacity(INITIAL_CAPACITY)
+    }
+
+    /// Create an empty HashSet with space for at least `n` elements in
+    /// the hash table.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    /// let mut set: HashSet<int> = HashSet::with_capacity(10);
+    /// ```
+    #[inline]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn with_capacity(capacity: usize) -> HashSet<T, RandomState> {
+        HashSet { map: HashMap::with_capacity(capacity) }
+    }
+}
+
+impl<T, S, H> HashSet<T, S>
+    where T: Eq + Hash<H>,
+          S: HashState<Hasher=H>,
+          H: hash::Hasher<Output=u64>
+{
+    /// Creates a new empty hash set which will use the given hasher to hash
+    /// keys.
+    ///
+    /// The hash set is also created with the default initial capacity.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    /// use std::collections::hash_map::RandomState;
+    ///
+    /// let s = RandomState::new();
+    /// let mut set = HashSet::with_hash_state(s);
+    /// set.insert(2);
+    /// ```
+    #[inline]
+    #[unstable(feature = "std_misc", reason = "hasher stuff is unclear")]
+    pub fn with_hash_state(hash_state: S) -> HashSet<T, S> {
+        HashSet::with_capacity_and_hash_state(INITIAL_CAPACITY, hash_state)
+    }
+
+    /// Create an empty HashSet with space for at least `capacity`
+    /// elements in the hash table, using `hasher` to hash the keys.
+    ///
+    /// Warning: `hasher` is normally randomly generated, and
+    /// is designed to allow `HashSet`s to be resistant to attacks that
+    /// cause many collisions and very poor performance. Setting it
+    /// manually using this function can expose a DoS attack vector.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    /// use std::collections::hash_map::RandomState;
+    ///
+    /// let s = RandomState::new();
+    /// let mut set = HashSet::with_capacity_and_hash_state(10, s);
+    /// set.insert(1);
+    /// ```
+    #[inline]
+    #[unstable(feature = "std_misc", reason = "hasher stuff is unclear")]
+    pub fn with_capacity_and_hash_state(capacity: usize, hash_state: S)
+                                        -> HashSet<T, S> {
+        HashSet {
+            map: HashMap::with_capacity_and_hash_state(capacity, hash_state),
+        }
+    }
+
+    /// Returns the number of elements the set can hold without reallocating.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    /// let set: HashSet<int> = HashSet::with_capacity(100);
+    /// assert!(set.capacity() >= 100);
+    /// ```
+    #[inline]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn capacity(&self) -> usize {
+        self.map.capacity()
+    }
+
+    /// Reserves capacity for at least `additional` more elements to be inserted
+    /// in the `HashSet`. The collection may reserve more space to avoid
+    /// frequent reallocations.
+    ///
+    /// # Panics
+    ///
+    /// Panics if the new allocation size overflows `usize`.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    /// let mut set: HashSet<int> = HashSet::new();
+    /// set.reserve(10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn reserve(&mut self, additional: usize) {
+        self.map.reserve(additional)
+    }
+
+    /// Shrinks the capacity of the set as much as possible. It will drop
+    /// down as much as possible while maintaining the internal rules
+    /// and possibly leaving some space in accordance with the resize policy.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let mut set: HashSet<int> = HashSet::with_capacity(100);
+    /// set.insert(1);
+    /// set.insert(2);
+    /// assert!(set.capacity() >= 100);
+    /// set.shrink_to_fit();
+    /// assert!(set.capacity() >= 2);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn shrink_to_fit(&mut self) {
+        self.map.shrink_to_fit()
+    }
+
+    /// An iterator visiting all elements in arbitrary order.
+    /// Iterator element type is &'a T.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    /// let mut set = HashSet::new();
+    /// set.insert("a");
+    /// set.insert("b");
+    ///
+    /// // Will print in an arbitrary order.
+    /// for x in set.iter() {
+    ///     println!("{}", x);
+    /// }
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn iter(&self) -> Iter<T> {
+        Iter { iter: self.map.keys() }
+    }
+
+    /// Creates a consuming iterator, that is, one that moves each value out
+    /// of the set in arbitrary order. The set cannot be used after calling
+    /// this.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    /// let mut set = HashSet::new();
+    /// set.insert("a".to_string());
+    /// set.insert("b".to_string());
+    ///
+    /// // Not possible to collect to a Vec<String> with a regular `.iter()`.
+    /// let v: Vec<String> = set.into_iter().collect();
+    ///
+    /// // Will print in an arbitrary order.
+    /// for x in v.iter() {
+    ///     println!("{}", x);
+    /// }
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn into_iter(self) -> IntoIter<T> {
+        fn first<A, B>((a, _): (A, B)) -> A { a }
+        let first: fn((T, ())) -> T = first;
+
+        IntoIter { iter: self.map.into_iter().map(first) }
+    }
+
+    /// Visit the values representing the difference.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    /// let a: HashSet<int> = [1, 2, 3].iter().map(|&x| x).collect();
+    /// let b: HashSet<int> = [4, 2, 3, 4].iter().map(|&x| x).collect();
+    ///
+    /// // Can be seen as `a - b`.
+    /// for x in a.difference(&b) {
+    ///     println!("{}", x); // Print 1
+    /// }
+    ///
+    /// let diff: HashSet<int> = a.difference(&b).map(|&x| x).collect();
+    /// assert_eq!(diff, [1].iter().map(|&x| x).collect());
+    ///
+    /// // Note that difference is not symmetric,
+    /// // and `b - a` means something else:
+    /// let diff: HashSet<int> = b.difference(&a).map(|&x| x).collect();
+    /// assert_eq!(diff, [4].iter().map(|&x| x).collect());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn difference<'a>(&'a self, other: &'a HashSet<T, S>) -> Difference<'a, T, S> {
+        Difference {
+            iter: self.iter(),
+            other: other,
+        }
+    }
+
+    /// Visit the values representing the symmetric difference.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    /// let a: HashSet<int> = [1, 2, 3].iter().map(|&x| x).collect();
+    /// let b: HashSet<int> = [4, 2, 3, 4].iter().map(|&x| x).collect();
+    ///
+    /// // Print 1, 4 in arbitrary order.
+    /// for x in a.symmetric_difference(&b) {
+    ///     println!("{}", x);
+    /// }
+    ///
+    /// let diff1: HashSet<int> = a.symmetric_difference(&b).map(|&x| x).collect();
+    /// let diff2: HashSet<int> = b.symmetric_difference(&a).map(|&x| x).collect();
+    ///
+    /// assert_eq!(diff1, diff2);
+    /// assert_eq!(diff1, [1, 4].iter().map(|&x| x).collect());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn symmetric_difference<'a>(&'a self, other: &'a HashSet<T, S>)
+        -> SymmetricDifference<'a, T, S> {
+        SymmetricDifference { iter: self.difference(other).chain(other.difference(self)) }
+    }
+
+    /// Visit the values representing the intersection.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    /// let a: HashSet<int> = [1, 2, 3].iter().map(|&x| x).collect();
+    /// let b: HashSet<int> = [4, 2, 3, 4].iter().map(|&x| x).collect();
+    ///
+    /// // Print 2, 3 in arbitrary order.
+    /// for x in a.intersection(&b) {
+    ///     println!("{}", x);
+    /// }
+    ///
+    /// let diff: HashSet<int> = a.intersection(&b).map(|&x| x).collect();
+    /// assert_eq!(diff, [2, 3].iter().map(|&x| x).collect());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn intersection<'a>(&'a self, other: &'a HashSet<T, S>) -> Intersection<'a, T, S> {
+        Intersection {
+            iter: self.iter(),
+            other: other,
+        }
+    }
+
+    /// Visit the values representing the union.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    /// let a: HashSet<int> = [1, 2, 3].iter().map(|&x| x).collect();
+    /// let b: HashSet<int> = [4, 2, 3, 4].iter().map(|&x| x).collect();
+    ///
+    /// // Print 1, 2, 3, 4 in arbitrary order.
+    /// for x in a.union(&b) {
+    ///     println!("{}", x);
+    /// }
+    ///
+    /// let diff: HashSet<int> = a.union(&b).map(|&x| x).collect();
+    /// assert_eq!(diff, [1, 2, 3, 4].iter().map(|&x| x).collect());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn union<'a>(&'a self, other: &'a HashSet<T, S>) -> Union<'a, T, S> {
+        Union { iter: self.iter().chain(other.difference(self)) }
+    }
+
+    /// Return the number of elements in the set
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let mut v = HashSet::new();
+    /// assert_eq!(v.len(), 0);
+    /// v.insert(1);
+    /// assert_eq!(v.len(), 1);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn len(&self) -> usize { self.map.len() }
+
+    /// Returns true if the set contains no elements
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let mut v = HashSet::new();
+    /// assert!(v.is_empty());
+    /// v.insert(1);
+    /// assert!(!v.is_empty());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn is_empty(&self) -> bool { self.map.len() == 0 }
+
+    /// Clears the set, returning all elements in an iterator.
+    #[inline]
+    #[unstable(feature = "std_misc",
+               reason = "matches collection reform specification, waiting for dust to settle")]
+    pub fn drain(&mut self) -> Drain<T> {
+        fn first<A, B>((a, _): (A, B)) -> A { a }
+        let first: fn((T, ())) -> T = first; // coerce to fn pointer
+
+        Drain { iter: self.map.drain().map(first) }
+    }
+
+    /// Clears the set, removing all values.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let mut v = HashSet::new();
+    /// v.insert(1);
+    /// v.clear();
+    /// assert!(v.is_empty());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn clear(&mut self) { self.map.clear() }
+
+    /// Returns `true` if the set contains a value.
+    ///
+    /// The value may be any borrowed form of the set's value type, but
+    /// `Hash` and `Eq` on the borrowed form *must* match those for
+    /// the value type.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let set: HashSet<_> = [1, 2, 3].iter().cloned().collect();
+    /// assert_eq!(set.contains(&1), true);
+    /// assert_eq!(set.contains(&4), false);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool
+        where T: Borrow<Q>, Q: Hash<H> + Eq
+    {
+        self.map.contains_key(value)
+    }
+
+    /// Returns `true` if the set has no elements in common with `other`.
+    /// This is equivalent to checking for an empty intersection.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let a: HashSet<_> = [1, 2, 3].iter().cloned().collect();
+    /// let mut b = HashSet::new();
+    ///
+    /// assert_eq!(a.is_disjoint(&b), true);
+    /// b.insert(4);
+    /// assert_eq!(a.is_disjoint(&b), true);
+    /// b.insert(1);
+    /// assert_eq!(a.is_disjoint(&b), false);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn is_disjoint(&self, other: &HashSet<T, S>) -> bool {
+        self.iter().all(|v| !other.contains(v))
+    }
+
+    /// Returns `true` if the set is a subset of another.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let sup: HashSet<_> = [1, 2, 3].iter().cloned().collect();
+    /// let mut set = HashSet::new();
+    ///
+    /// assert_eq!(set.is_subset(&sup), true);
+    /// set.insert(2);
+    /// assert_eq!(set.is_subset(&sup), true);
+    /// set.insert(4);
+    /// assert_eq!(set.is_subset(&sup), false);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn is_subset(&self, other: &HashSet<T, S>) -> bool {
+        self.iter().all(|v| other.contains(v))
+    }
+
+    /// Returns `true` if the set is a superset of another.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let sub: HashSet<_> = [1, 2].iter().cloned().collect();
+    /// let mut set = HashSet::new();
+    ///
+    /// assert_eq!(set.is_superset(&sub), false);
+    ///
+    /// set.insert(0);
+    /// set.insert(1);
+    /// assert_eq!(set.is_superset(&sub), false);
+    ///
+    /// set.insert(2);
+    /// assert_eq!(set.is_superset(&sub), true);
+    /// ```
+    #[inline]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn is_superset(&self, other: &HashSet<T, S>) -> bool {
+        other.is_subset(self)
+    }
+
+    /// Adds a value to the set. Returns `true` if the value was not already
+    /// present in the set.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let mut set = HashSet::new();
+    ///
+    /// assert_eq!(set.insert(2), true);
+    /// assert_eq!(set.insert(2), false);
+    /// assert_eq!(set.len(), 1);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()).is_none() }
+
+    /// Removes a value from the set. Returns `true` if the value was
+    /// present in the set.
+    ///
+    /// The value may be any borrowed form of the set's value type, but
+    /// `Hash` and `Eq` on the borrowed form *must* match those for
+    /// the value type.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let mut set = HashSet::new();
+    ///
+    /// set.insert(2);
+    /// assert_eq!(set.remove(&2), true);
+    /// assert_eq!(set.remove(&2), false);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool
+        where T: Borrow<Q>, Q: Hash<H> + Eq
+    {
+        self.map.remove(value).is_some()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T, S, H> PartialEq for HashSet<T, S>
+    where T: Eq + Hash<H>,
+          S: HashState<Hasher=H>,
+          H: hash::Hasher<Output=u64>
+{
+    fn eq(&self, other: &HashSet<T, S>) -> bool {
+        if self.len() != other.len() { return false; }
+
+        self.iter().all(|key| other.contains(key))
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T, S, H> Eq for HashSet<T, S>
+    where T: Eq + Hash<H>,
+          S: HashState<Hasher=H>,
+          H: hash::Hasher<Output=u64>
+{}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T, S, H> fmt::Debug for HashSet<T, S>
+    where T: Eq + Hash<H> + fmt::Debug,
+          S: HashState<Hasher=H>,
+          H: hash::Hasher<Output=u64>
+{
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        try!(write!(f, "HashSet {{"));
+
+        for (i, x) in self.iter().enumerate() {
+            if i != 0 { try!(write!(f, ", ")); }
+            try!(write!(f, "{:?}", *x));
+        }
+
+        write!(f, "}}")
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T, S, H> FromIterator<T> for HashSet<T, S>
+    where T: Eq + Hash<H>,
+          S: HashState<Hasher=H> + Default,
+          H: hash::Hasher<Output=u64>
+{
+    fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> HashSet<T, S> {
+        let iter = iter.into_iter();
+        let lower = iter.size_hint().0;
+        let mut set = HashSet::with_capacity_and_hash_state(lower, Default::default());
+        set.extend(iter);
+        set
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T, S, H> Extend<T> for HashSet<T, S>
+    where T: Eq + Hash<H>,
+          S: HashState<Hasher=H>,
+          H: hash::Hasher<Output=u64>
+{
+    fn extend<I: IntoIterator<Item=T>>(&mut self, iter: I) {
+        for k in iter {
+            self.insert(k);
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T, S, H> Default for HashSet<T, S>
+    where T: Eq + Hash<H>,
+          S: HashState<Hasher=H> + Default,
+          H: hash::Hasher<Output=u64>
+{
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn default() -> HashSet<T, S> {
+        HashSet::with_hash_state(Default::default())
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, 'b, T, S, H> BitOr<&'b HashSet<T, S>> for &'a HashSet<T, S>
+    where T: Eq + Hash<H> + Clone,
+          S: HashState<Hasher=H> + Default,
+          H: hash::Hasher<Output=u64>
+{
+    type Output = HashSet<T, S>;
+
+    /// Returns the union of `self` and `rhs` as a new `HashSet<T, S>`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
+    /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect();
+    ///
+    /// let set = &a | &b;
+    ///
+    /// let mut i = 0;
+    /// let expected = [1, 2, 3, 4, 5];
+    /// for x in set.iter() {
+    ///     assert!(expected.contains(x));
+    ///     i += 1;
+    /// }
+    /// assert_eq!(i, expected.len());
+    /// ```
+    fn bitor(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
+        self.union(rhs).cloned().collect()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, 'b, T, S, H> BitAnd<&'b HashSet<T, S>> for &'a HashSet<T, S>
+    where T: Eq + Hash<H> + Clone,
+          S: HashState<Hasher=H> + Default,
+          H: hash::Hasher<Output=u64>
+{
+    type Output = HashSet<T, S>;
+
+    /// Returns the intersection of `self` and `rhs` as a new `HashSet<T, S>`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
+    /// let b: HashSet<_> = vec![2, 3, 4].into_iter().collect();
+    ///
+    /// let set = &a & &b;
+    ///
+    /// let mut i = 0;
+    /// let expected = [2, 3];
+    /// for x in set.iter() {
+    ///     assert!(expected.contains(x));
+    ///     i += 1;
+    /// }
+    /// assert_eq!(i, expected.len());
+    /// ```
+    fn bitand(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
+        self.intersection(rhs).cloned().collect()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, 'b, T, S, H> BitXor<&'b HashSet<T, S>> for &'a HashSet<T, S>
+    where T: Eq + Hash<H> + Clone,
+          S: HashState<Hasher=H> + Default,
+          H: hash::Hasher<Output=u64>
+{
+    type Output = HashSet<T, S>;
+
+    /// Returns the symmetric difference of `self` and `rhs` as a new `HashSet<T, S>`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
+    /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect();
+    ///
+    /// let set = &a ^ &b;
+    ///
+    /// let mut i = 0;
+    /// let expected = [1, 2, 4, 5];
+    /// for x in set.iter() {
+    ///     assert!(expected.contains(x));
+    ///     i += 1;
+    /// }
+    /// assert_eq!(i, expected.len());
+    /// ```
+    fn bitxor(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
+        self.symmetric_difference(rhs).cloned().collect()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, 'b, T, S, H> Sub<&'b HashSet<T, S>> for &'a HashSet<T, S>
+    where T: Eq + Hash<H> + Clone,
+          S: HashState<Hasher=H> + Default,
+          H: hash::Hasher<Output=u64>
+{
+    type Output = HashSet<T, S>;
+
+    /// Returns the difference of `self` and `rhs` as a new `HashSet<T, S>`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
+    /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect();
+    ///
+    /// let set = &a - &b;
+    ///
+    /// let mut i = 0;
+    /// let expected = [1, 2];
+    /// for x in set.iter() {
+    ///     assert!(expected.contains(x));
+    ///     i += 1;
+    /// }
+    /// assert_eq!(i, expected.len());
+    /// ```
+    fn sub(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
+        self.difference(rhs).cloned().collect()
+    }
+}
+
+/// HashSet iterator
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Iter<'a, K: 'a> {
+    iter: Keys<'a, K, ()>
+}
+
+/// HashSet move iterator
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct IntoIter<K> {
+    iter: Map<map::IntoIter<K, ()>, fn((K, ())) -> K>
+}
+
+/// HashSet drain iterator
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Drain<'a, K: 'a> {
+    iter: Map<map::Drain<'a, K, ()>, fn((K, ())) -> K>,
+}
+
+/// Intersection iterator
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Intersection<'a, T: 'a, S: 'a> {
+    // iterator of the first set
+    iter: Iter<'a, T>,
+    // the second set
+    other: &'a HashSet<T, S>,
+}
+
+/// Difference iterator
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Difference<'a, T: 'a, S: 'a> {
+    // iterator of the first set
+    iter: Iter<'a, T>,
+    // the second set
+    other: &'a HashSet<T, S>,
+}
+
+/// Symmetric difference iterator.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct SymmetricDifference<'a, T: 'a, S: 'a> {
+    iter: Chain<Difference<'a, T, S>, Difference<'a, T, S>>
+}
+
+/// Set union iterator.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Union<'a, T: 'a, S: 'a> {
+    iter: Chain<Iter<'a, T>, Difference<'a, T, S>>
+}
+
+impl<'a, T, S, H> IntoIterator for &'a HashSet<T, S>
+    where T: Eq + Hash<H>,
+          S: HashState<Hasher=H>,
+          H: hash::Hasher<Output=u64>
+{
+    type Item = &'a T;
+    type IntoIter = Iter<'a, T>;
+
+    fn into_iter(self) -> Iter<'a, T> {
+        self.iter()
+    }
+}
+
+impl<T, S, H> IntoIterator for HashSet<T, S>
+    where T: Eq + Hash<H>,
+          S: HashState<Hasher=H>,
+          H: hash::Hasher<Output=u64>
+{
+    type Item = T;
+    type IntoIter = IntoIter<T>;
+
+    fn into_iter(self) -> IntoIter<T> {
+        self.into_iter()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, K> Iterator for Iter<'a, K> {
+    type Item = &'a K;
+
+    fn next(&mut self) -> Option<&'a K> { self.iter.next() }
+    fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
+}
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, K> ExactSizeIterator for Iter<'a, K> {
+    fn len(&self) -> usize { self.iter.len() }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<K> Iterator for IntoIter<K> {
+    type Item = K;
+
+    fn next(&mut self) -> Option<K> { self.iter.next() }
+    fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
+}
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<K> ExactSizeIterator for IntoIter<K> {
+    fn len(&self) -> usize { self.iter.len() }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, K> Iterator for Drain<'a, K> {
+    type Item = K;
+
+    fn next(&mut self) -> Option<K> { self.iter.next() }
+    fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
+}
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, K> ExactSizeIterator for Drain<'a, K> {
+    fn len(&self) -> usize { self.iter.len() }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T, S, H> Iterator for Intersection<'a, T, S>
+    where T: Eq + Hash<H>,
+          S: HashState<Hasher=H>,
+          H: hash::Hasher<Output=u64>
+{
+    type Item = &'a T;
+
+    fn next(&mut self) -> Option<&'a T> {
+        loop {
+            match self.iter.next() {
+                None => return None,
+                Some(elt) => if self.other.contains(elt) {
+                    return Some(elt)
+                },
+            }
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let (_, upper) = self.iter.size_hint();
+        (0, upper)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T, S, H> Iterator for Difference<'a, T, S>
+    where T: Eq + Hash<H>,
+          S: HashState<Hasher=H>,
+          H: hash::Hasher<Output=u64>
+{
+    type Item = &'a T;
+
+    fn next(&mut self) -> Option<&'a T> {
+        loop {
+            match self.iter.next() {
+                None => return None,
+                Some(elt) => if !self.other.contains(elt) {
+                    return Some(elt)
+                },
+            }
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let (_, upper) = self.iter.size_hint();
+        (0, upper)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T, S, H> Iterator for SymmetricDifference<'a, T, S>
+    where T: Eq + Hash<H>,
+          S: HashState<Hasher=H>,
+          H: hash::Hasher<Output=u64>
+{
+    type Item = &'a T;
+
+    fn next(&mut self) -> Option<&'a T> { self.iter.next() }
+    fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T, S, H> Iterator for Union<'a, T, S>
+    where T: Eq + Hash<H>,
+          S: HashState<Hasher=H>,
+          H: hash::Hasher<Output=u64>
+{
+    type Item = &'a T;
+
+    fn next(&mut self) -> Option<&'a T> { self.iter.next() }
+    fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
+}
+
+#[cfg(test)]
+mod test_set {
+    use prelude::v1::*;
+
+    use super::HashSet;
+
+    #[test]
+    fn test_disjoint() {
+        let mut xs = HashSet::new();
+        let mut ys = HashSet::new();
+        assert!(xs.is_disjoint(&ys));
+        assert!(ys.is_disjoint(&xs));
+        assert!(xs.insert(5));
+        assert!(ys.insert(11));
+        assert!(xs.is_disjoint(&ys));
+        assert!(ys.is_disjoint(&xs));
+        assert!(xs.insert(7));
+        assert!(xs.insert(19));
+        assert!(xs.insert(4));
+        assert!(ys.insert(2));
+        assert!(ys.insert(-11));
+        assert!(xs.is_disjoint(&ys));
+        assert!(ys.is_disjoint(&xs));
+        assert!(ys.insert(7));
+        assert!(!xs.is_disjoint(&ys));
+        assert!(!ys.is_disjoint(&xs));
+    }
+
+    #[test]
+    fn test_subset_and_superset() {
+        let mut a = HashSet::new();
+        assert!(a.insert(0));
+        assert!(a.insert(5));
+        assert!(a.insert(11));
+        assert!(a.insert(7));
+
+        let mut b = HashSet::new();
+        assert!(b.insert(0));
+        assert!(b.insert(7));
+        assert!(b.insert(19));
+        assert!(b.insert(250));
+        assert!(b.insert(11));
+        assert!(b.insert(200));
+
+        assert!(!a.is_subset(&b));
+        assert!(!a.is_superset(&b));
+        assert!(!b.is_subset(&a));
+        assert!(!b.is_superset(&a));
+
+        assert!(b.insert(5));
+
+        assert!(a.is_subset(&b));
+        assert!(!a.is_superset(&b));
+        assert!(!b.is_subset(&a));
+        assert!(b.is_superset(&a));
+    }
+
+    #[test]
+    fn test_iterate() {
+        let mut a = HashSet::new();
+        for i in 0..32 {
+            assert!(a.insert(i));
+        }
+        let mut observed: u32 = 0;
+        for k in &a {
+            observed |= 1 << *k;
+        }
+        assert_eq!(observed, 0xFFFF_FFFF);
+    }
+
+    #[test]
+    fn test_intersection() {
+        let mut a = HashSet::new();
+        let mut b = HashSet::new();
+
+        assert!(a.insert(11));
+        assert!(a.insert(1));
+        assert!(a.insert(3));
+        assert!(a.insert(77));
+        assert!(a.insert(103));
+        assert!(a.insert(5));
+        assert!(a.insert(-5));
+
+        assert!(b.insert(2));
+        assert!(b.insert(11));
+        assert!(b.insert(77));
+        assert!(b.insert(-9));
+        assert!(b.insert(-42));
+        assert!(b.insert(5));
+        assert!(b.insert(3));
+
+        let mut i = 0;
+        let expected = [3, 5, 11, 77];
+        for x in a.intersection(&b) {
+            assert!(expected.contains(x));
+            i += 1
+        }
+        assert_eq!(i, expected.len());
+    }
+
+    #[test]
+    fn test_difference() {
+        let mut a = HashSet::new();
+        let mut b = HashSet::new();
+
+        assert!(a.insert(1));
+        assert!(a.insert(3));
+        assert!(a.insert(5));
+        assert!(a.insert(9));
+        assert!(a.insert(11));
+
+        assert!(b.insert(3));
+        assert!(b.insert(9));
+
+        let mut i = 0;
+        let expected = [1, 5, 11];
+        for x in a.difference(&b) {
+            assert!(expected.contains(x));
+            i += 1
+        }
+        assert_eq!(i, expected.len());
+    }
+
+    #[test]
+    fn test_symmetric_difference() {
+        let mut a = HashSet::new();
+        let mut b = HashSet::new();
+
+        assert!(a.insert(1));
+        assert!(a.insert(3));
+        assert!(a.insert(5));
+        assert!(a.insert(9));
+        assert!(a.insert(11));
+
+        assert!(b.insert(-2));
+        assert!(b.insert(3));
+        assert!(b.insert(9));
+        assert!(b.insert(14));
+        assert!(b.insert(22));
+
+        let mut i = 0;
+        let expected = [-2, 1, 5, 11, 14, 22];
+        for x in a.symmetric_difference(&b) {
+            assert!(expected.contains(x));
+            i += 1
+        }
+        assert_eq!(i, expected.len());
+    }
+
+    #[test]
+    fn test_union() {
+        let mut a = HashSet::new();
+        let mut b = HashSet::new();
+
+        assert!(a.insert(1));
+        assert!(a.insert(3));
+        assert!(a.insert(5));
+        assert!(a.insert(9));
+        assert!(a.insert(11));
+        assert!(a.insert(16));
+        assert!(a.insert(19));
+        assert!(a.insert(24));
+
+        assert!(b.insert(-2));
+        assert!(b.insert(1));
+        assert!(b.insert(5));
+        assert!(b.insert(9));
+        assert!(b.insert(13));
+        assert!(b.insert(19));
+
+        let mut i = 0;
+        let expected = [-2, 1, 3, 5, 9, 11, 13, 16, 19, 24];
+        for x in a.union(&b) {
+            assert!(expected.contains(x));
+            i += 1
+        }
+        assert_eq!(i, expected.len());
+    }
+
+    #[test]
+    fn test_from_iter() {
+        let xs = [1, 2, 3, 4, 5, 6, 7, 8, 9];
+
+        let set: HashSet<_> = xs.iter().cloned().collect();
+
+        for x in &xs {
+            assert!(set.contains(x));
+        }
+    }
+
+    #[test]
+    fn test_move_iter() {
+        let hs = {
+            let mut hs = HashSet::new();
+
+            hs.insert('a');
+            hs.insert('b');
+
+            hs
+        };
+
+        let v = hs.into_iter().collect::<Vec<char>>();
+        assert!(['a', 'b'] == v || ['b', 'a'] == v);
+    }
+
+    #[test]
+    fn test_eq() {
+        // These constants once happened to expose a bug in insert().
+        // I'm keeping them around to prevent a regression.
+        let mut s1 = HashSet::new();
+
+        s1.insert(1);
+        s1.insert(2);
+        s1.insert(3);
+
+        let mut s2 = HashSet::new();
+
+        s2.insert(1);
+        s2.insert(2);
+
+        assert!(s1 != s2);
+
+        s2.insert(3);
+
+        assert_eq!(s1, s2);
+    }
+
+    #[test]
+    fn test_show() {
+        let mut set = HashSet::new();
+        let empty = HashSet::<i32>::new();
+
+        set.insert(1);
+        set.insert(2);
+
+        let set_str = format!("{:?}", set);
+
+        assert!(set_str == "HashSet {1, 2}" || set_str == "HashSet {2, 1}");
+        assert_eq!(format!("{:?}", empty), "HashSet {}");
+    }
+
+    #[test]
+    fn test_trivial_drain() {
+        let mut s = HashSet::<i32>::new();
+        for _ in s.drain() {}
+        assert!(s.is_empty());
+        drop(s);
+
+        let mut s = HashSet::<i32>::new();
+        drop(s.drain());
+        assert!(s.is_empty());
+    }
+
+    #[test]
+    fn test_drain() {
+        let mut s: HashSet<_> = (1..100).collect();
+
+        // try this a bunch of times to make sure we don't screw up internal state.
+        for _ in 0..20 {
+            assert_eq!(s.len(), 99);
+
+            {
+                let mut last_i = 0;
+                let mut d = s.drain();
+                for (i, x) in d.by_ref().take(50).enumerate() {
+                    last_i = i;
+                    assert!(x != 0);
+                }
+                assert_eq!(last_i, 49);
+            }
+
+            for _ in &s { panic!("s should be empty!"); }
+
+            // reset to try again.
+            s.extend(1..100);
+        }
+    }
+}
diff --git a/src/libstd/collections/hash/state.rs b/src/libstd/collections/hash/state.rs
index 79e01304fb8..7e6dd45b51e 100644
--- a/src/libstd/collections/hash/state.rs
+++ b/src/libstd/collections/hash/state.rs
@@ -11,6 +11,7 @@
 use clone::Clone;
 use default::Default;
 use hash;
+use marker;
 
 /// A trait representing stateful hashes which can be used to hash keys in a
 /// `HashMap`.
@@ -37,7 +38,7 @@ pub trait HashState {
 ///
 /// This struct has is 0-sized and does not need construction.
 #[unstable(feature = "std_misc", reason = "hasher stuff is unclear")]
-pub struct DefaultState<H>;
+pub struct DefaultState<H>(marker::PhantomData<H>);
 
 impl<H: Default + hash::Hasher> HashState for DefaultState<H> {
     type Hasher = H;
@@ -45,9 +46,9 @@ impl<H: Default + hash::Hasher> HashState for DefaultState<H> {
 }
 
 impl<H> Clone for DefaultState<H> {
-    fn clone(&self) -> DefaultState<H> { DefaultState }
+    fn clone(&self) -> DefaultState<H> { DefaultState(marker::PhantomData) }
 }
 
 impl<H> Default for DefaultState<H> {
-    fn default() -> DefaultState<H> { DefaultState }
+    fn default() -> DefaultState<H> { DefaultState(marker::PhantomData) }
 }
diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs
index 0bb6bd4cf35..f301f6db92f 100644
--- a/src/libstd/collections/hash/table.rs
+++ b/src/libstd/collections/hash/table.rs
@@ -23,8 +23,8 @@ use num::{Int, UnsignedInt};
 use ops::{Deref, DerefMut, Drop};
 use option::Option;
 use option::Option::{Some, None};
-use ptr::{self, PtrExt, copy_nonoverlapping_memory, zero_memory};
-use rt::heap::{allocate, deallocate};
+use ptr::{self, PtrExt, copy_nonoverlapping_memory, Unique, zero_memory};
+use rt::heap::{allocate, deallocate, EMPTY};
 use collections::hash_state::HashState;
 
 const EMPTY_BUCKET: u64 = 0u64;
@@ -69,10 +69,11 @@ const EMPTY_BUCKET: u64 = 0u64;
 pub struct RawTable<K, V> {
     capacity: usize,
     size:     usize,
-    hashes:   *mut u64,
+    hashes:   Unique<u64>,
+
     // Because K/V do not appear directly in any of the types in the struct,
     // inform rustc that in fact instances of K and V are reachable from here.
-    marker:   marker::CovariantType<(K,V)>,
+    marker:   marker::PhantomData<(K,V)>,
 }
 
 unsafe impl<K: Send, V: Send> Send for RawTable<K, V> {}
@@ -81,7 +82,8 @@ unsafe impl<K: Sync, V: Sync> Sync for RawTable<K, V> {}
 struct RawBucket<K, V> {
     hash: *mut u64,
     key:  *mut K,
-    val:  *mut V
+    val:  *mut V,
+    _marker: marker::PhantomData<(K,V)>,
 }
 
 impl<K,V> Copy for RawBucket<K,V> {}
@@ -141,6 +143,7 @@ impl SafeHash {
 /// We need to remove hashes of 0. That's reserved for empty buckets.
 /// This function wraps up `hash_keyed` to be the only way outside this
 /// module to generate a SafeHash.
+#[cfg(stage0)]
 pub fn make_hash<T: ?Sized, S, H>(hash_state: &S, t: &T) -> SafeHash
     where T: Hash<H>,
           S: HashState<Hasher=H>,
@@ -155,6 +158,22 @@ pub fn make_hash<T: ?Sized, S, H>(hash_state: &S, t: &T) -> SafeHash
     SafeHash { hash: 0x8000_0000_0000_0000 | state.finish() }
 }
 
+/// We need to remove hashes of 0. That's reserved for empty buckets.
+/// This function wraps up `hash_keyed` to be the only way outside this
+/// module to generate a SafeHash.
+#[cfg(not(stage0))]
+pub fn make_hash<T: ?Sized, S>(hash_state: &S, t: &T) -> SafeHash
+    where T: Hash, S: HashState
+{
+    let mut state = hash_state.hasher();
+    t.hash(&mut state);
+    // We need to avoid 0u64 in order to prevent collisions with
+    // EMPTY_HASH. We can maintain our precious uniform distribution
+    // of initial indexes by unconditionally setting the MSB,
+    // effectively reducing 64-bits hashes to 63 bits.
+    SafeHash { hash: 0x8000_0000_0000_0000 | state.finish() }
+}
+
 // `replace` casts a `*u64` to a `*SafeHash`. Since we statically
 // ensure that a `FullBucket` points to an index with a non-zero hash,
 // and a `SafeHash` is just a `u64` with a different name, this is
@@ -170,11 +189,12 @@ fn can_alias_safehash_as_u64() {
 }
 
 impl<K, V> RawBucket<K, V> {
-    unsafe fn offset(self, count: int) -> RawBucket<K, V> {
+    unsafe fn offset(self, count: isize) -> RawBucket<K, V> {
         RawBucket {
             hash: self.hash.offset(count),
             key:  self.key.offset(count),
             val:  self.val.offset(count),
+            _marker: marker::PhantomData,
         }
     }
 }
@@ -567,10 +587,11 @@ impl<K, V> RawTable<K, V> {
             return RawTable {
                 size: 0,
                 capacity: 0,
-                hashes: ptr::null_mut(),
-                marker: marker::CovariantType,
+                hashes: Unique::new(EMPTY as *mut u64),
+                marker: marker::PhantomData,
             };
         }
+
         // No need for `checked_mul` before a more restrictive check performed
         // later in this method.
         let hashes_size = capacity * size_of::<u64>();
@@ -606,8 +627,8 @@ impl<K, V> RawTable<K, V> {
         RawTable {
             capacity: capacity,
             size:     0,
-            hashes:   hashes,
-            marker:   marker::CovariantType,
+            hashes:   Unique::new(hashes),
+            marker:   marker::PhantomData,
         }
     }
 
@@ -615,16 +636,17 @@ impl<K, V> RawTable<K, V> {
         let hashes_size = self.capacity * size_of::<u64>();
         let keys_size = self.capacity * size_of::<K>();
 
-        let buffer = self.hashes as *mut u8;
+        let buffer = *self.hashes as *mut u8;
         let (keys_offset, vals_offset) = calculate_offsets(hashes_size,
                                                            keys_size, min_align_of::<K>(),
                                                            min_align_of::<V>());
 
         unsafe {
             RawBucket {
-                hash: self.hashes,
+                hash: *self.hashes,
                 key:  buffer.offset(keys_offset as isize) as *mut K,
-                val:  buffer.offset(vals_offset as isize) as *mut V
+                val:  buffer.offset(vals_offset as isize) as *mut V,
+                _marker: marker::PhantomData,
             }
         }
     }
@@ -634,7 +656,7 @@ impl<K, V> RawTable<K, V> {
     pub fn new(capacity: usize) -> RawTable<K, V> {
         unsafe {
             let ret = RawTable::new_uninitialized(capacity);
-            zero_memory(ret.hashes, capacity);
+            zero_memory(*ret.hashes, capacity);
             ret
         }
     }
@@ -656,7 +678,7 @@ impl<K, V> RawTable<K, V> {
             hashes_end: unsafe {
                 self.hashes.offset(self.capacity as isize)
             },
-            marker: marker::ContravariantLifetime,
+            marker: marker::PhantomData,
         }
     }
 
@@ -681,7 +703,7 @@ impl<K, V> RawTable<K, V> {
             iter: RawBuckets {
                 raw: raw,
                 hashes_end: hashes_end,
-                marker: marker::ContravariantLifetime,
+                marker: marker::PhantomData,
             },
             table: self,
         }
@@ -694,7 +716,7 @@ impl<K, V> RawTable<K, V> {
             iter: RawBuckets {
                 raw: raw,
                 hashes_end: hashes_end,
-                marker: marker::ContravariantLifetime::<'static>,
+                marker: marker::PhantomData,
             },
             table: self,
         }
@@ -708,7 +730,7 @@ impl<K, V> RawTable<K, V> {
             raw: raw_bucket.offset(self.capacity as isize),
             hashes_end: raw_bucket.hash,
             elems_left: self.size,
-            marker:     marker::ContravariantLifetime,
+            marker:     marker::PhantomData,
         }
     }
 }
@@ -718,7 +740,13 @@ impl<K, V> RawTable<K, V> {
 struct RawBuckets<'a, K, V> {
     raw: RawBucket<K, V>,
     hashes_end: *mut u64,
-    marker: marker::ContravariantLifetime<'a>,
+
+    // Strictly speaking, this should be &'a (K,V), but that would
+    // require that K:'a, and we often use RawBuckets<'static...> for
+    // move iterations, so that messes up a lot of other things. So
+    // just use `&'a (K,V)` as this is not a publicly exposed type
+    // anyway.
+    marker: marker::PhantomData<&'a ()>,
 }
 
 // FIXME(#19839) Remove in favor of `#[derive(Clone)]`
@@ -727,7 +755,7 @@ impl<'a, K, V> Clone for RawBuckets<'a, K, V> {
         RawBuckets {
             raw: self.raw,
             hashes_end: self.hashes_end,
-            marker: marker::ContravariantLifetime,
+            marker: marker::PhantomData,
         }
     }
 }
@@ -759,7 +787,11 @@ struct RevMoveBuckets<'a, K, V> {
     raw: RawBucket<K, V>,
     hashes_end: *mut u64,
     elems_left: usize,
-    marker: marker::ContravariantLifetime<'a>,
+
+    // As above, `&'a (K,V)` would seem better, but we often use
+    // 'static for the lifetime, and this is not a publicly exposed
+    // type.
+    marker: marker::PhantomData<&'a ()>,
 }
 
 impl<'a, K, V> Iterator for RevMoveBuckets<'a, K, V> {
@@ -966,9 +998,10 @@ impl<K: Clone, V: Clone> Clone for RawTable<K, V> {
 #[unsafe_destructor]
 impl<K, V> Drop for RawTable<K, V> {
     fn drop(&mut self) {
-        if self.hashes.is_null() {
+        if self.capacity == 0 {
             return;
         }
+
         // This is done in reverse because we've likely partially taken
         // some elements out with `.into_iter()` from the front.
         // Check if the size is 0, so we don't do a useless scan when
@@ -986,7 +1019,7 @@ impl<K, V> Drop for RawTable<K, V> {
                                                     vals_size, min_align_of::<V>());
 
         unsafe {
-            deallocate(self.hashes as *mut u8, size, align);
+            deallocate(*self.hashes as *mut u8, size, align);
             // Remember how everything was allocated out of one buffer
             // during initialization? We only need one call to free here.
         }
diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs
index be441bfec88..0e64370df60 100644
--- a/src/libstd/collections/mod.rs
+++ b/src/libstd/collections/mod.rs
@@ -23,7 +23,7 @@
 //!
 //! Rust's collections can be grouped into four major categories:
 //!
-//! * Sequences: `Vec`, `RingBuf`, `DList`, `BitV`
+//! * Sequences: `Vec`, `VecDeque`, `LinkedList`, `BitV`
 //! * Maps: `HashMap`, `BTreeMap`, `VecMap`
 //! * Sets: `HashSet`, `BTreeSet`, `BitVSet`
 //! * Misc: `BinaryHeap`
@@ -43,13 +43,13 @@
 //! * You want a resizable array.
 //! * You want a heap-allocated array.
 //!
-//! ### Use a `RingBuf` when:
+//! ### Use a `VecDeque` when:
 //! * You want a `Vec` that supports efficient insertion at both ends of the sequence.
 //! * You want a queue.
 //! * You want a double-ended queue (deque).
 //!
-//! ### Use a `DList` when:
-//! * You want a `Vec` or `RingBuf` of unknown size, and can't tolerate amortization.
+//! ### Use a `LinkedList` when:
+//! * You want a `Vec` or `VecDeque` of unknown size, and can't tolerate amortization.
 //! * You want to efficiently split and append lists.
 //! * You are *absolutely* certain you *really*, *truly*, want a doubly linked list.
 //!
@@ -75,7 +75,7 @@
 //!
 //! ### Use a `BitV` when:
 //! * You want to store an unbounded number of booleans in a small space.
-//! * You want a bitvector.
+//! * You want a bit vector.
 //!
 //! ### Use a `BitVSet` when:
 //! * You want a `VecSet`.
@@ -106,20 +106,20 @@
 //!
 //! ## Sequences
 //!
-//! |         | get(i)         | insert(i)       | remove(i)      | append | split_off(i)   |
-//! |---------|----------------|-----------------|----------------|--------|----------------|
-//! | Vec     | O(1)           | O(n-i)*         | O(n-i)         | O(m)*  | O(n-i)         |
-//! | RingBuf | O(1)           | O(min(i, n-i))* | O(min(i, n-i)) | O(m)*  | O(min(i, n-i)) |
-//! | DList   | O(min(i, n-i)) | O(min(i, n-i))  | O(min(i, n-i)) | O(1)   | O(min(i, n-i)) |
-//! | Bitv    | O(1)           | O(n-i)*         | O(n-i)         | O(m)*  | O(n-i)         |
+//! |              | get(i)         | insert(i)       | remove(i)      | append | split_off(i)   |
+//! |--------------|----------------|-----------------|----------------|--------|----------------|
+//! | Vec          | O(1)           | O(n-i)*         | O(n-i)         | O(m)*  | O(n-i)         |
+//! | VecDeque     | O(1)           | O(min(i, n-i))* | O(min(i, n-i)) | O(m)*  | O(min(i, n-i)) |
+//! | LinkedList   | O(min(i, n-i)) | O(min(i, n-i))  | O(min(i, n-i)) | O(1)   | O(min(i, n-i)) |
+//! | BitVec       | O(1)           | O(n-i)*         | O(n-i)         | O(m)*  | O(n-i)         |
 //!
-//! Note that where ties occur, Vec is generally going to be faster than RingBuf, and RingBuf
-//! is generally going to be faster than DList. Bitv is not a general purpose collection, and
+//! Note that where ties occur, Vec is generally going to be faster than VecDeque, and VecDeque
+//! is generally going to be faster than LinkedList. BitVec is not a general purpose collection, and
 //! therefore cannot reasonably be compared.
 //!
 //! ## Maps
 //!
-//! For Sets, all operations have the cost of the equivalent Map operation. For BitvSet,
+//! For Sets, all operations have the cost of the equivalent Map operation. For BitSet,
 //! refer to VecMap.
 //!
 //! |          | get       | insert   | remove   | predecessor |
@@ -166,7 +166,7 @@
 //!
 //! Any `with_capacity` constructor will instruct the collection to allocate enough space
 //! for the specified number of elements. Ideally this will be for exactly that many
-//! elements, but some implementation details may prevent this. `Vec` and `RingBuf` can
+//! elements, but some implementation details may prevent this. `Vec` and `VecDeque` can
 //! be relied on to allocate exactly the requested amount, though. Use `with_capacity`
 //! when you know exactly how many elements will be inserted, or at least have a
 //! reasonable upper-bound on that number.
@@ -240,10 +240,10 @@
 //! ```
 //!
 //! ```
-//! use std::collections::RingBuf;
+//! use std::collections::VecDeque;
 //!
 //! let vec = vec![1, 2, 3, 4];
-//! let buf: RingBuf<_> = vec.into_iter().collect();
+//! let buf: VecDeque<_> = vec.into_iter().collect();
 //! ```
 //!
 //! Iterators also provide a series of *adapter* methods for performing common tasks to
@@ -362,11 +362,11 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 pub use core_collections::Bound;
-pub use core_collections::{BinaryHeap, Bitv, BitvSet, BTreeMap, BTreeSet};
-pub use core_collections::{DList, RingBuf, VecMap};
+pub use core_collections::{BinaryHeap, BitVec, BitSet, BTreeMap, BTreeSet};
+pub use core_collections::{LinkedList, VecDeque, VecMap};
 
-pub use core_collections::{binary_heap, bitv, bitv_set, btree_map, btree_set};
-pub use core_collections::{dlist, ring_buf, vec_map};
+pub use core_collections::{binary_heap, bit_vec, bit_set, btree_map, btree_set};
+pub use core_collections::{linked_list, vec_deque, vec_map};
 
 pub use self::hash_map::HashMap;
 pub use self::hash_set::HashSet;
diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs
index c5dd66630b4..b0fb9c29403 100644
--- a/src/libstd/dynamic_lib.rs
+++ b/src/libstd/dynamic_lib.rs
@@ -112,7 +112,7 @@ impl DynamicLibrary {
         // This function should have a lifetime constraint of 'a on
         // T but that feature is still unimplemented
 
-        let raw_string = CString::from_slice(symbol.as_bytes());
+        let raw_string = CString::new(symbol).unwrap();
         let maybe_symbol_value = dl::check_for_errors_in(|| {
             dl::symbol(self.handle, raw_string.as_ptr())
         });
@@ -187,7 +187,7 @@ mod test {
 mod dl {
     use prelude::v1::*;
 
-    use ffi::{self, CString};
+    use ffi::{CString, CStr};
     use str;
     use libc;
     use ptr;
@@ -206,7 +206,7 @@ mod dl {
     const LAZY: libc::c_int = 1;
 
     unsafe fn open_external(filename: &[u8]) -> *mut u8 {
-        let s = CString::from_slice(filename);
+        let s = CString::new(filename).unwrap();
         dlopen(s.as_ptr(), LAZY) as *mut u8
     }
 
@@ -231,7 +231,7 @@ mod dl {
             let ret = if ptr::null() == last_error {
                 Ok(result)
             } else {
-                let s = ffi::c_str_to_bytes(&last_error);
+                let s = CStr::from_ptr(last_error).to_bytes();
                 Err(str::from_utf8(s).unwrap().to_string())
             };
 
diff --git a/src/libstd/env.rs b/src/libstd/env.rs
index 93dc3efe2c4..8676586e7dc 100644
--- a/src/libstd/env.rs
+++ b/src/libstd/env.rs
@@ -926,7 +926,7 @@ mod tests {
     #[cfg(unix)]
     fn join_paths_unix() {
         fn test_eq(input: &[&str], output: &str) -> bool {
-            &*join_paths(input.iter().map(|s| *s)).unwrap() ==
+            &*join_paths(input.iter().cloned()).unwrap() ==
                 OsStr::from_str(output)
         }
 
@@ -935,14 +935,14 @@ mod tests {
                          "/bin:/usr/bin:/usr/local/bin"));
         assert!(test_eq(&["", "/bin", "", "", "/usr/bin", ""],
                          ":/bin:::/usr/bin:"));
-        assert!(join_paths(["/te:st"].iter().map(|s| *s)).is_err());
+        assert!(join_paths(["/te:st"].iter().cloned()).is_err());
     }
 
     #[test]
     #[cfg(windows)]
     fn join_paths_windows() {
         fn test_eq(input: &[&str], output: &str) -> bool {
-            &*join_paths(input.iter().map(|s| *s)).unwrap() ==
+            &*join_paths(input.iter().cloned()).unwrap() ==
                 OsStr::from_str(output)
         }
 
@@ -953,6 +953,6 @@ mod tests {
                         r";c:\windows;;;c:\;"));
         assert!(test_eq(&[r"c:\te;st", r"c:\"],
                         r#""c:\te;st";c:\"#));
-        assert!(join_paths([r#"c:\te"st"#].iter().map(|s| *s)).is_err());
+        assert!(join_paths([r#"c:\te"st"#].iter().cloned()).is_err());
     }
     }
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
index 45089176cba..8976813d3f9 100644
--- a/src/libstd/ffi/c_str.rs
+++ b/src/libstd/ffi/c_str.rs
@@ -8,18 +8,25 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
+use error::{Error, FromError};
 use fmt;
+use io;
 use iter::IteratorExt;
 use libc;
 use mem;
+use old_io;
 use ops::Deref;
+use option::Option::{self, Some, None};
+use result::Result::{self, Ok, Err};
 use slice::{self, SliceExt};
+use str::StrExt;
 use string::String;
 use vec::Vec;
 
-/// A type representing a C-compatible string
+/// A type representing an owned C-compatible string
 ///
-/// This type serves the primary purpose of being able to generate a
+/// This type serves the primary purpose of being able to safely generate a
 /// C-compatible string from a Rust byte slice or vector. An instance of this
 /// type is a static guarantee that the underlying bytes contain no interior 0
 /// bytes and the final byte is 0.
@@ -44,8 +51,8 @@ use vec::Vec;
 ///     fn my_printer(s: *const libc::c_char);
 /// }
 ///
-/// let to_print = "Hello, world!";
-/// let c_to_print = CString::from_slice(to_print.as_bytes());
+/// let to_print = b"Hello, world!";
+/// let c_to_print = CString::new(to_print).unwrap();
 /// unsafe {
 ///     my_printer(c_to_print.as_ptr());
 /// }
@@ -53,19 +60,135 @@ use vec::Vec;
 /// ```
 #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
 pub struct CString {
-    inner: Vec<libc::c_char>,
+    inner: Vec<u8>,
+}
+
+/// Representation of a borrowed C string.
+///
+/// This dynamically sized type is only safely constructed via a borrowed
+/// version of an instance of `CString`. This type can be constructed from a raw
+/// C string as well and represents a C string borrowed from another location.
+///
+/// Note that this structure is **not** `repr(C)` and is not recommended to be
+/// placed in the signatures of FFI functions. Instead safe wrappers of FFI
+/// functions may leverage the unsafe `from_ptr` constructor to provide a safe
+/// interface to other consumers.
+///
+/// # Examples
+///
+/// Inspecting a foreign C string
+///
+/// ```no_run
+/// extern crate libc;
+/// use std::ffi::CStr;
+///
+/// extern { fn my_string() -> *const libc::c_char; }
+///
+/// fn main() {
+///     unsafe {
+///         let slice = CStr::from_ptr(my_string());
+///         println!("string length: {}", slice.to_bytes().len());
+///     }
+/// }
+/// ```
+///
+/// Passing a Rust-originating C string
+///
+/// ```no_run
+/// extern crate libc;
+/// use std::ffi::{CString, CStr};
+///
+/// fn work(data: &CStr) {
+///     extern { fn work_with(data: *const libc::c_char); }
+///
+///     unsafe { work_with(data.as_ptr()) }
+/// }
+///
+/// fn main() {
+///     let s = CString::new("data data data data").unwrap();
+///     work(&s);
+/// }
+/// ```
+#[derive(Hash)]
+pub struct CStr {
+    inner: [libc::c_char]
+}
+
+/// An error returned from `CString::new` to indicate that a nul byte was found
+/// in the vector provided.
+#[derive(Clone, PartialEq, Debug)]
+pub struct NulError(usize, Vec<u8>);
+
+/// A conversion trait used by the constructor of `CString` for types that can
+/// be converted to a vector of bytes.
+pub trait IntoBytes {
+    /// Consumes this container, returning a vector of bytes.
+    fn into_bytes(self) -> Vec<u8>;
 }
 
 impl CString {
+    /// Create a new C-compatible string from a container of bytes.
+    ///
+    /// This method will consume the provided data and use the underlying bytes
+    /// to construct a new string, ensuring that there is a trailing 0 byte.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// extern crate libc;
+    /// use std::ffi::CString;
+    ///
+    /// extern { fn puts(s: *const libc::c_char); }
+    ///
+    /// fn main() {
+    ///     let to_print = CString::new("Hello!").unwrap();
+    ///     unsafe {
+    ///         puts(to_print.as_ptr());
+    ///     }
+    /// }
+    /// ```
+    ///
+    /// # Errors
+    ///
+    /// This function will return an error if the bytes yielded contain an
+    /// internal 0 byte. The error returned will contain the bytes as well as
+    /// the position of the nul byte.
+    pub fn new<T: IntoBytes>(t: T) -> Result<CString, NulError> {
+        let bytes = t.into_bytes();
+        match bytes.iter().position(|x| *x == 0) {
+            Some(i) => Err(NulError(i, bytes)),
+            None => Ok(unsafe { CString::from_vec_unchecked(bytes) }),
+        }
+    }
+
     /// Create a new C-compatible string from a byte slice.
     ///
     /// This method will copy the data of the slice provided into a new
     /// allocation, ensuring that there is a trailing 0 byte.
     ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// extern crate libc;
+    /// use std::ffi::CString;
+    ///
+    /// extern { fn puts(s: *const libc::c_char); }
+    ///
+    /// fn main() {
+    ///     let to_print = CString::new("Hello!").unwrap();
+    ///     unsafe {
+    ///         puts(to_print.as_ptr());
+    ///     }
+    /// }
+    /// ```
+    ///
     /// # Panics
     ///
-    /// This function will panic if there are any 0 bytes already in the slice
-    /// provided.
+    /// This function will panic if the provided slice contains any
+    /// interior nul bytes.
+    #[unstable(feature = "std_misc")]
+    #[deprecated(since = "1.0.0", reason = "use CString::new instead")]
+    #[allow(deprecated)]
     pub fn from_slice(v: &[u8]) -> CString {
         CString::from_vec(v.to_vec())
     }
@@ -77,11 +200,15 @@ impl CString {
     ///
     /// # Panics
     ///
-    /// This function will panic if there are any 0 bytes already in the vector
-    /// provided.
+    /// This function will panic if the provided slice contains any
+    /// interior nul bytes.
+    #[unstable(feature = "std_misc")]
+    #[deprecated(since = "1.0.0", reason = "use CString::new instead")]
     pub fn from_vec(v: Vec<u8>) -> CString {
-        assert!(!v.iter().any(|&x| x == 0));
-        unsafe { CString::from_vec_unchecked(v) }
+        match v.iter().position(|x| *x == 0) {
+            Some(i) => panic!("null byte found in slice at: {}", i),
+            None => unsafe { CString::from_vec_unchecked(v) },
+        }
     }
 
     /// Create a C-compatible string from a byte vector without checking for
@@ -91,31 +218,29 @@ impl CString {
     /// is made that `v` contains no 0 bytes.
     pub unsafe fn from_vec_unchecked(mut v: Vec<u8>) -> CString {
         v.push(0);
-        CString { inner: mem::transmute(v) }
+        CString { inner: v }
     }
 
-    /// Create a view into this C string which includes the trailing nul
-    /// terminator at the end of the string.
-    pub fn as_slice_with_nul(&self) -> &[libc::c_char] { &self.inner }
-
-    /// Similar to the `as_slice` method, but returns a `u8` slice instead of a
-    /// `libc::c_char` slice.
+    /// Returns the contents of this `CString` as a slice of bytes.
+    ///
+    /// The returned slice does **not** contain the trailing nul separator and
+    /// it is guaranteet to not have any interior nul bytes.
     pub fn as_bytes(&self) -> &[u8] {
-        unsafe { mem::transmute(&**self) }
+        &self.inner[..self.inner.len() - 1]
     }
 
-    /// Equivalent to `as_slice_with_nul` except that the type returned is a
-    /// `u8` slice instead of a `libc::c_char` slice.
+    /// Equivalent to the `as_bytes` function except that the returned slice
+    /// includes the trailing nul byte.
     pub fn as_bytes_with_nul(&self) -> &[u8] {
-        unsafe { mem::transmute(self.as_slice_with_nul()) }
+        &self.inner
     }
 }
 
 impl Deref for CString {
-    type Target = [libc::c_char];
+    type Target = CStr;
 
-    fn deref(&self) -> &[libc::c_char] {
-        &self.inner[..(self.inner.len() - 1)]
+    fn deref(&self) -> &CStr {
+        unsafe { mem::transmute(self.as_bytes_with_nul()) }
     }
 }
 
@@ -126,54 +251,172 @@ impl fmt::Debug for CString {
     }
 }
 
-/// Interpret a C string as a byte slice.
-///
-/// This function will calculate the length of the C string provided, and it
-/// will then return a corresponding slice for the contents of the C string not
-/// including the nul terminator.
-///
-/// This function will tie the lifetime of the returned slice to the lifetime of
-/// the pointer provided. This is done to help prevent the slice from escaping
-/// the lifetime of the pointer itself. If a longer lifetime is needed, then
-/// `mem::copy_lifetime` should be used.
-///
-/// This function is unsafe because there is no guarantee of the validity of the
-/// pointer `raw` or a guarantee that a nul terminator will be found.
-///
-/// # Example
-///
-/// ```no_run
-/// # extern crate libc;
-/// # fn main() {
-/// use std::ffi;
-/// use std::str;
-/// use libc;
-///
-/// extern {
-///     fn my_string() -> *const libc::c_char;
-/// }
-///
-/// unsafe {
-///     let to_print = my_string();
-///     let slice = ffi::c_str_to_bytes(&to_print);
-///     println!("string returned: {}", str::from_utf8(slice).unwrap());
-/// }
-/// # }
-/// ```
+impl NulError {
+    /// Returns the position of the nul byte in the slice that was provided to
+    /// `CString::from_vec`.
+    pub fn nul_position(&self) -> usize { self.0 }
+
+    /// Consumes this error, returning the underlying vector of bytes which
+    /// generated the error in the first place.
+    pub fn into_vec(self) -> Vec<u8> { self.1 }
+}
+
+impl Error for NulError {
+    fn description(&self) -> &str { "nul byte found in data" }
+}
+
+impl fmt::Display for NulError {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "nul byte found in provided data at position: {}", self.0)
+    }
+}
+
+impl FromError<NulError> for io::Error {
+    fn from_error(_: NulError) -> io::Error {
+        io::Error::new(io::ErrorKind::InvalidInput,
+                       "data provided contains a nul byte", None)
+    }
+}
+
+impl FromError<NulError> for old_io::IoError {
+    fn from_error(_: NulError) -> old_io::IoError {
+        old_io::IoError {
+            kind: old_io::IoErrorKind::InvalidInput,
+            desc: "data provided contains a nul byte",
+            detail: None
+        }
+    }
+}
+
+impl CStr {
+    /// Cast a raw C string to a safe C string wrapper.
+    ///
+    /// This function will cast the provided `ptr` to the `CStr` wrapper which
+    /// allows inspection and interoperation of non-owned C strings. This method
+    /// is unsafe for a number of reasons:
+    ///
+    /// * There is no guarantee to the validity of `ptr`
+    /// * The returned lifetime is not guaranteed to be the actual lifetime of
+    ///   `ptr`
+    /// * There is no guarantee that the memory pointed to by `ptr` contains a
+    ///   valid nul terminator byte at the end of the string.
+    ///
+    /// > **Note**: This operation is intended to be a 0-cost cast but it is
+    /// > currently implemented with an up-front calculation of the length of
+    /// > the string. This is not guaranteed to always be the case.
+    ///
+    /// # Example
+    ///
+    /// ```no_run
+    /// # extern crate libc;
+    /// # fn main() {
+    /// use std::ffi::CStr;
+    /// use std::str;
+    /// use libc;
+    ///
+    /// extern {
+    ///     fn my_string() -> *const libc::c_char;
+    /// }
+    ///
+    /// unsafe {
+    ///     let slice = CStr::from_ptr(my_string());
+    ///     println!("string returned: {}",
+    ///              str::from_utf8(slice.to_bytes()).unwrap());
+    /// }
+    /// # }
+    /// ```
+    pub unsafe fn from_ptr<'a>(ptr: *const libc::c_char) -> &'a CStr {
+        let len = libc::strlen(ptr);
+        mem::transmute(slice::from_raw_parts(ptr, len as usize + 1))
+    }
+
+    /// Return the inner pointer to this C string.
+    ///
+    /// The returned pointer will be valid for as long as `self` is and points
+    /// to a continguous region of memory terminated with a 0 byte to represent
+    /// the end of the string.
+    pub fn as_ptr(&self) -> *const libc::c_char {
+        self.inner.as_ptr()
+    }
+
+    /// Convert this C string to a byte slice.
+    ///
+    /// This function will calculate the length of this string (which normally
+    /// requires a linear amount of work to be done) and then return the
+    /// resulting slice of `u8` elements.
+    ///
+    /// The returned slice will **not** contain the trailing nul that this C
+    /// string has.
+    ///
+    /// > **Note**: This method is currently implemented as a 0-cost cast, but
+    /// > it is planned to alter its definition in the future to perform the
+    /// > length calculation whenever this method is called.
+    pub fn to_bytes(&self) -> &[u8] {
+        let bytes = self.to_bytes_with_nul();
+        &bytes[..bytes.len() - 1]
+    }
+
+    /// Convert this C string to a byte slice containing the trailing 0 byte.
+    ///
+    /// This function is the equivalent of `to_bytes` except that it will retain
+    /// the trailing nul instead of chopping it off.
+    ///
+    /// > **Note**: This method is currently implemented as a 0-cost cast, but
+    /// > it is planned to alter its definition in the future to perform the
+    /// > length calculation whenever this method is called.
+    pub fn to_bytes_with_nul(&self) -> &[u8] {
+        unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.inner) }
+    }
+}
+
+impl PartialEq for CStr {
+    fn eq(&self, other: &CStr) -> bool {
+        self.to_bytes().eq(&other.to_bytes())
+    }
+}
+impl Eq for CStr {}
+impl PartialOrd for CStr {
+    fn partial_cmp(&self, other: &CStr) -> Option<Ordering> {
+        self.to_bytes().partial_cmp(&other.to_bytes())
+    }
+}
+impl Ord for CStr {
+    fn cmp(&self, other: &CStr) -> Ordering {
+        self.to_bytes().cmp(&other.to_bytes())
+    }
+}
+
+/// Deprecated in favor of `CStr`
+#[unstable(feature = "std_misc")]
+#[deprecated(since = "1.0.0", reason = "use CStr::from_ptr(p).to_bytes() instead")]
 pub unsafe fn c_str_to_bytes<'a>(raw: &'a *const libc::c_char) -> &'a [u8] {
     let len = libc::strlen(*raw);
     slice::from_raw_parts(*(raw as *const _ as *const *const u8), len as usize)
 }
 
-/// Interpret a C string as a byte slice with the nul terminator.
-///
-/// This function is identical to `from_raw_buf` except that the returned slice
-/// will include the nul terminator of the string.
-pub unsafe fn c_str_to_bytes_with_nul<'a>(raw: &'a *const libc::c_char) -> &'a [u8] {
+/// Deprecated in favor of `CStr`
+#[unstable(feature = "std_misc")]
+#[deprecated(since = "1.0.0",
+             reason = "use CStr::from_ptr(p).to_bytes_with_nul() instead")]
+pub unsafe fn c_str_to_bytes_with_nul<'a>(raw: &'a *const libc::c_char)
+                                          -> &'a [u8] {
     let len = libc::strlen(*raw) + 1;
     slice::from_raw_parts(*(raw as *const _ as *const *const u8), len as usize)
 }
 
+impl<'a> IntoBytes for &'a str {
+    fn into_bytes(self) -> Vec<u8> { self.as_bytes().to_vec() }
+}
+impl<'a> IntoBytes for &'a [u8] {
+    fn into_bytes(self) -> Vec<u8> { self.to_vec() }
+}
+impl IntoBytes for String {
+    fn into_bytes(self) -> Vec<u8> { self.into_bytes() }
+}
+impl IntoBytes for Vec<u8> {
+    fn into_bytes(self) -> Vec<u8> { self }
+}
+
 #[cfg(test)]
 mod tests {
     use prelude::v1::*;
@@ -193,21 +436,19 @@ mod tests {
 
     #[test]
     fn simple() {
-        let s = CString::from_slice(b"1234");
+        let s = CString::new(b"1234").unwrap();
         assert_eq!(s.as_bytes(), b"1234");
         assert_eq!(s.as_bytes_with_nul(), b"1234\0");
-        unsafe {
-            assert_eq!(&*s,
-                       mem::transmute::<_, &[libc::c_char]>(b"1234"));
-            assert_eq!(s.as_slice_with_nul(),
-                       mem::transmute::<_, &[libc::c_char]>(b"1234\0"));
-        }
     }
 
-    #[should_fail] #[test]
-    fn build_with_zero1() { CString::from_slice(b"\0"); }
-    #[should_fail] #[test]
-    fn build_with_zero2() { CString::from_vec(vec![0]); }
+    #[test]
+    fn build_with_zero1() {
+        assert!(CString::new(b"\0").is_err());
+    }
+    #[test]
+    fn build_with_zero2() {
+        assert!(CString::new(vec![0]).is_err());
+    }
 
     #[test]
     fn build_with_zero3() {
@@ -219,7 +460,16 @@ mod tests {
 
     #[test]
     fn formatted() {
-        let s = CString::from_slice(b"12");
+        let s = CString::new(b"12").unwrap();
         assert_eq!(format!("{:?}", s), "\"12\"");
     }
+
+    #[test]
+    fn borrowed() {
+        unsafe {
+            let s = CStr::from_ptr(b"12\0".as_ptr() as *const _);
+            assert_eq!(s.to_bytes(), b"12");
+            assert_eq!(s.to_bytes_with_nul(), b"12\0");
+        }
+    }
 }
diff --git a/src/libstd/ffi/mod.rs b/src/libstd/ffi/mod.rs
index 07a4f17796c..1bff6afb776 100644
--- a/src/libstd/ffi/mod.rs
+++ b/src/libstd/ffi/mod.rs
@@ -14,8 +14,10 @@
             reason = "module just underwent fairly large reorganization and the dust \
                       still needs to settle")]
 
-pub use self::c_str::CString;
+pub use self::c_str::{CString, CStr, NulError, IntoBytes};
+#[allow(deprecated)]
 pub use self::c_str::c_str_to_bytes;
+#[allow(deprecated)]
 pub use self::c_str::c_str_to_bytes_with_nul;
 
 pub use self::os_str::OsString;
diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs
index 1d14b141778..84149a2eb8e 100644
--- a/src/libstd/ffi/os_str.rs
+++ b/src/libstd/ffi/os_str.rs
@@ -34,13 +34,14 @@
 
 use core::prelude::*;
 
-use core::borrow::{BorrowFrom, ToOwned};
+use borrow::{Borrow, ToOwned};
 use fmt::{self, Debug};
 use mem;
 use string::{String, CowString};
 use ops;
 use cmp;
-use hash::{Hash, Hasher, Writer};
+use hash::{Hash, Hasher};
+#[cfg(stage0)] use hash::Writer;
 use old_path::{Path, GenericPath};
 
 use sys::os_str::{Buf, Slice};
@@ -103,7 +104,7 @@ impl ops::Deref for OsString {
 
     #[inline]
     fn deref(&self) -> &OsStr {
-        &self[]
+        &self[..]
     }
 }
 
@@ -162,12 +163,21 @@ impl Ord for OsString {
     }
 }
 
+#[cfg(stage0)]
 impl<'a, S: Hasher + Writer> Hash<S> for OsString {
     #[inline]
     fn hash(&self, state: &mut S) {
         (&**self).hash(state)
     }
 }
+#[cfg(not(stage0))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Hash for OsString {
+    #[inline]
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        (&**self).hash(state)
+    }
+}
 
 impl OsStr {
     /// Coerce directly from a `&str` slice to a `&OsStr` slice.
@@ -253,12 +263,21 @@ impl Ord for OsStr {
     fn cmp(&self, other: &OsStr) -> cmp::Ordering { self.bytes().cmp(other.bytes()) }
 }
 
+#[cfg(stage0)]
 impl<'a, S: Hasher + Writer> Hash<S> for OsStr {
     #[inline]
     fn hash(&self, state: &mut S) {
         self.bytes().hash(state)
     }
 }
+#[cfg(not(stage0))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Hash for OsStr {
+    #[inline]
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        self.bytes().hash(state)
+    }
+}
 
 impl Debug for OsStr {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
@@ -266,11 +285,12 @@ impl Debug for OsStr {
     }
 }
 
-impl BorrowFrom<OsString> for OsStr {
-    fn borrow_from(owned: &OsString) -> &OsStr { &owned[] }
+impl Borrow<OsStr> for OsString {
+    fn borrow(&self) -> &OsStr { &self[..] }
 }
 
-impl ToOwned<OsString> for OsStr {
+impl ToOwned for OsStr {
+    type Owned = OsString;
     fn to_owned(&self) -> OsString { self.to_os_string() }
 }
 
@@ -288,7 +308,7 @@ impl AsOsStr for OsStr {
 
 impl AsOsStr for OsString {
     fn as_os_str(&self) -> &OsStr {
-        &self[]
+        &self[..]
     }
 }
 
@@ -300,7 +320,7 @@ impl AsOsStr for str {
 
 impl AsOsStr for String {
     fn as_os_str(&self) -> &OsStr {
-        OsStr::from_str(&self[])
+        OsStr::from_str(&self[..])
     }
 }
 
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index 2fd6631ecc4..e9a8dbb4098 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -618,14 +618,14 @@ mod tests {
     #[test]
     fn read_char_buffered() {
         let buf = [195u8, 159u8];
-        let mut reader = BufReader::with_capacity(1, &buf[]);
+        let mut reader = BufReader::with_capacity(1, &buf[..]);
         assert_eq!(reader.chars().next(), Some(Ok('ß')));
     }
 
     #[test]
     fn test_chars() {
         let buf = [195u8, 159u8, b'a'];
-        let mut reader = BufReader::with_capacity(1, &buf[]);
+        let mut reader = BufReader::with_capacity(1, &buf[..]);
         let mut it = reader.chars();
         assert_eq!(it.next(), Some(Ok('ß')));
         assert_eq!(it.next(), Some(Ok('a')));
diff --git a/src/libstd/io/cursor.rs b/src/libstd/io/cursor.rs
index 9f3655de20f..f6cb4a8c9f3 100644
--- a/src/libstd/io/cursor.rs
+++ b/src/libstd/io/cursor.rs
@@ -180,7 +180,7 @@ mod tests {
     fn test_buf_writer() {
         let mut buf = [0 as u8; 9];
         {
-            let mut writer = Cursor::new(&mut buf[]);
+            let mut writer = Cursor::new(&mut buf[..]);
             assert_eq!(writer.position(), 0);
             assert_eq!(writer.write(&[0]), Ok(1));
             assert_eq!(writer.position(), 1);
@@ -201,7 +201,7 @@ mod tests {
     fn test_buf_writer_seek() {
         let mut buf = [0 as u8; 8];
         {
-            let mut writer = Cursor::new(&mut buf[]);
+            let mut writer = Cursor::new(&mut buf[..]);
             assert_eq!(writer.position(), 0);
             assert_eq!(writer.write(&[1]), Ok(1));
             assert_eq!(writer.position(), 1);
@@ -229,7 +229,7 @@ mod tests {
     #[test]
     fn test_buf_writer_error() {
         let mut buf = [0 as u8; 2];
-        let mut writer = Cursor::new(&mut buf[]);
+        let mut writer = Cursor::new(&mut buf[..]);
         assert_eq!(writer.write(&[0]), Ok(1));
         assert_eq!(writer.write(&[0, 0]), Ok(1));
         assert_eq!(writer.write(&[0, 0]), Ok(0));
@@ -331,7 +331,7 @@ mod tests {
     #[test]
     fn seek_past_end() {
         let buf = [0xff];
-        let mut r = Cursor::new(&buf[]);
+        let mut r = Cursor::new(&buf[..]);
         assert_eq!(r.seek(SeekFrom::Start(10)), Ok(10));
         assert_eq!(r.read(&mut [0]), Ok(0));
 
@@ -340,7 +340,7 @@ mod tests {
         assert_eq!(r.read(&mut [0]), Ok(0));
 
         let mut buf = [0];
-        let mut r = Cursor::new(&mut buf[]);
+        let mut r = Cursor::new(&mut buf[..]);
         assert_eq!(r.seek(SeekFrom::Start(10)), Ok(10));
         assert_eq!(r.write(&[3]), Ok(0));
     }
@@ -348,14 +348,14 @@ mod tests {
     #[test]
     fn seek_before_0() {
         let buf = [0xff_u8];
-        let mut r = Cursor::new(&buf[]);
+        let mut r = Cursor::new(&buf[..]);
         assert!(r.seek(SeekFrom::End(-2)).is_err());
 
         let mut r = Cursor::new(vec!(10u8));
         assert!(r.seek(SeekFrom::End(-2)).is_err());
 
         let mut buf = [0];
-        let mut r = Cursor::new(&mut buf[]);
+        let mut r = Cursor::new(&mut buf[..]);
         assert!(r.seek(SeekFrom::End(-2)).is_err());
     }
 
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 7c9a8a7b4b5..fbd403ea593 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -161,7 +161,6 @@ extern crate libc;
 // NB: These reexports are in the order they should be listed in rustdoc
 
 pub use core::any;
-pub use core::borrow;
 pub use core::cell;
 pub use core::clone;
 #[cfg(not(test))] pub use core::cmp;
@@ -184,6 +183,7 @@ pub use core::error;
 #[cfg(not(test))] pub use alloc::boxed;
 pub use alloc::rc;
 
+pub use core_collections::borrow;
 pub use core_collections::fmt;
 pub use core_collections::slice;
 pub use core_collections::str;
diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs
index 66d4d34f8eb..51944adf3b4 100644
--- a/src/libstd/net/addr.rs
+++ b/src/libstd/net/addr.rs
@@ -147,6 +147,7 @@ impl PartialEq for Repr {
 }
 impl Eq for Repr {}
 
+#[cfg(stage0)]
 impl<S: hash::Hasher + hash::Writer> hash::Hash<S> for Repr {
     fn hash(&self, s: &mut S) {
         match *self {
@@ -160,6 +161,21 @@ impl<S: hash::Hasher + hash::Writer> hash::Hash<S> for Repr {
         }
     }
 }
+#[cfg(not(stage0))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl hash::Hash for Repr {
+    fn hash<H: hash::Hasher>(&self, s: &mut H) {
+        match *self {
+            Repr::V4(ref a) => {
+                (a.sin_family, a.sin_port, a.sin_addr.s_addr).hash(s)
+            }
+            Repr::V6(ref a) => {
+                (a.sin6_family, a.sin6_port, &a.sin6_addr.s6_addr,
+                 a.sin6_flowinfo, a.sin6_scope_id).hash(s)
+            }
+        }
+    }
+}
 
 /// A trait for objects which can be converted or resolved to one or more
 /// `SocketAddr` values.
diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs
index 08f7a6e2e96..571a1b03ef0 100644
--- a/src/libstd/net/ip.rs
+++ b/src/libstd/net/ip.rs
@@ -189,11 +189,19 @@ impl PartialEq for Ipv4Addr {
 }
 impl Eq for Ipv4Addr {}
 
+#[cfg(stage0)]
 impl<S: hash::Hasher + hash::Writer> hash::Hash<S> for Ipv4Addr {
     fn hash(&self, s: &mut S) {
         self.inner.s_addr.hash(s)
     }
 }
+#[cfg(not(stage0))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl hash::Hash for Ipv4Addr {
+    fn hash<H: hash::Hasher>(&self, s: &mut H) {
+        self.inner.s_addr.hash(s)
+    }
+}
 
 impl PartialOrd for Ipv4Addr {
     fn partial_cmp(&self, other: &Ipv4Addr) -> Option<Ordering> {
@@ -421,11 +429,19 @@ impl PartialEq for Ipv6Addr {
 }
 impl Eq for Ipv6Addr {}
 
+#[cfg(stage0)]
 impl<S: hash::Hasher + hash::Writer> hash::Hash<S> for Ipv6Addr {
     fn hash(&self, s: &mut S) {
         self.inner.s6_addr.hash(s)
     }
 }
+#[cfg(not(stage0))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl hash::Hash for Ipv6Addr {
+    fn hash<H: hash::Hasher>(&self, s: &mut H) {
+        self.inner.s6_addr.hash(s)
+    }
+}
 
 impl PartialOrd for Ipv6Addr {
     fn partial_cmp(&self, other: &Ipv6Addr) -> Option<Ordering> {
diff --git a/src/libstd/old_io/buffered.rs b/src/libstd/old_io/buffered.rs
index 59a437ad916..2d2d0d8b33a 100644
--- a/src/libstd/old_io/buffered.rs
+++ b/src/libstd/old_io/buffered.rs
@@ -546,7 +546,7 @@ mod test {
         assert_eq!(a, &w.get_ref()[]);
         let w = w.into_inner();
         let a: &[_] = &[0, 1];
-        assert_eq!(a, &w[]);
+        assert_eq!(a, &w[..]);
     }
 
     // This is just here to make sure that we don't infinite loop in the
@@ -643,14 +643,14 @@ mod test {
     #[test]
     fn read_char_buffered() {
         let buf = [195u8, 159u8];
-        let mut reader = BufferedReader::with_capacity(1, &buf[]);
+        let mut reader = BufferedReader::with_capacity(1, &buf[..]);
         assert_eq!(reader.read_char(), Ok('ß'));
     }
 
     #[test]
     fn test_chars() {
         let buf = [195u8, 159u8, b'a'];
-        let mut reader = BufferedReader::with_capacity(1, &buf[]);
+        let mut reader = BufferedReader::with_capacity(1, &buf[..]);
         let mut it = reader.chars();
         assert_eq!(it.next(), Some(Ok('ß')));
         assert_eq!(it.next(), Some(Ok('a')));
diff --git a/src/libstd/old_io/mod.rs b/src/libstd/old_io/mod.rs
index 21282a0c28a..fc3deb67f41 100644
--- a/src/libstd/old_io/mod.rs
+++ b/src/libstd/old_io/mod.rs
@@ -252,7 +252,7 @@ use error::Error;
 use fmt;
 use isize;
 use iter::{Iterator, IteratorExt};
-use marker::Sized;
+use marker::{PhantomFn, Sized};
 use mem::transmute;
 use ops::FnOnce;
 use option::Option;
@@ -433,7 +433,7 @@ pub enum IoErrorKind {
 }
 
 /// A trait that lets you add a `detail` to an IoError easily
-trait UpdateIoError<T> {
+trait UpdateIoError {
     /// Returns an IoError with updated description and detail
     fn update_err<D>(self, desc: &'static str, detail: D) -> Self where
         D: FnOnce(&IoError) -> String;
@@ -446,7 +446,7 @@ trait UpdateIoError<T> {
     fn update_desc(self, desc: &'static str) -> Self;
 }
 
-impl<T> UpdateIoError<T> for IoResult<T> {
+impl<T> UpdateIoError for IoResult<T> {
     fn update_err<D>(self, desc: &'static str, detail: D) -> IoResult<T> where
         D: FnOnce(&IoError) -> String,
     {
@@ -1572,7 +1572,9 @@ pub trait Seek {
 /// connections.
 ///
 /// Doing so produces some sort of Acceptor.
-pub trait Listener<T, A: Acceptor<T>> {
+pub trait Listener<T, A: Acceptor<T>>
+    : PhantomFn<T,T> // FIXME should be an assoc type anyhow
+{
     /// Spin up the listener and start queuing incoming connections
     ///
     /// # Error
diff --git a/src/libstd/old_io/net/pipe.rs b/src/libstd/old_io/net/pipe.rs
index 8a4e8668b10..d05669d32b8 100644
--- a/src/libstd/old_io/net/pipe.rs
+++ b/src/libstd/old_io/net/pipe.rs
@@ -55,7 +55,7 @@ impl UnixStream {
     /// stream.write(&[1, 2, 3]);
     /// ```
     pub fn connect<P: BytesContainer>(path: P) -> IoResult<UnixStream> {
-        let path = CString::from_slice(path.container_as_bytes());
+        let path = try!(CString::new(path.container_as_bytes()));
         UnixStreamImp::connect(&path, None)
             .map(|inner| UnixStream { inner: inner })
     }
@@ -77,7 +77,7 @@ impl UnixStream {
             return Err(standard_error(TimedOut));
         }
 
-        let path = CString::from_slice(path.container_as_bytes());
+        let path = try!(CString::new(path.container_as_bytes()));
         UnixStreamImp::connect(&path, Some(timeout.num_milliseconds() as u64))
             .map(|inner| UnixStream { inner: inner })
     }
@@ -184,7 +184,7 @@ impl UnixListener {
     /// # }
     /// ```
     pub fn bind<P: BytesContainer>(path: P) -> IoResult<UnixListener> {
-        let path = CString::from_slice(path.container_as_bytes());
+        let path = try!(CString::new(path.container_as_bytes()));
         UnixListenerImp::bind(&path)
             .map(|inner| UnixListener { inner: inner })
     }
diff --git a/src/libstd/old_io/process.rs b/src/libstd/old_io/process.rs
index ea6510c61b7..c803cfbcb7d 100644
--- a/src/libstd/old_io/process.rs
+++ b/src/libstd/old_io/process.rs
@@ -104,7 +104,7 @@ struct EnvKey(CString);
 #[derive(Eq, Clone, Debug)]
 struct EnvKey(CString);
 
-#[cfg(windows)]
+#[cfg(all(windows, stage0))]
 impl<H: hash::Writer + hash::Hasher> hash::Hash<H> for EnvKey {
     fn hash(&self, state: &mut H) {
         let &EnvKey(ref x) = self;
@@ -116,6 +116,18 @@ impl<H: hash::Writer + hash::Hasher> hash::Hash<H> for EnvKey {
         }
     }
 }
+#[cfg(all(windows, not(stage0)))]
+impl hash::Hash for EnvKey {
+    fn hash<H: hash::Hasher>(&self, state: &mut H) {
+        let &EnvKey(ref x) = self;
+        match str::from_utf8(x.as_bytes()) {
+            Ok(s) => for ch in s.chars() {
+                (ch as u8 as char).to_lowercase().hash(state);
+            },
+            Err(..) => x.hash(state)
+        }
+    }
+}
 
 #[cfg(windows)]
 impl PartialEq for EnvKey {
@@ -204,7 +216,7 @@ impl Command {
     /// otherwise configure the process.
     pub fn new<T: BytesContainer>(program: T) -> Command {
         Command {
-            program: CString::from_slice(program.container_as_bytes()),
+            program: CString::new(program.container_as_bytes()).unwrap(),
             args: Vec::new(),
             env: None,
             cwd: None,
@@ -219,14 +231,14 @@ impl Command {
 
     /// Add an argument to pass to the program.
     pub fn arg<'a, T: BytesContainer>(&'a mut self, arg: T) -> &'a mut Command {
-        self.args.push(CString::from_slice(arg.container_as_bytes()));
+        self.args.push(CString::new(arg.container_as_bytes()).unwrap());
         self
     }
 
     /// Add multiple arguments to pass to the program.
     pub fn args<'a, T: BytesContainer>(&'a mut self, args: &[T]) -> &'a mut Command {
         self.args.extend(args.iter().map(|arg| {
-            CString::from_slice(arg.container_as_bytes())
+            CString::new(arg.container_as_bytes()).unwrap()
         }));
         self
     }
@@ -239,8 +251,8 @@ impl Command {
                 // if the env is currently just inheriting from the parent's,
                 // materialize the parent's env into a hashtable.
                 self.env = Some(os::env_as_bytes().into_iter().map(|(k, v)| {
-                    (EnvKey(CString::from_slice(&k)),
-                     CString::from_slice(&v))
+                    (EnvKey(CString::new(k).unwrap()),
+                     CString::new(v).unwrap())
                 }).collect());
                 self.env.as_mut().unwrap()
             }
@@ -254,8 +266,8 @@ impl Command {
     pub fn env<'a, T, U>(&'a mut self, key: T, val: U)
                          -> &'a mut Command
                          where T: BytesContainer, U: BytesContainer {
-        let key = EnvKey(CString::from_slice(key.container_as_bytes()));
-        let val = CString::from_slice(val.container_as_bytes());
+        let key = EnvKey(CString::new(key.container_as_bytes()).unwrap());
+        let val = CString::new(val.container_as_bytes()).unwrap();
         self.get_env_map().insert(key, val);
         self
     }
@@ -263,7 +275,7 @@ impl Command {
     /// Removes an environment variable mapping.
     pub fn env_remove<'a, T>(&'a mut self, key: T) -> &'a mut Command
                              where T: BytesContainer {
-        let key = EnvKey(CString::from_slice(key.container_as_bytes()));
+        let key = EnvKey(CString::new(key.container_as_bytes()).unwrap());
         self.get_env_map().remove(&key);
         self
     }
@@ -276,15 +288,15 @@ impl Command {
                                  -> &'a mut Command
                                  where T: BytesContainer, U: BytesContainer {
         self.env = Some(env.iter().map(|&(ref k, ref v)| {
-            (EnvKey(CString::from_slice(k.container_as_bytes())),
-             CString::from_slice(v.container_as_bytes()))
+            (EnvKey(CString::new(k.container_as_bytes()).unwrap()),
+             CString::new(v.container_as_bytes()).unwrap())
         }).collect());
         self
     }
 
     /// Set the working directory for the child process.
     pub fn cwd<'a>(&'a mut self, dir: &Path) -> &'a mut Command {
-        self.cwd = Some(CString::from_slice(dir.as_vec()));
+        self.cwd = Some(CString::new(dir.as_vec()).unwrap());
         self
     }
 
@@ -1226,7 +1238,7 @@ mod tests {
         cmd.env("path", "foo");
         cmd.env("Path", "bar");
         let env = &cmd.env.unwrap();
-        let val = env.get(&EnvKey(CString::from_slice(b"PATH")));
-        assert!(val.unwrap() == &CString::from_slice(b"bar"));
+        let val = env.get(&EnvKey(CString::new(b"PATH").unwrap()));
+        assert!(val.unwrap() == &CString::new(b"bar").unwrap());
     }
 }
diff --git a/src/libstd/old_path/mod.rs b/src/libstd/old_path/mod.rs
index 37de2993c4d..e9005aa22bc 100644
--- a/src/libstd/old_path/mod.rs
+++ b/src/libstd/old_path/mod.rs
@@ -877,7 +877,7 @@ impl BytesContainer for String {
     }
     #[inline]
     fn container_as_str(&self) -> Option<&str> {
-        Some(&self[])
+        Some(&self[..])
     }
     #[inline]
     fn is_str(_: Option<&String>) -> bool { true }
@@ -893,7 +893,7 @@ impl BytesContainer for [u8] {
 impl BytesContainer for Vec<u8> {
     #[inline]
     fn container_as_bytes(&self) -> &[u8] {
-        &self[]
+        &self[..]
     }
 }
 
diff --git a/src/libstd/old_path/posix.rs b/src/libstd/old_path/posix.rs
index 0a184a01a1d..15eee9e4a0c 100644
--- a/src/libstd/old_path/posix.rs
+++ b/src/libstd/old_path/posix.rs
@@ -100,12 +100,21 @@ impl FromStr for Path {
 #[derive(Debug, Clone, PartialEq, Copy)]
 pub struct ParsePathError;
 
+#[cfg(stage0)]
 impl<S: hash::Writer + hash::Hasher> hash::Hash<S> for Path {
     #[inline]
     fn hash(&self, state: &mut S) {
         self.repr.hash(state)
     }
 }
+#[cfg(not(stage0))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl hash::Hash for Path {
+    #[inline]
+    fn hash<H: hash::Hasher>(&self, state: &mut H) {
+        self.repr.hash(state)
+    }
+}
 
 impl BytesContainer for Path {
     #[inline]
@@ -1172,7 +1181,7 @@ mod tests {
                     let exp: &[&[u8]] = &[$($exp),*];
                     assert_eq!(comps, exp);
                     let comps = path.components().rev().collect::<Vec<&[u8]>>();
-                    let exp = exp.iter().rev().map(|&x|x).collect::<Vec<&[u8]>>();
+                    let exp = exp.iter().rev().cloned().collect::<Vec<&[u8]>>();
                     assert_eq!(comps, exp)
                 }
             )
@@ -1204,7 +1213,7 @@ mod tests {
                     let exp: &[Option<&str>] = &$exp;
                     assert_eq!(comps, exp);
                     let comps = path.str_components().rev().collect::<Vec<Option<&str>>>();
-                    let exp = exp.iter().rev().map(|&x|x).collect::<Vec<Option<&str>>>();
+                    let exp = exp.iter().rev().cloned().collect::<Vec<Option<&str>>>();
                     assert_eq!(comps, exp);
                 }
             )
diff --git a/src/libstd/old_path/windows.rs b/src/libstd/old_path/windows.rs
index 02a21321c4c..887dc804c7a 100644
--- a/src/libstd/old_path/windows.rs
+++ b/src/libstd/old_path/windows.rs
@@ -127,6 +127,7 @@ impl FromStr for Path {
 #[derive(Debug, Clone, PartialEq, Copy)]
 pub struct ParsePathError;
 
+#[cfg(stage0)]
 impl<S: hash::Writer + hash::Hasher> hash::Hash<S> for Path {
     #[cfg(not(test))]
     #[inline]
@@ -140,6 +141,21 @@ impl<S: hash::Writer + hash::Hasher> hash::Hash<S> for Path {
         // No-op because the `hash` implementation will be wrong.
     }
 }
+#[cfg(not(stage0))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl hash::Hash for Path {
+    #[cfg(not(test))]
+    #[inline]
+    fn hash<H: hash::Hasher>(&self, state: &mut H) {
+        self.repr.hash(state)
+    }
+
+    #[cfg(test)]
+    #[inline]
+    fn hash<H: hash::Hasher>(&self, _: &mut H) {
+        // No-op because the `hash` implementation will be wrong.
+    }
+}
 
 impl BytesContainer for Path {
     #[inline]
@@ -182,7 +198,7 @@ impl GenericPathUnsafe for Path {
                 s.push_str("..");
                 s.push(SEP);
                 s.push_str(filename);
-                self.update_normalized(&s[]);
+                self.update_normalized(&s[..]);
             }
             None => {
                 self.update_normalized(filename);
@@ -192,20 +208,20 @@ impl GenericPathUnsafe for Path {
                 s.push_str(&self.repr[..end]);
                 s.push(SEP);
                 s.push_str(filename);
-                self.update_normalized(&s[]);
+                self.update_normalized(&s[..]);
             }
             Some((idxb,idxa,_)) if self.prefix == Some(DiskPrefix) && idxa == self.prefix_len() => {
                 let mut s = String::with_capacity(idxb + filename.len());
                 s.push_str(&self.repr[..idxb]);
                 s.push_str(filename);
-                self.update_normalized(&s[]);
+                self.update_normalized(&s[..]);
             }
             Some((idxb,_,_)) => {
                 let mut s = String::with_capacity(idxb + 1 + filename.len());
                 s.push_str(&self.repr[..idxb]);
                 s.push(SEP);
                 s.push_str(filename);
-                self.update_normalized(&s[]);
+                self.update_normalized(&s[..]);
             }
         }
     }
@@ -229,7 +245,7 @@ impl GenericPathUnsafe for Path {
         }
         fn shares_volume(me: &Path, path: &str) -> bool {
             // path is assumed to have a prefix of Some(DiskPrefix)
-            let repr = &me.repr[];
+            let repr = &me.repr[..];
             match me.prefix {
                 Some(DiskPrefix) => {
                     repr.as_bytes()[0] == path.as_bytes()[0].to_ascii_uppercase()
@@ -261,7 +277,7 @@ impl GenericPathUnsafe for Path {
                         else { None };
             let pathlen = path_.as_ref().map_or(path.len(), |p| p.len());
             let mut s = String::with_capacity(me.repr.len() + 1 + pathlen);
-            s.push_str(&me.repr[]);
+            s.push_str(&me.repr[..]);
             let plen = me.prefix_len();
             // if me is "C:" we don't want to add a path separator
             match me.prefix {
@@ -273,9 +289,9 @@ impl GenericPathUnsafe for Path {
             }
             match path_ {
                 None => s.push_str(path),
-                Some(p) => s.push_str(&p[]),
+                Some(p) => s.push_str(&p[..]),
             };
-            me.update_normalized(&s[])
+            me.update_normalized(&s[..])
         }
 
         if !path.is_empty() {
@@ -329,7 +345,7 @@ impl GenericPath for Path {
     /// Always returns a `Some` value.
     #[inline]
     fn as_str<'a>(&'a self) -> Option<&'a str> {
-        Some(&self.repr[])
+        Some(&self.repr[..])
     }
 
     #[inline]
@@ -351,13 +367,13 @@ impl GenericPath for Path {
     /// Always returns a `Some` value.
     fn dirname_str<'a>(&'a self) -> Option<&'a str> {
         Some(match self.sepidx_or_prefix_len() {
-            None if ".." == self.repr => &self.repr[],
+            None if ".." == self.repr => &self.repr[..],
             None => ".",
             Some((_,idxa,end)) if &self.repr[idxa..end] == ".." => {
-                &self.repr[]
+                &self.repr[..]
             }
             Some((idxb,_,end)) if &self.repr[idxb..end] == "\\" => {
-                &self.repr[]
+                &self.repr[..]
             }
             Some((0,idxa,_)) => &self.repr[..idxa],
             Some((idxb,idxa,_)) => {
@@ -379,7 +395,7 @@ impl GenericPath for Path {
     /// See `GenericPath::filename_str` for info.
     /// Always returns a `Some` value if `filename` returns a `Some` value.
     fn filename_str<'a>(&'a self) -> Option<&'a str> {
-        let repr = &self.repr[];
+        let repr = &self.repr[..];
         match self.sepidx_or_prefix_len() {
             None if "." == repr || ".." == repr => None,
             None => Some(repr),
@@ -639,7 +655,7 @@ impl Path {
     /// Does not distinguish between absolute and cwd-relative paths, e.g.
     /// C:\foo and C:foo.
     pub fn str_components<'a>(&'a self) -> StrComponents<'a> {
-        let repr = &self.repr[];
+        let repr = &self.repr[..];
         let s = match self.prefix {
             Some(_) => {
                 let plen = self.prefix_len();
@@ -667,8 +683,8 @@ impl Path {
     }
 
     fn equiv_prefix(&self, other: &Path) -> bool {
-        let s_repr = &self.repr[];
-        let o_repr = &other.repr[];
+        let s_repr = &self.repr[..];
+        let o_repr = &other.repr[..];
         match (self.prefix, other.prefix) {
             (Some(DiskPrefix), Some(VerbatimDiskPrefix)) => {
                 self.is_absolute() &&
@@ -823,7 +839,7 @@ impl Path {
     fn update_sepidx(&mut self) {
         let s = if self.has_nonsemantic_trailing_slash() {
                     &self.repr[..self.repr.len()-1]
-                } else { &self.repr[] };
+                } else { &self.repr[..] };
         let sep_test: fn(char) -> bool = if !prefix_is_verbatim(self.prefix) {
             is_sep
         } else {
@@ -902,7 +918,7 @@ pub fn is_verbatim(path: &Path) -> bool {
 /// non-verbatim, the non-verbatim version is returned.
 /// Otherwise, None is returned.
 pub fn make_non_verbatim(path: &Path) -> Option<Path> {
-    let repr = &path.repr[];
+    let repr = &path.repr[..];
     let new_path = match path.prefix {
         Some(VerbatimPrefix(_)) | Some(DeviceNSPrefix(_)) => return None,
         Some(UNCPrefix(_,_)) | Some(DiskPrefix) | None => return Some(path.clone()),
@@ -2226,7 +2242,7 @@ mod tests {
                     assert_eq!(comps, exp);
                     let comps = path.str_components().rev().map(|x|x.unwrap())
                                 .collect::<Vec<&str>>();
-                    let exp = exp.iter().rev().map(|&x|x).collect::<Vec<&str>>();
+                    let exp = exp.iter().rev().cloned().collect::<Vec<&str>>();
                     assert_eq!(comps, exp);
                 }
             );
@@ -2282,7 +2298,7 @@ mod tests {
                     let exp: &[&[u8]] = &$exp;
                     assert_eq!(comps, exp);
                     let comps = path.components().rev().collect::<Vec<&[u8]>>();
-                    let exp = exp.iter().rev().map(|&x|x).collect::<Vec<&[u8]>>();
+                    let exp = exp.iter().rev().cloned().collect::<Vec<&[u8]>>();
                     assert_eq!(comps, exp);
                 }
             )
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index a4213e7373b..f181fc5df57 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -561,10 +561,11 @@ pub fn get_exit_status() -> int {
 #[cfg(target_os = "macos")]
 unsafe fn load_argc_and_argv(argc: int,
                              argv: *const *const c_char) -> Vec<Vec<u8>> {
+    use ffi::CStr;
     use iter::range;
 
-    (0..argc as uint).map(|i| {
-        ffi::c_str_to_bytes(&*argv.offset(i as int)).to_vec()
+    (0..argc).map(|i| {
+        CStr::from_ptr(*argv.offset(i)).to_bytes().to_vec()
     }).collect()
 }
 
diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs
index 35221a7e647..2e05f6d974e 100644
--- a/src/libstd/panicking.rs
+++ b/src/libstd/panicking.rs
@@ -37,7 +37,7 @@ pub fn on_panic(obj: &(Any+Send), file: &'static str, line: uint) {
     let msg = match obj.downcast_ref::<&'static str>() {
         Some(s) => *s,
         None => match obj.downcast_ref::<String>() {
-            Some(s) => &s[],
+            Some(s) => &s[..],
             None => "Box<Any>",
         }
     };
diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index 1d992668900..49a5efec7c2 100755
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -108,12 +108,11 @@
 use core::prelude::*;
 
 use ascii::*;
-use borrow::BorrowFrom;
+use borrow::{Borrow, ToOwned, Cow};
 use cmp;
-use iter;
+use iter::{self, IntoIterator};
 use mem;
 use ops::{self, Deref};
-use string::CowString;
 use vec::Vec;
 use fmt;
 
@@ -953,7 +952,7 @@ impl PathBuf {
 }
 
 impl<'a, P: ?Sized + 'a> iter::FromIterator<&'a P> for PathBuf where P: AsPath {
-    fn from_iter<I: Iterator<Item = &'a P>>(iter: I) -> PathBuf {
+    fn from_iter<I: IntoIterator<Item = &'a P>>(iter: I) -> PathBuf {
         let mut buf = PathBuf::new("");
         buf.extend(iter);
         buf
@@ -961,7 +960,7 @@ impl<'a, P: ?Sized + 'a> iter::FromIterator<&'a P> for PathBuf where P: AsPath {
 }
 
 impl<'a, P: ?Sized + 'a> iter::Extend<&'a P> for PathBuf where P: AsPath {
-    fn extend<I: Iterator<Item = &'a P>>(&mut self, iter: I) {
+    fn extend<I: IntoIterator<Item = &'a P>>(&mut self, iter: I) {
         for p in iter {
             self.push(p)
         }
@@ -978,16 +977,21 @@ impl ops::Deref for PathBuf {
     type Target = Path;
 
     fn deref(&self) -> &Path {
-        unsafe { mem::transmute(&self.inner[]) }
+        unsafe { mem::transmute(&self.inner[..]) }
     }
 }
 
-impl BorrowFrom<PathBuf> for Path {
-    fn borrow_from(owned: &PathBuf) -> &Path {
-        owned.deref()
+impl Borrow<Path> for PathBuf {
+    fn borrow(&self) -> &Path {
+        self.deref()
     }
 }
 
+impl ToOwned for Path {
+    type Owned = PathBuf;
+    fn to_owned(&self) -> PathBuf { self.to_path_buf() }
+}
+
 impl cmp::PartialEq for PathBuf {
     fn eq(&self, other: &PathBuf) -> bool {
         self.components() == other.components()
@@ -1010,7 +1014,7 @@ impl cmp::Ord for PathBuf {
 
 impl AsOsStr for PathBuf {
     fn as_os_str(&self) -> &OsStr {
-        &self.inner[]
+        &self.inner[..]
     }
 }
 
@@ -1066,10 +1070,10 @@ impl Path {
         self.inner.to_str()
     }
 
-    /// Convert a `Path` to a `CowString`.
+    /// Convert a `Path` to a `Cow<str>`.
     ///
     /// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER.
-    pub fn to_string_lossy(&self) -> CowString {
+    pub fn to_string_lossy(&self) -> Cow<str> {
         self.inner.to_string_lossy()
     }
 
diff --git a/src/libstd/rand/mod.rs b/src/libstd/rand/mod.rs
index 25d372b406f..5c891441198 100644
--- a/src/libstd/rand/mod.rs
+++ b/src/libstd/rand/mod.rs
@@ -547,7 +547,7 @@ mod test {
     #[test]
     fn test_choose() {
         let mut r = thread_rng();
-        assert_eq!(r.choose(&[1, 1, 1]).map(|&x|x), Some(1));
+        assert_eq!(r.choose(&[1, 1, 1]).cloned(), Some(1));
 
         let v: &[int] = &[];
         assert_eq!(r.choose(v), None);
diff --git a/src/libstd/rt/args.rs b/src/libstd/rt/args.rs
index c2f5133eaf3..61f5bd0f013 100644
--- a/src/libstd/rt/args.rs
+++ b/src/libstd/rt/args.rs
@@ -49,7 +49,7 @@ mod imp {
 
     use libc;
     use mem;
-    use ffi;
+    use ffi::CStr;
 
     use sync::{StaticMutex, MUTEX_INIT};
 
@@ -96,10 +96,11 @@ mod imp {
         unsafe { mem::transmute(&GLOBAL_ARGS_PTR) }
     }
 
-    unsafe fn load_argc_and_argv(argc: int, argv: *const *const u8) -> Vec<Vec<u8>> {
+    unsafe fn load_argc_and_argv(argc: isize,
+                                 argv: *const *const u8) -> Vec<Vec<u8>> {
         let argv = argv as *const *const libc::c_char;
-        (0..argc as uint).map(|i| {
-            ffi::c_str_to_bytes(&*argv.offset(i as int)).to_vec()
+        (0..argc).map(|i| {
+            CStr::from_ptr(*argv.offset(i)).to_bytes().to_vec()
         }).collect()
     }
 
diff --git a/src/libstd/sys/common/net.rs b/src/libstd/sys/common/net.rs
index 7325e0a5ac8..e2ac5ac24f8 100644
--- a/src/libstd/sys/common/net.rs
+++ b/src/libstd/sys/common/net.rs
@@ -12,8 +12,7 @@ use prelude::v1::*;
 use self::SocketStatus::*;
 use self::InAddr::*;
 
-use ffi::CString;
-use ffi;
+use ffi::{CString, CStr};
 use old_io::net::addrinfo;
 use old_io::net::ip::{SocketAddr, IpAddr, Ipv4Addr, Ipv6Addr};
 use old_io::{IoResult, IoError};
@@ -235,9 +234,15 @@ pub fn get_host_addresses(host: Option<&str>, servname: Option<&str>,
 
     assert!(host.is_some() || servname.is_some());
 
-    let c_host = host.map(|x| CString::from_slice(x.as_bytes()));
+    let c_host = match host {
+        Some(x) => Some(try!(CString::new(x))),
+        None => None,
+    };
     let c_host = c_host.as_ref().map(|x| x.as_ptr()).unwrap_or(null());
-    let c_serv = servname.map(|x| CString::from_slice(x.as_bytes()));
+    let c_serv = match servname {
+        Some(x) => Some(try!(CString::new(x))),
+        None => None,
+    };
     let c_serv = c_serv.as_ref().map(|x| x.as_ptr()).unwrap_or(null());
 
     let hint = hint.map(|hint| {
@@ -325,8 +330,8 @@ pub fn get_address_name(addr: IpAddr) -> Result<String, IoError> {
     }
 
     unsafe {
-        Ok(str::from_utf8(ffi::c_str_to_bytes(&hostbuf.as_ptr()))
-               .unwrap().to_string())
+        let data = CStr::from_ptr(hostbuf.as_ptr());
+        Ok(str::from_utf8(data.to_bytes()).unwrap().to_string())
     }
 }
 
diff --git a/src/libstd/sys/common/net2.rs b/src/libstd/sys/common/net2.rs
index 5af59ec6d2b..713f79c5d08 100644
--- a/src/libstd/sys/common/net2.rs
+++ b/src/libstd/sys/common/net2.rs
@@ -121,7 +121,7 @@ impl Drop for LookupHost {
 pub fn lookup_host(host: &str) -> io::Result<LookupHost> {
     init();
 
-    let c_host = CString::from_slice(host.as_bytes());
+    let c_host = try!(CString::new(host));
     let mut res = 0 as *mut _;
     unsafe {
         try!(cvt_gai(getaddrinfo(c_host.as_ptr(), 0 as *const _, 0 as *const _,
diff --git a/src/libstd/sys/common/wtf8.rs b/src/libstd/sys/common/wtf8.rs
index b610f6c370b..ca3ae1a7a34 100644
--- a/src/libstd/sys/common/wtf8.rs
+++ b/src/libstd/sys/common/wtf8.rs
@@ -31,8 +31,9 @@ use ascii::*;
 use borrow::Cow;
 use cmp;
 use fmt;
-use hash::{Hash, Writer, Hasher};
-use iter::FromIterator;
+use hash::{Hash, Hasher};
+#[cfg(stage0)] use hash::Writer;
+use iter::{FromIterator, IntoIterator};
 use mem;
 use num::Int;
 use ops;
@@ -356,9 +357,9 @@ impl Wtf8Buf {
 /// This replaces surrogate code point pairs with supplementary code points,
 /// like concatenating ill-formed UTF-16 strings effectively would.
 impl FromIterator<CodePoint> for Wtf8Buf {
-    fn from_iter<T: Iterator<Item=CodePoint>>(iterator: T) -> Wtf8Buf {
+    fn from_iter<T: IntoIterator<Item=CodePoint>>(iter: T) -> Wtf8Buf {
         let mut string = Wtf8Buf::new();
-        string.extend(iterator);
+        string.extend(iter);
         string
     }
 }
@@ -368,7 +369,8 @@ impl FromIterator<CodePoint> for Wtf8Buf {
 /// This replaces surrogate code point pairs with supplementary code points,
 /// like concatenating ill-formed UTF-16 strings effectively would.
 impl Extend<CodePoint> for Wtf8Buf {
-    fn extend<T: Iterator<Item=CodePoint>>(&mut self, iterator: T) {
+    fn extend<T: IntoIterator<Item=CodePoint>>(&mut self, iterable: T) {
+        let iterator = iterable.into_iter();
         let (low, _high) = iterator.size_hint();
         // Lower bound of one byte per code point (ASCII only)
         self.bytes.reserve(low);
@@ -794,13 +796,22 @@ impl<'a> Iterator for EncodeWide<'a> {
     }
 }
 
+#[cfg(stage0)]
 impl<S: Writer + Hasher> Hash<S> for CodePoint {
     #[inline]
     fn hash(&self, state: &mut S) {
         self.value.hash(state)
     }
 }
+#[cfg(not(stage0))]
+impl Hash for CodePoint {
+    #[inline]
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        self.value.hash(state)
+    }
+}
 
+#[cfg(stage0)]
 impl<S: Writer + Hasher> Hash<S> for Wtf8Buf {
     #[inline]
     fn hash(&self, state: &mut S) {
@@ -808,7 +819,16 @@ impl<S: Writer + Hasher> Hash<S> for Wtf8Buf {
         0xfeu8.hash(state)
     }
 }
+#[cfg(not(stage0))]
+impl Hash for Wtf8Buf {
+    #[inline]
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        state.write(&self.bytes);
+        0xfeu8.hash(state)
+    }
+}
 
+#[cfg(stage0)]
 impl<'a, S: Writer + Hasher> Hash<S> for Wtf8 {
     #[inline]
     fn hash(&self, state: &mut S) {
@@ -816,6 +836,14 @@ impl<'a, S: Writer + Hasher> Hash<S> for Wtf8 {
         0xfeu8.hash(state)
     }
 }
+#[cfg(not(stage0))]
+impl Hash for Wtf8 {
+    #[inline]
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        state.write(&self.bytes);
+        0xfeu8.hash(state)
+    }
+}
 
 impl AsciiExt for Wtf8 {
     type Owned = Wtf8Buf;
diff --git a/src/libstd/sys/unix/backtrace.rs b/src/libstd/sys/unix/backtrace.rs
index 5e512e9261b..8b560339f30 100644
--- a/src/libstd/sys/unix/backtrace.rs
+++ b/src/libstd/sys/unix/backtrace.rs
@@ -85,7 +85,7 @@
 
 use prelude::v1::*;
 
-use ffi;
+use ffi::CStr;
 use old_io::IoResult;
 use libc;
 use mem;
@@ -233,7 +233,7 @@ fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> {
         output(w, idx,addr, None)
     } else {
         output(w, idx, addr, Some(unsafe {
-            ffi::c_str_to_bytes(&info.dli_sname)
+            CStr::from_ptr(info.dli_sname).to_bytes()
         }))
     }
 }
@@ -364,7 +364,7 @@ fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> {
     if ret == 0 || data.is_null() {
         output(w, idx, addr, None)
     } else {
-        output(w, idx, addr, Some(unsafe { ffi::c_str_to_bytes(&data) }))
+        output(w, idx, addr, Some(unsafe { CStr::from_ptr(data).to_bytes() }))
     }
 }
 
diff --git a/src/libstd/sys/unix/ext.rs b/src/libstd/sys/unix/ext.rs
index bbbe022fbaf..b8b9dcfb3c6 100644
--- a/src/libstd/sys/unix/ext.rs
+++ b/src/libstd/sys/unix/ext.rs
@@ -33,7 +33,7 @@
 
 use prelude::v1::*;
 
-use ffi::{CString, OsStr, OsString};
+use ffi::{CString, NulError, OsStr, OsString};
 use fs::{self, Permissions, OpenOptions};
 use net;
 use mem;
@@ -155,7 +155,7 @@ pub trait OsStrExt {
     fn as_bytes(&self) -> &[u8];
 
     /// Convert the `OsStr` slice into a `CString`.
-    fn to_cstring(&self) -> CString;
+    fn to_cstring(&self) -> Result<CString, NulError>;
 }
 
 impl OsStrExt for OsStr {
@@ -166,8 +166,8 @@ impl OsStrExt for OsStr {
         &self.as_inner().inner
     }
 
-    fn to_cstring(&self) -> CString {
-        CString::from_slice(self.as_bytes())
+    fn to_cstring(&self) -> Result<CString, NulError> {
+        CString::new(self.as_bytes())
     }
 }
 
@@ -249,5 +249,7 @@ impl ExitStatusExt for process::ExitStatus {
 /// Includes all extension traits, and some important type definitions.
 pub mod prelude {
     #[doc(no_inline)]
-    pub use super::{Fd, AsRawFd, OsStrExt, OsStringExt, PermissionsExt, CommandExt, ExitStatusExt};
+    pub use super::{Fd, AsRawFd, OsStrExt, OsStringExt, PermissionsExt};
+    #[doc(no_inline)]
+    pub use super::{CommandExt, ExitStatusExt};
 }
diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs
index 0ee2b5b6809..5c847002d23 100644
--- a/src/libstd/sys/unix/fs.rs
+++ b/src/libstd/sys/unix/fs.rs
@@ -12,7 +12,7 @@
 
 use prelude::v1::*;
 
-use ffi::{self, CString};
+use ffi::{CString, CStr};
 use old_io::{FilePermission, Write, UnstableFileStat, Open, FileAccess, FileMode};
 use old_io::{IoResult, FileStat, SeekStyle};
 use old_io::{Read, Truncate, SeekCur, SeekSet, ReadWrite, SeekEnd, Append};
@@ -151,8 +151,8 @@ impl Drop for FileDesc {
     }
 }
 
-fn cstr(path: &Path) -> CString {
-    CString::from_slice(path.as_vec())
+fn cstr(path: &Path) -> IoResult<CString> {
+    Ok(try!(CString::new(path.as_vec())))
 }
 
 pub fn open(path: &Path, fm: FileMode, fa: FileAccess) -> IoResult<FileDesc> {
@@ -170,7 +170,7 @@ pub fn open(path: &Path, fm: FileMode, fa: FileAccess) -> IoResult<FileDesc> {
                             libc::S_IRUSR | libc::S_IWUSR),
     };
 
-    let path = cstr(path);
+    let path = try!(cstr(path));
     match retry(|| unsafe { libc::open(path.as_ptr(), flags, mode) }) {
         -1 => Err(super::last_error()),
         fd => Ok(FileDesc::new(fd, true)),
@@ -178,7 +178,7 @@ pub fn open(path: &Path, fm: FileMode, fa: FileAccess) -> IoResult<FileDesc> {
 }
 
 pub fn mkdir(p: &Path, mode: uint) -> IoResult<()> {
-    let p = cstr(p);
+    let p = try!(cstr(p));
     mkerr_libc(unsafe { libc::mkdir(p.as_ptr(), mode as libc::mode_t) })
 }
 
@@ -203,7 +203,7 @@ pub fn readdir(p: &Path) -> IoResult<Vec<Path>> {
     let mut buf = Vec::<u8>::with_capacity(size as uint);
     let ptr = buf.as_mut_ptr() as *mut dirent_t;
 
-    let p = CString::from_slice(p.as_vec());
+    let p = try!(CString::new(p.as_vec()));
     let dir_ptr = unsafe {opendir(p.as_ptr())};
 
     if dir_ptr as uint != 0 {
@@ -212,7 +212,7 @@ pub fn readdir(p: &Path) -> IoResult<Vec<Path>> {
         while unsafe { readdir_r(dir_ptr, ptr, &mut entry_ptr) == 0 } {
             if entry_ptr.is_null() { break }
             paths.push(unsafe {
-                Path::new(ffi::c_str_to_bytes(&rust_list_dir_val(entry_ptr)))
+                Path::new(CStr::from_ptr(rust_list_dir_val(entry_ptr)).to_bytes())
             });
         }
         assert_eq!(unsafe { closedir(dir_ptr) }, 0);
@@ -223,39 +223,39 @@ pub fn readdir(p: &Path) -> IoResult<Vec<Path>> {
 }
 
 pub fn unlink(p: &Path) -> IoResult<()> {
-    let p = cstr(p);
+    let p = try!(cstr(p));
     mkerr_libc(unsafe { libc::unlink(p.as_ptr()) })
 }
 
 pub fn rename(old: &Path, new: &Path) -> IoResult<()> {
-    let old = cstr(old);
-    let new = cstr(new);
+    let old = try!(cstr(old));
+    let new = try!(cstr(new));
     mkerr_libc(unsafe {
         libc::rename(old.as_ptr(), new.as_ptr())
     })
 }
 
 pub fn chmod(p: &Path, mode: uint) -> IoResult<()> {
-    let p = cstr(p);
+    let p = try!(cstr(p));
     mkerr_libc(retry(|| unsafe {
         libc::chmod(p.as_ptr(), mode as libc::mode_t)
     }))
 }
 
 pub fn rmdir(p: &Path) -> IoResult<()> {
-    let p = cstr(p);
+    let p = try!(cstr(p));
     mkerr_libc(unsafe { libc::rmdir(p.as_ptr()) })
 }
 
 pub fn chown(p: &Path, uid: int, gid: int) -> IoResult<()> {
-    let p = cstr(p);
+    let p = try!(cstr(p));
     mkerr_libc(retry(|| unsafe {
         libc::chown(p.as_ptr(), uid as libc::uid_t, gid as libc::gid_t)
     }))
 }
 
 pub fn readlink(p: &Path) -> IoResult<Path> {
-    let c_path = cstr(p);
+    let c_path = try!(cstr(p));
     let p = c_path.as_ptr();
     let mut len = unsafe { libc::pathconf(p as *mut _, libc::_PC_NAME_MAX) };
     if len == -1 {
@@ -276,14 +276,14 @@ pub fn readlink(p: &Path) -> IoResult<Path> {
 }
 
 pub fn symlink(src: &Path, dst: &Path) -> IoResult<()> {
-    let src = cstr(src);
-    let dst = cstr(dst);
+    let src = try!(cstr(src));
+    let dst = try!(cstr(dst));
     mkerr_libc(unsafe { libc::symlink(src.as_ptr(), dst.as_ptr()) })
 }
 
 pub fn link(src: &Path, dst: &Path) -> IoResult<()> {
-    let src = cstr(src);
-    let dst = cstr(dst);
+    let src = try!(cstr(src));
+    let dst = try!(cstr(dst));
     mkerr_libc(unsafe { libc::link(src.as_ptr(), dst.as_ptr()) })
 }
 
@@ -331,7 +331,7 @@ fn mkstat(stat: &libc::stat) -> FileStat {
 }
 
 pub fn stat(p: &Path) -> IoResult<FileStat> {
-    let p = cstr(p);
+    let p = try!(cstr(p));
     let mut stat: libc::stat = unsafe { mem::zeroed() };
     match unsafe { libc::stat(p.as_ptr(), &mut stat) } {
         0 => Ok(mkstat(&stat)),
@@ -340,7 +340,7 @@ pub fn stat(p: &Path) -> IoResult<FileStat> {
 }
 
 pub fn lstat(p: &Path) -> IoResult<FileStat> {
-    let p = cstr(p);
+    let p = try!(cstr(p));
     let mut stat: libc::stat = unsafe { mem::zeroed() };
     match unsafe { libc::lstat(p.as_ptr(), &mut stat) } {
         0 => Ok(mkstat(&stat)),
@@ -349,7 +349,7 @@ pub fn lstat(p: &Path) -> IoResult<FileStat> {
 }
 
 pub fn utime(p: &Path, atime: u64, mtime: u64) -> IoResult<()> {
-    let p = cstr(p);
+    let p = try!(cstr(p));
     let buf = libc::utimbuf {
         actime: (atime / 1000) as libc::time_t,
         modtime: (mtime / 1000) as libc::time_t,
diff --git a/src/libstd/sys/unix/fs2.rs b/src/libstd/sys/unix/fs2.rs
index e5904b074bc..92a47c6c385 100644
--- a/src/libstd/sys/unix/fs2.rs
+++ b/src/libstd/sys/unix/fs2.rs
@@ -12,7 +12,7 @@ use core::prelude::*;
 use io::prelude::*;
 use os::unix::prelude::*;
 
-use ffi::{self, CString, OsString, AsOsStr, OsStr};
+use ffi::{CString, CStr, OsString, AsOsStr, OsStr};
 use io::{self, Error, Seek, SeekFrom};
 use libc::{self, c_int, c_void, size_t, off_t, c_char, mode_t};
 use mem;
@@ -147,8 +147,7 @@ impl DirEntry {
             fn rust_list_dir_val(ptr: *mut libc::dirent_t) -> *const c_char;
         }
         unsafe {
-            let ptr = rust_list_dir_val(self.dirent);
-            ffi::c_str_to_bytes(mem::copy_lifetime(self, &ptr))
+            CStr::from_ptr(rust_list_dir_val(self.dirent)).to_bytes()
         }
     }
 }
@@ -204,7 +203,7 @@ impl File {
             (true, false) |
             (false, false) => libc::O_RDONLY,
         };
-        let path = cstr(path);
+        let path = try!(cstr(path));
         let fd = try!(cvt_r(|| unsafe {
             libc::open(path.as_ptr(), flags, opts.mode)
         }));
@@ -268,19 +267,20 @@ impl File {
     pub fn fd(&self) -> &FileDesc { &self.0 }
 }
 
-fn cstr(path: &Path) -> CString {
-    CString::from_slice(path.as_os_str().as_bytes())
+fn cstr(path: &Path) -> io::Result<CString> {
+    let cstring = try!(path.as_os_str().to_cstring());
+    Ok(cstring)
 }
 
 pub fn mkdir(p: &Path) -> io::Result<()> {
-    let p = cstr(p);
+    let p = try!(cstr(p));
     try!(cvt(unsafe { libc::mkdir(p.as_ptr(), 0o777) }));
     Ok(())
 }
 
 pub fn readdir(p: &Path) -> io::Result<ReadDir> {
     let root = Rc::new(p.to_path_buf());
-    let p = cstr(p);
+    let p = try!(cstr(p));
     unsafe {
         let ptr = libc::opendir(p.as_ptr());
         if ptr.is_null() {
@@ -292,32 +292,32 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
 }
 
 pub fn unlink(p: &Path) -> io::Result<()> {
-    let p = cstr(p);
+    let p = try!(cstr(p));
     try!(cvt(unsafe { libc::unlink(p.as_ptr()) }));
     Ok(())
 }
 
 pub fn rename(old: &Path, new: &Path) -> io::Result<()> {
-    let old = cstr(old);
-    let new = cstr(new);
+    let old = try!(cstr(old));
+    let new = try!(cstr(new));
     try!(cvt(unsafe { libc::rename(old.as_ptr(), new.as_ptr()) }));
     Ok(())
 }
 
 pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> {
-    let p = cstr(p);
+    let p = try!(cstr(p));
     try!(cvt_r(|| unsafe { libc::chmod(p.as_ptr(), perm.mode) }));
     Ok(())
 }
 
 pub fn rmdir(p: &Path) -> io::Result<()> {
-    let p = cstr(p);
+    let p = try!(cstr(p));
     try!(cvt(unsafe { libc::rmdir(p.as_ptr()) }));
     Ok(())
 }
 
 pub fn chown(p: &Path, uid: isize, gid: isize) -> io::Result<()> {
-    let p = cstr(p);
+    let p = try!(cstr(p));
     try!(cvt_r(|| unsafe {
         libc::chown(p.as_ptr(), uid as libc::uid_t, gid as libc::gid_t)
     }));
@@ -325,7 +325,7 @@ pub fn chown(p: &Path, uid: isize, gid: isize) -> io::Result<()> {
 }
 
 pub fn readlink(p: &Path) -> io::Result<PathBuf> {
-    let c_path = cstr(p);
+    let c_path = try!(cstr(p));
     let p = c_path.as_ptr();
     let mut len = unsafe { libc::pathconf(p as *mut _, libc::_PC_NAME_MAX) };
     if len < 0 {
@@ -343,35 +343,35 @@ pub fn readlink(p: &Path) -> io::Result<PathBuf> {
 }
 
 pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> {
-    let src = cstr(src);
-    let dst = cstr(dst);
+    let src = try!(cstr(src));
+    let dst = try!(cstr(dst));
     try!(cvt(unsafe { libc::symlink(src.as_ptr(), dst.as_ptr()) }));
     Ok(())
 }
 
 pub fn link(src: &Path, dst: &Path) -> io::Result<()> {
-    let src = cstr(src);
-    let dst = cstr(dst);
+    let src = try!(cstr(src));
+    let dst = try!(cstr(dst));
     try!(cvt(unsafe { libc::link(src.as_ptr(), dst.as_ptr()) }));
     Ok(())
 }
 
 pub fn stat(p: &Path) -> io::Result<FileAttr> {
-    let p = cstr(p);
+    let p = try!(cstr(p));
     let mut stat: libc::stat = unsafe { mem::zeroed() };
     try!(cvt(unsafe { libc::stat(p.as_ptr(), &mut stat) }));
     Ok(FileAttr { stat: stat })
 }
 
 pub fn lstat(p: &Path) -> io::Result<FileAttr> {
-    let p = cstr(p);
+    let p = try!(cstr(p));
     let mut stat: libc::stat = unsafe { mem::zeroed() };
     try!(cvt(unsafe { libc::lstat(p.as_ptr(), &mut stat) }));
     Ok(FileAttr { stat: stat })
 }
 
 pub fn utimes(p: &Path, atime: u64, mtime: u64) -> io::Result<()> {
-    let p = cstr(p);
+    let p = try!(cstr(p));
     let buf = [super::ms_to_timeval(atime), super::ms_to_timeval(mtime)];
     try!(cvt(unsafe { c::utimes(p.as_ptr(), buf.as_ptr()) }));
     Ok(())
diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs
index 850189140d1..b79ad7031fa 100644
--- a/src/libstd/sys/unix/mod.rs
+++ b/src/libstd/sys/unix/mod.rs
@@ -17,7 +17,7 @@
 
 use prelude::v1::*;
 
-use ffi;
+use ffi::CStr;
 use io::{self, ErrorKind};
 use libc;
 use num::{Int, SignedInt};
@@ -91,7 +91,8 @@ pub fn last_gai_error(s: libc::c_int) -> IoError {
 
     let mut err = decode_error(s);
     err.detail = Some(unsafe {
-        str::from_utf8(ffi::c_str_to_bytes(&gai_strerror(s))).unwrap().to_string()
+        let data = CStr::from_ptr(gai_strerror(s));
+        str::from_utf8(data.to_bytes()).unwrap().to_string()
     });
     err
 }
diff --git a/src/libstd/sys/unix/net.rs b/src/libstd/sys/unix/net.rs
index 54aec7cf4b1..83b6a14b78d 100644
--- a/src/libstd/sys/unix/net.rs
+++ b/src/libstd/sys/unix/net.rs
@@ -10,7 +10,7 @@
 
 use prelude::v1::*;
 
-use ffi;
+use ffi::CStr;
 use io;
 use libc::{self, c_int, size_t};
 use str;
@@ -31,7 +31,7 @@ pub fn cvt_gai(err: c_int) -> io::Result<()> {
     if err == 0 { return Ok(()) }
 
     let detail = unsafe {
-        str::from_utf8(ffi::c_str_to_bytes(&c::gai_strerror(err))).unwrap()
+        str::from_utf8(CStr::from_ptr(c::gai_strerror(err)).to_bytes()).unwrap()
             .to_string()
     };
     Err(io::Error::new(io::ErrorKind::Other,
diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs
index 5fe84cafb71..3d1ef3a2c37 100644
--- a/src/libstd/sys/unix/os.rs
+++ b/src/libstd/sys/unix/os.rs
@@ -14,7 +14,7 @@ use prelude::v1::*;
 use os::unix::*;
 
 use error::Error as StdError;
-use ffi::{self, CString, OsString, OsStr, AsOsStr};
+use ffi::{CString, CStr, OsString, OsStr, AsOsStr};
 use fmt;
 use iter;
 use libc::{self, c_int, c_char, c_void};
@@ -88,7 +88,7 @@ pub fn error_string(errno: i32) -> String {
         }
 
         let p = p as *const _;
-        str::from_utf8(ffi::c_str_to_bytes(&p)).unwrap().to_string()
+        str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap().to_string()
     }
 }
 
@@ -98,13 +98,13 @@ pub fn getcwd() -> IoResult<Path> {
         if libc::getcwd(buf.as_mut_ptr(), buf.len() as libc::size_t).is_null() {
             Err(IoError::last_error())
         } else {
-            Ok(Path::new(ffi::c_str_to_bytes(&buf.as_ptr())))
+            Ok(Path::new(CStr::from_ptr(buf.as_ptr()).to_bytes()))
         }
     }
 }
 
 pub fn chdir(p: &Path) -> IoResult<()> {
-    let p = CString::from_slice(p.as_vec());
+    let p = CString::new(p.as_vec()).unwrap();
     unsafe {
         match libc::chdir(p.as_ptr()) == (0 as c_int) {
             true => Ok(()),
@@ -211,7 +211,7 @@ pub fn current_exe() -> IoResult<Path> {
         if v.is_null() {
             Err(IoError::last_error())
         } else {
-            Ok(Path::new(ffi::c_str_to_bytes(&v).to_vec()))
+            Ok(Path::new(CStr::from_ptr(&v).to_bytes().to_vec()))
         }
     }
 }
@@ -266,7 +266,7 @@ pub fn args() -> Args {
         let (argc, argv) = (*_NSGetArgc() as isize,
                             *_NSGetArgv() as *const *const c_char);
         range(0, argc as isize).map(|i| {
-            let bytes = ffi::c_str_to_bytes(&*argv.offset(i)).to_vec();
+            let bytes = CStr::from_ptr(*argv.offset(i)).to_bytes().to_vec();
             OsStringExt::from_vec(bytes)
         }).collect::<Vec<_>>()
     };
@@ -324,7 +324,7 @@ pub fn args() -> Args {
             let tmp = objc_msgSend(args, object_at_sel, i);
             let utf_c_str: *const libc::c_char =
                 mem::transmute(objc_msgSend(tmp, utf8_sel));
-            let bytes = ffi::c_str_to_bytes(&utf_c_str);
+            let bytes = CStr::from_ptr(utf_c_str).to_bytes();
             res.push(OsString::from_str(str::from_utf8(bytes).unwrap()))
         }
     }
@@ -380,7 +380,7 @@ pub fn env() -> Env {
         }
         let mut result = Vec::new();
         while *environ != ptr::null() {
-            result.push(parse(ffi::c_str_to_bytes(&*environ)));
+            result.push(parse(CStr::from_ptr(*environ).to_bytes()));
             environ = environ.offset(1);
         }
         Env { iter: result.into_iter(), _dont_send_or_sync_me: 0 as *mut _ }
@@ -397,20 +397,20 @@ pub fn env() -> Env {
 
 pub fn getenv(k: &OsStr) -> Option<OsString> {
     unsafe {
-        let s = CString::from_slice(k.as_bytes());
+        let s = k.to_cstring().unwrap();
         let s = libc::getenv(s.as_ptr()) as *const _;
         if s.is_null() {
             None
         } else {
-            Some(OsStringExt::from_vec(ffi::c_str_to_bytes(&s).to_vec()))
+            Some(OsStringExt::from_vec(CStr::from_ptr(s).to_bytes().to_vec()))
         }
     }
 }
 
 pub fn setenv(k: &OsStr, v: &OsStr) {
     unsafe {
-        let k = CString::from_slice(k.as_bytes());
-        let v = CString::from_slice(v.as_bytes());
+        let k = k.to_cstring().unwrap();
+        let v = v.to_cstring().unwrap();
         if libc::funcs::posix01::unistd::setenv(k.as_ptr(), v.as_ptr(), 1) != 0 {
             panic!("failed setenv: {}", IoError::last_error());
         }
@@ -419,7 +419,7 @@ pub fn setenv(k: &OsStr, v: &OsStr) {
 
 pub fn unsetenv(n: &OsStr) {
     unsafe {
-        let nbuf = CString::from_slice(n.as_bytes());
+        let nbuf = n.to_cstring().unwrap();
         if libc::funcs::posix01::unistd::unsetenv(nbuf.as_ptr()) != 0 {
             panic!("failed unsetenv: {}", IoError::last_error());
         }
@@ -480,7 +480,7 @@ pub fn home_dir() -> Option<Path> {
                 _ => return None
             }
             let ptr = passwd.pw_dir as *const _;
-            let bytes = ffi::c_str_to_bytes(&ptr).to_vec();
+            let bytes = CStr::from_ptr(ptr).to_bytes().to_vec();
             return Some(OsStringExt::from_vec(bytes))
         }
     }
diff --git a/src/libstd/sys/unix/pipe.rs b/src/libstd/sys/unix/pipe.rs
index 45d5b1506c3..3c9cdc65975 100644
--- a/src/libstd/sys/unix/pipe.rs
+++ b/src/libstd/sys/unix/pipe.rs
@@ -38,7 +38,7 @@ fn addr_to_sockaddr_un(addr: &CString,
             mem::size_of::<libc::sockaddr_un>());
     let s = unsafe { &mut *(storage as *mut _ as *mut libc::sockaddr_un) };
 
-    let len = addr.len();
+    let len = addr.as_bytes().len();
     if len > s.sun_path.len() - 1 {
         return Err(IoError {
             kind: old_io::InvalidInput,
@@ -47,8 +47,8 @@ fn addr_to_sockaddr_un(addr: &CString,
         })
     }
     s.sun_family = libc::AF_UNIX as libc::sa_family_t;
-    for (slot, value) in s.sun_path.iter_mut().zip(addr.iter()) {
-        *slot = *value;
+    for (slot, value) in s.sun_path.iter_mut().zip(addr.as_bytes().iter()) {
+        *slot = *value as libc::c_char;
     }
 
     // count the null terminator
diff --git a/src/libstd/sys/unix/process.rs b/src/libstd/sys/unix/process.rs
index f954024b0e9..b30ac889120 100644
--- a/src/libstd/sys/unix/process.rs
+++ b/src/libstd/sys/unix/process.rs
@@ -12,6 +12,7 @@ use prelude::v1::*;
 use self::Req::*;
 
 use collections::HashMap;
+#[cfg(stage0)]
 use collections::hash_map::Hasher;
 use ffi::CString;
 use hash::Hash;
@@ -63,6 +64,7 @@ impl Process {
         mkerr_libc(r)
     }
 
+    #[cfg(stage0)]
     pub fn spawn<K, V, C, P>(cfg: &C, in_fd: Option<P>,
                               out_fd: Option<P>, err_fd: Option<P>)
                               -> IoResult<Process>
@@ -278,6 +280,214 @@ impl Process {
             })
         })
     }
+    #[cfg(not(stage0))]
+    pub fn spawn<K, V, C, P>(cfg: &C, in_fd: Option<P>,
+                              out_fd: Option<P>, err_fd: Option<P>)
+                              -> IoResult<Process>
+        where C: ProcessConfig<K, V>, P: AsInner<FileDesc>,
+              K: BytesContainer + Eq + Hash, V: BytesContainer
+    {
+        use libc::funcs::posix88::unistd::{fork, dup2, close, chdir, execvp};
+        use libc::funcs::bsd44::getdtablesize;
+
+        mod rustrt {
+            extern {
+                pub fn rust_unset_sigprocmask();
+            }
+        }
+
+        unsafe fn set_cloexec(fd: c_int) {
+            let ret = c::ioctl(fd, c::FIOCLEX);
+            assert_eq!(ret, 0);
+        }
+
+        let dirp = cfg.cwd().map(|c| c.as_ptr()).unwrap_or(ptr::null());
+
+        // temporary until unboxed closures land
+        let cfg = unsafe {
+            mem::transmute::<&ProcessConfig<K,V>,&'static ProcessConfig<K,V>>(cfg)
+        };
+
+        with_envp(cfg.env(), move|envp: *const c_void| {
+            with_argv(cfg.program(), cfg.args(), move|argv: *const *const libc::c_char| unsafe {
+                let (input, mut output) = try!(sys::os::pipe());
+
+                // We may use this in the child, so perform allocations before the
+                // fork
+                let devnull = b"/dev/null\0";
+
+                set_cloexec(output.fd());
+
+                let pid = fork();
+                if pid < 0 {
+                    return Err(super::last_error())
+                } else if pid > 0 {
+                    #[inline]
+                    fn combine(arr: &[u8]) -> i32 {
+                        let a = arr[0] as u32;
+                        let b = arr[1] as u32;
+                        let c = arr[2] as u32;
+                        let d = arr[3] as u32;
+
+                        ((a << 24) | (b << 16) | (c << 8) | (d << 0)) as i32
+                    }
+
+                    let p = Process{ pid: pid };
+                    drop(output);
+                    let mut bytes = [0; 8];
+                    return match input.read(&mut bytes) {
+                        Ok(8) => {
+                            assert!(combine(CLOEXEC_MSG_FOOTER) == combine(&bytes[4.. 8]),
+                                "Validation on the CLOEXEC pipe failed: {:?}", bytes);
+                            let errno = combine(&bytes[0.. 4]);
+                            assert!(p.wait(0).is_ok(), "wait(0) should either return Ok or panic");
+                            Err(super::decode_error(errno))
+                        }
+                        Err(ref e) if e.kind == EndOfFile => Ok(p),
+                        Err(e) => {
+                            assert!(p.wait(0).is_ok(), "wait(0) should either return Ok or panic");
+                            panic!("the CLOEXEC pipe failed: {:?}", e)
+                        },
+                        Ok(..) => { // pipe I/O up to PIPE_BUF bytes should be atomic
+                            assert!(p.wait(0).is_ok(), "wait(0) should either return Ok or panic");
+                            panic!("short read on the CLOEXEC pipe")
+                        }
+                    };
+                }
+
+                // And at this point we've reached a special time in the life of the
+                // child. The child must now be considered hamstrung and unable to
+                // do anything other than syscalls really. Consider the following
+                // scenario:
+                //
+                //      1. Thread A of process 1 grabs the malloc() mutex
+                //      2. Thread B of process 1 forks(), creating thread C
+                //      3. Thread C of process 2 then attempts to malloc()
+                //      4. The memory of process 2 is the same as the memory of
+                //         process 1, so the mutex is locked.
+                //
+                // This situation looks a lot like deadlock, right? It turns out
+                // that this is what pthread_atfork() takes care of, which is
+                // presumably implemented across platforms. The first thing that
+                // threads to *before* forking is to do things like grab the malloc
+                // mutex, and then after the fork they unlock it.
+                //
+                // Despite this information, libnative's spawn has been witnessed to
+                // deadlock on both OSX and FreeBSD. I'm not entirely sure why, but
+                // all collected backtraces point at malloc/free traffic in the
+                // child spawned process.
+                //
+                // For this reason, the block of code below should contain 0
+                // invocations of either malloc of free (or their related friends).
+                //
+                // As an example of not having malloc/free traffic, we don't close
+                // this file descriptor by dropping the FileDesc (which contains an
+                // allocation). Instead we just close it manually. This will never
+                // have the drop glue anyway because this code never returns (the
+                // child will either exec() or invoke libc::exit)
+                let _ = libc::close(input.fd());
+
+                fn fail(output: &mut FileDesc) -> ! {
+                    let errno = sys::os::errno() as u32;
+                    let bytes = [
+                        (errno >> 24) as u8,
+                        (errno >> 16) as u8,
+                        (errno >>  8) as u8,
+                        (errno >>  0) as u8,
+                        CLOEXEC_MSG_FOOTER[0], CLOEXEC_MSG_FOOTER[1],
+                        CLOEXEC_MSG_FOOTER[2], CLOEXEC_MSG_FOOTER[3]
+                    ];
+                    // pipe I/O up to PIPE_BUF bytes should be atomic
+                    assert!(output.write(&bytes).is_ok());
+                    unsafe { libc::_exit(1) }
+                }
+
+                rustrt::rust_unset_sigprocmask();
+
+                // If a stdio file descriptor is set to be ignored (via a -1 file
+                // descriptor), then we don't actually close it, but rather open
+                // up /dev/null into that file descriptor. Otherwise, the first file
+                // descriptor opened up in the child would be numbered as one of the
+                // stdio file descriptors, which is likely to wreak havoc.
+                let setup = |src: Option<P>, dst: c_int| {
+                    let src = match src {
+                        None => {
+                            let flags = if dst == libc::STDIN_FILENO {
+                                libc::O_RDONLY
+                            } else {
+                                libc::O_RDWR
+                            };
+                            libc::open(devnull.as_ptr() as *const _, flags, 0)
+                        }
+                        Some(obj) => {
+                            let fd = obj.as_inner().fd();
+                            // Leak the memory and the file descriptor. We're in the
+                            // child now an all our resources are going to be
+                            // cleaned up very soon
+                            mem::forget(obj);
+                            fd
+                        }
+                    };
+                    src != -1 && retry(|| dup2(src, dst)) != -1
+                };
+
+                if !setup(in_fd, libc::STDIN_FILENO) { fail(&mut output) }
+                if !setup(out_fd, libc::STDOUT_FILENO) { fail(&mut output) }
+                if !setup(err_fd, libc::STDERR_FILENO) { fail(&mut output) }
+
+                // close all other fds
+                for fd in (3..getdtablesize()).rev() {
+                    if fd != output.fd() {
+                        let _ = close(fd as c_int);
+                    }
+                }
+
+                match cfg.gid() {
+                    Some(u) => {
+                        if libc::setgid(u as libc::gid_t) != 0 {
+                            fail(&mut output);
+                        }
+                    }
+                    None => {}
+                }
+                match cfg.uid() {
+                    Some(u) => {
+                        // When dropping privileges from root, the `setgroups` call
+                        // will remove any extraneous groups. If we don't call this,
+                        // then even though our uid has dropped, we may still have
+                        // groups that enable us to do super-user things. This will
+                        // fail if we aren't root, so don't bother checking the
+                        // return value, this is just done as an optimistic
+                        // privilege dropping function.
+                        extern {
+                            fn setgroups(ngroups: libc::c_int,
+                                         ptr: *const libc::c_void) -> libc::c_int;
+                        }
+                        let _ = setgroups(0, ptr::null());
+
+                        if libc::setuid(u as libc::uid_t) != 0 {
+                            fail(&mut output);
+                        }
+                    }
+                    None => {}
+                }
+                if cfg.detach() {
+                    // Don't check the error of setsid because it fails if we're the
+                    // process leader already. We just forked so it shouldn't return
+                    // error, but ignore it anyway.
+                    let _ = libc::setsid();
+                }
+                if !dirp.is_null() && chdir(dirp) == -1 {
+                    fail(&mut output);
+                }
+                if !envp.is_null() {
+                    *sys::os::environ() = envp as *const _;
+                }
+                let _ = execvp(*argv, argv as *mut _);
+                fail(&mut output);
+            })
+        })
+    }
 
     pub fn wait(&self, deadline: u64) -> IoResult<ProcessExit> {
         use cmp;
@@ -556,6 +766,7 @@ fn with_argv<T,F>(prog: &CString, args: &[CString],
     cb(ptrs.as_ptr())
 }
 
+#[cfg(stage0)]
 fn with_envp<K,V,T,F>(env: Option<&HashMap<K, V>>,
                       cb: F)
                       -> T
@@ -593,6 +804,44 @@ fn with_envp<K,V,T,F>(env: Option<&HashMap<K, V>>,
         _ => cb(ptr::null())
     }
 }
+#[cfg(not(stage0))]
+fn with_envp<K,V,T,F>(env: Option<&HashMap<K, V>>,
+                      cb: F)
+                      -> T
+    where F : FnOnce(*const c_void) -> T,
+          K : BytesContainer + Eq + Hash,
+          V : BytesContainer
+{
+    // On posixy systems we can pass a char** for envp, which is a
+    // null-terminated array of "k=v\0" strings. Since we must create
+    // these strings locally, yet expose a raw pointer to them, we
+    // create a temporary vector to own the CStrings that outlives the
+    // call to cb.
+    match env {
+        Some(env) => {
+            let mut tmps = Vec::with_capacity(env.len());
+
+            for pair in env {
+                let mut kv = Vec::new();
+                kv.push_all(pair.0.container_as_bytes());
+                kv.push('=' as u8);
+                kv.push_all(pair.1.container_as_bytes());
+                kv.push(0); // terminating null
+                tmps.push(kv);
+            }
+
+            // As with `with_argv`, this is unsafe, since cb could leak the pointers.
+            let mut ptrs: Vec<*const libc::c_char> =
+                tmps.iter()
+                    .map(|tmp| tmp.as_ptr() as *const libc::c_char)
+                    .collect();
+            ptrs.push(ptr::null());
+
+            cb(ptrs.as_ptr() as *const c_void)
+        }
+        _ => cb(ptr::null())
+    }
+}
 
 fn translate_status(status: c_int) -> ProcessExit {
     #![allow(non_snake_case)]
diff --git a/src/libstd/sys/unix/process2.rs b/src/libstd/sys/unix/process2.rs
index 5e2c207f375..06fa5c4bba7 100644
--- a/src/libstd/sys/unix/process2.rs
+++ b/src/libstd/sys/unix/process2.rs
@@ -11,7 +11,6 @@
 use prelude::v1::*;
 
 use collections::HashMap;
-use collections::hash_map::Hasher;
 use env;
 use ffi::{OsString, OsStr, CString};
 use fmt;
@@ -46,7 +45,7 @@ pub struct Command {
 impl Command {
     pub fn new(program: &OsStr) -> Command {
         Command {
-            program: program.to_cstring(),
+            program: program.to_cstring().unwrap(),
             args: Vec::new(),
             env: None,
             cwd: None,
@@ -57,10 +56,10 @@ impl Command {
     }
 
     pub fn arg(&mut self, arg: &OsStr) {
-        self.args.push(arg.to_cstring())
+        self.args.push(arg.to_cstring().unwrap())
     }
     pub fn args<'a, I: Iterator<Item = &'a OsStr>>(&mut self, args: I) {
-        self.args.extend(args.map(OsStrExt::to_cstring))
+        self.args.extend(args.map(|s| OsStrExt::to_cstring(s).unwrap()))
     }
     fn init_env_map(&mut self) {
         if self.env.is_none() {
@@ -79,7 +78,7 @@ impl Command {
         self.env = Some(HashMap::new())
     }
     pub fn cwd(&mut self, dir: &OsStr) {
-        self.cwd = Some(dir.to_cstring())
+        self.cwd = Some(dir.to_cstring().unwrap())
     }
 }
 
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs
index 82c52471d10..c90ba7645fe 100644
--- a/src/libstd/sys/unix/thread.rs
+++ b/src/libstd/sys/unix/thread.rs
@@ -237,7 +237,7 @@ pub unsafe fn create(stack: uint, p: Thunk) -> io::Result<rust_thread> {
 pub unsafe fn set_name(name: &str) {
     // pthread_setname_np() since glibc 2.12
     // availability autodetected via weak linkage
-    let cname = CString::from_slice(name.as_bytes());
+    let cname = CString::new(name).unwrap();
     type F = unsafe extern "C" fn(libc::pthread_t, *const libc::c_char) -> libc::c_int;
     extern {
         #[linkage = "extern_weak"]
@@ -255,14 +255,14 @@ pub unsafe fn set_name(name: &str) {
           target_os = "openbsd"))]
 pub unsafe fn set_name(name: &str) {
     // pthread_set_name_np() since almost forever on all BSDs
-    let cname = CString::from_slice(name.as_bytes());
+    let cname = CString::new(name).unwrap();
     pthread_set_name_np(pthread_self(), cname.as_ptr());
 }
 
 #[cfg(any(target_os = "macos", target_os = "ios"))]
 pub unsafe fn set_name(name: &str) {
     // pthread_setname_np() since OS X 10.6 and iOS 3.2
-    let cname = CString::from_slice(name.as_bytes());
+    let cname = CString::new(name).unwrap();
     pthread_setname_np(cname.as_ptr());
 }
 
diff --git a/src/libstd/sys/windows/backtrace.rs b/src/libstd/sys/windows/backtrace.rs
index 92e309da34b..51cf3032423 100644
--- a/src/libstd/sys/windows/backtrace.rs
+++ b/src/libstd/sys/windows/backtrace.rs
@@ -25,7 +25,7 @@
 #![allow(dead_code)]
 
 use dynamic_lib::DynamicLibrary;
-use ffi;
+use ffi::CStr;
 use intrinsics;
 use old_io::{IoResult, Writer};
 use libc;
@@ -362,7 +362,7 @@ pub fn write(w: &mut Writer) -> IoResult<()> {
         if ret == libc::TRUE {
             try!(write!(w, " - "));
             let ptr = info.Name.as_ptr() as *const libc::c_char;
-            let bytes = unsafe { ffi::c_str_to_bytes(&ptr) };
+            let bytes = unsafe { CStr::from_ptr(ptr).to_bytes() };
             match str::from_utf8(bytes) {
                 Ok(s) => try!(demangle(w, s)),
                 Err(..) => try!(w.write_all(&bytes[..bytes.len()-1])),
diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs
index f861255a00a..2d1a5e10bd6 100644
--- a/src/libstd/sys/windows/c.rs
+++ b/src/libstd/sys/windows/c.rs
@@ -283,7 +283,7 @@ pub mod compat {
                   fallback: usize) -> usize {
         let mut module: Vec<u16> = module.utf16_units().collect();
         module.push(0);
-        let symbol = CString::from_slice(symbol.as_bytes());
+        let symbol = CString::new(symbol).unwrap();
         let func = unsafe {
             let handle = GetModuleHandleW(module.as_ptr());
             GetProcAddress(handle, symbol.as_ptr()) as usize
diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs
index 4d6d033deee..a756fb29f81 100644
--- a/src/libstd/sys/windows/mod.rs
+++ b/src/libstd/sys/windows/mod.rs
@@ -265,12 +265,12 @@ fn fill_utf16_buf_base<F1, F2, T>(mut f1: F1, f2: F2) -> Result<T, ()>
         let mut n = stack_buf.len();
         loop {
             let buf = if n <= stack_buf.len() {
-                &mut stack_buf[]
+                &mut stack_buf[..]
             } else {
                 let extra = n - heap_buf.len();
                 heap_buf.reserve(extra);
                 heap_buf.set_len(n);
-                &mut heap_buf[]
+                &mut heap_buf[..]
             };
 
             // This function is typically called on windows API functions which
diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs
index 502d70d4e1a..6520d30487c 100644
--- a/src/libstd/sys/windows/os.rs
+++ b/src/libstd/sys/windows/os.rs
@@ -114,7 +114,7 @@ impl Iterator for Env {
 
             let (k, v) = match s.iter().position(|&b| b == '=' as u16) {
                 Some(n) => (&s[..n], &s[n+1..]),
-                None => (s, &[][]),
+                None => (s, &[][..]),
             };
             Some((OsStringExt::from_wide(k), OsStringExt::from_wide(v)))
         }
@@ -186,7 +186,7 @@ impl<'a> Iterator for SplitPaths<'a> {
         if !must_yield && in_progress.is_empty() {
             None
         } else {
-            Some(super::os2path(&in_progress[]))
+            Some(super::os2path(&in_progress[..]))
         }
     }
 }
@@ -208,14 +208,14 @@ pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError>
             return Err(JoinPathsError)
         } else if v.contains(&sep) {
             joined.push(b'"' as u16);
-            joined.push_all(&v[]);
+            joined.push_all(&v[..]);
             joined.push(b'"' as u16);
         } else {
-            joined.push_all(&v[]);
+            joined.push_all(&v[..]);
         }
     }
 
-    Ok(OsStringExt::from_wide(&joined[]))
+    Ok(OsStringExt::from_wide(&joined[..]))
 }
 
 impl fmt::Display for JoinPathsError {
diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs
index 96ffc4daddd..60d24e6174f 100644
--- a/src/libstd/sys/windows/process.rs
+++ b/src/libstd/sys/windows/process.rs
@@ -10,7 +10,7 @@
 
 use prelude::v1::*;
 
-use collections::hash_map::Hasher;
+#[cfg(stage0)] use collections::hash_map::Hasher;
 use collections;
 use env;
 use ffi::CString;
@@ -106,6 +106,7 @@ impl Process {
     }
 
     #[allow(deprecated)]
+    #[cfg(stage0)]
     pub fn spawn<K, V, C, P>(cfg: &C, in_fd: Option<P>,
                               out_fd: Option<P>, err_fd: Option<P>)
                               -> IoResult<Process>
@@ -267,6 +268,169 @@ impl Process {
             })
         }
     }
+    #[allow(deprecated)]
+    #[cfg(not(stage0))]
+    pub fn spawn<K, V, C, P>(cfg: &C, in_fd: Option<P>,
+                              out_fd: Option<P>, err_fd: Option<P>)
+                              -> IoResult<Process>
+        where C: ProcessConfig<K, V>, P: AsInner<FileDesc>,
+              K: BytesContainer + Eq + Hash, V: BytesContainer
+    {
+        use libc::types::os::arch::extra::{DWORD, HANDLE, STARTUPINFO};
+        use libc::consts::os::extra::{
+            TRUE, FALSE,
+            STARTF_USESTDHANDLES,
+            INVALID_HANDLE_VALUE,
+            DUPLICATE_SAME_ACCESS
+        };
+        use libc::funcs::extra::kernel32::{
+            GetCurrentProcess,
+            DuplicateHandle,
+            CloseHandle,
+            CreateProcessW
+        };
+        use libc::funcs::extra::msvcrt::get_osfhandle;
+
+        use mem;
+        use iter::IteratorExt;
+        use str::StrExt;
+
+        if cfg.gid().is_some() || cfg.uid().is_some() {
+            return Err(IoError {
+                kind: old_io::IoUnavailable,
+                desc: "unsupported gid/uid requested on windows",
+                detail: None,
+            })
+        }
+
+        // To have the spawning semantics of unix/windows stay the same, we need to
+        // read the *child's* PATH if one is provided. See #15149 for more details.
+        let program = cfg.env().and_then(|env| {
+            for (key, v) in env {
+                if b"PATH" != key.container_as_bytes() { continue }
+
+                // Split the value and test each path to see if the
+                // program exists.
+                for path in os::split_paths(v.container_as_bytes()) {
+                    let path = path.join(cfg.program().as_bytes())
+                                   .with_extension(env::consts::EXE_EXTENSION);
+                    if path.exists() {
+                        return Some(CString::from_slice(path.as_vec()))
+                    }
+                }
+                break
+            }
+            None
+        });
+
+        unsafe {
+            let mut si = zeroed_startupinfo();
+            si.cb = mem::size_of::<STARTUPINFO>() as DWORD;
+            si.dwFlags = STARTF_USESTDHANDLES;
+
+            let cur_proc = GetCurrentProcess();
+
+            // Similarly to unix, we don't actually leave holes for the stdio file
+            // descriptors, but rather open up /dev/null equivalents. These
+            // equivalents are drawn from libuv's windows process spawning.
+            let set_fd = |fd: &Option<P>, slot: &mut HANDLE,
+                          is_stdin: bool| {
+                match *fd {
+                    None => {
+                        let access = if is_stdin {
+                            libc::FILE_GENERIC_READ
+                        } else {
+                            libc::FILE_GENERIC_WRITE | libc::FILE_READ_ATTRIBUTES
+                        };
+                        let size = mem::size_of::<libc::SECURITY_ATTRIBUTES>();
+                        let mut sa = libc::SECURITY_ATTRIBUTES {
+                            nLength: size as libc::DWORD,
+                            lpSecurityDescriptor: ptr::null_mut(),
+                            bInheritHandle: 1,
+                        };
+                        let mut filename: Vec<u16> = "NUL".utf16_units().collect();
+                        filename.push(0);
+                        *slot = libc::CreateFileW(filename.as_ptr(),
+                                                  access,
+                                                  libc::FILE_SHARE_READ |
+                                                      libc::FILE_SHARE_WRITE,
+                                                  &mut sa,
+                                                  libc::OPEN_EXISTING,
+                                                  0,
+                                                  ptr::null_mut());
+                        if *slot == INVALID_HANDLE_VALUE {
+                            return Err(super::last_error())
+                        }
+                    }
+                    Some(ref fd) => {
+                        let orig = get_osfhandle(fd.as_inner().fd()) as HANDLE;
+                        if orig == INVALID_HANDLE_VALUE {
+                            return Err(super::last_error())
+                        }
+                        if DuplicateHandle(cur_proc, orig, cur_proc, slot,
+                                           0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE {
+                            return Err(super::last_error())
+                        }
+                    }
+                }
+                Ok(())
+            };
+
+            try!(set_fd(&in_fd, &mut si.hStdInput, true));
+            try!(set_fd(&out_fd, &mut si.hStdOutput, false));
+            try!(set_fd(&err_fd, &mut si.hStdError, false));
+
+            let cmd_str = make_command_line(program.as_ref().unwrap_or(cfg.program()),
+                                            cfg.args());
+            let mut pi = zeroed_process_information();
+            let mut create_err = None;
+
+            // stolen from the libuv code.
+            let mut flags = libc::CREATE_UNICODE_ENVIRONMENT;
+            if cfg.detach() {
+                flags |= libc::DETACHED_PROCESS | libc::CREATE_NEW_PROCESS_GROUP;
+            }
+
+            with_envp(cfg.env(), |envp| {
+                with_dirp(cfg.cwd(), |dirp| {
+                    let mut cmd_str: Vec<u16> = cmd_str.utf16_units().collect();
+                    cmd_str.push(0);
+                    let _lock = CREATE_PROCESS_LOCK.lock().unwrap();
+                    let created = CreateProcessW(ptr::null(),
+                                                 cmd_str.as_mut_ptr(),
+                                                 ptr::null_mut(),
+                                                 ptr::null_mut(),
+                                                 TRUE,
+                                                 flags, envp, dirp,
+                                                 &mut si, &mut pi);
+                    if created == FALSE {
+                        create_err = Some(super::last_error());
+                    }
+                })
+            });
+
+            assert!(CloseHandle(si.hStdInput) != 0);
+            assert!(CloseHandle(si.hStdOutput) != 0);
+            assert!(CloseHandle(si.hStdError) != 0);
+
+            match create_err {
+                Some(err) => return Err(err),
+                None => {}
+            }
+
+            // We close the thread handle because we don't care about keeping the
+            // thread id valid, and we aren't keeping the thread handle around to be
+            // able to close it later. We don't close the process handle however
+            // because std::we want the process id to stay valid at least until the
+            // calling code closes the process handle.
+            assert!(CloseHandle(pi.hThread) != 0);
+
+            Ok(Process {
+                pid: pi.dwProcessId as pid_t,
+                handle: pi.hProcess as *mut ()
+            })
+        }
+    }
 
     /// Waits for a process to exit and returns the exit code, failing
     /// if there is no process with the specified id.
@@ -425,6 +589,7 @@ fn make_command_line(prog: &CString, args: &[CString]) -> String {
     }
 }
 
+#[cfg(stage0)]
 fn with_envp<K, V, T, F>(env: Option<&collections::HashMap<K, V>>, cb: F) -> T
     where K: BytesContainer + Eq + Hash<Hasher>,
           V: BytesContainer,
@@ -452,6 +617,34 @@ fn with_envp<K, V, T, F>(env: Option<&collections::HashMap<K, V>>, cb: F) -> T
         _ => cb(ptr::null_mut())
     }
 }
+#[cfg(not(stage0))]
+fn with_envp<K, V, T, F>(env: Option<&collections::HashMap<K, V>>, cb: F) -> T
+    where K: BytesContainer + Eq + Hash,
+          V: BytesContainer,
+          F: FnOnce(*mut c_void) -> T,
+{
+    // On Windows we pass an "environment block" which is not a char**, but
+    // rather a concatenation of null-terminated k=v\0 sequences, with a final
+    // \0 to terminate.
+    match env {
+        Some(env) => {
+            let mut blk = Vec::new();
+
+            for pair in env {
+                let kv = format!("{}={}",
+                                 pair.0.container_as_str().unwrap(),
+                                 pair.1.container_as_str().unwrap());
+                blk.extend(kv.utf16_units());
+                blk.push(0);
+            }
+
+            blk.push(0);
+
+            cb(blk.as_mut_ptr() as *mut c_void)
+        }
+        _ => cb(ptr::null_mut())
+    }
+}
 
 fn with_dirp<T, F>(d: Option<&CString>, cb: F) -> T where
     F: FnOnce(*const u16) -> T,
diff --git a/src/libstd/thread.rs b/src/libstd/thread.rs
index 3137d779c40..3653e7e31d5 100644
--- a/src/libstd/thread.rs
+++ b/src/libstd/thread.rs
@@ -153,7 +153,7 @@ use any::Any;
 use cell::UnsafeCell;
 use fmt;
 use io;
-use marker;
+use marker::PhantomData;
 use old_io::stdio;
 use rt::{self, unwind};
 use sync::{Mutex, Condvar, Arc};
@@ -260,7 +260,7 @@ impl Builder {
         T: Send + 'a, F: FnOnce() -> T, F: Send + 'a
     {
         self.spawn_inner(Thunk::new(f)).map(|inner| {
-            JoinGuard { inner: inner, _marker: marker::CovariantType }
+            JoinGuard { inner: inner, _marker: PhantomData }
         })
     }
 
@@ -642,7 +642,7 @@ impl Drop for JoinHandle {
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct JoinGuard<'a, T: 'a> {
     inner: JoinInner<T>,
-    _marker: marker::CovariantType<&'a T>,
+    _marker: PhantomData<&'a T>,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index d6778be553e..140e21b5d04 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -198,7 +198,7 @@ impl Encodable for Ident {
 
 impl Decodable for Ident {
     fn decode<D: Decoder>(d: &mut D) -> Result<Ident, D::Error> {
-        Ok(str_to_ident(&try!(d.read_str())[]))
+        Ok(str_to_ident(&try!(d.read_str())[..]))
     }
 }
 
diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs
index 5535e5911e0..ba08f61b557 100644
--- a/src/libsyntax/ast_map/mod.rs
+++ b/src/libsyntax/ast_map/mod.rs
@@ -86,7 +86,7 @@ pub fn path_to_string<PI: Iterator<Item=PathElem>>(path: PI) -> String {
         if !s.is_empty() {
             s.push_str("::");
         }
-        s.push_str(&e[]);
+        s.push_str(&e[..]);
         s
     })
 }
@@ -251,7 +251,7 @@ impl<'ast> Map<'ast> {
     }
 
     fn find_entry(&self, id: NodeId) -> Option<MapEntry<'ast>> {
-        self.map.borrow().get(id as usize).map(|e| *e)
+        self.map.borrow().get(id as usize).cloned()
     }
 
     pub fn krate(&self) -> &'ast Crate {
@@ -463,20 +463,20 @@ impl<'ast> Map<'ast> {
         F: FnOnce(Option<&[Attribute]>) -> T,
     {
         let attrs = match self.get(id) {
-            NodeItem(i) => Some(&i.attrs[]),
-            NodeForeignItem(fi) => Some(&fi.attrs[]),
+            NodeItem(i) => Some(&i.attrs[..]),
+            NodeForeignItem(fi) => Some(&fi.attrs[..]),
             NodeTraitItem(ref tm) => match **tm {
-                RequiredMethod(ref type_m) => Some(&type_m.attrs[]),
-                ProvidedMethod(ref m) => Some(&m.attrs[]),
-                TypeTraitItem(ref typ) => Some(&typ.attrs[]),
+                RequiredMethod(ref type_m) => Some(&type_m.attrs[..]),
+                ProvidedMethod(ref m) => Some(&m.attrs[..]),
+                TypeTraitItem(ref typ) => Some(&typ.attrs[..]),
             },
             NodeImplItem(ref ii) => {
                 match **ii {
-                    MethodImplItem(ref m) => Some(&m.attrs[]),
-                    TypeImplItem(ref t) => Some(&t.attrs[]),
+                    MethodImplItem(ref m) => Some(&m.attrs[..]),
+                    TypeImplItem(ref t) => Some(&t.attrs[..]),
                 }
             }
-            NodeVariant(ref v) => Some(&v.node.attrs[]),
+            NodeVariant(ref v) => Some(&v.node.attrs[..]),
             // unit/tuple structs take the attributes straight from
             // the struct definition.
             // FIXME(eddyb) make this work again (requires access to the map).
@@ -577,7 +577,7 @@ impl<'a, 'ast> NodesMatchingSuffix<'a, 'ast> {
                 None => return false,
                 Some((node_id, name)) => (node_id, name),
             };
-            if &part[] != mod_name.as_str() {
+            if &part[..] != mod_name.as_str() {
                 return false;
             }
             cursor = self.map.get_parent(mod_id);
@@ -615,7 +615,7 @@ impl<'a, 'ast> NodesMatchingSuffix<'a, 'ast> {
     // We are looking at some node `n` with a given name and parent
     // id; do their names match what I am seeking?
     fn matches_names(&self, parent_of_n: NodeId, name: Name) -> bool {
-        name.as_str() == &self.item_name[] &&
+        name.as_str() == &self.item_name[..] &&
             self.suffix_matches(parent_of_n)
     }
 }
@@ -1026,7 +1026,7 @@ impl<'a> NodePrinter for pprust::State<'a> {
 
 fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
     let id_str = format!(" (id={})", id);
-    let id_str = if include_id { &id_str[] } else { "" };
+    let id_str = if include_id { &id_str[..] } else { "" };
 
     match map.find(id) {
         Some(NodeItem(item)) => {
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 117507ad8b7..f660296fcd7 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -257,11 +257,11 @@ pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: &Ty) -> Ident {
     match *trait_ref {
         Some(ref trait_ref) => {
             pretty.push('.');
-            pretty.push_str(&pprust::path_to_string(&trait_ref.path)[]);
+            pretty.push_str(&pprust::path_to_string(&trait_ref.path));
         }
         None => {}
     }
-    token::gensym_ident(&pretty[])
+    token::gensym_ident(&pretty[..])
 }
 
 pub fn trait_method_to_ty_method(method: &Method) -> TypeMethod {
@@ -673,7 +673,7 @@ pub fn pat_is_ident(pat: P<ast::Pat>) -> bool {
 pub fn path_name_eq(a : &ast::Path, b : &ast::Path) -> bool {
     (a.span == b.span)
     && (a.global == b.global)
-    && (segments_name_eq(&a.segments[], &b.segments[]))
+    && (segments_name_eq(&a.segments[..], &b.segments[..]))
 }
 
 // are two arrays of segments equal when compared unhygienically?
diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs
index a3afe5780d0..62e676891a0 100644
--- a/src/libsyntax/attr.rs
+++ b/src/libsyntax/attr.rs
@@ -26,11 +26,11 @@ use parse::token;
 use ptr::P;
 
 use std::cell::{RefCell, Cell};
-use std::collections::BitvSet;
+use std::collections::BitSet;
 use std::collections::HashSet;
 use std::fmt;
 
-thread_local! { static USED_ATTRS: RefCell<BitvSet> = RefCell::new(BitvSet::new()) }
+thread_local! { static USED_ATTRS: RefCell<BitSet> = RefCell::new(BitSet::new()) }
 
 pub fn mark_used(attr: &Attribute) {
     let AttrId(id) = attr.node.id;
@@ -44,7 +44,7 @@ pub fn is_used(attr: &Attribute) -> bool {
 
 pub trait AttrMetaMethods {
     fn check_name(&self, name: &str) -> bool {
-        name == &self.name()[]
+        name == &self.name()[..]
     }
 
     /// Retrieve the name of the meta item, e.g. `foo` in `#[foo]`,
@@ -62,7 +62,7 @@ pub trait AttrMetaMethods {
 
 impl AttrMetaMethods for Attribute {
     fn check_name(&self, name: &str) -> bool {
-        let matches = name == &self.name()[];
+        let matches = name == &self.name()[..];
         if matches {
             mark_used(self);
         }
@@ -101,7 +101,7 @@ impl AttrMetaMethods for MetaItem {
 
     fn meta_item_list<'a>(&'a self) -> Option<&'a [P<MetaItem>]> {
         match self.node {
-            MetaList(_, ref l) => Some(&l[]),
+            MetaList(_, ref l) => Some(&l[..]),
             _ => None
         }
     }
@@ -142,7 +142,7 @@ impl AttributeMethods for Attribute {
             let meta = mk_name_value_item_str(
                 InternedString::new("doc"),
                 token::intern_and_get_ident(&strip_doc_comment_decoration(
-                        &comment)[]));
+                        &comment)));
             if self.node.style == ast::AttrOuter {
                 f(&mk_attr_outer(self.node.id, meta))
             } else {
@@ -302,9 +302,9 @@ pub fn find_inline_attr(attrs: &[Attribute]) -> InlineAttr {
             }
             MetaList(ref n, ref items) if *n == "inline" => {
                 mark_used(attr);
-                if contains_name(&items[], "always") {
+                if contains_name(&items[..], "always") {
                     InlineAlways
-                } else if contains_name(&items[], "never") {
+                } else if contains_name(&items[..], "never") {
                     InlineNever
                 } else {
                     InlineHint
@@ -326,11 +326,11 @@ pub fn requests_inline(attrs: &[Attribute]) -> bool {
 /// Tests if a cfg-pattern matches the cfg set
 pub fn cfg_matches(diagnostic: &SpanHandler, cfgs: &[P<MetaItem>], cfg: &ast::MetaItem) -> bool {
     match cfg.node {
-        ast::MetaList(ref pred, ref mis) if &pred[] == "any" =>
+        ast::MetaList(ref pred, ref mis) if &pred[..] == "any" =>
             mis.iter().any(|mi| cfg_matches(diagnostic, cfgs, &**mi)),
-        ast::MetaList(ref pred, ref mis) if &pred[] == "all" =>
+        ast::MetaList(ref pred, ref mis) if &pred[..] == "all" =>
             mis.iter().all(|mi| cfg_matches(diagnostic, cfgs, &**mi)),
-        ast::MetaList(ref pred, ref mis) if &pred[] == "not" => {
+        ast::MetaList(ref pred, ref mis) if &pred[..] == "not" => {
             if mis.len() != 1 {
                 diagnostic.span_err(cfg.span, "expected 1 cfg-pattern");
                 return false;
@@ -382,7 +382,7 @@ fn find_stability_generic<'a,
 
     'outer: for attr in attrs {
         let tag = attr.name();
-        let tag = &tag[];
+        let tag = &tag[..];
         if tag != "deprecated" && tag != "unstable" && tag != "stable" {
             continue // not a stability level
         }
@@ -404,7 +404,7 @@ fn find_stability_generic<'a,
                             }
                         }
                     }
-                    if &meta.name()[] == "since" {
+                    if &meta.name()[..] == "since" {
                         match meta.value_str() {
                             Some(v) => since = Some(v),
                             None => {
@@ -413,7 +413,7 @@ fn find_stability_generic<'a,
                             }
                         }
                     }
-                    if &meta.name()[] == "reason" {
+                    if &meta.name()[..] == "reason" {
                         match meta.value_str() {
                             Some(v) => reason = Some(v),
                             None => {
@@ -501,7 +501,7 @@ pub fn require_unique_names(diagnostic: &SpanHandler, metas: &[P<MetaItem>]) {
 
         if !set.insert(name.clone()) {
             diagnostic.span_fatal(meta.span,
-                                  &format!("duplicate meta item `{}`", name)[]);
+                                  &format!("duplicate meta item `{}`", name));
         }
     }
 }
@@ -521,7 +521,7 @@ pub fn find_repr_attrs(diagnostic: &SpanHandler, attr: &Attribute) -> Vec<ReprAt
             for item in items {
                 match item.node {
                     ast::MetaWord(ref word) => {
-                        let hint = match &word[] {
+                        let hint = match &word[..] {
                             // Can't use "extern" because it's not a lexical identifier.
                             "C" => Some(ReprExtern),
                             "packed" => Some(ReprPacked),
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index 3231342cb50..099f6462942 100644
--- a/src/libsyntax/codemap.rs
+++ b/src/libsyntax/codemap.rs
@@ -360,7 +360,7 @@ impl CodeMap {
         let mut src = if src.starts_with("\u{feff}") {
             String::from_str(&src[3..])
         } else {
-            String::from_str(&src[])
+            String::from_str(&src[..])
         };
 
         // Append '\n' in case it's not already there.
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs
index 7ca0591be50..dfe3477bddc 100644
--- a/src/libsyntax/config.rs
+++ b/src/libsyntax/config.rs
@@ -311,7 +311,7 @@ impl<'a> fold::Folder for CfgAttrFolder<'a> {
             }
         };
 
-        if attr::cfg_matches(self.diag, &self.config[], &cfg) {
+        if attr::cfg_matches(self.diag, &self.config[..], &cfg) {
             Some(respan(mi.span, ast::Attribute_ {
                 id: attr::mk_attr_id(),
                 style: attr.node.style,
diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs
index 83a4d938bb5..27219774cf1 100644
--- a/src/libsyntax/diagnostic.rs
+++ b/src/libsyntax/diagnostic.rs
@@ -129,7 +129,7 @@ impl SpanHandler {
         panic!(ExplicitBug);
     }
     pub fn span_unimpl(&self, sp: Span, msg: &str) -> ! {
-        self.span_bug(sp, &format!("unimplemented {}", msg)[]);
+        self.span_bug(sp, &format!("unimplemented {}", msg));
     }
     pub fn handler<'a>(&'a self) -> &'a Handler {
         &self.handler
@@ -173,7 +173,7 @@ impl Handler {
                         self.err_count.get());
           }
         }
-        self.fatal(&s[]);
+        self.fatal(&s[..]);
     }
     pub fn warn(&self, msg: &str) {
         self.emit.borrow_mut().emit(None, msg, None, Warning);
@@ -189,7 +189,7 @@ impl Handler {
         panic!(ExplicitBug);
     }
     pub fn unimpl(&self, msg: &str) -> ! {
-        self.bug(&format!("unimplemented {}", msg)[]);
+        self.bug(&format!("unimplemented {}", msg));
     }
     pub fn emit(&self,
                 cmsp: Option<(&codemap::CodeMap, Span)>,
@@ -311,16 +311,16 @@ fn print_diagnostic(dst: &mut EmitterWriter, topic: &str, lvl: Level,
     }
 
     try!(print_maybe_styled(dst,
-                            &format!("{}: ", lvl.to_string())[],
+                            &format!("{}: ", lvl.to_string()),
                             term::attr::ForegroundColor(lvl.color())));
     try!(print_maybe_styled(dst,
-                            &format!("{}", msg)[],
+                            &format!("{}", msg),
                             term::attr::Bold));
 
     match code {
         Some(code) => {
             let style = term::attr::ForegroundColor(term::color::BRIGHT_MAGENTA);
-            try!(print_maybe_styled(dst, &format!(" [{}]", code.clone())[], style));
+            try!(print_maybe_styled(dst, &format!(" [{}]", code.clone()), style));
         }
         None => ()
     }
@@ -419,12 +419,12 @@ fn emit(dst: &mut EmitterWriter, cm: &codemap::CodeMap, rsp: RenderSpan,
         // the span)
         let span_end = Span { lo: sp.hi, hi: sp.hi, expn_id: sp.expn_id};
         let ses = cm.span_to_string(span_end);
-        try!(print_diagnostic(dst, &ses[], lvl, msg, code));
+        try!(print_diagnostic(dst, &ses[..], lvl, msg, code));
         if rsp.is_full_span() {
             try!(custom_highlight_lines(dst, cm, sp, lvl, cm.span_to_lines(sp)));
         }
     } else {
-        try!(print_diagnostic(dst, &ss[], lvl, msg, code));
+        try!(print_diagnostic(dst, &ss[..], lvl, msg, code));
         if rsp.is_full_span() {
             try!(highlight_lines(dst, cm, sp, lvl, cm.span_to_lines(sp)));
         }
@@ -436,9 +436,9 @@ fn emit(dst: &mut EmitterWriter, cm: &codemap::CodeMap, rsp: RenderSpan,
         Some(code) =>
             match dst.registry.as_ref().and_then(|registry| registry.find_description(code)) {
                 Some(_) => {
-                    try!(print_diagnostic(dst, &ss[], Help,
+                    try!(print_diagnostic(dst, &ss[..], Help,
                                           &format!("pass `--explain {}` to see a detailed \
-                                                   explanation", code)[], None));
+                                                   explanation", code), None));
                 }
                 None => ()
             },
@@ -455,7 +455,7 @@ fn highlight_lines(err: &mut EmitterWriter,
     let fm = &*lines.file;
 
     let mut elided = false;
-    let mut display_lines = &lines.lines[];
+    let mut display_lines = &lines.lines[..];
     if display_lines.len() > MAX_LINES {
         display_lines = &display_lines[0..MAX_LINES];
         elided = true;
@@ -542,7 +542,7 @@ fn highlight_lines(err: &mut EmitterWriter,
             }
 
             try!(print_maybe_styled(err,
-                                    &format!("{}\n", s)[],
+                                    &format!("{}\n", s),
                                     term::attr::ForegroundColor(lvl.color())));
         }
     }
@@ -563,7 +563,7 @@ fn custom_highlight_lines(w: &mut EmitterWriter,
                           -> old_io::IoResult<()> {
     let fm = &*lines.file;
 
-    let lines = &lines.lines[];
+    let lines = &lines.lines[..];
     if lines.len() > MAX_LINES {
         if let Some(line) = fm.get_line(lines[0]) {
             try!(write!(&mut w.dst, "{}:{} {}\n", fm.name,
@@ -610,7 +610,7 @@ fn custom_highlight_lines(w: &mut EmitterWriter,
     s.push('^');
     s.push('\n');
     print_maybe_styled(w,
-                       &s[],
+                       &s[..],
                        term::attr::ForegroundColor(lvl.color()))
 }
 
@@ -618,22 +618,25 @@ fn print_macro_backtrace(w: &mut EmitterWriter,
                          cm: &codemap::CodeMap,
                          sp: Span)
                          -> old_io::IoResult<()> {
-    let cs = try!(cm.with_expn_info(sp.expn_id, |expn_info| match expn_info {
-        Some(ei) => {
-            let ss = ei.callee.span.map_or(String::new(), |span| cm.span_to_string(span));
-            let (pre, post) = match ei.callee.format {
-                codemap::MacroAttribute => ("#[", "]"),
-                codemap::MacroBang => ("", "!")
-            };
-            try!(print_diagnostic(w, &ss[], Note,
-                                  &format!("in expansion of {}{}{}", pre,
-                                          ei.callee.name,
-                                          post)[], None));
-            let ss = cm.span_to_string(ei.call_site);
-            try!(print_diagnostic(w, &ss[], Note, "expansion site", None));
-            Ok(Some(ei.call_site))
-        }
-        None => Ok(None)
+    let cs = try!(cm.with_expn_info(sp.expn_id, |expn_info| -> old_io::IoResult<_> {
+        match expn_info {
+            Some(ei) => {
+                let ss = ei.callee.span.map_or(String::new(),
+                                               |span| cm.span_to_string(span));
+                let (pre, post) = match ei.callee.format {
+                    codemap::MacroAttribute => ("#[", "]"),
+                    codemap::MacroBang => ("", "!")
+                };
+                try!(print_diagnostic(w, &ss, Note,
+                                      &format!("in expansion of {}{}{}", pre,
+                                              ei.callee.name,
+                                              post), None));
+                let ss = cm.span_to_string(ei.call_site);
+                try!(print_diagnostic(w, &ss, Note, "expansion site", None));
+                Ok(Some(ei.call_site))
+            }
+            None => Ok(None)
+    }
     }));
     cs.map_or(Ok(()), |call_site| print_macro_backtrace(w, cm, call_site))
 }
@@ -643,6 +646,6 @@ pub fn expect<T, M>(diag: &SpanHandler, opt: Option<T>, msg: M) -> T where
 {
     match opt {
         Some(t) => t,
-        None => diag.handler().bug(&msg()[]),
+        None => diag.handler().bug(&msg()),
     }
 }
diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs
index 833a6d52acb..b3afc3fc4dd 100644
--- a/src/libsyntax/diagnostics/plugin.rs
+++ b/src/libsyntax/diagnostics/plugin.rs
@@ -59,7 +59,7 @@ pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt,
             Some(previous_span) => {
                 ecx.span_warn(span, &format!(
                     "diagnostic code {} already used", &token::get_ident(code)
-                )[]);
+                ));
                 ecx.span_note(previous_span, "previous invocation");
             },
             None => ()
@@ -70,7 +70,7 @@ pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt,
         if !diagnostics.contains_key(&code.name) {
             ecx.span_err(span, &format!(
                 "used diagnostic code {} not registered", &token::get_ident(code)
-            )[]);
+            ));
         }
     });
     MacExpr::new(quote_expr!(ecx, ()))
@@ -95,12 +95,12 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt,
         if diagnostics.insert(code.name, description).is_some() {
             ecx.span_err(span, &format!(
                 "diagnostic code {} already registered", &token::get_ident(*code)
-            )[]);
+            ));
         }
     });
     let sym = Ident::new(token::gensym(&(
         "__register_diagnostic_".to_string() + &token::get_ident(*code)
-    )[]));
+    )));
     MacItems::new(vec![quote_item!(ecx, mod $sym {}).unwrap()].into_iter())
 }
 
diff --git a/src/libsyntax/diagnostics/registry.rs b/src/libsyntax/diagnostics/registry.rs
index 62d48189c43..a6cfd1a5a9a 100644
--- a/src/libsyntax/diagnostics/registry.rs
+++ b/src/libsyntax/diagnostics/registry.rs
@@ -17,10 +17,10 @@ pub struct Registry {
 
 impl Registry {
     pub fn new(descriptions: &[(&'static str, &'static str)]) -> Registry {
-        Registry { descriptions: descriptions.iter().map(|&tuple| tuple).collect() }
+        Registry { descriptions: descriptions.iter().cloned().collect() }
     }
 
     pub fn find_description(&self, code: &str) -> Option<&'static str> {
-        self.descriptions.get(code).map(|desc| *desc)
+        self.descriptions.get(code).cloned()
     }
 }
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 8800ffd1e9b..d4ccabbd63b 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -640,7 +640,7 @@ impl<'a> ExtCtxt<'a> {
     pub fn mod_path(&self) -> Vec<ast::Ident> {
         let mut v = Vec::new();
         v.push(token::str_to_ident(&self.ecfg.crate_name[]));
-        v.extend(self.mod_path.iter().map(|a| *a));
+        v.extend(self.mod_path.iter().cloned());
         return v;
     }
     pub fn bt_push(&mut self, ei: ExpnInfo) {
diff --git a/src/libsyntax/ext/concat.rs b/src/libsyntax/ext/concat.rs
index 80d128959ea..38098e50dee 100644
--- a/src/libsyntax/ext/concat.rs
+++ b/src/libsyntax/ext/concat.rs
@@ -62,5 +62,5 @@ pub fn expand_syntax_ext(cx: &mut base::ExtCtxt,
     }
     base::MacExpr::new(cx.expr_str(
             sp,
-            token::intern_and_get_ident(&accumulator[])))
+            token::intern_and_get_ident(&accumulator[..])))
 }
diff --git a/src/libsyntax/ext/concat_idents.rs b/src/libsyntax/ext/concat_idents.rs
index 63a8bd9ddf1..9410a51e7a5 100644
--- a/src/libsyntax/ext/concat_idents.rs
+++ b/src/libsyntax/ext/concat_idents.rs
@@ -49,7 +49,7 @@ pub fn expand_syntax_ext<'cx>(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]
             }
         }
     }
-    let res = str_to_ident(&res_str[]);
+    let res = str_to_ident(&res_str[..]);
 
     let e = P(ast::Expr {
         id: ast::DUMMY_NODE_ID,
diff --git a/src/libsyntax/ext/deriving/bounds.rs b/src/libsyntax/ext/deriving/bounds.rs
index 879718a6399..93098484ae0 100644
--- a/src/libsyntax/ext/deriving/bounds.rs
+++ b/src/libsyntax/ext/deriving/bounds.rs
@@ -24,7 +24,7 @@ pub fn expand_deriving_bound<F>(cx: &mut ExtCtxt,
 {
     let name = match mitem.node {
         MetaWord(ref tname) => {
-            match &tname[] {
+            match &tname[..] {
                 "Copy" => "Copy",
                 "Send" | "Sync" => {
                     return cx.span_err(span,
diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs
index f878cb5ca8b..b912ed34ae0 100644
--- a/src/libsyntax/ext/deriving/generic/mod.rs
+++ b/src/libsyntax/ext/deriving/generic/mod.rs
@@ -367,7 +367,7 @@ impl<'a> TraitDef<'a> {
                 "allow" | "warn" | "deny" | "forbid" => true,
                 _ => false,
             }
-        }).map(|a| a.clone()));
+        }).cloned());
         push(P(ast::Item {
             attrs: attrs,
             ..(*newitem).clone()
@@ -410,7 +410,7 @@ impl<'a> TraitDef<'a> {
         let mut ty_params = ty_params.into_vec();
 
         // Copy the lifetimes
-        lifetimes.extend(generics.lifetimes.iter().map(|l| (*l).clone()));
+        lifetimes.extend(generics.lifetimes.iter().cloned());
 
         // Create the type parameters.
         ty_params.extend(generics.ty_params.iter().map(|ty_param| {
@@ -445,14 +445,14 @@ impl<'a> TraitDef<'a> {
                         span: self.span,
                         bound_lifetimes: wb.bound_lifetimes.clone(),
                         bounded_ty: wb.bounded_ty.clone(),
-                        bounds: OwnedSlice::from_vec(wb.bounds.iter().map(|b| b.clone()).collect())
+                        bounds: OwnedSlice::from_vec(wb.bounds.iter().cloned().collect())
                     })
                 }
                 ast::WherePredicate::RegionPredicate(ref rb) => {
                     ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate {
                         span: self.span,
                         lifetime: rb.lifetime,
-                        bounds: rb.bounds.iter().map(|b| b.clone()).collect()
+                        bounds: rb.bounds.iter().cloned().collect()
                     })
                 }
                 ast::WherePredicate::EqPredicate(ref we) => {
@@ -500,7 +500,7 @@ impl<'a> TraitDef<'a> {
         let opt_trait_ref = Some(trait_ref);
         let ident = ast_util::impl_pretty_name(&opt_trait_ref, &*self_type);
         let mut a = vec![attr];
-        a.extend(self.attributes.iter().map(|a| a.clone()));
+        a.extend(self.attributes.iter().cloned());
         cx.item(
             self.span,
             ident,
@@ -536,15 +536,15 @@ impl<'a> TraitDef<'a> {
                     self,
                     struct_def,
                     type_ident,
-                    &self_args[],
-                    &nonself_args[])
+                    &self_args[..],
+                    &nonself_args[..])
             } else {
                 method_def.expand_struct_method_body(cx,
                                                      self,
                                                      struct_def,
                                                      type_ident,
-                                                     &self_args[],
-                                                     &nonself_args[])
+                                                     &self_args[..],
+                                                     &nonself_args[..])
             };
 
             method_def.create_method(cx,
@@ -576,15 +576,15 @@ impl<'a> TraitDef<'a> {
                     self,
                     enum_def,
                     type_ident,
-                    &self_args[],
-                    &nonself_args[])
+                    &self_args[..],
+                    &nonself_args[..])
             } else {
                 method_def.expand_enum_method_body(cx,
                                                    self,
                                                    enum_def,
                                                    type_ident,
                                                    self_args,
-                                                   &nonself_args[])
+                                                   &nonself_args[..])
             };
 
             method_def.create_method(cx,
@@ -934,22 +934,22 @@ impl<'a> MethodDef<'a> {
             .collect::<Vec<String>>();
 
         let self_arg_idents = self_arg_names.iter()
-            .map(|name|cx.ident_of(&name[]))
+            .map(|name|cx.ident_of(&name[..]))
             .collect::<Vec<ast::Ident>>();
 
         // The `vi_idents` will be bound, solely in the catch-all, to
         // a series of let statements mapping each self_arg to a usize
         // corresponding to its variant index.
         let vi_idents: Vec<ast::Ident> = self_arg_names.iter()
-            .map(|name| { let vi_suffix = format!("{}_vi", &name[]);
-                          cx.ident_of(&vi_suffix[]) })
+            .map(|name| { let vi_suffix = format!("{}_vi", &name[..]);
+                          cx.ident_of(&vi_suffix[..]) })
             .collect::<Vec<ast::Ident>>();
 
         // Builds, via callback to call_substructure_method, the
         // delegated expression that handles the catch-all case,
         // using `__variants_tuple` to drive logic if necessary.
         let catch_all_substructure = EnumNonMatchingCollapsed(
-            self_arg_idents, &variants[], &vi_idents[]);
+            self_arg_idents, &variants[..], &vi_idents[..]);
 
         // These arms are of the form:
         // (Variant1, Variant1, ...) => Body1
@@ -976,7 +976,7 @@ impl<'a> MethodDef<'a> {
                     idents
                 };
                 for self_arg_name in self_arg_names.tail() {
-                    let (p, idents) = mk_self_pat(cx, &self_arg_name[]);
+                    let (p, idents) = mk_self_pat(cx, &self_arg_name[..]);
                     subpats.push(p);
                     self_pats_idents.push(idents);
                 }
@@ -1032,7 +1032,7 @@ impl<'a> MethodDef<'a> {
                                                 &**variant,
                                                 field_tuples);
                 let arm_expr = self.call_substructure_method(
-                    cx, trait_, type_ident, &self_args[], nonself_args,
+                    cx, trait_, type_ident, &self_args[..], nonself_args,
                     &substructure);
 
                 cx.arm(sp, vec![single_pat], arm_expr)
@@ -1085,7 +1085,7 @@ impl<'a> MethodDef<'a> {
             }
 
             let arm_expr = self.call_substructure_method(
-                cx, trait_, type_ident, &self_args[], nonself_args,
+                cx, trait_, type_ident, &self_args[..], nonself_args,
                 &catch_all_substructure);
 
             // Builds the expression:
@@ -1391,7 +1391,7 @@ pub fn cs_fold<F>(use_foldl: bool,
             }
         },
         EnumNonMatchingCollapsed(ref all_args, _, tuple) =>
-            enum_nonmatch_f(cx, trait_span, (&all_args[], tuple),
+            enum_nonmatch_f(cx, trait_span, (&all_args[..], tuple),
                             substructure.nonself_args),
         StaticEnum(..) | StaticStruct(..) => {
             cx.span_bug(trait_span, "static function in `derive`")
@@ -1431,7 +1431,7 @@ pub fn cs_same_method<F>(f: F,
             f(cx, trait_span, called)
         },
         EnumNonMatchingCollapsed(ref all_self_args, _, tuple) =>
-            enum_nonmatch_f(cx, trait_span, (&all_self_args[], tuple),
+            enum_nonmatch_f(cx, trait_span, (&all_self_args[..], tuple),
                             substructure.nonself_args),
         StaticEnum(..) | StaticStruct(..) => {
             cx.span_bug(trait_span, "static function in `derive`")
diff --git a/src/libsyntax/ext/deriving/hash.rs b/src/libsyntax/ext/deriving/hash.rs
index 5aa9f9a0c3e..2149c7a7f77 100644
--- a/src/libsyntax/ext/deriving/hash.rs
+++ b/src/libsyntax/ext/deriving/hash.rs
@@ -14,7 +14,6 @@ use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
 use ext::deriving::generic::*;
 use ext::deriving::generic::ty::*;
-use parse::token::InternedString;
 use ptr::P;
 
 pub fn expand_deriving_hash<F>(cx: &mut ExtCtxt,
@@ -26,30 +25,26 @@ pub fn expand_deriving_hash<F>(cx: &mut ExtCtxt,
 {
 
     let path = Path::new_(pathvec_std!(cx, core::hash::Hash), None,
-                          vec!(box Literal(Path::new_local("__S"))), true);
-    let generics = LifetimeBounds {
-        lifetimes: Vec::new(),
-        bounds: vec!(("__S",
-                      vec!(path_std!(cx, core::hash::Writer),
-                           path_std!(cx, core::hash::Hasher)))),
-    };
-    let args = Path::new_local("__S");
-    let inline = cx.meta_word(span, InternedString::new("inline"));
-    let attrs = vec!(cx.attribute(span, inline));
+                          vec!(), true);
+    let arg = Path::new_local("__H");
     let hash_trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
         path: path,
         additional_bounds: Vec::new(),
-        generics: generics,
+        generics: LifetimeBounds::empty(),
         methods: vec!(
             MethodDef {
                 name: "hash",
-                generics: LifetimeBounds::empty(),
+                generics: LifetimeBounds {
+                    lifetimes: Vec::new(),
+                    bounds: vec![("__H",
+                                  vec![path_std!(cx, core::hash::Hasher)])],
+                },
                 explicit_self: borrowed_explicit_self(),
-                args: vec!(Ptr(box Literal(args), Borrowed(None, MutMutable))),
+                args: vec!(Ptr(box Literal(arg), Borrowed(None, MutMutable))),
                 ret_ty: nil_ty(),
-                attributes: attrs,
+                attributes: vec![],
                 combine_substructure: combine_substructure(box |a, b, c| {
                     hash_substructure(a, b, c)
                 })
diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs
index 0ed9e85e576..f8bc331bfcf 100644
--- a/src/libsyntax/ext/deriving/mod.rs
+++ b/src/libsyntax/ext/deriving/mod.rs
@@ -102,7 +102,7 @@ pub fn expand_meta_derive(cx: &mut ExtCtxt,
                                                    |i| push(i)))
                         }
 
-                        match &tname[] {
+                        match &tname[..] {
                             "Clone" => expand!(clone::expand_deriving_clone),
 
                             "Hash" => expand!(hash::expand_deriving_hash),
diff --git a/src/libsyntax/ext/deriving/show.rs b/src/libsyntax/ext/deriving/show.rs
index 3f5947672e0..281f23f9e61 100644
--- a/src/libsyntax/ext/deriving/show.rs
+++ b/src/libsyntax/ext/deriving/show.rs
@@ -128,7 +128,7 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span,
     let formatter = substr.nonself_args[0].clone();
 
     let meth = cx.ident_of("write_fmt");
-    let s = token::intern_and_get_ident(&format_string[]);
+    let s = token::intern_and_get_ident(&format_string[..]);
     let format_string = cx.expr_str(span, s);
 
     // phew, not our responsibility any more!
diff --git a/src/libsyntax/ext/env.rs b/src/libsyntax/ext/env.rs
index 5d56707c87a..9c04d1e9282 100644
--- a/src/libsyntax/ext/env.rs
+++ b/src/libsyntax/ext/env.rs
@@ -30,7 +30,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenT
         Some(v) => v
     };
 
-    let e = match env::var(&var[]) {
+    let e = match env::var(&var[..]) {
       Err(..) => {
           cx.expr_path(cx.path_all(sp,
                                    true,
@@ -56,7 +56,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenT
                                    cx.ident_of("Some")),
                               vec!(cx.expr_str(sp,
                                                token::intern_and_get_ident(
-                                          &s[]))))
+                                          &s[..]))))
       }
     };
     MacExpr::new(e)
@@ -101,7 +101,7 @@ pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
         }
     }
 
-    let e = match env::var(&var[]) {
+    let e = match env::var(&var[..]) {
         Err(_) => {
             cx.span_err(sp, &msg);
             cx.expr_usize(sp, 0)
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 6b7cecee815..d4dda7390a5 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -405,7 +405,7 @@ fn expand_mac_invoc<T, F, G>(mac: ast::Mac, span: codemap::Span,
                                 },
                             });
                         let fm = fresh_mark();
-                        let marked_before = mark_tts(&tts[], fm);
+                        let marked_before = mark_tts(&tts[..], fm);
 
                         // The span that we pass to the expanders we want to
                         // be the root of the call stack. That's the most
@@ -416,7 +416,7 @@ fn expand_mac_invoc<T, F, G>(mac: ast::Mac, span: codemap::Span,
                         let opt_parsed = {
                             let expanded = expandfun.expand(fld.cx,
                                                             mac_span,
-                                                            &marked_before[]);
+                                                            &marked_before[..]);
                             parse_thunk(expanded)
                         };
                         let parsed = match opt_parsed {
@@ -425,7 +425,7 @@ fn expand_mac_invoc<T, F, G>(mac: ast::Mac, span: codemap::Span,
                                 fld.cx.span_err(
                                     pth.span,
                                     &format!("non-expression macro in expression position: {}",
-                                            &extnamestr[]
+                                            &extnamestr[..]
                                             )[]);
                                 return None;
                             }
@@ -633,8 +633,8 @@ pub fn expand_item_mac(it: P<ast::Item>,
                         }
                     });
                     // mark before expansion:
-                    let marked_before = mark_tts(&tts[], fm);
-                    expander.expand(fld.cx, it.span, &marked_before[])
+                    let marked_before = mark_tts(&tts[..], fm);
+                    expander.expand(fld.cx, it.span, &marked_before[..])
                 }
                 IdentTT(ref expander, span) => {
                     if it.ident.name == parse::token::special_idents::invalid.name {
@@ -652,7 +652,7 @@ pub fn expand_item_mac(it: P<ast::Item>,
                         }
                     });
                     // mark before expansion:
-                    let marked_tts = mark_tts(&tts[], fm);
+                    let marked_tts = mark_tts(&tts[..], fm);
                     expander.expand(fld.cx, it.span, it.ident, marked_tts)
                 }
                 MacroRulesTT => {
@@ -971,11 +971,11 @@ fn expand_pat(p: P<ast::Pat>, fld: &mut MacroExpander) -> P<ast::Pat> {
                     });
 
                     let fm = fresh_mark();
-                    let marked_before = mark_tts(&tts[], fm);
+                    let marked_before = mark_tts(&tts[..], fm);
                     let mac_span = fld.cx.original_span();
                     let expanded = match expander.expand(fld.cx,
                                         mac_span,
-                                        &marked_before[]).make_pat() {
+                                        &marked_before[..]).make_pat() {
                         Some(e) => e,
                         None => {
                             fld.cx.span_err(
@@ -1128,7 +1128,7 @@ fn expand_annotatable(a: Annotatable,
                 if valid_ident {
                     fld.cx.mod_push(it.ident);
                 }
-                let macro_use = contains_macro_use(fld, &new_attrs[]);
+                let macro_use = contains_macro_use(fld, &new_attrs[..]);
                 let result = with_exts_frame!(fld.cx.syntax_env,
                                               macro_use,
                                               noop_fold_item(it, fld));
@@ -1508,7 +1508,7 @@ impl Folder for Marker {
             node: match node {
                 MacInvocTT(path, tts, ctxt) => {
                     MacInvocTT(self.fold_path(path),
-                               self.fold_tts(&tts[]),
+                               self.fold_tts(&tts[..]),
                                mtwt::apply_mark(self.mark, ctxt))
                 }
             },
@@ -1914,7 +1914,7 @@ mod test {
                         .collect();
                     println!("varref #{}: {:?}, resolves to {}",idx, varref_idents, varref_name);
                     let string = token::get_ident(final_varref_ident);
-                    println!("varref's first segment's string: \"{}\"", &string[]);
+                    println!("varref's first segment's string: \"{}\"", &string[..]);
                     println!("binding #{}: {}, resolves to {}",
                              binding_idx, bindings[binding_idx], binding_name);
                     mtwt::with_sctable(|x| mtwt::display_sctable(x));
@@ -1967,10 +1967,10 @@ foo_module!();
         let cxbinds: Vec<&ast::Ident> =
             bindings.iter().filter(|b| {
                 let ident = token::get_ident(**b);
-                let string = &ident[];
+                let string = &ident[..];
                 "xx" == string
             }).collect();
-        let cxbinds: &[&ast::Ident] = &cxbinds[];
+        let cxbinds: &[&ast::Ident] = &cxbinds[..];
         let cxbind = match cxbinds {
             [b] => b,
             _ => panic!("expected just one binding for ext_cx")
diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs
index 170a455a913..e17329d7d33 100644
--- a/src/libsyntax/ext/format.rs
+++ b/src/libsyntax/ext/format.rs
@@ -118,7 +118,7 @@ fn parse_args(ecx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                 }
             };
             let interned_name = token::get_ident(ident);
-            let name = &interned_name[];
+            let name = &interned_name[..];
 
             p.expect(&token::Eq);
             let e = p.parse_expr();
@@ -218,7 +218,7 @@ impl<'a, 'b> Context<'a, 'b> {
                     let msg = format!("invalid reference to argument `{}` ({})",
                                       arg, self.describe_num_args());
 
-                    self.ecx.span_err(self.fmtsp, &msg[]);
+                    self.ecx.span_err(self.fmtsp, &msg[..]);
                     return;
                 }
                 {
@@ -238,7 +238,7 @@ impl<'a, 'b> Context<'a, 'b> {
                     Some(e) => e.span,
                     None => {
                         let msg = format!("there is no argument named `{}`", name);
-                        self.ecx.span_err(self.fmtsp, &msg[]);
+                        self.ecx.span_err(self.fmtsp, &msg[..]);
                         return;
                     }
                 };
@@ -587,7 +587,7 @@ impl<'a, 'b> Context<'a, 'b> {
                   -> P<ast::Expr> {
         let trait_ = match *ty {
             Known(ref tyname) => {
-                match &tyname[] {
+                match &tyname[..] {
                     ""  => "Display",
                     "?" => "Debug",
                     "e" => "LowerExp",
diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs
index 67990895d07..2c7bf713aad 100644
--- a/src/libsyntax/ext/quote.rs
+++ b/src/libsyntax/ext/quote.rs
@@ -668,7 +668,7 @@ fn mk_tt(cx: &ExtCtxt, tt: &ast::TokenTree) -> Vec<P<ast::Stmt>> {
             for i in 0..tt.len() {
                 seq.push(tt.get_tt(i));
             }
-            mk_tts(cx, &seq[])
+            mk_tts(cx, &seq[..])
         }
         ast::TtToken(sp, ref tok) => {
             let e_sp = cx.expr_ident(sp, id_ext("_sp"));
@@ -757,7 +757,7 @@ fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree])
     let stmt_let_tt = cx.stmt_let(sp, true, id_ext("tt"), cx.expr_vec_ng(sp));
 
     let mut vector = vec!(stmt_let_sp, stmt_let_tt);
-    vector.extend(mk_tts(cx, &tts[]).into_iter());
+    vector.extend(mk_tts(cx, &tts[..]).into_iter());
     let block = cx.expr_block(
         cx.block_all(sp,
                      vector,
diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs
index 7a3a3562bdf..c8d48750c75 100644
--- a/src/libsyntax/ext/source_util.rs
+++ b/src/libsyntax/ext/source_util.rs
@@ -65,7 +65,7 @@ pub fn expand_stringify(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                         -> Box<base::MacResult+'static> {
     let s = pprust::tts_to_string(tts);
     base::MacExpr::new(cx.expr_str(sp,
-                                   token::intern_and_get_ident(&s[])))
+                                   token::intern_and_get_ident(&s[..])))
 }
 
 pub fn expand_mod(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
@@ -78,7 +78,7 @@ pub fn expand_mod(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                    .connect("::");
     base::MacExpr::new(cx.expr_str(
             sp,
-            token::intern_and_get_ident(&string[])))
+            token::intern_and_get_ident(&string[..])))
 }
 
 /// include! : parse the given file as an expr
@@ -117,7 +117,7 @@ pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree
                     None => self.p.span_fatal(
                         self.p.span,
                         &format!("expected item, found `{}`",
-                                 self.p.this_token_to_string())[]
+                                 self.p.this_token_to_string())
                     )
                 }
             }
@@ -141,7 +141,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
             cx.span_err(sp,
                         &format!("couldn't read {}: {}",
                                 file.display(),
-                                e)[]);
+                                e));
             return DummyResult::expr(sp);
         }
         Ok(bytes) => bytes,
@@ -151,7 +151,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
             // Add this input file to the code map to make it available as
             // dependency information
             let filename = format!("{}", file.display());
-            let interned = token::intern_and_get_ident(&src[]);
+            let interned = token::intern_and_get_ident(&src[..]);
             cx.codemap().new_filemap(filename, src);
 
             base::MacExpr::new(cx.expr_str(sp, interned))
@@ -159,7 +159,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
         Err(_) => {
             cx.span_err(sp,
                         &format!("{} wasn't a utf-8 file",
-                                file.display())[]);
+                                file.display()));
             return DummyResult::expr(sp);
         }
     }
@@ -175,11 +175,11 @@ pub fn expand_include_bytes(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
     match File::open(&file).read_to_end() {
         Err(e) => {
             cx.span_err(sp,
-                        &format!("couldn't read {}: {}", file.display(), e)[]);
+                        &format!("couldn't read {}: {}", file.display(), e));
             return DummyResult::expr(sp);
         }
         Ok(bytes) => {
-            let bytes = bytes.iter().map(|x| *x).collect();
+            let bytes = bytes.iter().cloned().collect();
             base::MacExpr::new(cx.expr_lit(sp, ast::LitBinary(Rc::new(bytes))))
         }
     }
diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs
index d649e497ef7..664f7b3e088 100644
--- a/src/libsyntax/ext/tt/macro_parser.rs
+++ b/src/libsyntax/ext/tt/macro_parser.rs
@@ -165,7 +165,7 @@ pub fn count_names(ms: &[TokenTree]) -> usize {
 
 pub fn initial_matcher_pos(ms: Rc<Vec<TokenTree>>, sep: Option<Token>, lo: BytePos)
                            -> Box<MatcherPos> {
-    let match_idx_hi = count_names(&ms[]);
+    let match_idx_hi = count_names(&ms[..]);
     let matches: Vec<_> = (0..match_idx_hi).map(|_| Vec::new()).collect();
     box MatcherPos {
         stack: vec![],
@@ -229,7 +229,7 @@ pub fn nameize(p_s: &ParseSess, ms: &[TokenTree], res: &[Rc<NamedMatch>])
                         p_s.span_diagnostic
                            .span_fatal(sp,
                                        &format!("duplicated bind name: {}",
-                                               &string)[])
+                                               &string))
                     }
                 }
             }
@@ -254,13 +254,13 @@ pub fn parse_or_else(sess: &ParseSess,
                      rdr: TtReader,
                      ms: Vec<TokenTree> )
                      -> HashMap<Ident, Rc<NamedMatch>> {
-    match parse(sess, cfg, rdr, &ms[]) {
+    match parse(sess, cfg, rdr, &ms[..]) {
         Success(m) => m,
         Failure(sp, str) => {
-            sess.span_diagnostic.span_fatal(sp, &str[])
+            sess.span_diagnostic.span_fatal(sp, &str[..])
         }
         Error(sp, str) => {
-            sess.span_diagnostic.span_fatal(sp, &str[])
+            sess.span_diagnostic.span_fatal(sp, &str[..])
         }
     }
 }
@@ -283,7 +283,7 @@ pub fn parse(sess: &ParseSess,
              -> ParseResult {
     let mut cur_eis = Vec::new();
     cur_eis.push(initial_matcher_pos(Rc::new(ms.iter()
-                                                .map(|x| (*x).clone())
+                                                .cloned()
                                                 .collect()),
                                      None,
                                      rdr.peek().sp.lo));
@@ -447,7 +447,7 @@ pub fn parse(sess: &ParseSess,
                 for dv in &mut (&mut eof_eis[0]).matches {
                     v.push(dv.pop().unwrap());
                 }
-                return Success(nameize(sess, ms, &v[]));
+                return Success(nameize(sess, ms, &v[..]));
             } else if eof_eis.len() > 1 {
                 return Error(sp, "ambiguity: multiple successful parses".to_string());
             } else {
@@ -533,7 +533,7 @@ pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal {
         _ => {
             let token_str = pprust::token_to_string(&p.token);
             p.fatal(&format!("expected ident, found {}",
-                             &token_str[])[])
+                             &token_str[..]))
         }
       },
       "path" => {
@@ -542,7 +542,7 @@ pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal {
       "meta" => token::NtMeta(p.parse_meta_item()),
       _ => {
           p.span_fatal_help(sp,
-                            &format!("invalid fragment specifier `{}`", name)[],
+                            &format!("invalid fragment specifier `{}`", name),
                             "valid fragment specifiers are `ident`, `block`, \
                              `stmt`, `expr`, `pat`, `ty`, `path`, `meta`, `tt` \
                              and `item`")
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index f322cf8bad0..fa6d934a457 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -50,7 +50,7 @@ impl<'a> ParserAnyMacro<'a> {
                                following",
                               token_str);
             let span = parser.span;
-            parser.span_err(span, &msg[]);
+            parser.span_err(span, &msg[..]);
         }
     }
 }
@@ -123,8 +123,8 @@ impl TTMacroExpander for MacroRulesMacroExpander {
                           self.name,
                           self.imported_from,
                           arg,
-                          &self.lhses[],
-                          &self.rhses[])
+                          &self.lhses,
+                          &self.rhses)
     }
 }
 
@@ -151,7 +151,7 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
         match **lhs {
           MatchedNonterminal(NtTT(ref lhs_tt)) => {
             let lhs_tt = match **lhs_tt {
-                TtDelimited(_, ref delim) => &delim.tts[],
+                TtDelimited(_, ref delim) => &delim.tts[..],
                 _ => cx.span_fatal(sp, "malformed macro lhs")
             };
             // `None` is because we're not interpolating
@@ -159,7 +159,7 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
                                                       None,
                                                       None,
                                                       arg.iter()
-                                                         .map(|x| (*x).clone())
+                                                         .cloned()
                                                          .collect(),
                                                       true);
             match parse(cx.parse_sess(), cx.cfg(), arg_rdr, lhs_tt) {
@@ -192,13 +192,13 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
                 best_fail_spot = sp;
                 best_fail_msg = (*msg).clone();
               },
-              Error(sp, ref msg) => cx.span_fatal(sp, &msg[])
+              Error(sp, ref msg) => cx.span_fatal(sp, &msg[..])
             }
           }
           _ => cx.bug("non-matcher found in parsed lhses")
         }
     }
-    cx.span_fatal(best_fail_spot, &best_fail_msg[]);
+    cx.span_fatal(best_fail_spot, &best_fail_msg[..]);
 }
 
 // Note that macro-by-example's input is also matched against a token tree:
diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs
index 83234e3b7a5..0d92bd761b4 100644
--- a/src/libsyntax/ext/tt/transcribe.rs
+++ b/src/libsyntax/ext/tt/transcribe.rs
@@ -255,7 +255,7 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
                     }
                     LisContradiction(ref msg) => {
                         // FIXME #2887 blame macro invoker instead
-                        r.sp_diag.span_fatal(sp.clone(), &msg[]);
+                        r.sp_diag.span_fatal(sp.clone(), &msg[..]);
                     }
                     LisConstraint(len, _) => {
                         if len == 0 {
@@ -309,7 +309,7 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
                                 r.sp_diag.span_fatal(
                                     r.cur_span, /* blame the macro writer */
                                     &format!("variable '{:?}' is still repeating at this depth",
-                                            token::get_ident(ident))[]);
+                                            token::get_ident(ident)));
                             }
                         }
                     }
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 0110823ae98..071158fcebb 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -356,7 +356,7 @@ pub fn emit_feature_err(diag: &SpanHandler, feature: &str, span: Span, explain:
     diag.span_err(span, explain);
     diag.span_help(span, &format!("add #![feature({})] to the \
                                    crate attributes to enable",
-                                  feature)[]);
+                                  feature));
 }
 
 pub fn emit_feature_warn(diag: &SpanHandler, feature: &str, span: Span, explain: &str) {
@@ -364,7 +364,7 @@ pub fn emit_feature_warn(diag: &SpanHandler, feature: &str, span: Span, explain:
     if diag.handler.can_emit_warnings {
         diag.span_help(span, &format!("add #![feature({})] to the \
                                        crate attributes to silence this warning",
-                                      feature)[]);
+                                      feature));
     }
 }
 
@@ -438,7 +438,7 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
     fn visit_item(&mut self, i: &ast::Item) {
         match i.node {
             ast::ItemExternCrate(_) => {
-                if attr::contains_name(&i.attrs[], "macro_reexport") {
+                if attr::contains_name(&i.attrs[..], "macro_reexport") {
                     self.gate_feature("macro_reexport", i.span,
                                       "macros reexports are experimental \
                                        and possibly buggy");
@@ -446,7 +446,7 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
             }
 
             ast::ItemForeignMod(ref foreign_module) => {
-                if attr::contains_name(&i.attrs[], "link_args") {
+                if attr::contains_name(&i.attrs[..], "link_args") {
                     self.gate_feature("link_args", i.span,
                                       "the `link_args` attribute is not portable \
                                        across platforms, it is recommended to \
@@ -460,17 +460,17 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
             }
 
             ast::ItemFn(..) => {
-                if attr::contains_name(&i.attrs[], "plugin_registrar") {
+                if attr::contains_name(&i.attrs[..], "plugin_registrar") {
                     self.gate_feature("plugin_registrar", i.span,
                                       "compiler plugins are experimental and possibly buggy");
                 }
-                if attr::contains_name(&i.attrs[], "start") {
+                if attr::contains_name(&i.attrs[..], "start") {
                     self.gate_feature("start", i.span,
                                       "a #[start] function is an experimental \
                                        feature whose signature may change \
                                        over time");
                 }
-                if attr::contains_name(&i.attrs[], "main") {
+                if attr::contains_name(&i.attrs[..], "main") {
                     self.gate_feature("main", i.span,
                                       "declaration of a nonstandard #[main] \
                                        function may change over time, for now \
@@ -479,7 +479,7 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
             }
 
             ast::ItemStruct(..) => {
-                if attr::contains_name(&i.attrs[], "simd") {
+                if attr::contains_name(&i.attrs[..], "simd") {
                     self.gate_feature("simd", i.span,
                                       "SIMD types are experimental and possibly buggy");
                 }
@@ -505,7 +505,7 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
                                        removed in the future");
                 }
 
-                if attr::contains_name(&i.attrs[],
+                if attr::contains_name(&i.attrs[..],
                                        "old_orphan_check") {
                     self.gate_feature(
                         "old_orphan_check",
@@ -513,7 +513,7 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
                         "the new orphan check rules will eventually be strictly enforced");
                 }
 
-                if attr::contains_name(&i.attrs[],
+                if attr::contains_name(&i.attrs[..],
                                        "old_impl_check") {
                     self.gate_feature("old_impl_check",
                                       i.span,
@@ -528,7 +528,7 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
     }
 
     fn visit_foreign_item(&mut self, i: &ast::ForeignItem) {
-        if attr::contains_name(&i.attrs[], "linkage") {
+        if attr::contains_name(&i.attrs, "linkage") {
             self.gate_feature("linkage", i.span,
                               "the `linkage` attribute is experimental \
                                and not portable across platforms")
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index e8bdcd62b58..3a7fa54edbd 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -28,7 +28,6 @@
 #![feature(collections)]
 #![feature(core)]
 #![feature(env)]
-#![feature(hash)]
 #![feature(int_uint)]
 #![feature(old_io)]
 #![feature(libc)]
diff --git a/src/libsyntax/owned_slice.rs b/src/libsyntax/owned_slice.rs
index 0f9a56baa17..f5201d4a8bc 100644
--- a/src/libsyntax/owned_slice.rs
+++ b/src/libsyntax/owned_slice.rs
@@ -10,7 +10,7 @@
 
 use std::default::Default;
 use std::fmt;
-use std::iter::FromIterator;
+use std::iter::{IntoIterator, FromIterator};
 use std::ops::Deref;
 use std::vec;
 use serialize::{Encodable, Decodable, Encoder, Decoder};
@@ -77,8 +77,8 @@ impl<T: Clone> Clone for OwnedSlice<T> {
 }
 
 impl<T> FromIterator<T> for OwnedSlice<T> {
-    fn from_iter<I: Iterator<Item=T>>(iter: I) -> OwnedSlice<T> {
-        OwnedSlice::from_vec(iter.collect())
+    fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> OwnedSlice<T> {
+        OwnedSlice::from_vec(iter.into_iter().collect())
     }
 }
 
diff --git a/src/libsyntax/parse/lexer/comments.rs b/src/libsyntax/parse/lexer/comments.rs
index b17fc7fe82e..1f06db60027 100644
--- a/src/libsyntax/parse/lexer/comments.rs
+++ b/src/libsyntax/parse/lexer/comments.rs
@@ -61,7 +61,7 @@ pub fn doc_comment_style(comment: &str) -> ast::AttrStyle {
 
 pub fn strip_doc_comment_decoration(comment: &str) -> String {
     /// remove whitespace-only lines from the start/end of lines
-    fn vertical_trim(lines: Vec<String> ) -> Vec<String> {
+    fn vertical_trim(lines: Vec<String>) -> Vec<String> {
         let mut i = 0;
         let mut j = lines.len();
         // first line of all-stars should be omitted
@@ -82,7 +82,7 @@ pub fn strip_doc_comment_decoration(comment: &str) -> String {
         while j > i && lines[j - 1].trim().is_empty() {
             j -= 1;
         }
-        return lines[i..j].iter().map(|x| (*x).clone()).collect();
+        lines[i..j].iter().cloned().collect()
     }
 
     /// remove a "[ \t]*\*" block from each line, if possible
@@ -187,7 +187,7 @@ fn read_line_comments(rdr: &mut StringReader, code_to_the_left: bool,
         let line = rdr.read_one_line_comment();
         debug!("{}", line);
         // Doc comments are not put in comments.
-        if is_doc_comment(&line[]) {
+        if is_doc_comment(&line[..]) {
             break;
         }
         lines.push(line);
@@ -224,7 +224,7 @@ fn all_whitespace(s: &str, col: CharPos) -> Option<usize> {
 fn trim_whitespace_prefix_and_push_line(lines: &mut Vec<String> ,
                                         s: String, col: CharPos) {
     let len = s.len();
-    let s1 = match all_whitespace(&s[], col) {
+    let s1 = match all_whitespace(&s[..], col) {
         Some(col) => {
             if col < len {
                 (&s[col..len]).to_string()
@@ -261,7 +261,7 @@ fn read_block_comment(rdr: &mut StringReader,
             rdr.bump();
             rdr.bump();
         }
-        if is_block_doc_comment(&curr_line[]) {
+        if is_block_doc_comment(&curr_line[..]) {
             return
         }
         assert!(!curr_line.contains_char('\n'));
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index 38ba0b38df5..fd08cbd161b 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -16,14 +16,13 @@ use ext::tt::transcribe::tt_next_token;
 use parse::token;
 use parse::token::{str_to_ident};
 
-use std::borrow::IntoCow;
+use std::borrow::{IntoCow, Cow};
 use std::char;
 use std::fmt;
 use std::mem::replace;
 use std::num;
 use std::rc::Rc;
 use std::str;
-use std::string::CowString;
 
 pub use ext::tt::transcribe::{TtReader, new_tt_reader, new_tt_reader_with_doc_flag};
 
@@ -196,7 +195,7 @@ impl<'a> StringReader<'a> {
         let mut m = m.to_string();
         m.push_str(": ");
         for c in c.escape_default() { m.push(c) }
-        self.fatal_span_(from_pos, to_pos, &m[]);
+        self.fatal_span_(from_pos, to_pos, &m[..]);
     }
 
     /// Report a lexical error spanning [`from_pos`, `to_pos`), appending an
@@ -205,7 +204,7 @@ impl<'a> StringReader<'a> {
         let mut m = m.to_string();
         m.push_str(": ");
         for c in c.escape_default() { m.push(c) }
-        self.err_span_(from_pos, to_pos, &m[]);
+        self.err_span_(from_pos, to_pos, &m[..]);
     }
 
     /// Report a lexical error spanning [`from_pos`, `to_pos`), appending the
@@ -215,7 +214,7 @@ impl<'a> StringReader<'a> {
         let from = self.byte_offset(from_pos).to_usize();
         let to = self.byte_offset(to_pos).to_usize();
         m.push_str(&self.filemap.src[from..to]);
-        self.fatal_span_(from_pos, to_pos, &m[]);
+        self.fatal_span_(from_pos, to_pos, &m[..]);
     }
 
     /// Advance peek_tok and peek_span to refer to the next token, and
@@ -278,7 +277,7 @@ impl<'a> StringReader<'a> {
 
     /// Converts CRLF to LF in the given string, raising an error on bare CR.
     fn translate_crlf<'b>(&self, start: BytePos,
-                          s: &'b str, errmsg: &'b str) -> CowString<'b> {
+                          s: &'b str, errmsg: &'b str) -> Cow<'b, str> {
         let mut i = 0;
         while i < s.len() {
             let str::CharRange { ch, next } = s.char_range_at(i);
@@ -556,7 +555,7 @@ impl<'a> StringReader<'a> {
                     self.translate_crlf(start_bpos, string,
                                         "bare CR not allowed in block doc-comment")
                 } else { string.into_cow() };
-                token::DocComment(token::intern(&string[]))
+                token::DocComment(token::intern(&string[..]))
             } else {
                 token::Comment
             };
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 6ea23cf3f04..7ed48bdbb92 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -258,7 +258,7 @@ pub fn file_to_filemap(sess: &ParseSess, path: &Path, spanopt: Option<Span>)
             unreachable!()
         }
     };
-    match str::from_utf8(&bytes[]).ok() {
+    match str::from_utf8(&bytes[..]).ok() {
         Some(s) => {
             return string_to_filemap(sess, s.to_string(),
                                      path.as_str().unwrap().to_string())
@@ -398,7 +398,7 @@ pub fn char_lit(lit: &str) -> (char, isize) {
     }
 
     let msg = format!("lexer should have rejected a bad character escape {}", lit);
-    let msg2 = &msg[];
+    let msg2 = &msg[..];
 
     fn esc(len: usize, lit: &str) -> Option<(char, isize)> {
         num::from_str_radix(&lit[2..len], 16).ok()
@@ -662,7 +662,7 @@ pub fn integer_lit(s: &str, suffix: Option<&str>, sd: &SpanHandler, sp: Span) ->
     // s can only be ascii, byte indexing is fine
 
     let s2 = s.chars().filter(|&c| c != '_').collect::<String>();
-    let mut s = &s2[];
+    let mut s = &s2[..];
 
     debug!("integer_lit: {}, {:?}", s, suffix);
 
@@ -819,7 +819,7 @@ mod test {
     #[test]
     fn string_to_tts_macro () {
         let tts = string_to_tts("macro_rules! zip (($a)=>($a))".to_string());
-        let tts: &[ast::TokenTree] = &tts[];
+        let tts: &[ast::TokenTree] = &tts[..];
         match tts {
             [ast::TtToken(_, token::Ident(name_macro_rules, token::Plain)),
              ast::TtToken(_, token::Not),
@@ -1114,24 +1114,24 @@ mod test {
         let use_s = "use foo::bar::baz;";
         let vitem = string_to_item(use_s.to_string()).unwrap();
         let vitem_s = item_to_string(&*vitem);
-        assert_eq!(&vitem_s[], use_s);
+        assert_eq!(&vitem_s[..], use_s);
 
         let use_s = "use foo::bar as baz;";
         let vitem = string_to_item(use_s.to_string()).unwrap();
         let vitem_s = item_to_string(&*vitem);
-        assert_eq!(&vitem_s[], use_s);
+        assert_eq!(&vitem_s[..], use_s);
     }
 
     #[test] fn parse_extern_crate() {
         let ex_s = "extern crate foo;";
         let vitem = string_to_item(ex_s.to_string()).unwrap();
         let vitem_s = item_to_string(&*vitem);
-        assert_eq!(&vitem_s[], ex_s);
+        assert_eq!(&vitem_s[..], ex_s);
 
         let ex_s = "extern crate \"foo\" as bar;";
         let vitem = string_to_item(ex_s.to_string()).unwrap();
         let vitem_s = item_to_string(&*vitem);
-        assert_eq!(&vitem_s[], ex_s);
+        assert_eq!(&vitem_s[..], ex_s);
     }
 
     fn get_spans_of_pat_idents(src: &str) -> Vec<Span> {
@@ -1203,19 +1203,19 @@ mod test {
         let source = "/// doc comment\r\nfn foo() {}".to_string();
         let item = parse_item_from_source_str(name.clone(), source, Vec::new(), &sess).unwrap();
         let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap();
-        assert_eq!(&doc[], "/// doc comment");
+        assert_eq!(&doc[..], "/// doc comment");
 
         let source = "/// doc comment\r\n/// line 2\r\nfn foo() {}".to_string();
         let item = parse_item_from_source_str(name.clone(), source, Vec::new(), &sess).unwrap();
         let docs = item.attrs.iter().filter(|a| &a.name()[] == "doc")
                     .map(|a| a.value_str().unwrap().to_string()).collect::<Vec<_>>();
         let b: &[_] = &["/// doc comment".to_string(), "/// line 2".to_string()];
-        assert_eq!(&docs[], b);
+        assert_eq!(&docs[..], b);
 
         let source = "/** doc comment\r\n *  with CRLF */\r\nfn foo() {}".to_string();
         let item = parse_item_from_source_str(name, source, Vec::new(), &sess).unwrap();
         let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap();
-        assert_eq!(&doc[], "/** doc comment\n *  with CRLF */");
+        assert_eq!(&doc[..], "/** doc comment\n *  with CRLF */");
     }
 
     #[test]
@@ -1235,7 +1235,7 @@ mod test {
         let span = tts.iter().rev().next().unwrap().get_span();
 
         match sess.span_diagnostic.cm.span_to_snippet(span) {
-            Ok(s) => assert_eq!(&s[], "{ body }"),
+            Ok(s) => assert_eq!(&s[..], "{ body }"),
             Err(_) => panic!("could not get snippet"),
         }
     }
diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs
index 1df2e762ee7..8480772ce6c 100644
--- a/src/libsyntax/parse/obsolete.rs
+++ b/src/libsyntax/parse/obsolete.rs
@@ -28,6 +28,7 @@ pub enum ObsoleteSyntax {
     ProcExpr,
     ClosureType,
     ClosureKind,
+    EmptyIndex,
 }
 
 pub trait ParserObsoleteMethods {
@@ -40,7 +41,8 @@ pub trait ParserObsoleteMethods {
               sp: Span,
               kind: ObsoleteSyntax,
               kind_str: &str,
-              desc: &str);
+              desc: &str,
+              error: bool);
     fn is_obsolete_ident(&mut self, ident: &str) -> bool;
     fn eat_obsolete_ident(&mut self, ident: &str) -> bool;
 }
@@ -48,35 +50,46 @@ pub trait ParserObsoleteMethods {
 impl<'a> ParserObsoleteMethods for parser::Parser<'a> {
     /// Reports an obsolete syntax non-fatal error.
     fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax) {
-        let (kind_str, desc) = match kind {
+        let (kind_str, desc, error) = match kind {
             ObsoleteSyntax::ForSized => (
                 "for Sized?",
                 "no longer required. Traits (and their `Self` type) do not have the `Sized` bound \
                  by default",
+                true,
             ),
             ObsoleteSyntax::ProcType => (
                 "the `proc` type",
                 "use unboxed closures instead",
+                true,
             ),
             ObsoleteSyntax::ProcExpr => (
                 "`proc` expression",
                 "use a `move ||` expression instead",
+                true,
             ),
             ObsoleteSyntax::ClosureType => (
                 "`|usize| -> bool` closure type",
-                "use unboxed closures instead, no type annotation needed"
+                "use unboxed closures instead, no type annotation needed",
+                true,
             ),
             ObsoleteSyntax::ClosureKind => (
                 "`:`, `&mut:`, or `&:`",
-                "rely on inference instead"
+                "rely on inference instead",
+                true,
             ),
             ObsoleteSyntax::Sized => (
                 "`Sized? T` for removing the `Sized` bound",
-                "write `T: ?Sized` instead"
+                "write `T: ?Sized` instead",
+                true,
+            ),
+            ObsoleteSyntax::EmptyIndex => (
+                "[]",
+                "write `[..]` instead",
+                false, // warning for now
             ),
         };
 
-        self.report(sp, kind, kind_str, desc);
+        self.report(sp, kind, kind_str, desc, error);
     }
 
     /// Reports an obsolete syntax non-fatal error, and returns
@@ -90,9 +103,13 @@ impl<'a> ParserObsoleteMethods for parser::Parser<'a> {
               sp: Span,
               kind: ObsoleteSyntax,
               kind_str: &str,
-              desc: &str) {
-        self.span_err(sp,
-                      &format!("obsolete syntax: {}", kind_str)[]);
+              desc: &str,
+              error: bool) {
+        if error {
+            self.span_err(sp, &format!("obsolete syntax: {}", kind_str)[]);
+        } else {
+            self.span_warn(sp, &format!("obsolete syntax: {}", kind_str)[]);
+        }
 
         if !self.obsolete_set.contains(&kind) {
             self.sess
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 407740e580d..370201e5382 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -240,9 +240,8 @@ macro_rules! maybe_whole {
 
 fn maybe_append(mut lhs: Vec<Attribute>, rhs: Option<Vec<Attribute>>)
                 -> Vec<Attribute> {
-    match rhs {
-        Some(ref attrs) => lhs.extend(attrs.iter().map(|a| a.clone())),
-        None => {}
+    if let Some(ref attrs) = rhs {
+        lhs.extend(attrs.iter().cloned())
     }
     lhs
 }
@@ -362,7 +361,7 @@ impl<'a> Parser<'a> {
         let token_str = Parser::token_to_string(t);
         let last_span = self.last_span;
         self.span_fatal(last_span, &format!("unexpected token: `{}`",
-                                                token_str)[]);
+                                                token_str));
     }
 
     pub fn unexpected(&mut self) -> ! {
@@ -381,7 +380,7 @@ impl<'a> Parser<'a> {
                 let this_token_str = self.this_token_to_string();
                 self.fatal(&format!("expected `{}`, found `{}`",
                                    token_str,
-                                   this_token_str)[])
+                                   this_token_str))
             }
         } else {
             self.expect_one_of(slice::ref_slice(t), &[]);
@@ -422,7 +421,7 @@ impl<'a> Parser<'a> {
             expected.push_all(&*self.expected_tokens);
             expected.sort_by(|a, b| a.to_string().cmp(&b.to_string()));
             expected.dedup();
-            let expect = tokens_to_string(&expected[]);
+            let expect = tokens_to_string(&expected[..]);
             let actual = self.this_token_to_string();
             self.fatal(
                 &(if expected.len() > 1 {
@@ -436,7 +435,7 @@ impl<'a> Parser<'a> {
                     (format!("expected {}, found `{}`",
                              expect,
                              actual))
-                }[])
+                })[..]
             )
         }
     }
@@ -467,9 +466,9 @@ impl<'a> Parser<'a> {
         debug!("commit_expr {:?}", e);
         if let ExprPath(..) = e.node {
             // might be unit-struct construction; check for recoverableinput error.
-            let mut expected = edible.iter().map(|x| x.clone()).collect::<Vec<_>>();
+            let mut expected = edible.iter().cloned().collect::<Vec<_>>();
             expected.push_all(inedible);
-            self.check_for_erroneous_unit_struct_expecting(&expected[]);
+            self.check_for_erroneous_unit_struct_expecting(&expected[..]);
         }
         self.expect_one_of(edible, inedible)
     }
@@ -485,10 +484,9 @@ impl<'a> Parser<'a> {
         if self.last_token
                .as_ref()
                .map_or(false, |t| t.is_ident() || t.is_path()) {
-            let mut expected = edible.iter().map(|x| x.clone()).collect::<Vec<_>>();
-            expected.push_all(&inedible[]);
-            self.check_for_erroneous_unit_struct_expecting(
-                &expected[]);
+            let mut expected = edible.iter().cloned().collect::<Vec<_>>();
+            expected.push_all(&inedible);
+            self.check_for_erroneous_unit_struct_expecting(&expected);
         }
         self.expect_one_of(edible, inedible)
     }
@@ -511,7 +509,7 @@ impl<'a> Parser<'a> {
             _ => {
                 let token_str = self.this_token_to_string();
                 self.fatal(&format!("expected ident, found `{}`",
-                                    token_str)[])
+                                    token_str))
             }
         }
     }
@@ -599,7 +597,7 @@ impl<'a> Parser<'a> {
             let span = self.span;
             self.span_err(span,
                           &format!("expected identifier, found keyword `{}`",
-                                  token_str)[]);
+                                  token_str));
         }
     }
 
@@ -608,7 +606,7 @@ impl<'a> Parser<'a> {
         if self.token.is_reserved_keyword() {
             let token_str = self.this_token_to_string();
             self.fatal(&format!("`{}` is a reserved keyword",
-                               token_str)[])
+                               token_str))
         }
     }
 
@@ -734,7 +732,7 @@ impl<'a> Parser<'a> {
                 let this_token_str = self.this_token_to_string();
                 self.fatal(&format!("expected `{}`, found `{}`",
                                    gt_str,
-                                   this_token_str)[])
+                                   this_token_str))
             }
         }
     }
@@ -1364,7 +1362,7 @@ impl<'a> Parser<'a> {
                     let (inner_attrs, body) =
                         p.parse_inner_attrs_and_block();
                     let mut attrs = attrs;
-                    attrs.push_all(&inner_attrs[]);
+                    attrs.push_all(&inner_attrs[..]);
                     ProvidedMethod(P(ast::Method {
                         attrs: attrs,
                         id: ast::DUMMY_NODE_ID,
@@ -1383,7 +1381,7 @@ impl<'a> Parser<'a> {
                   _ => {
                       let token_str = p.this_token_to_string();
                       p.fatal(&format!("expected `;` or `{{`, found `{}`",
-                                       token_str)[])
+                                       token_str)[..])
                   }
                 }
             }
@@ -1551,7 +1549,7 @@ impl<'a> Parser<'a> {
         } else {
             let this_token_str = self.this_token_to_string();
             let msg = format!("expected type, found `{}`", this_token_str);
-            self.fatal(&msg[]);
+            self.fatal(&msg[..]);
         };
 
         let sp = mk_sp(lo, self.last_span.hi);
@@ -1699,14 +1697,14 @@ impl<'a> Parser<'a> {
                     token::StrRaw(s, n) => {
                         (true,
                          LitStr(
-                            token::intern_and_get_ident(&parse::raw_str_lit(s.as_str())[]),
+                            token::intern_and_get_ident(&parse::raw_str_lit(s.as_str())),
                             ast::RawStr(n)))
                     }
                     token::Binary(i) =>
                         (true, LitBinary(parse::binary_lit(i.as_str()))),
                     token::BinaryRaw(i, _) =>
                         (true,
-                         LitBinary(Rc::new(i.as_str().as_bytes().iter().map(|&x| x).collect()))),
+                         LitBinary(Rc::new(i.as_str().as_bytes().iter().cloned().collect()))),
                 };
 
                 if suffix_illegal {
@@ -1944,7 +1942,7 @@ impl<'a> Parser<'a> {
                 };
             }
             _ => {
-                self.fatal(&format!("expected a lifetime name")[]);
+                self.fatal(&format!("expected a lifetime name"));
             }
         }
     }
@@ -1982,7 +1980,7 @@ impl<'a> Parser<'a> {
                     let msg = format!("expected `,` or `>` after lifetime \
                                       name, found `{}`",
                                       this_token_str);
-                    self.fatal(&msg[]);
+                    self.fatal(&msg[..]);
                 }
             }
         }
@@ -2497,7 +2495,7 @@ impl<'a> Parser<'a> {
                     let last_span = self.last_span;
                     let fstr = n.as_str();
                     self.span_err(last_span,
-                                  &format!("unexpected token: `{}`", n.as_str())[]);
+                                  &format!("unexpected token: `{}`", n.as_str()));
                     if fstr.chars().all(|x| "0123456789.".contains_char(x)) {
                         let float = match fstr.parse::<f64>().ok() {
                             Some(f) => f,
@@ -2506,7 +2504,7 @@ impl<'a> Parser<'a> {
                         self.span_help(last_span,
                             &format!("try parenthesizing the first index; e.g., `(foo.{}){}`",
                                     float.trunc() as usize,
-                                    &float.fract().to_string()[1..])[]);
+                                    &float.fract().to_string()[1..]));
                     }
                     self.abort_if_errors();
 
@@ -2552,8 +2550,9 @@ impl<'a> Parser<'a> {
                             parameters: ast::PathParameters::none(),
                         }
                     }).collect();
+                    let span = mk_sp(lo, hi);
                     let path = ast::Path {
-                        span: mk_sp(lo, hi),
+                        span: span,
                         global: true,
                         segments: segments,
                     };
@@ -2562,10 +2561,8 @@ impl<'a> Parser<'a> {
                     let ix = self.mk_expr(bracket_pos, hi, range);
                     let index = self.mk_index(e, ix);
                     e = self.mk_expr(lo, hi, index);
-                    // Enable after snapshot.
-                    // self.span_warn(e.span, "deprecated slicing syntax: `[]`");
-                    // self.span_note(e.span,
-                    //               "use `&expr[..]` to construct a slice of the whole of expr");
+
+                    self.obsolete(span, ObsoleteSyntax::EmptyIndex);
                 } else {
                     let ix = self.parse_expr();
                     hi = self.span.hi;
@@ -2639,7 +2636,7 @@ impl<'a> Parser<'a> {
             match self.token {
                 token::SubstNt(name, _) =>
                     self.fatal(&format!("unknown macro variable `{}`",
-                                       token::get_ident(name))[]),
+                                       token::get_ident(name))),
                 _ => {}
             }
         }
@@ -2701,7 +2698,7 @@ impl<'a> Parser<'a> {
                     };
                     let token_str = p.this_token_to_string();
                     p.fatal(&format!("incorrect close delimiter: `{}`",
-                                    token_str)[])
+                                    token_str))
                 },
                 /* we ought to allow different depths of unquotation */
                 token::Dollar | token::SubstNt(..) if p.quote_depth > 0 => {
@@ -2822,7 +2819,7 @@ impl<'a> Parser<'a> {
                         let this_token_to_string = self.this_token_to_string();
                         self.span_err(span,
                                       &format!("expected expression, found `{}`",
-                                              this_token_to_string)[]);
+                                              this_token_to_string));
                         let box_span = mk_sp(lo, self.last_span.hi);
                         self.span_help(box_span,
                                        "perhaps you meant `box() (foo)` instead?");
@@ -3275,7 +3272,7 @@ impl<'a> Parser<'a> {
                 if self.token != token::CloseDelim(token::Brace) {
                     let token_str = self.this_token_to_string();
                     self.fatal(&format!("expected `{}`, found `{}`", "}",
-                                       token_str)[])
+                                       token_str))
                 }
                 etc = true;
                 break;
@@ -3576,7 +3573,7 @@ impl<'a> Parser<'a> {
             let span = self.span;
             let tok_str = self.this_token_to_string();
             self.span_fatal(span,
-                            &format!("expected identifier, found `{}`", tok_str)[]);
+                            &format!("expected identifier, found `{}`", tok_str));
         }
         let ident = self.parse_ident();
         let last_span = self.last_span;
@@ -3673,7 +3670,7 @@ impl<'a> Parser<'a> {
 
         let lo = self.span.lo;
         if self.check_keyword(keywords::Let) {
-            check_expected_item(self, &item_attrs[]);
+            check_expected_item(self, &item_attrs[..]);
             self.expect_keyword(keywords::Let);
             let decl = self.parse_let();
             P(spanned(lo, decl.span.hi, StmtDecl(decl, ast::DUMMY_NODE_ID)))
@@ -3682,7 +3679,7 @@ impl<'a> Parser<'a> {
             && self.look_ahead(1, |t| *t == token::Not) {
             // it's a macro invocation:
 
-            check_expected_item(self, &item_attrs[]);
+            check_expected_item(self, &item_attrs[..]);
 
             // Potential trouble: if we allow macros with paths instead of
             // idents, we'd need to look ahead past the whole path here...
@@ -3710,7 +3707,7 @@ impl<'a> Parser<'a> {
                     let tok_str = self.this_token_to_string();
                     self.fatal(&format!("expected {}`(` or `{{`, found `{}`",
                                        ident_str,
-                                       tok_str)[])
+                                       tok_str))
                 },
             };
 
@@ -3758,7 +3755,7 @@ impl<'a> Parser<'a> {
             }
         } else {
             let found_attrs = !item_attrs.is_empty();
-            let item_err = Parser::expected_item_err(&item_attrs[]);
+            let item_err = Parser::expected_item_err(&item_attrs[..]);
             match self.parse_item_(item_attrs, false) {
                 Ok(i) => {
                     let hi = i.span.hi;
@@ -3795,7 +3792,7 @@ impl<'a> Parser<'a> {
             let sp = self.span;
             let tok = self.this_token_to_string();
             self.span_fatal_help(sp,
-                                 &format!("expected `{{`, found `{}`", tok)[],
+                                 &format!("expected `{{`, found `{}`", tok),
                                  "place this code inside a block");
         }
 
@@ -3830,13 +3827,13 @@ impl<'a> Parser<'a> {
         while self.token != token::CloseDelim(token::Brace) {
             // parsing items even when they're not allowed lets us give
             // better error messages and recover more gracefully.
-            attributes_box.push_all(&self.parse_outer_attributes()[]);
+            attributes_box.push_all(&self.parse_outer_attributes());
             match self.token {
                 token::Semi => {
                     if !attributes_box.is_empty() {
                         let last_span = self.last_span;
                         self.span_err(last_span,
-                                      Parser::expected_item_err(&attributes_box[]));
+                                      Parser::expected_item_err(&attributes_box[..]));
                         attributes_box = Vec::new();
                     }
                     self.bump(); // empty
@@ -3928,7 +3925,7 @@ impl<'a> Parser<'a> {
         if !attributes_box.is_empty() {
             let last_span = self.last_span;
             self.span_err(last_span,
-                          Parser::expected_item_err(&attributes_box[]));
+                          Parser::expected_item_err(&attributes_box[..]));
         }
 
         let hi = self.span.hi;
@@ -4383,7 +4380,7 @@ impl<'a> Parser<'a> {
             _ => {
                 let token_str = self.this_token_to_string();
                 self.fatal(&format!("expected `self`, found `{}`",
-                                   token_str)[])
+                                   token_str))
             }
         }
     }
@@ -4404,7 +4401,7 @@ impl<'a> Parser<'a> {
             _ => {
                 let token_str = self.this_token_to_string();
                 self.fatal(&format!("expected `Self`, found `{}`",
-                                   token_str)[])
+                                   token_str))
             }
         }
     }
@@ -4539,7 +4536,7 @@ impl<'a> Parser<'a> {
                 _ => {
                     let token_str = self.this_token_to_string();
                     self.fatal(&format!("expected `,` or `)`, found `{}`",
-                                       token_str)[])
+                                       token_str))
                 }
             }
             }
@@ -4712,7 +4709,7 @@ impl<'a> Parser<'a> {
                 let (inner_attrs, body) = self.parse_inner_attrs_and_block();
                 let body_span = body.span;
                 let mut new_attrs = attrs;
-                new_attrs.push_all(&inner_attrs[]);
+                new_attrs.push_all(&inner_attrs[..]);
                 (ast::MethDecl(ident,
                                generics,
                                abi,
@@ -4942,7 +4939,7 @@ impl<'a> Parser<'a> {
             if fields.len() == 0 {
                 self.fatal(&format!("unit-like struct definition should be \
                     written as `struct {};`",
-                    token::get_ident(class_name.clone()))[]);
+                    token::get_ident(class_name.clone())));
             }
 
             self.bump();
@@ -4950,7 +4947,7 @@ impl<'a> Parser<'a> {
             let token_str = self.this_token_to_string();
             self.fatal(&format!("expected `where`, or `{}` after struct \
                                 name, found `{}`", "{",
-                                token_str)[]);
+                                token_str));
         }
 
         fields
@@ -4981,7 +4978,7 @@ impl<'a> Parser<'a> {
             if fields.len() == 0 {
                 self.fatal(&format!("unit-like struct definition should be \
                     written as `struct {};`",
-                    token::get_ident(class_name.clone()))[]);
+                    token::get_ident(class_name.clone())));
             }
 
             self.parse_where_clause(generics);
@@ -4996,7 +4993,7 @@ impl<'a> Parser<'a> {
         } else {
             let token_str = self.this_token_to_string();
             self.fatal(&format!("expected `where`, `{}`, `(`, or `;` after struct \
-                name, found `{}`", "{", token_str)[]);
+                name, found `{}`", "{", token_str));
         }
     }
 
@@ -5016,7 +5013,7 @@ impl<'a> Parser<'a> {
                 let token_str = self.this_token_to_string();
                 self.span_fatal_help(span,
                                      &format!("expected `,`, or `}}`, found `{}`",
-                                             token_str)[],
+                                             token_str),
                                      "struct fields should be separated by commas")
             }
         }
@@ -5088,7 +5085,7 @@ impl<'a> Parser<'a> {
         // Parse all of the items up to closing or an attribute.
 
         let mut attrs = first_item_attrs;
-        attrs.push_all(&self.parse_outer_attributes()[]);
+        attrs.push_all(&self.parse_outer_attributes());
         let mut items = vec![];
 
         loop {
@@ -5108,14 +5105,14 @@ impl<'a> Parser<'a> {
 
         while self.token != term {
             let mut attrs = mem::replace(&mut attrs, vec![]);
-            attrs.push_all(&self.parse_outer_attributes()[]);
+            attrs.push_all(&self.parse_outer_attributes());
             debug!("parse_mod_items: parse_item_(attrs={:?})", attrs);
             match self.parse_item_(attrs, true /* macros allowed */) {
               Ok(item) => items.push(item),
               Err(_) => {
                   let token_str = self.this_token_to_string();
                   self.fatal(&format!("expected item, found `{}`",
-                                     token_str)[])
+                                     token_str))
               }
             }
         }
@@ -5124,7 +5121,7 @@ impl<'a> Parser<'a> {
             // We parsed attributes for the first item but didn't find it
             let last_span = self.last_span;
             self.span_err(last_span,
-                          Parser::expected_item_err(&attrs[]));
+                          Parser::expected_item_err(&attrs[..]));
         }
 
         ast::Mod {
@@ -5203,8 +5200,8 @@ impl<'a> Parser<'a> {
                 let mod_name = mod_string.to_string();
                 let default_path_str = format!("{}.rs", mod_name);
                 let secondary_path_str = format!("{}/mod.rs", mod_name);
-                let default_path = dir_path.join(&default_path_str[]);
-                let secondary_path = dir_path.join(&secondary_path_str[]);
+                let default_path = dir_path.join(&default_path_str[..]);
+                let secondary_path = dir_path.join(&secondary_path_str[..]);
                 let default_exists = default_path.exists();
                 let secondary_exists = secondary_path.exists();
 
@@ -5219,13 +5216,13 @@ impl<'a> Parser<'a> {
                                    &format!("maybe move this module `{0}` \
                                             to its own directory via \
                                             `{0}/mod.rs`",
-                                           this_module)[]);
+                                           this_module));
                     if default_exists || secondary_exists {
                         self.span_note(id_sp,
                                        &format!("... or maybe `use` the module \
                                                 `{}` instead of possibly \
                                                 redeclaring it",
-                                               mod_name)[]);
+                                               mod_name));
                     }
                     self.abort_if_errors();
                 }
@@ -5236,12 +5233,12 @@ impl<'a> Parser<'a> {
                     (false, false) => {
                         self.span_fatal_help(id_sp,
                                              &format!("file not found for module `{}`",
-                                                     mod_name)[],
+                                                     mod_name),
                                              &format!("name the file either {} or {} inside \
                                                      the directory {:?}",
                                                      default_path_str,
                                                      secondary_path_str,
-                                                     dir_path.display())[]);
+                                                     dir_path.display()));
                     }
                     (true, true) => {
                         self.span_fatal_help(
@@ -5250,7 +5247,7 @@ impl<'a> Parser<'a> {
                                      and {}",
                                     mod_name,
                                     default_path_str,
-                                    secondary_path_str)[],
+                                    secondary_path_str),
                             "delete or rename one of them to remove the ambiguity");
                     }
                 }
@@ -5272,11 +5269,11 @@ impl<'a> Parser<'a> {
                 let mut err = String::from_str("circular modules: ");
                 let len = included_mod_stack.len();
                 for p in &included_mod_stack[i.. len] {
-                    err.push_str(&p.display().as_cow()[]);
+                    err.push_str(&p.display().as_cow());
                     err.push_str(" -> ");
                 }
-                err.push_str(&path.display().as_cow()[]);
-                self.span_fatal(id_sp, &err[]);
+                err.push_str(&path.display().as_cow());
+                self.span_fatal(id_sp, &err[..]);
             }
             None => ()
         }
@@ -5381,7 +5378,7 @@ impl<'a> Parser<'a> {
                     self.span_help(span,
                                    &format!("perhaps you meant to enclose the crate name `{}` in \
                                            a string?",
-                                          the_ident.as_str())[]);
+                                          the_ident.as_str()));
                     None
                 } else {
                     None
@@ -5407,7 +5404,7 @@ impl<'a> Parser<'a> {
                 self.span_fatal(span,
                                 &format!("expected extern crate name but \
                                          found `{}`",
-                                        token_str)[]);
+                                        token_str));
             }
         };
 
@@ -5505,7 +5502,7 @@ impl<'a> Parser<'a> {
                     self.span_err(start_span,
                         &format!("unit-like struct variant should be written \
                                  without braces, as `{},`",
-                                token::get_ident(ident))[]);
+                                token::get_ident(ident)));
                 }
                 kind = StructVariantKind(struct_def);
             } else if self.check(&token::OpenDelim(token::Paren)) {
@@ -5583,7 +5580,7 @@ impl<'a> Parser<'a> {
                             &format!("illegal ABI: expected one of [{}], \
                                      found `{}`",
                                     abi::all_names().connect(", "),
-                                    the_string)[]);
+                                    the_string));
                         None
                     }
                 }
@@ -5663,7 +5660,7 @@ impl<'a> Parser<'a> {
             let token_str = self.this_token_to_string();
             self.span_fatal(span,
                             &format!("expected `{}` or `fn`, found `{}`", "{",
-                                    token_str)[]);
+                                    token_str));
         }
 
         if self.eat_keyword_noexpect(keywords::Virtual) {
@@ -5772,7 +5769,7 @@ impl<'a> Parser<'a> {
         if self.eat_keyword(keywords::Mod) {
             // MODULE ITEM
             let (ident, item_, extra_attrs) =
-                self.parse_item_mod(&attrs[]);
+                self.parse_item_mod(&attrs[..]);
             let last_span = self.last_span;
             let item = self.mk_item(lo,
                                     last_span.hi,
@@ -6057,7 +6054,7 @@ impl<'a> Parser<'a> {
     fn parse_foreign_items(&mut self, first_item_attrs: Vec<Attribute>)
                            -> Vec<P<ForeignItem>> {
         let mut attrs = first_item_attrs;
-        attrs.push_all(&self.parse_outer_attributes()[]);
+        attrs.push_all(&self.parse_outer_attributes());
         let mut foreign_items = Vec::new();
         loop {
             match self.parse_foreign_item(attrs) {
@@ -6078,7 +6075,7 @@ impl<'a> Parser<'a> {
         if !attrs.is_empty() {
             let last_span = self.last_span;
             self.span_err(last_span,
-                          Parser::expected_item_err(&attrs[]));
+                          Parser::expected_item_err(&attrs[..]));
         }
 
         foreign_items
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 0747a97fa37..433c013591c 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -482,7 +482,7 @@ macro_rules! declare_special_idents_and_keywords {(
         $(init_vec.push($si_str);)*
         $(init_vec.push($sk_str);)*
         $(init_vec.push($rk_str);)*
-        interner::StrInterner::prefill(&init_vec[])
+        interner::StrInterner::prefill(&init_vec[..])
     }
 }}
 
@@ -644,7 +644,7 @@ impl BytesContainer for InternedString {
         // of `BytesContainer`, which is itself a workaround for the lack of
         // DST.
         unsafe {
-            let this = &self[];
+            let this = &self[..];
             mem::transmute::<&[u8],&[u8]>(this.container_as_bytes())
         }
     }
diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs
index 6c6cf186e70..1593bfb97fe 100644
--- a/src/libsyntax/print/pp.rs
+++ b/src/libsyntax/print/pp.rs
@@ -539,8 +539,8 @@ impl Printer {
     pub fn print(&mut self, token: Token, l: isize) -> old_io::IoResult<()> {
         debug!("print {} {} (remaining line space={})", tok_str(&token), l,
                self.space);
-        debug!("{}", buf_str(&self.token[],
-                             &self.size[],
+        debug!("{}", buf_str(&self.token,
+                             &self.size,
                              self.left,
                              self.right,
                              6));
@@ -607,7 +607,7 @@ impl Printer {
             assert_eq!(l, len);
             // assert!(l <= space);
             self.space -= len;
-            self.print_str(&s[])
+            self.print_str(&s[..])
           }
           Token::Eof => {
             // Eof should never get here.
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 4b021f2434f..f26578e7401 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -134,7 +134,7 @@ pub fn print_crate<'a>(cm: &'a CodeMap,
         try!(s.print_attribute(&fake_attr));
     }
 
-    try!(s.print_mod(&krate.module, &krate.attrs[]));
+    try!(s.print_mod(&krate.module, &krate.attrs));
     try!(s.print_remaining_comments());
     eof(&mut s.s)
 }
@@ -602,7 +602,7 @@ impl<'a> State<'a> {
     pub fn synth_comment(&mut self, text: String) -> IoResult<()> {
         try!(word(&mut self.s, "/*"));
         try!(space(&mut self.s));
-        try!(word(&mut self.s, &text[]));
+        try!(word(&mut self.s, &text[..]));
         try!(space(&mut self.s));
         word(&mut self.s, "*/")
     }
@@ -701,7 +701,7 @@ impl<'a> State<'a> {
             }
             ast::TyTup(ref elts) => {
                 try!(self.popen());
-                try!(self.commasep(Inconsistent, &elts[],
+                try!(self.commasep(Inconsistent, &elts[..],
                                    |s, ty| s.print_type(&**ty)));
                 if elts.len() == 1 {
                     try!(word(&mut self.s, ","));
@@ -734,10 +734,10 @@ impl<'a> State<'a> {
             }
             ast::TyObjectSum(ref ty, ref bounds) => {
                 try!(self.print_type(&**ty));
-                try!(self.print_bounds("+", &bounds[]));
+                try!(self.print_bounds("+", &bounds[..]));
             }
             ast::TyPolyTraitRef(ref bounds) => {
-                try!(self.print_bounds("", &bounds[]));
+                try!(self.print_bounds("", &bounds[..]));
             }
             ast::TyQPath(ref qpath) => {
                 try!(self.print_qpath(&**qpath, false))
@@ -765,7 +765,7 @@ impl<'a> State<'a> {
                               item: &ast::ForeignItem) -> IoResult<()> {
         try!(self.hardbreak_if_not_bol());
         try!(self.maybe_print_comment(item.span.lo));
-        try!(self.print_outer_attributes(&item.attrs[]));
+        try!(self.print_outer_attributes(&item.attrs));
         match item.node {
             ast::ForeignItemFn(ref decl, ref generics) => {
                 try!(self.print_fn(&**decl, None, abi::Rust, item.ident, generics,
@@ -776,7 +776,7 @@ impl<'a> State<'a> {
             }
             ast::ForeignItemStatic(ref t, m) => {
                 try!(self.head(&visibility_qualified(item.vis,
-                                                    "static")[]));
+                                                    "static")));
                 if m {
                     try!(self.word_space("mut"));
                 }
@@ -793,7 +793,7 @@ impl<'a> State<'a> {
     fn print_associated_type(&mut self, typedef: &ast::AssociatedType)
                              -> IoResult<()>
     {
-        try!(self.print_outer_attributes(&typedef.attrs[]));
+        try!(self.print_outer_attributes(&typedef.attrs));
         try!(self.word_space("type"));
         try!(self.print_ty_param(&typedef.ty_param));
         word(&mut self.s, ";")
@@ -812,12 +812,12 @@ impl<'a> State<'a> {
     pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> {
         try!(self.hardbreak_if_not_bol());
         try!(self.maybe_print_comment(item.span.lo));
-        try!(self.print_outer_attributes(&item.attrs[]));
+        try!(self.print_outer_attributes(&item.attrs));
         try!(self.ann.pre(self, NodeItem(item)));
         match item.node {
             ast::ItemExternCrate(ref optional_path) => {
                 try!(self.head(&visibility_qualified(item.vis,
-                                                     "extern crate")[]));
+                                                     "extern crate")));
                 if let Some((ref p, style)) = *optional_path {
                     try!(self.print_string(p, style));
                     try!(space(&mut self.s));
@@ -831,7 +831,7 @@ impl<'a> State<'a> {
             }
             ast::ItemUse(ref vp) => {
                 try!(self.head(&visibility_qualified(item.vis,
-                                                     "use")[]));
+                                                     "use")));
                 try!(self.print_view_path(&**vp));
                 try!(word(&mut self.s, ";"));
                 try!(self.end()); // end inner head-block
@@ -839,7 +839,7 @@ impl<'a> State<'a> {
             }
             ast::ItemStatic(ref ty, m, ref expr) => {
                 try!(self.head(&visibility_qualified(item.vis,
-                                                    "static")[]));
+                                                    "static")));
                 if m == ast::MutMutable {
                     try!(self.word_space("mut"));
                 }
@@ -856,7 +856,7 @@ impl<'a> State<'a> {
             }
             ast::ItemConst(ref ty, ref expr) => {
                 try!(self.head(&visibility_qualified(item.vis,
-                                                    "const")[]));
+                                                    "const")));
                 try!(self.print_ident(item.ident));
                 try!(self.word_space(":"));
                 try!(self.print_type(&**ty));
@@ -879,28 +879,28 @@ impl<'a> State<'a> {
                     item.vis
                 ));
                 try!(word(&mut self.s, " "));
-                try!(self.print_block_with_attrs(&**body, &item.attrs[]));
+                try!(self.print_block_with_attrs(&**body, &item.attrs));
             }
             ast::ItemMod(ref _mod) => {
                 try!(self.head(&visibility_qualified(item.vis,
-                                                    "mod")[]));
+                                                    "mod")));
                 try!(self.print_ident(item.ident));
                 try!(self.nbsp());
                 try!(self.bopen());
-                try!(self.print_mod(_mod, &item.attrs[]));
+                try!(self.print_mod(_mod, &item.attrs));
                 try!(self.bclose(item.span));
             }
             ast::ItemForeignMod(ref nmod) => {
                 try!(self.head("extern"));
-                try!(self.word_nbsp(&nmod.abi.to_string()[]));
+                try!(self.word_nbsp(&nmod.abi.to_string()));
                 try!(self.bopen());
-                try!(self.print_foreign_mod(nmod, &item.attrs[]));
+                try!(self.print_foreign_mod(nmod, &item.attrs));
                 try!(self.bclose(item.span));
             }
             ast::ItemTy(ref ty, ref params) => {
                 try!(self.ibox(indent_unit));
                 try!(self.ibox(0));
-                try!(self.word_nbsp(&visibility_qualified(item.vis, "type")[]));
+                try!(self.word_nbsp(&visibility_qualified(item.vis, "type")));
                 try!(self.print_ident(item.ident));
                 try!(self.print_generics(params));
                 try!(self.end()); // end the inner ibox
@@ -922,7 +922,7 @@ impl<'a> State<'a> {
                 ));
             }
             ast::ItemStruct(ref struct_def, ref generics) => {
-                try!(self.head(&visibility_qualified(item.vis,"struct")[]));
+                try!(self.head(&visibility_qualified(item.vis,"struct")));
                 try!(self.print_struct(&**struct_def, generics, item.ident, item.span));
             }
 
@@ -963,7 +963,7 @@ impl<'a> State<'a> {
 
                 try!(space(&mut self.s));
                 try!(self.bopen());
-                try!(self.print_inner_attributes(&item.attrs[]));
+                try!(self.print_inner_attributes(&item.attrs));
                 for impl_item in impl_items {
                     match *impl_item {
                         ast::MethodImplItem(ref meth) => {
@@ -983,18 +983,17 @@ impl<'a> State<'a> {
                 try!(self.word_nbsp("trait"));
                 try!(self.print_ident(item.ident));
                 try!(self.print_generics(generics));
-                let bounds: Vec<_> = bounds.iter().map(|b| b.clone()).collect();
                 let mut real_bounds = Vec::with_capacity(bounds.len());
-                for b in bounds {
-                    if let TraitTyParamBound(ref ptr, ast::TraitBoundModifier::Maybe) = b {
+                for b in bounds.iter() {
+                    if let TraitTyParamBound(ref ptr, ast::TraitBoundModifier::Maybe) = *b {
                         try!(space(&mut self.s));
                         try!(self.word_space("for ?"));
                         try!(self.print_trait_ref(&ptr.trait_ref));
                     } else {
-                        real_bounds.push(b);
+                        real_bounds.push(b.clone());
                     }
                 }
-                try!(self.print_bounds(":", &real_bounds[]));
+                try!(self.print_bounds(":", &real_bounds[..]));
                 try!(self.print_where_clause(generics));
                 try!(word(&mut self.s, " "));
                 try!(self.bopen());
@@ -1012,7 +1011,7 @@ impl<'a> State<'a> {
                 try!(self.print_ident(item.ident));
                 try!(self.cbox(indent_unit));
                 try!(self.popen());
-                try!(self.print_tts(&tts[]));
+                try!(self.print_tts(&tts[..]));
                 try!(self.pclose());
                 try!(word(&mut self.s, ";"));
                 try!(self.end());
@@ -1050,12 +1049,12 @@ impl<'a> State<'a> {
                           generics: &ast::Generics, ident: ast::Ident,
                           span: codemap::Span,
                           visibility: ast::Visibility) -> IoResult<()> {
-        try!(self.head(&visibility_qualified(visibility, "enum")[]));
+        try!(self.head(&visibility_qualified(visibility, "enum")));
         try!(self.print_ident(ident));
         try!(self.print_generics(generics));
         try!(self.print_where_clause(generics));
         try!(space(&mut self.s));
-        self.print_variants(&enum_definition.variants[], span)
+        self.print_variants(&enum_definition.variants, span)
     }
 
     pub fn print_variants(&mut self,
@@ -1065,7 +1064,7 @@ impl<'a> State<'a> {
         for v in variants {
             try!(self.space_if_not_bol());
             try!(self.maybe_print_comment(v.span.lo));
-            try!(self.print_outer_attributes(&v.node.attrs[]));
+            try!(self.print_outer_attributes(&v.node.attrs));
             try!(self.ibox(indent_unit));
             try!(self.print_variant(&**v));
             try!(word(&mut self.s, ","));
@@ -1093,7 +1092,7 @@ impl<'a> State<'a> {
             if !struct_def.fields.is_empty() {
                 try!(self.popen());
                 try!(self.commasep(
-                    Inconsistent, &struct_def.fields[],
+                    Inconsistent, &struct_def.fields,
                     |s, field| {
                         match field.node.kind {
                             ast::NamedField(..) => panic!("unexpected named field"),
@@ -1123,7 +1122,7 @@ impl<'a> State<'a> {
                     ast::NamedField(ident, visibility) => {
                         try!(self.hardbreak_if_not_bol());
                         try!(self.maybe_print_comment(field.span.lo));
-                        try!(self.print_outer_attributes(&field.node.attrs[]));
+                        try!(self.print_outer_attributes(&field.node.attrs));
                         try!(self.print_visibility(visibility));
                         try!(self.print_ident(ident));
                         try!(self.word_nbsp(":"));
@@ -1147,7 +1146,7 @@ impl<'a> State<'a> {
     pub fn print_tt(&mut self, tt: &ast::TokenTree) -> IoResult<()> {
         match *tt {
             ast::TtToken(_, ref tk) => {
-                try!(word(&mut self.s, &token_to_string(tk)[]));
+                try!(word(&mut self.s, &token_to_string(tk)));
                 match *tk {
                     parse::token::DocComment(..) => {
                         hardbreak(&mut self.s)
@@ -1156,11 +1155,11 @@ impl<'a> State<'a> {
                 }
             }
             ast::TtDelimited(_, ref delimed) => {
-                try!(word(&mut self.s, &token_to_string(&delimed.open_token())[]));
+                try!(word(&mut self.s, &token_to_string(&delimed.open_token())));
                 try!(space(&mut self.s));
-                try!(self.print_tts(&delimed.tts[]));
+                try!(self.print_tts(&delimed.tts));
                 try!(space(&mut self.s));
-                word(&mut self.s, &token_to_string(&delimed.close_token())[])
+                word(&mut self.s, &token_to_string(&delimed.close_token()))
             },
             ast::TtSequence(_, ref seq) => {
                 try!(word(&mut self.s, "$("));
@@ -1170,7 +1169,7 @@ impl<'a> State<'a> {
                 try!(word(&mut self.s, ")"));
                 match seq.separator {
                     Some(ref tk) => {
-                        try!(word(&mut self.s, &token_to_string(tk)[]));
+                        try!(word(&mut self.s, &token_to_string(tk)));
                     }
                     None => {},
                 }
@@ -1210,7 +1209,7 @@ impl<'a> State<'a> {
                 if !args.is_empty() {
                     try!(self.popen());
                     try!(self.commasep(Consistent,
-                                       &args[],
+                                       &args[..],
                                        |s, arg| s.print_type(&*arg.ty)));
                     try!(self.pclose());
                 }
@@ -1234,7 +1233,7 @@ impl<'a> State<'a> {
     pub fn print_ty_method(&mut self, m: &ast::TypeMethod) -> IoResult<()> {
         try!(self.hardbreak_if_not_bol());
         try!(self.maybe_print_comment(m.span.lo));
-        try!(self.print_outer_attributes(&m.attrs[]));
+        try!(self.print_outer_attributes(&m.attrs));
         try!(self.print_ty_fn(m.abi,
                               m.unsafety,
                               &*m.decl,
@@ -1263,7 +1262,7 @@ impl<'a> State<'a> {
     pub fn print_method(&mut self, meth: &ast::Method) -> IoResult<()> {
         try!(self.hardbreak_if_not_bol());
         try!(self.maybe_print_comment(meth.span.lo));
-        try!(self.print_outer_attributes(&meth.attrs[]));
+        try!(self.print_outer_attributes(&meth.attrs));
         match meth.node {
             ast::MethDecl(ident,
                           ref generics,
@@ -1281,7 +1280,7 @@ impl<'a> State<'a> {
                                    Some(&explicit_self.node),
                                    vis));
                 try!(word(&mut self.s, " "));
-                self.print_block_with_attrs(&**body, &meth.attrs[])
+                self.print_block_with_attrs(&**body, &meth.attrs)
             },
             ast::MethMac(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _),
                                             ..}) => {
@@ -1290,7 +1289,7 @@ impl<'a> State<'a> {
                 try!(word(&mut self.s, "! "));
                 try!(self.cbox(indent_unit));
                 try!(self.popen());
-                try!(self.print_tts(&tts[]));
+                try!(self.print_tts(&tts[..]));
                 try!(self.pclose());
                 try!(word(&mut self.s, ";"));
                 self.end()
@@ -1552,7 +1551,7 @@ impl<'a> State<'a> {
     fn print_expr_vec(&mut self, exprs: &[P<ast::Expr>]) -> IoResult<()> {
         try!(self.ibox(indent_unit));
         try!(word(&mut self.s, "["));
-        try!(self.commasep_exprs(Inconsistent, &exprs[]));
+        try!(self.commasep_exprs(Inconsistent, &exprs[..]));
         try!(word(&mut self.s, "]"));
         self.end()
     }
@@ -1578,7 +1577,7 @@ impl<'a> State<'a> {
             try!(word(&mut self.s, "{"));
             try!(self.commasep_cmnt(
                 Consistent,
-                &fields[],
+                &fields[..],
                 |s, field| {
                     try!(s.ibox(indent_unit));
                     try!(s.print_ident(field.ident.node));
@@ -1607,7 +1606,7 @@ impl<'a> State<'a> {
 
     fn print_expr_tup(&mut self, exprs: &[P<ast::Expr>]) -> IoResult<()> {
         try!(self.popen());
-        try!(self.commasep_exprs(Inconsistent, &exprs[]));
+        try!(self.commasep_exprs(Inconsistent, &exprs[..]));
         if exprs.len() == 1 {
             try!(word(&mut self.s, ","));
         }
@@ -1672,22 +1671,22 @@ impl<'a> State<'a> {
                 try!(self.print_expr_box(place, &**expr));
             }
             ast::ExprVec(ref exprs) => {
-                try!(self.print_expr_vec(&exprs[]));
+                try!(self.print_expr_vec(&exprs[..]));
             }
             ast::ExprRepeat(ref element, ref count) => {
                 try!(self.print_expr_repeat(&**element, &**count));
             }
             ast::ExprStruct(ref path, ref fields, ref wth) => {
-                try!(self.print_expr_struct(path, &fields[], wth));
+                try!(self.print_expr_struct(path, &fields[..], wth));
             }
             ast::ExprTup(ref exprs) => {
-                try!(self.print_expr_tup(&exprs[]));
+                try!(self.print_expr_tup(&exprs[..]));
             }
             ast::ExprCall(ref func, ref args) => {
-                try!(self.print_expr_call(&**func, &args[]));
+                try!(self.print_expr_call(&**func, &args[..]));
             }
             ast::ExprMethodCall(ident, ref tys, ref args) => {
-                try!(self.print_expr_method_call(ident, &tys[], &args[]));
+                try!(self.print_expr_method_call(ident, &tys[..], &args[..]));
             }
             ast::ExprBinary(op, ref lhs, ref rhs) => {
                 try!(self.print_expr_binary(op, &**lhs, &**rhs));
@@ -1875,11 +1874,11 @@ impl<'a> State<'a> {
                 try!(self.print_string(&a.asm, a.asm_str_style));
                 try!(self.word_space(":"));
 
-                try!(self.commasep(Inconsistent, &a.outputs[],
+                try!(self.commasep(Inconsistent, &a.outputs,
                                    |s, &(ref co, ref o, is_rw)| {
                     match co.slice_shift_char() {
                         Some(('=', operand)) if is_rw => {
-                            try!(s.print_string(&format!("+{}", operand)[],
+                            try!(s.print_string(&format!("+{}", operand),
                                                 ast::CookedStr))
                         }
                         _ => try!(s.print_string(&co, ast::CookedStr))
@@ -1892,7 +1891,7 @@ impl<'a> State<'a> {
                 try!(space(&mut self.s));
                 try!(self.word_space(":"));
 
-                try!(self.commasep(Inconsistent, &a.inputs[],
+                try!(self.commasep(Inconsistent, &a.inputs,
                                    |s, &(ref co, ref o)| {
                     try!(s.print_string(&co, ast::CookedStr));
                     try!(s.popen());
@@ -1903,7 +1902,7 @@ impl<'a> State<'a> {
                 try!(space(&mut self.s));
                 try!(self.word_space(":"));
 
-                try!(self.commasep(Inconsistent, &a.clobbers[],
+                try!(self.commasep(Inconsistent, &a.clobbers,
                                    |s, co| {
                     try!(s.print_string(&co, ast::CookedStr));
                     Ok(())
@@ -1977,7 +1976,7 @@ impl<'a> State<'a> {
     pub fn print_ident(&mut self, ident: ast::Ident) -> IoResult<()> {
         if self.encode_idents_with_hygiene {
             let encoded = ident.encode_with_hygiene();
-            try!(word(&mut self.s, &encoded[]))
+            try!(word(&mut self.s, &encoded[..]))
         } else {
             try!(word(&mut self.s, &token::get_ident(ident)))
         }
@@ -1985,7 +1984,7 @@ impl<'a> State<'a> {
     }
 
     pub fn print_usize(&mut self, i: usize) -> IoResult<()> {
-        word(&mut self.s, &i.to_string()[])
+        word(&mut self.s, &i.to_string())
     }
 
     pub fn print_name(&mut self, name: ast::Name) -> IoResult<()> {
@@ -2075,7 +2074,7 @@ impl<'a> State<'a> {
                     }
                     try!(self.commasep(
                         Inconsistent,
-                        &data.types[],
+                        &data.types,
                         |s, ty| s.print_type(&**ty)));
                         comma = true;
                 }
@@ -2098,7 +2097,7 @@ impl<'a> State<'a> {
                 try!(word(&mut self.s, "("));
                 try!(self.commasep(
                     Inconsistent,
-                    &data.inputs[],
+                    &data.inputs,
                     |s, ty| s.print_type(&**ty)));
                 try!(word(&mut self.s, ")"));
 
@@ -2151,7 +2150,7 @@ impl<'a> State<'a> {
                     Some(ref args) => {
                         if !args.is_empty() {
                             try!(self.popen());
-                            try!(self.commasep(Inconsistent, &args[],
+                            try!(self.commasep(Inconsistent, &args[..],
                                               |s, p| s.print_pat(&**p)));
                             try!(self.pclose());
                         }
@@ -2163,7 +2162,7 @@ impl<'a> State<'a> {
                 try!(self.nbsp());
                 try!(self.word_space("{"));
                 try!(self.commasep_cmnt(
-                    Consistent, &fields[],
+                    Consistent, &fields[..],
                     |s, f| {
                         try!(s.cbox(indent_unit));
                         if !f.node.is_shorthand {
@@ -2184,7 +2183,7 @@ impl<'a> State<'a> {
             ast::PatTup(ref elts) => {
                 try!(self.popen());
                 try!(self.commasep(Inconsistent,
-                                   &elts[],
+                                   &elts[..],
                                    |s, p| s.print_pat(&**p)));
                 if elts.len() == 1 {
                     try!(word(&mut self.s, ","));
@@ -2212,7 +2211,7 @@ impl<'a> State<'a> {
             ast::PatVec(ref before, ref slice, ref after) => {
                 try!(word(&mut self.s, "["));
                 try!(self.commasep(Inconsistent,
-                                   &before[],
+                                   &before[..],
                                    |s, p| s.print_pat(&**p)));
                 if let Some(ref p) = *slice {
                     if !before.is_empty() { try!(self.word_space(",")); }
@@ -2226,7 +2225,7 @@ impl<'a> State<'a> {
                     if !after.is_empty() { try!(self.word_space(",")); }
                 }
                 try!(self.commasep(Inconsistent,
-                                   &after[],
+                                   &after[..],
                                    |s, p| s.print_pat(&**p)));
                 try!(word(&mut self.s, "]"));
             }
@@ -2243,7 +2242,7 @@ impl<'a> State<'a> {
         }
         try!(self.cbox(indent_unit));
         try!(self.ibox(0));
-        try!(self.print_outer_attributes(&arm.attrs[]));
+        try!(self.print_outer_attributes(&arm.attrs));
         let mut first = true;
         for p in &arm.pats {
             if first {
@@ -2475,7 +2474,7 @@ impl<'a> State<'a> {
             ints.push(i);
         }
 
-        try!(self.commasep(Inconsistent, &ints[], |s, &idx| {
+        try!(self.commasep(Inconsistent, &ints[..], |s, &idx| {
             if idx < generics.lifetimes.len() {
                 let lifetime = &generics.lifetimes[idx];
                 s.print_lifetime_def(lifetime)
@@ -2492,7 +2491,7 @@ impl<'a> State<'a> {
 
     pub fn print_ty_param(&mut self, param: &ast::TyParam) -> IoResult<()> {
         try!(self.print_ident(param.ident));
-        try!(self.print_bounds(":", &param.bounds[]));
+        try!(self.print_bounds(":", &param.bounds));
         match param.default {
             Some(ref default) => {
                 try!(space(&mut self.s));
@@ -2562,7 +2561,7 @@ impl<'a> State<'a> {
                 try!(word(&mut self.s, &name));
             }
             ast::MetaNameValue(ref name, ref value) => {
-                try!(self.word_space(&name[]));
+                try!(self.word_space(&name[..]));
                 try!(self.word_space("="));
                 try!(self.print_literal(value));
             }
@@ -2570,7 +2569,7 @@ impl<'a> State<'a> {
                 try!(word(&mut self.s, &name));
                 try!(self.popen());
                 try!(self.commasep(Consistent,
-                                   &items[],
+                                   &items[..],
                                    |s, i| s.print_meta_item(&**i)));
                 try!(self.pclose());
             }
@@ -2606,7 +2605,7 @@ impl<'a> State<'a> {
                     try!(self.print_path(path, false));
                     try!(word(&mut self.s, "::{"));
                 }
-                try!(self.commasep(Inconsistent, &idents[], |s, w| {
+                try!(self.commasep(Inconsistent, &idents[..], |s, w| {
                     match w.node {
                         ast::PathListIdent { name, .. } => {
                             s.print_ident(name)
@@ -2753,7 +2752,7 @@ impl<'a> State<'a> {
         try!(self.maybe_print_comment(lit.span.lo));
         match self.next_lit(lit.span.lo) {
             Some(ref ltrl) => {
-                return word(&mut self.s, &(*ltrl).lit[]);
+                return word(&mut self.s, &(*ltrl).lit);
             }
             _ => ()
         }
@@ -2763,33 +2762,33 @@ impl<'a> State<'a> {
                 let mut res = String::from_str("b'");
                 res.extend(ascii::escape_default(byte).map(|c| c as char));
                 res.push('\'');
-                word(&mut self.s, &res[])
+                word(&mut self.s, &res[..])
             }
             ast::LitChar(ch) => {
                 let mut res = String::from_str("'");
                 res.extend(ch.escape_default());
                 res.push('\'');
-                word(&mut self.s, &res[])
+                word(&mut self.s, &res[..])
             }
             ast::LitInt(i, t) => {
                 match t {
                     ast::SignedIntLit(st, ast::Plus) => {
                         word(&mut self.s,
-                             &ast_util::int_ty_to_string(st, Some(i as i64))[])
+                             &ast_util::int_ty_to_string(st, Some(i as i64)))
                     }
                     ast::SignedIntLit(st, ast::Minus) => {
                         let istr = ast_util::int_ty_to_string(st, Some(-(i as i64)));
                         word(&mut self.s,
-                             &format!("-{}", istr)[])
+                             &format!("-{}", istr))
                     }
                     ast::UnsignedIntLit(ut) => {
                         word(&mut self.s, &ast_util::uint_ty_to_string(ut, Some(i)))
                     }
                     ast::UnsuffixedIntLit(ast::Plus) => {
-                        word(&mut self.s, &format!("{}", i)[])
+                        word(&mut self.s, &format!("{}", i))
                     }
                     ast::UnsuffixedIntLit(ast::Minus) => {
-                        word(&mut self.s, &format!("-{}", i)[])
+                        word(&mut self.s, &format!("-{}", i))
                     }
                 }
             }
@@ -2798,9 +2797,9 @@ impl<'a> State<'a> {
                      &format!(
                          "{}{}",
                          &f,
-                         &ast_util::float_ty_to_string(t)[])[])
+                         &ast_util::float_ty_to_string(t)))
             }
-            ast::LitFloatUnsuffixed(ref f) => word(&mut self.s, &f[]),
+            ast::LitFloatUnsuffixed(ref f) => word(&mut self.s, &f[..]),
             ast::LitBool(val) => {
                 if val { word(&mut self.s, "true") } else { word(&mut self.s, "false") }
             }
@@ -2810,7 +2809,7 @@ impl<'a> State<'a> {
                     escaped.extend(ascii::escape_default(ch as u8)
                                          .map(|c| c as char));
                 }
-                word(&mut self.s, &format!("b\"{}\"", escaped)[])
+                word(&mut self.s, &format!("b\"{}\"", escaped))
             }
         }
     }
@@ -2851,7 +2850,7 @@ impl<'a> State<'a> {
             comments::Mixed => {
                 assert_eq!(cmnt.lines.len(), 1);
                 try!(zerobreak(&mut self.s));
-                try!(word(&mut self.s, &cmnt.lines[0][]));
+                try!(word(&mut self.s, &cmnt.lines[0]));
                 zerobreak(&mut self.s)
             }
             comments::Isolated => {
@@ -2860,7 +2859,7 @@ impl<'a> State<'a> {
                     // Don't print empty lines because they will end up as trailing
                     // whitespace
                     if !line.is_empty() {
-                        try!(word(&mut self.s, &line[]));
+                        try!(word(&mut self.s, &line[..]));
                     }
                     try!(hardbreak(&mut self.s));
                 }
@@ -2869,13 +2868,13 @@ impl<'a> State<'a> {
             comments::Trailing => {
                 try!(word(&mut self.s, " "));
                 if cmnt.lines.len() == 1 {
-                    try!(word(&mut self.s, &cmnt.lines[0][]));
+                    try!(word(&mut self.s, &cmnt.lines[0]));
                     hardbreak(&mut self.s)
                 } else {
                     try!(self.ibox(0));
                     for line in &cmnt.lines {
                         if !line.is_empty() {
-                            try!(word(&mut self.s, &line[]));
+                            try!(word(&mut self.s, &line[..]));
                         }
                         try!(hardbreak(&mut self.s));
                     }
@@ -2908,7 +2907,7 @@ impl<'a> State<'a> {
                          string=st))
             }
         };
-        word(&mut self.s, &st[])
+        word(&mut self.s, &st[..])
     }
 
     pub fn next_comment(&mut self) -> Option<comments::Comment> {
@@ -2939,7 +2938,7 @@ impl<'a> State<'a> {
             Some(abi::Rust) => Ok(()),
             Some(abi) => {
                 try!(self.word_nbsp("extern"));
-                self.word_nbsp(&abi.to_string()[])
+                self.word_nbsp(&abi.to_string())
             }
             None => Ok(())
         }
@@ -2950,7 +2949,7 @@ impl<'a> State<'a> {
         match opt_abi {
             Some(abi) => {
                 try!(self.word_nbsp("extern"));
-                self.word_nbsp(&abi.to_string()[])
+                self.word_nbsp(&abi.to_string())
             }
             None => Ok(())
         }
@@ -2965,7 +2964,7 @@ impl<'a> State<'a> {
 
         if abi != abi::Rust {
             try!(self.word_nbsp("extern"));
-            try!(self.word_nbsp(&abi.to_string()[]));
+            try!(self.word_nbsp(&abi.to_string()));
         }
 
         word(&mut self.s, "fn")
diff --git a/src/libsyntax/ptr.rs b/src/libsyntax/ptr.rs
index 01f3839b039..adb5383a8fd 100644
--- a/src/libsyntax/ptr.rs
+++ b/src/libsyntax/ptr.rs
@@ -111,11 +111,18 @@ impl<T: Display> Display for P<T> {
     }
 }
 
+#[cfg(stage0)]
 impl<S: Hasher, T: Hash<S>> Hash<S> for P<T> {
     fn hash(&self, state: &mut S) {
         (**self).hash(state);
     }
 }
+#[cfg(not(stage0))]
+impl<T: Hash> Hash for P<T> {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        (**self).hash(state);
+    }
+}
 
 impl<T: 'static + Decodable> Decodable for P<T> {
     fn decode<D: Decoder>(d: &mut D) -> Result<P<T>, D::Error> {
diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs
index 98c193c7e6b..4e4a571ede7 100644
--- a/src/libsyntax/std_inject.rs
+++ b/src/libsyntax/std_inject.rs
@@ -45,16 +45,16 @@ fn no_prelude(attrs: &[ast::Attribute]) -> bool {
     attr::contains_name(attrs, "no_implicit_prelude")
 }
 
-struct StandardLibraryInjector<'a> {
-    alt_std_name: Option<String>
+struct StandardLibraryInjector {
+    alt_std_name: Option<String>,
 }
 
-impl<'a> fold::Folder for StandardLibraryInjector<'a> {
+impl fold::Folder for StandardLibraryInjector {
     fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
 
         // The name to use in `extern crate "name" as std;`
         let actual_crate_name = match self.alt_std_name {
-            Some(ref s) => token::intern_and_get_ident(&s[]),
+            Some(ref s) => token::intern_and_get_ident(&s[..]),
             None => token::intern_and_get_ident("std"),
         };
 
@@ -80,9 +80,10 @@ fn inject_crates_ref(krate: ast::Crate, alt_std_name: Option<String>) -> ast::Cr
     fold.fold_crate(krate)
 }
 
-struct PreludeInjector<'a>;
+struct PreludeInjector;
 
-impl<'a> fold::Folder for PreludeInjector<'a> {
+
+impl fold::Folder for PreludeInjector {
     fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
         // only add `use std::prelude::*;` if there wasn't a
         // `#![no_implicit_prelude]` at the crate level.
diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs
index 6511dffa6bf..7b1fc91e45b 100644
--- a/src/libsyntax/test.rs
+++ b/src/libsyntax/test.rs
@@ -119,7 +119,7 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
             self.cx.path.push(ident);
         }
         debug!("current path: {}",
-               ast_util::path_name_i(&self.cx.path[]));
+               ast_util::path_name_i(&self.cx.path));
 
         if is_test_fn(&self.cx, &*i) || is_bench_fn(&self.cx, &*i) {
             match i.node {
@@ -274,8 +274,8 @@ fn strip_test_functions(krate: ast::Crate) -> ast::Crate {
     // When not compiling with --test we should not compile the
     // #[test] functions
     config::strip_items(krate, |attrs| {
-        !attr::contains_name(&attrs[], "test") &&
-        !attr::contains_name(&attrs[], "bench")
+        !attr::contains_name(&attrs[..], "test") &&
+        !attr::contains_name(&attrs[..], "bench")
     })
 }
 
@@ -563,7 +563,7 @@ fn mk_tests(cx: &TestCtxt) -> P<ast::Item> {
 
 fn is_test_crate(krate: &ast::Crate) -> bool {
     match attr::find_crate_name(&krate.attrs[]) {
-        Some(ref s) if "test" == &s[] => true,
+        Some(ref s) if "test" == &s[..] => true,
         _ => false
     }
 }
@@ -603,11 +603,11 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P<ast::Expr> {
     // creates $name: $expr
     let field = |name, expr| ecx.field_imm(span, ecx.ident_of(name), expr);
 
-    debug!("encoding {}", ast_util::path_name_i(&path[]));
+    debug!("encoding {}", ast_util::path_name_i(&path[..]));
 
     // path to the #[test] function: "foo::bar::baz"
-    let path_string = ast_util::path_name_i(&path[]);
-    let name_expr = ecx.expr_str(span, token::intern_and_get_ident(&path_string[]));
+    let path_string = ast_util::path_name_i(&path[..]);
+    let name_expr = ecx.expr_str(span, token::intern_and_get_ident(&path_string[..]));
 
     // self::test::StaticTestName($name_expr)
     let name_expr = ecx.expr_call(span,
diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs
index 51144267519..dffeac6f3f7 100644
--- a/src/libsyntax/util/interner.rs
+++ b/src/libsyntax/util/interner.rs
@@ -14,13 +14,13 @@
 
 use ast::Name;
 
-use std::borrow::BorrowFrom;
+use std::borrow::Borrow;
 use std::cell::RefCell;
 use std::cmp::Ordering;
 use std::collections::HashMap;
+#[cfg(stage0)] use std::collections::hash_map::Hasher;
 use std::fmt;
 use std::hash::Hash;
-use std::collections::hash_map::Hasher;
 use std::ops::Deref;
 use std::rc::Rc;
 
@@ -30,6 +30,7 @@ pub struct Interner<T> {
 }
 
 // when traits can extend traits, we should extend index<Name,T> to get []
+#[cfg(stage0)]
 impl<T: Eq + Hash<Hasher> + Clone + 'static> Interner<T> {
     pub fn new() -> Interner<T> {
         Interner {
@@ -79,7 +80,71 @@ impl<T: Eq + Hash<Hasher> + Clone + 'static> Interner<T> {
     }
 
     pub fn find<Q: ?Sized>(&self, val: &Q) -> Option<Name>
-    where Q: BorrowFrom<T> + Eq + Hash<Hasher> {
+    where T: Borrow<Q>, Q: Eq + Hash<Hasher> {
+        let map = self.map.borrow();
+        match (*map).get(val) {
+            Some(v) => Some(*v),
+            None => None,
+        }
+    }
+
+    pub fn clear(&self) {
+        *self.map.borrow_mut() = HashMap::new();
+        *self.vect.borrow_mut() = Vec::new();
+    }
+}
+// when traits can extend traits, we should extend index<Name,T> to get []
+#[cfg(not(stage0))]
+impl<T: Eq + Hash + Clone + 'static> Interner<T> {
+    pub fn new() -> Interner<T> {
+        Interner {
+            map: RefCell::new(HashMap::new()),
+            vect: RefCell::new(Vec::new()),
+        }
+    }
+
+    pub fn prefill(init: &[T]) -> Interner<T> {
+        let rv = Interner::new();
+        for v in init {
+            rv.intern((*v).clone());
+        }
+        rv
+    }
+
+    pub fn intern(&self, val: T) -> Name {
+        let mut map = self.map.borrow_mut();
+        match (*map).get(&val) {
+            Some(&idx) => return idx,
+            None => (),
+        }
+
+        let mut vect = self.vect.borrow_mut();
+        let new_idx = Name((*vect).len() as u32);
+        (*map).insert(val.clone(), new_idx);
+        (*vect).push(val);
+        new_idx
+    }
+
+    pub fn gensym(&self, val: T) -> Name {
+        let mut vect = self.vect.borrow_mut();
+        let new_idx = Name((*vect).len() as u32);
+        // leave out of .map to avoid colliding
+        (*vect).push(val);
+        new_idx
+    }
+
+    pub fn get(&self, idx: Name) -> T {
+        let vect = self.vect.borrow();
+        (*vect)[idx.usize()].clone()
+    }
+
+    pub fn len(&self) -> usize {
+        let vect = self.vect.borrow();
+        (*vect).len()
+    }
+
+    pub fn find<Q: ?Sized>(&self, val: &Q) -> Option<Name>
+    where T: Borrow<Q>, Q: Eq + Hash {
         let map = self.map.borrow();
         match (*map).get(val) {
             Some(v) => Some(*v),
@@ -110,34 +175,34 @@ impl Eq for RcStr {}
 
 impl Ord for RcStr {
     fn cmp(&self, other: &RcStr) -> Ordering {
-        self[].cmp(&other[])
+        self[..].cmp(&other[..])
     }
 }
 
 impl fmt::Debug for RcStr {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         use std::fmt::Debug;
-        self[].fmt(f)
+        self[..].fmt(f)
     }
 }
 
 impl fmt::Display for RcStr {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         use std::fmt::Display;
-        self[].fmt(f)
+        self[..].fmt(f)
     }
 }
 
-impl BorrowFrom<RcStr> for str {
-    fn borrow_from(owned: &RcStr) -> &str {
-        &owned.string[]
+impl Borrow<str> for RcStr {
+    fn borrow(&self) -> &str {
+        &self.string[..]
     }
 }
 
 impl Deref for RcStr {
     type Target = str;
 
-    fn deref(&self) -> &str { &self.string[] }
+    fn deref(&self) -> &str { &self.string[..] }
 }
 
 /// A StrInterner differs from Interner<String> in that it accepts
@@ -210,8 +275,17 @@ impl StrInterner {
         self.vect.borrow().len()
     }
 
+    #[cfg(stage0)]
+    pub fn find<Q: ?Sized>(&self, val: &Q) -> Option<Name>
+    where RcStr: Borrow<Q>, Q: Eq + Hash<Hasher> {
+        match (*self.map.borrow()).get(val) {
+            Some(v) => Some(*v),
+            None => None,
+        }
+    }
+    #[cfg(not(stage0))]
     pub fn find<Q: ?Sized>(&self, val: &Q) -> Option<Name>
-    where Q: BorrowFrom<RcStr> + Eq + Hash<Hasher> {
+    where RcStr: Borrow<Q>, Q: Eq + Hash {
         match (*self.map.borrow()).get(val) {
             Some(v) => Some(*v),
             None => None,
diff --git a/src/libsyntax/util/small_vector.rs b/src/libsyntax/util/small_vector.rs
index b2009a7e848..0a39d380904 100644
--- a/src/libsyntax/util/small_vector.rs
+++ b/src/libsyntax/util/small_vector.rs
@@ -11,7 +11,7 @@
 use self::SmallVectorRepr::*;
 use self::IntoIterRepr::*;
 
-use std::iter::FromIterator;
+use std::iter::{IntoIterator, FromIterator};
 use std::mem;
 use std::slice;
 use std::vec;
@@ -30,7 +30,7 @@ enum SmallVectorRepr<T> {
 }
 
 impl<T> FromIterator<T> for SmallVector<T> {
-    fn from_iter<I: Iterator<Item=T>>(iter: I) -> SmallVector<T> {
+    fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> SmallVector<T> {
         let mut v = SmallVector::zero();
         v.extend(iter);
         v
@@ -38,7 +38,7 @@ impl<T> FromIterator<T> for SmallVector<T> {
 }
 
 impl<T> Extend<T> for SmallVector<T> {
-    fn extend<I: Iterator<Item=T>>(&mut self, iter: I) {
+    fn extend<I: IntoIterator<Item=T>>(&mut self, iter: I) {
         for val in iter {
             self.push(val);
         }
diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs
index 304f370a199..5418533aff1 100644
--- a/src/libterm/lib.rs
+++ b/src/libterm/lib.rs
@@ -50,7 +50,6 @@
        html_playground_url = "http://play.rust-lang.org/")]
 #![deny(missing_docs)]
 
-#![feature(core)]
 #![feature(box_syntax)]
 #![feature(collections)]
 #![feature(int_uint)]
diff --git a/src/libterm/terminfo/mod.rs b/src/libterm/terminfo/mod.rs
index b978d2d8054..be1c623c859 100644
--- a/src/libterm/terminfo/mod.rs
+++ b/src/libterm/terminfo/mod.rs
@@ -180,7 +180,7 @@ impl<T: Writer+Send+'static> TerminfoTerminal<T> {
             }
         };
 
-        let entry = open(&term[]);
+        let entry = open(&term[..]);
         if entry.is_err() {
             if env::var("MSYSCON").ok().map_or(false, |s| {
                     "mintty.exe" == s
diff --git a/src/libterm/terminfo/parm.rs b/src/libterm/terminfo/parm.rs
index 82b5ec11d95..0b577f8de74 100644
--- a/src/libterm/terminfo/parm.rs
+++ b/src/libterm/terminfo/parm.rs
@@ -608,7 +608,7 @@ mod test {
             Result<Vec<u8>, String>
         {
             let mut u8v: Vec<_> = fmt.bytes().collect();
-            u8v.extend(cap.as_bytes().iter().map(|&b| b));
+            u8v.extend(cap.bytes());
             expand(&u8v, params, vars)
         }
 
diff --git a/src/libterm/terminfo/searcher.rs b/src/libterm/terminfo/searcher.rs
index fd6e6a843e1..c40a5534efb 100644
--- a/src/libterm/terminfo/searcher.rs
+++ b/src/libterm/terminfo/searcher.rs
@@ -60,13 +60,13 @@ pub fn get_dbpath_for_term(term: &str) -> Option<Box<Path>> {
     for p in &dirs_to_search {
         if p.exists() {
             let f = first_char.to_string();
-            let newp = p.join_many(&[&f[], term]);
+            let newp = p.join_many(&[&f[..], term]);
             if newp.exists() {
                 return Some(box newp);
             }
             // on some installations the dir is named after the hex of the char (e.g. OS X)
             let f = format!("{:x}", first_char as uint);
-            let newp = p.join_many(&[&f[], term]);
+            let newp = p.join_many(&[&f[..], term]);
             if newp.exists() {
                 return Some(box newp);
             }
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index 2cb30ad9804..82c1a4b1195 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -37,7 +37,6 @@
 #![feature(collections)]
 #![feature(core)]
 #![feature(env)]
-#![feature(hash)]
 #![feature(int_uint)]
 #![feature(old_io)]
 #![feature(old_path)]
@@ -721,7 +720,7 @@ fn should_sort_failures_before_printing_them() {
 
     st.write_failures().unwrap();
     let s = match st.out {
-        Raw(ref m) => String::from_utf8_lossy(&m[]),
+        Raw(ref m) => String::from_utf8_lossy(&m[..]),
         Pretty(_) => unreachable!()
     };
 
@@ -834,7 +833,7 @@ pub fn filter_tests(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> Vec<TestDescA
         None => filtered,
         Some(ref filter) => {
             filtered.into_iter().filter(|test| {
-                test.desc.name.as_slice().contains(&filter[])
+                test.desc.name.as_slice().contains(&filter[..])
             }).collect()
         }
     };
diff --git a/src/libtest/stats.rs b/src/libtest/stats.rs
index 31ce3e91a77..4e94be59ade 100644
--- a/src/libtest/stats.rs
+++ b/src/libtest/stats.rs
@@ -12,7 +12,7 @@
 
 use std::cmp::Ordering::{self, Less, Greater, Equal};
 use std::collections::hash_map::Entry::{Occupied, Vacant};
-use std::collections::hash_map::{self, Hasher};
+use std::collections::hash_map;
 use std::hash::Hash;
 use std::mem;
 use std::num::{Float, FromPrimitive};
@@ -333,7 +333,7 @@ pub fn winsorize<T: Float + FromPrimitive>(samples: &mut [T], pct: T) {
 /// Returns a HashMap with the number of occurrences of every element in the
 /// sequence that the iterator exposes.
 pub fn freq_count<T, U>(iter: T) -> hash_map::HashMap<U, uint>
-  where T: Iterator<Item=U>, U: Eq + Clone + Hash<Hasher>
+  where T: Iterator<Item=U>, U: Eq + Clone + Hash
 {
     let mut map: hash_map::HashMap<U,uint> = hash_map::HashMap::new();
     for elem in iter {
diff --git a/src/llvm b/src/llvm
-Subproject 2089cab13e7f92b487ba0dc1df9f6c05116b004
+Subproject 4891e6382e3e8aa89d530aa18427836428c4715
diff --git a/src/rustbook/build.rs b/src/rustbook/build.rs
index 6f5fc5c1969..224f1ef1a8b 100644
--- a/src/rustbook/build.rs
+++ b/src/rustbook/build.rs
@@ -92,7 +92,7 @@ fn render(book: &Book, tgt: &Path) -> CliResult<()> {
         {
             let urls = markdown_data.replace(".md)", ".html)");
             try!(File::create(&preprocessed_path)
-                      .write_str(&urls[]));
+                      .write_str(&urls[..]));
         }
 
         // write the prelude to a temporary HTML file for rustdoc inclusion
diff --git a/src/rustbook/error.rs b/src/rustbook/error.rs
index 1c10a270acc..43c882c7d5b 100644
--- a/src/rustbook/error.rs
+++ b/src/rustbook/error.rs
@@ -52,7 +52,7 @@ impl<'a> Error for &'a str {
 
 impl Error for String {
     fn description<'a>(&'a self) -> &'a str {
-        &self[]
+        &self[..]
     }
 }
 
@@ -75,7 +75,7 @@ impl Error for IoError {
         self.desc
     }
     fn detail(&self) -> Option<&str> {
-        self.detail.as_ref().map(|s| &s[])
+        self.detail.as_ref().map(|s| &s[..])
     }
 }
 
diff --git a/src/rustbook/test.rs b/src/rustbook/test.rs
index d3cb8a7316e..c5d4875423a 100644
--- a/src/rustbook/test.rs
+++ b/src/rustbook/test.rs
@@ -65,7 +65,7 @@ impl Subcommand for Test {
             }
             Err(errors) => {
                 for err in errors {
-                    term.err(&err[]);
+                    term.err(&err[..]);
                 }
                 return Err(box "There was an error." as Box<Error>);
             }
diff --git a/src/test/auxiliary/coherence-orphan-lib.rs b/src/test/auxiliary/coherence-orphan-lib.rs
index 2e5d18b58f2..cc42b288e66 100644
--- a/src/test/auxiliary/coherence-orphan-lib.rs
+++ b/src/test/auxiliary/coherence-orphan-lib.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub trait TheTrait<T> {
+pub trait TheTrait<T> : ::std::marker::PhantomFn<T> {
     fn the_fn(&self);
 }
 
diff --git a/src/test/auxiliary/default_type_params_xc.rs b/src/test/auxiliary/default_type_params_xc.rs
index d12f716decf..0a65174911e 100644
--- a/src/test/auxiliary/default_type_params_xc.rs
+++ b/src/test/auxiliary/default_type_params_xc.rs
@@ -12,4 +12,5 @@ pub struct Heap;
 
 pub struct FakeHeap;
 
-pub struct FakeVec<T, A = FakeHeap>;
+pub struct FakeVec<T, A = FakeHeap> { pub f: Option<(T,A)> }
+
diff --git a/src/test/auxiliary/inner_static.rs b/src/test/auxiliary/inner_static.rs
index 94acea06618..ca5c6072cb3 100644
--- a/src/test/auxiliary/inner_static.rs
+++ b/src/test/auxiliary/inner_static.rs
@@ -8,11 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub struct A<T>;
-pub struct B<T>;
+pub struct A<T> { pub v: T }
+pub struct B<T> { pub v: T }
 
 pub mod test {
-    pub struct A<T>;
+    pub struct A<T> { pub v: T }
 
     impl<T> A<T> {
         pub fn foo(&self) -> int {
@@ -52,9 +52,9 @@ impl<T> B<T> {
 }
 
 pub fn foo() -> int {
-    let a = A::<()>;
-    let b = B::<()>;
-    let c = test::A::<()>;
+    let a = A { v: () };
+    let b = B { v: () };
+    let c = test::A { v: () };
     return a.foo() + a.bar() +
            b.foo() + b.bar() +
            c.foo() + c.bar();
diff --git a/src/test/auxiliary/issue-14421.rs b/src/test/auxiliary/issue-14421.rs
index 7c69cba179c..a48088609f9 100644
--- a/src/test/auxiliary/issue-14421.rs
+++ b/src/test/auxiliary/issue-14421.rs
@@ -10,6 +10,7 @@
 
 #![crate_type="lib"]
 #![deny(warnings)]
+#![allow(dead_code)]
 
 pub use src::aliases::B;
 pub use src::hidden_core::make;
@@ -23,9 +24,9 @@ mod src {
     pub mod hidden_core {
         use super::aliases::B;
 
-        pub struct A<T>;
+        pub struct A<T> { t: T }
 
-        pub fn make() -> B { A }
+        pub fn make() -> B { A { t: 1.0 } }
 
         impl<T> A<T> {
             pub fn foo(&mut self) { println!("called foo"); }
diff --git a/src/test/auxiliary/issue-16643.rs b/src/test/auxiliary/issue-16643.rs
index c5b3fceaf4a..b590160a0c2 100644
--- a/src/test/auxiliary/issue-16643.rs
+++ b/src/test/auxiliary/issue-16643.rs
@@ -10,7 +10,7 @@
 
 #![crate_type = "lib"]
 
-pub struct TreeBuilder<H>;
+pub struct TreeBuilder<H> { pub h: H }
 
 impl<H> TreeBuilder<H> {
     pub fn process_token(&mut self) {
diff --git a/src/test/auxiliary/issue-17662.rs b/src/test/auxiliary/issue-17662.rs
index be10ca1dd8f..fb55a077005 100644
--- a/src/test/auxiliary/issue-17662.rs
+++ b/src/test/auxiliary/issue-17662.rs
@@ -11,7 +11,7 @@
 #![crate_type = "lib"]
 
 pub trait Foo<'a, T> {
-    fn foo(&self) -> T;
+    fn foo(&'a self) -> T;
 }
 
 pub fn foo<'a, T>(x: &'a Foo<'a, T>) -> T {
diff --git a/src/test/auxiliary/issue-2380.rs b/src/test/auxiliary/issue-2380.rs
index 8eb6cd6e263..96f33f97a69 100644
--- a/src/test/auxiliary/issue-2380.rs
+++ b/src/test/auxiliary/issue-2380.rs
@@ -14,7 +14,10 @@
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-pub trait i<T> { }
+pub trait i<T>
+{
+    fn dummy(&self, t: T) -> T { panic!() }
+}
 
 pub fn f<T>() -> Box<i<T>+'static> {
     impl<T> i<T> for () { }
diff --git a/src/test/auxiliary/issue-2526.rs b/src/test/auxiliary/issue-2526.rs
index e3ce4e8f656..89b3b56121a 100644
--- a/src/test/auxiliary/issue-2526.rs
+++ b/src/test/auxiliary/issue-2526.rs
@@ -13,8 +13,11 @@
 
 #![feature(unsafe_destructor)]
 
+use std::marker;
+
 struct arc_destruct<T> {
-  _data: int,
+    _data: int,
+    _marker: marker::PhantomData<T>
 }
 
 #[unsafe_destructor]
@@ -24,7 +27,8 @@ impl<T: Sync> Drop for arc_destruct<T> {
 
 fn arc_destruct<T: Sync>(data: int) -> arc_destruct<T> {
     arc_destruct {
-        _data: data
+        _data: data,
+        _marker: marker::PhantomData
     }
 }
 
diff --git a/src/test/auxiliary/issue_20389.rs b/src/test/auxiliary/issue_20389.rs
index 7a378b06df9..4ce7e3079e3 100644
--- a/src/test/auxiliary/issue_20389.rs
+++ b/src/test/auxiliary/issue_20389.rs
@@ -10,4 +10,5 @@
 
 pub trait T {
     type C;
+    fn dummy(&self) { }
 }
diff --git a/src/test/auxiliary/issue_3907.rs b/src/test/auxiliary/issue_3907.rs
index 2e254e5431d..545e15fe166 100644
--- a/src/test/auxiliary/issue_3907.rs
+++ b/src/test/auxiliary/issue_3907.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub trait Foo {
+use std::marker::MarkerTrait;
+
+pub trait Foo : MarkerTrait {
     fn bar();
 }
 
diff --git a/src/test/auxiliary/issue_8401.rs b/src/test/auxiliary/issue_8401.rs
index 0831993119a..9006a5d1775 100644
--- a/src/test/auxiliary/issue_8401.rs
+++ b/src/test/auxiliary/issue_8401.rs
@@ -12,7 +12,9 @@
 
 use std::mem;
 
-trait A {}
+trait A {
+    fn dummy(&self) { }
+}
 struct B;
 impl A for B {}
 
diff --git a/src/test/auxiliary/issue_9123.rs b/src/test/auxiliary/issue_9123.rs
index 000cc100a12..4f2792aebcd 100644
--- a/src/test/auxiliary/issue_9123.rs
+++ b/src/test/auxiliary/issue_9123.rs
@@ -15,5 +15,6 @@ pub trait X {
         fn f() { }
         f();
     }
+    fn dummy(&self) { }
 }
 
diff --git a/src/test/auxiliary/lang-item-public.rs b/src/test/auxiliary/lang-item-public.rs
index 834667968c8..b9cc20b63cc 100644
--- a/src/test/auxiliary/lang-item-public.rs
+++ b/src/test/auxiliary/lang-item-public.rs
@@ -12,8 +12,12 @@
 #![no_std]
 #![feature(lang_items)]
 
+#[lang="phantom_fn"]
+pub trait PhantomFn<A:?Sized,R:?Sized=()> { }
+impl<A:?Sized, R:?Sized, U:?Sized> PhantomFn<A,R> for U { }
+
 #[lang="sized"]
-pub trait Sized {}
+pub trait Sized : PhantomFn<Self> {}
 
 #[lang="panic"]
 fn panic(_: &(&'static str, &'static str, uint)) -> ! { loop {} }
@@ -25,6 +29,8 @@ extern fn stack_exhausted() {}
 extern fn eh_personality() {}
 
 #[lang="copy"]
-pub trait Copy {}
+pub trait Copy : PhantomFn<Self> {
+    // Empty.
+}
 
 
diff --git a/src/test/auxiliary/lint_group_plugin_test.rs b/src/test/auxiliary/lint_group_plugin_test.rs
index 36b3091852b..e9d98889ff8 100644
--- a/src/test/auxiliary/lint_group_plugin_test.rs
+++ b/src/test/auxiliary/lint_group_plugin_test.rs
@@ -37,9 +37,9 @@ impl LintPass for Pass {
 
     fn check_item(&mut self, cx: &Context, it: &ast::Item) {
         let name = token::get_ident(it.ident);
-        if &name[] == "lintme" {
+        if &name[..] == "lintme" {
             cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'");
-        } else if &name[] == "pleaselintme" {
+        } else if &name[..] == "pleaselintme" {
             cx.span_lint(PLEASE_LINT, it.span, "item is named 'pleaselintme'");
         }
     }
diff --git a/src/test/auxiliary/lint_plugin_test.rs b/src/test/auxiliary/lint_plugin_test.rs
index 9020bb7b0fb..ffb234f70c8 100644
--- a/src/test/auxiliary/lint_plugin_test.rs
+++ b/src/test/auxiliary/lint_plugin_test.rs
@@ -35,7 +35,7 @@ impl LintPass for Pass {
 
     fn check_item(&mut self, cx: &Context, it: &ast::Item) {
         let name = token::get_ident(it.ident);
-        if &name[] == "lintme" {
+        if &name[..] == "lintme" {
             cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'");
         }
     }
diff --git a/src/test/auxiliary/lint_stability.rs b/src/test/auxiliary/lint_stability.rs
index 01b2b748ba9..fb535eb8336 100644
--- a/src/test/auxiliary/lint_stability.rs
+++ b/src/test/auxiliary/lint_stability.rs
@@ -96,7 +96,7 @@ pub trait Trait {
 impl Trait for MethodTester {}
 
 #[unstable(feature = "test_feature")]
-pub trait UnstableTrait {}
+pub trait UnstableTrait { fn dummy(&self) { } }
 
 #[stable(feature = "test_feature", since = "1.0.0")]
 #[deprecated(since = "1.0.0")]
diff --git a/src/test/auxiliary/nested_item.rs b/src/test/auxiliary/nested_item.rs
index 21784bda27a..fc1bea5a9fd 100644
--- a/src/test/auxiliary/nested_item.rs
+++ b/src/test/auxiliary/nested_item.rs
@@ -25,7 +25,7 @@ impl Foo {
 }
 
 // issue 8134
-pub struct Parser<T>;
+pub struct Parser<T>(T);
 impl<T: std::iter::Iterator<Item=char>> Parser<T> {
     fn in_doctype(&mut self) {
         static DOCTYPEPattern: [char; 6] = ['O', 'C', 'T', 'Y', 'P', 'E'];
diff --git a/src/test/auxiliary/orphan_check_diagnostics.rs b/src/test/auxiliary/orphan_check_diagnostics.rs
index 7647f159401..cf3e9903b5a 100644
--- a/src/test/auxiliary/orphan_check_diagnostics.rs
+++ b/src/test/auxiliary/orphan_check_diagnostics.rs
@@ -8,4 +8,4 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub trait RemoteTrait {}
+pub trait RemoteTrait { fn dummy(&self) { } }
diff --git a/src/test/auxiliary/overloaded_autoderef_xc.rs b/src/test/auxiliary/overloaded_autoderef_xc.rs
index caa9bbe5736..3c8cba13ae7 100644
--- a/src/test/auxiliary/overloaded_autoderef_xc.rs
+++ b/src/test/auxiliary/overloaded_autoderef_xc.rs
@@ -11,7 +11,8 @@
 use std::ops::Deref;
 
 struct DerefWithHelper<H, T> {
-    pub helper: H
+    pub helper: H,
+    pub value: Option<T>
 }
 
 trait Helper<T> {
@@ -34,6 +35,6 @@ impl<T, H: Helper<T>> Deref for DerefWithHelper<H, T> {
 
 // Test cross-crate autoderef + vtable.
 pub fn check<T: PartialEq>(x: T, y: T) -> bool {
-    let d: DerefWithHelper<Option<T>, T> = DerefWithHelper { helper: Some(x) };
+    let d: DerefWithHelper<Option<T>, T> = DerefWithHelper { helper: Some(x), value: None };
     d.eq(&y)
 }
diff --git a/src/test/auxiliary/plugin_args.rs b/src/test/auxiliary/plugin_args.rs
index 907d80b50db..d0ab944813a 100644
--- a/src/test/auxiliary/plugin_args.rs
+++ b/src/test/auxiliary/plugin_args.rs
@@ -37,7 +37,7 @@ impl TTMacroExpander for Expander {
                    _: &[ast::TokenTree]) -> Box<MacResult+'cx> {
         let args = self.args.iter().map(|i| pprust::meta_item_to_string(&*i))
             .collect::<Vec<_>>().connect(", ");
-        let interned = token::intern_and_get_ident(&args[]);
+        let interned = token::intern_and_get_ident(&args[..]);
         MacExpr::new(ecx.expr_str(sp, interned))
     }
 }
diff --git a/src/test/auxiliary/private_trait_xc.rs b/src/test/auxiliary/private_trait_xc.rs
index 37ee10c8d37..42691579491 100644
--- a/src/test/auxiliary/private_trait_xc.rs
+++ b/src/test/auxiliary/private_trait_xc.rs
@@ -8,4 +8,4 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo {}
+trait Foo : ::std::marker::MarkerTrait {}
diff --git a/src/test/auxiliary/svh-a-base.rs b/src/test/auxiliary/svh-a-base.rs
index 12833daf604..04f1062c16f 100644
--- a/src/test/auxiliary/svh-a-base.rs
+++ b/src/test/auxiliary/svh-a-base.rs
@@ -15,12 +15,14 @@
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
diff --git a/src/test/auxiliary/svh-a-change-lit.rs b/src/test/auxiliary/svh-a-change-lit.rs
index 9e74bf28135..fabd2289e9a 100644
--- a/src/test/auxiliary/svh-a-change-lit.rs
+++ b/src/test/auxiliary/svh-a-change-lit.rs
@@ -15,12 +15,14 @@
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
diff --git a/src/test/auxiliary/svh-a-change-significant-cfg.rs b/src/test/auxiliary/svh-a-change-significant-cfg.rs
index c900550041b..3fdb861bd40 100644
--- a/src/test/auxiliary/svh-a-change-significant-cfg.rs
+++ b/src/test/auxiliary/svh-a-change-significant-cfg.rs
@@ -15,12 +15,14 @@
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
diff --git a/src/test/auxiliary/svh-a-change-trait-bound.rs b/src/test/auxiliary/svh-a-change-trait-bound.rs
index 04f8eb3cf9b..3116d24673d 100644
--- a/src/test/auxiliary/svh-a-change-trait-bound.rs
+++ b/src/test/auxiliary/svh-a-change-trait-bound.rs
@@ -15,12 +15,14 @@
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
diff --git a/src/test/auxiliary/svh-a-change-type-arg.rs b/src/test/auxiliary/svh-a-change-type-arg.rs
index c7e0a18768a..b49a1533628 100644
--- a/src/test/auxiliary/svh-a-change-type-arg.rs
+++ b/src/test/auxiliary/svh-a-change-type-arg.rs
@@ -15,12 +15,14 @@
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
diff --git a/src/test/auxiliary/svh-a-change-type-ret.rs b/src/test/auxiliary/svh-a-change-type-ret.rs
index 5100af32318..6562a93135f 100644
--- a/src/test/auxiliary/svh-a-change-type-ret.rs
+++ b/src/test/auxiliary/svh-a-change-type-ret.rs
@@ -15,12 +15,14 @@
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
diff --git a/src/test/auxiliary/svh-a-change-type-static.rs b/src/test/auxiliary/svh-a-change-type-static.rs
index 077c33cb90d..c7b392c6ee8 100644
--- a/src/test/auxiliary/svh-a-change-type-static.rs
+++ b/src/test/auxiliary/svh-a-change-type-static.rs
@@ -15,12 +15,14 @@
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
diff --git a/src/test/auxiliary/svh-a-comment.rs b/src/test/auxiliary/svh-a-comment.rs
index d481fa5a1fa..450f6102026 100644
--- a/src/test/auxiliary/svh-a-comment.rs
+++ b/src/test/auxiliary/svh-a-comment.rs
@@ -15,12 +15,14 @@
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
diff --git a/src/test/auxiliary/svh-a-doc.rs b/src/test/auxiliary/svh-a-doc.rs
index 9e99a355ac1..c000737c854 100644
--- a/src/test/auxiliary/svh-a-doc.rs
+++ b/src/test/auxiliary/svh-a-doc.rs
@@ -15,12 +15,14 @@
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
diff --git a/src/test/auxiliary/svh-a-macro.rs b/src/test/auxiliary/svh-a-macro.rs
index b8dd497ac99..1e12659dc4b 100644
--- a/src/test/auxiliary/svh-a-macro.rs
+++ b/src/test/auxiliary/svh-a-macro.rs
@@ -15,12 +15,14 @@
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
diff --git a/src/test/auxiliary/svh-a-no-change.rs b/src/test/auxiliary/svh-a-no-change.rs
index 12833daf604..04f1062c16f 100644
--- a/src/test/auxiliary/svh-a-no-change.rs
+++ b/src/test/auxiliary/svh-a-no-change.rs
@@ -15,12 +15,14 @@
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
diff --git a/src/test/auxiliary/svh-a-redundant-cfg.rs b/src/test/auxiliary/svh-a-redundant-cfg.rs
index 690ddc670f5..1e82b74f1ef 100644
--- a/src/test/auxiliary/svh-a-redundant-cfg.rs
+++ b/src/test/auxiliary/svh-a-redundant-cfg.rs
@@ -15,12 +15,14 @@
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
diff --git a/src/test/auxiliary/svh-a-whitespace.rs b/src/test/auxiliary/svh-a-whitespace.rs
index 216e8e997f2..3c3dac9cdab 100644
--- a/src/test/auxiliary/svh-a-whitespace.rs
+++ b/src/test/auxiliary/svh-a-whitespace.rs
@@ -15,12 +15,14 @@
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
diff --git a/src/test/auxiliary/trait_bounds_on_structs_and_enums_xc.rs b/src/test/auxiliary/trait_bounds_on_structs_and_enums_xc.rs
index 1695e474de9..a7c469fccaa 100644
--- a/src/test/auxiliary/trait_bounds_on_structs_and_enums_xc.rs
+++ b/src/test/auxiliary/trait_bounds_on_structs_and_enums_xc.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub trait Trait {}
+pub trait Trait {
+    fn dummy(&self) { }
+}
 
 pub struct Foo<T:Trait> {
     pub x: T,
diff --git a/src/test/auxiliary/trait_impl_conflict.rs b/src/test/auxiliary/trait_impl_conflict.rs
index 990bc216049..0982efbdbf4 100644
--- a/src/test/auxiliary/trait_impl_conflict.rs
+++ b/src/test/auxiliary/trait_impl_conflict.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub trait Foo {
+pub trait Foo : ::std::marker::MarkerTrait {
 }
 
 impl Foo for int {
diff --git a/src/test/auxiliary/use_from_trait_xc.rs b/src/test/auxiliary/use_from_trait_xc.rs
index 22e0d3168ca..56fb40bc0a4 100644
--- a/src/test/auxiliary/use_from_trait_xc.rs
+++ b/src/test/auxiliary/use_from_trait_xc.rs
@@ -11,7 +11,7 @@
 pub use self::sub::{Bar, Baz};
 
 pub trait Trait {
-    fn foo();
+    fn foo(&self);
 }
 
 struct Foo;
diff --git a/src/test/bench/core-set.rs b/src/test/bench/core-set.rs
index 1d440c4540c..994c9605fc3 100644
--- a/src/test/bench/core-set.rs
+++ b/src/test/bench/core-set.rs
@@ -16,9 +16,8 @@ extern crate collections;
 extern crate rand;
 
 use std::collections::BTreeSet;
-use std::collections::BitvSet;
+use std::collections::BitSet;
 use std::collections::HashSet;
-use std::collections::hash_map::Hasher;
 use std::hash::Hash;
 use std::env;
 use std::time::Duration;
@@ -43,7 +42,7 @@ trait MutableSet<T> {
     fn contains(&self, k: &T) -> bool;
 }
 
-impl<T: Hash<Hasher> + Eq> MutableSet<T> for HashSet<T> {
+impl<T: Hash + Eq> MutableSet<T> for HashSet<T> {
     fn insert(&mut self, k: T) { self.insert(k); }
     fn remove(&mut self, k: &T) -> bool { self.remove(k) }
     fn contains(&self, k: &T) -> bool { self.contains(k) }
@@ -53,7 +52,7 @@ impl<T: Ord> MutableSet<T> for BTreeSet<T> {
     fn remove(&mut self, k: &T) -> bool { self.remove(k) }
     fn contains(&self, k: &T) -> bool { self.contains(k) }
 }
-impl MutableSet<usize> for BitvSet {
+impl MutableSet<usize> for BitSet {
     fn insert(&mut self, k: usize) { self.insert(k); }
     fn remove(&mut self, k: &usize) -> bool { self.remove(k) }
     fn contains(&self, k: &usize) -> bool { self.contains(k) }
@@ -222,7 +221,7 @@ fn main() {
     {
         let mut rng: rand::IsaacRng = rand::SeedableRng::from_seed(seed);
         let mut results = empty_results();
-        results.bench_int(&mut rng, num_keys, max, || BitvSet::new());
-        write_results("collections::bitv::BitvSet", &results);
+        results.bench_int(&mut rng, num_keys, max, || BitSet::new());
+        write_results("collections::bit_vec::BitSet", &results);
     }
 }
diff --git a/src/test/bench/shootout-fasta.rs b/src/test/bench/shootout-fasta.rs
index fd559608011..2c640c4b092 100644
--- a/src/test/bench/shootout-fasta.rs
+++ b/src/test/bench/shootout-fasta.rs
@@ -132,7 +132,7 @@ fn run<W: Writer>(writer: &mut W) -> std::old_io::IoResult<()> {
                         ('t', 0.3015094502008)];
 
     try!(make_fasta(writer, ">ONE Homo sapiens alu\n",
-                    alu.as_bytes().iter().cycle().map(|c| *c), n * 2));
+                    alu.as_bytes().iter().cycle().cloned(), n * 2));
     try!(make_fasta(writer, ">TWO IUB ambiguity codes\n",
                     AAGen::new(rng, iub), n * 3));
     try!(make_fasta(writer, ">THREE Homo sapiens frequency\n",
diff --git a/src/test/bench/shootout-meteor.rs b/src/test/bench/shootout-meteor.rs
index 73dce2910c9..a94fe0ccd95 100644
--- a/src/test/bench/shootout-meteor.rs
+++ b/src/test/bench/shootout-meteor.rs
@@ -202,7 +202,7 @@ fn filter_masks(masks: &mut Vec<Vec<Vec<u64>>>) {
     for i in 0..masks.len() {
         for j in 0..(*masks)[i].len() {
             masks[i][j] =
-                (*masks)[i][j].iter().map(|&m| m)
+                (*masks)[i][j].iter().cloned()
                 .filter(|&m| !is_board_unfeasible(m, masks))
                 .collect();
         }
@@ -270,7 +270,7 @@ fn handle_sol(raw_sol: &List<u64>, data: &mut Data) {
     // reverse order, i.e. the board rotated by half a turn.
     data.nb += 2;
     let sol1 = to_vec(raw_sol);
-    let sol2: Vec<u8> = sol1.iter().rev().map(|x| *x).collect();
+    let sol2: Vec<u8> = sol1.iter().rev().cloned().collect();
 
     if data.nb == 2 {
         data.min = sol1.clone();
diff --git a/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs b/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs
index 621f5ec9660..edd1b8255cc 100644
--- a/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs
+++ b/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs
@@ -16,8 +16,12 @@
 #![feature(no_std)]
 #![no_std]
 
+#[lang="phantom_fn"]
+pub trait PhantomFn<A:?Sized,R:?Sized=()> { }
+impl<A:?Sized, R:?Sized, U:?Sized> PhantomFn<A,R> for U { }
+
 #[lang="sized"]
-pub trait Sized {
+pub trait Sized : PhantomFn<Self> {
     // Empty.
 }
 
diff --git a/src/test/compile-fail/associated-types-coherence-failure.rs b/src/test/compile-fail/associated-types-coherence-failure.rs
index 95a68dd6698..b7a16c68a34 100644
--- a/src/test/compile-fail/associated-types-coherence-failure.rs
+++ b/src/test/compile-fail/associated-types-coherence-failure.rs
@@ -11,9 +11,10 @@
 // Test that coherence detects overlap when some of the types in the
 // impls are projections of associated type. Issue #20624.
 
+use std::marker::PhantomData;
 use std::ops::Deref;
 
-pub struct Cow<'a, B: ?Sized>;
+pub struct Cow<'a, B: ?Sized>(PhantomData<(&'a (),B)>);
 
 /// Trait for moving into a `Cow`
 pub trait IntoCow<'a, B: ?Sized> {
diff --git a/src/test/compile-fail/associated-types-eq-expr-path.rs b/src/test/compile-fail/associated-types-eq-expr-path.rs
index 9baa7f1ad5a..c48f9972ebc 100644
--- a/src/test/compile-fail/associated-types-eq-expr-path.rs
+++ b/src/test/compile-fail/associated-types-eq-expr-path.rs
@@ -10,7 +10,7 @@
 
 // Check that an associated type cannot be bound in an expression path.
 
-trait Foo {
+trait Foo : ::std::marker::MarkerTrait {
     type A;
     fn bar() -> isize;
 }
diff --git a/src/test/compile-fail/associated-types-issue-17359.rs b/src/test/compile-fail/associated-types-issue-17359.rs
index fa09ae793bf..625f4cdb8ef 100644
--- a/src/test/compile-fail/associated-types-issue-17359.rs
+++ b/src/test/compile-fail/associated-types-issue-17359.rs
@@ -11,7 +11,7 @@
 // Test that we do not ICE when an impl is missing an associated type (and that we report
 // a useful error, of course).
 
-trait Trait {
+trait Trait : ::std::marker::MarkerTrait {
     type Type;
 }
 
diff --git a/src/test/compile-fail/associated-types-multiple-types-one-trait.rs b/src/test/compile-fail/associated-types-multiple-types-one-trait.rs
index 9436f825de8..5632f148da6 100644
--- a/src/test/compile-fail/associated-types-multiple-types-one-trait.rs
+++ b/src/test/compile-fail/associated-types-multiple-types-one-trait.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo {
+trait Foo : ::std::marker::MarkerTrait {
     type X;
     type Y;
 }
diff --git a/src/test/compile-fail/associated-types-no-suitable-supertrait.rs b/src/test/compile-fail/associated-types-no-suitable-supertrait.rs
index a3f2850b294..2b84c38f80b 100644
--- a/src/test/compile-fail/associated-types-no-suitable-supertrait.rs
+++ b/src/test/compile-fail/associated-types-no-suitable-supertrait.rs
@@ -11,7 +11,7 @@
 // Check that we get an error when you use `<Self as Get>::Value` in
 // the trait definition but `Self` does not, in fact, implement `Get`.
 
-trait Get {
+trait Get : ::std::marker::MarkerTrait {
     type Value;
 }
 
diff --git a/src/test/compile-fail/associated-types-path-2.rs b/src/test/compile-fail/associated-types-path-2.rs
index 51a37b517dd..b9a62ff4e41 100644
--- a/src/test/compile-fail/associated-types-path-2.rs
+++ b/src/test/compile-fail/associated-types-path-2.rs
@@ -12,6 +12,8 @@
 
 pub trait Foo {
     type A;
+
+    fn dummy(&self) { }
 }
 
 impl Foo for i32 {
diff --git a/src/test/compile-fail/associated-types-unconstrained.rs b/src/test/compile-fail/associated-types-unconstrained.rs
index aecbf217a5b..8832028f9ab 100644
--- a/src/test/compile-fail/associated-types-unconstrained.rs
+++ b/src/test/compile-fail/associated-types-unconstrained.rs
@@ -10,7 +10,7 @@
 
 // Check that an associated type cannot be bound in an expression path.
 
-trait Foo {
+trait Foo : ::std::marker::MarkerTrait {
     type A;
     fn bar() -> isize;
 }
diff --git a/src/test/compile-fail/bad-mid-path-type-params.rs b/src/test/compile-fail/bad-mid-path-type-params.rs
index c91849ca53e..3e02a11c378 100644
--- a/src/test/compile-fail/bad-mid-path-type-params.rs
+++ b/src/test/compile-fail/bad-mid-path-type-params.rs
@@ -10,13 +10,6 @@
 
 // ignore-tidy-linelength
 
-#![feature(no_std)]
-#![no_std]
-#![feature(lang_items)]
-
-#[lang="sized"]
-pub trait Sized {}
-
 struct S<T> {
     contents: T,
 }
diff --git a/src/test/compile-fail/bad-sized.rs b/src/test/compile-fail/bad-sized.rs
index 69be6414e4c..1944acbe1f3 100644
--- a/src/test/compile-fail/bad-sized.rs
+++ b/src/test/compile-fail/bad-sized.rs
@@ -12,7 +12,7 @@
 
 use std::cell::RefCell;
 
-trait Trait {}
+trait Trait : ::std::marker::MarkerTrait {}
 
 pub fn main() {
     let x: Vec<Trait + Sized> = Vec::new();
diff --git a/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-implemented.rs b/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-implemented.rs
index 27d97d18c94..d4decb71349 100644
--- a/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-implemented.rs
+++ b/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-implemented.rs
@@ -10,6 +10,7 @@
 
 use std::fmt::Show;
 use std::default::Default;
+use std::marker::MarkerTrait;
 
 // Test that two blanket impls conflict (at least without negative
 // bounds).  After all, some other crate could implement Even or Odd
@@ -19,9 +20,9 @@ trait MyTrait {
     fn get(&self) -> usize;
 }
 
-trait Even { }
+trait Even : MarkerTrait { }
 
-trait Odd { }
+trait Odd : MarkerTrait { }
 
 impl Even for isize { }
 
diff --git a/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-unimplemented.rs b/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-unimplemented.rs
index 0f233b78c72..b1ee1762b6e 100644
--- a/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-unimplemented.rs
+++ b/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-unimplemented.rs
@@ -19,9 +19,9 @@ trait MyTrait {
     fn get(&self) -> usize;
 }
 
-trait Even { }
+trait Even : ::std::marker::MarkerTrait { }
 
-trait Odd { }
+trait Odd : ::std::marker::MarkerTrait { }
 
 impl<T:Even> MyTrait for T { //~ ERROR E0119
     fn get(&self) -> usize { 0 }
diff --git a/src/test/compile-fail/coherence-conflicting-negative-trait-impl.rs b/src/test/compile-fail/coherence-conflicting-negative-trait-impl.rs
index c9dfb8201a9..a225f6cf473 100644
--- a/src/test/compile-fail/coherence-conflicting-negative-trait-impl.rs
+++ b/src/test/compile-fail/coherence-conflicting-negative-trait-impl.rs
@@ -10,18 +10,18 @@
 
 #![feature(optin_builtin_traits)]
 
-trait MyTrait {}
+trait MyTrait : ::std::marker::MarkerTrait {}
 
-struct TestType<T>;
+struct TestType<T>(::std::marker::PhantomData<T>);
 
-unsafe impl<T: MyTrait> Send for TestType<T> {}
+unsafe impl<T: MyTrait+'static> Send for TestType<T> {}
 //~^ ERROR conflicting implementations for trait `core::marker::Send`
 //~^^ ERROR conflicting implementations for trait `core::marker::Send`
 
 impl<T: MyTrait> !Send for TestType<T> {}
 //~^ ERROR conflicting implementations for trait `core::marker::Send`
 
-unsafe impl<T> Send for TestType<T> {}
+unsafe impl<T:'static> Send for TestType<T> {}
 //~^ ERROR error: conflicting implementations for trait `core::marker::Send`
 
 impl !Send for TestType<i32> {}
diff --git a/src/test/compile-fail/coherence-subtyping.rs b/src/test/compile-fail/coherence-subtyping.rs
new file mode 100644
index 00000000000..897cb083f84
--- /dev/null
+++ b/src/test/compile-fail/coherence-subtyping.rs
@@ -0,0 +1,50 @@
+// Copyright 2015 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.
+
+// Test that two distinct impls which match subtypes of one another
+// yield coherence errors (or not) depending on the variance.
+
+trait Contravariant {
+    fn foo(&self) { }
+}
+
+impl Contravariant for for<'a,'b> fn(&'a u8, &'b u8) {
+    //~^ ERROR E0119
+}
+
+impl Contravariant for for<'a> fn(&'a u8, &'a u8) {
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+trait Covariant {
+    fn foo(&self) { }
+}
+
+impl Covariant for for<'a,'b> fn(&'a u8, &'b u8) {
+    //~^ ERROR E0119
+}
+
+impl Covariant for for<'a> fn(&'a u8, &'a u8) {
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+trait Invariant {
+    fn foo(&self) -> Self { }
+}
+
+impl Invariant for for<'a,'b> fn(&'a u8, &'b u8) {
+}
+
+impl Invariant for for<'a> fn(&'a u8, &'a u8) {
+}
+
+fn main() { }
diff --git a/src/test/compile-fail/cross-borrow-trait.rs b/src/test/compile-fail/cross-borrow-trait.rs
index 86b7a8c8918..6bd21101a60 100644
--- a/src/test/compile-fail/cross-borrow-trait.rs
+++ b/src/test/compile-fail/cross-borrow-trait.rs
@@ -14,7 +14,7 @@
 #![feature(box_syntax)]
 
 struct Foo;
-trait Trait {}
+trait Trait { fn foo(&self) {} }
 impl Trait for Foo {}
 
 pub fn main() {
diff --git a/src/test/compile-fail/destructure-trait-ref.rs b/src/test/compile-fail/destructure-trait-ref.rs
index f2e068cc4ff..4161cce2843 100644
--- a/src/test/compile-fail/destructure-trait-ref.rs
+++ b/src/test/compile-fail/destructure-trait-ref.rs
@@ -14,7 +14,7 @@
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 
-trait T {}
+trait T { fn foo(&self) {} }
 impl T for isize {}
 
 fn main() {
diff --git a/src/test/compile-fail/dst-bad-coerce1.rs b/src/test/compile-fail/dst-bad-coerce1.rs
index 2b96c5ebe12..ddc92901771 100644
--- a/src/test/compile-fail/dst-bad-coerce1.rs
+++ b/src/test/compile-fail/dst-bad-coerce1.rs
@@ -15,7 +15,7 @@ struct Fat<T: ?Sized> {
 }
 
 struct Foo;
-trait Bar {}
+trait Bar { fn bar(&self) {} }
 
 pub fn main() {
     // With a vec of isize.
diff --git a/src/test/compile-fail/dst-bad-coerce2.rs b/src/test/compile-fail/dst-bad-coerce2.rs
index 160197368d6..aa687266acb 100644
--- a/src/test/compile-fail/dst-bad-coerce2.rs
+++ b/src/test/compile-fail/dst-bad-coerce2.rs
@@ -15,7 +15,7 @@ struct Fat<T: ?Sized> {
 }
 
 struct Foo;
-trait Bar {}
+trait Bar : ::std::marker::MarkerTrait {}
 impl Bar for Foo {}
 
 pub fn main() {
diff --git a/src/test/compile-fail/dst-bad-coerce3.rs b/src/test/compile-fail/dst-bad-coerce3.rs
index 347a2d2ecbe..7bad3bd69d3 100644
--- a/src/test/compile-fail/dst-bad-coerce3.rs
+++ b/src/test/compile-fail/dst-bad-coerce3.rs
@@ -15,7 +15,7 @@ struct Fat<T: ?Sized> {
 }
 
 struct Foo;
-trait Bar {}
+trait Bar { fn bar(&self) {} }
 impl Bar for Foo {}
 
 fn baz<'a>() {
diff --git a/src/test/compile-fail/dst-bad-coercions.rs b/src/test/compile-fail/dst-bad-coercions.rs
index b30eada162b..8ec1034bc4d 100644
--- a/src/test/compile-fail/dst-bad-coercions.rs
+++ b/src/test/compile-fail/dst-bad-coercions.rs
@@ -10,8 +10,10 @@
 
 // Test implicit coercions involving DSTs and raw pointers.
 
+use std::marker::MarkerTrait;
+
 struct S;
-trait T {}
+trait T : MarkerTrait {}
 impl T for S {}
 
 struct Foo<T: ?Sized> {
diff --git a/src/test/compile-fail/dst-object-from-unsized-type.rs b/src/test/compile-fail/dst-object-from-unsized-type.rs
index 87ff4291f50..b4fd45845f7 100644
--- a/src/test/compile-fail/dst-object-from-unsized-type.rs
+++ b/src/test/compile-fail/dst-object-from-unsized-type.rs
@@ -10,7 +10,7 @@
 
 // Test that we cannot create objects from unsized types.
 
-trait Foo {}
+trait Foo { fn foo(&self) {} }
 impl Foo for str {}
 
 fn test1<T: ?Sized + Foo>(t: &T) {
diff --git a/src/test/compile-fail/exclusive-drop-and-copy.rs b/src/test/compile-fail/exclusive-drop-and-copy.rs
index 17453bc677f..f47f14d5879 100644
--- a/src/test/compile-fail/exclusive-drop-and-copy.rs
+++ b/src/test/compile-fail/exclusive-drop-and-copy.rs
@@ -20,7 +20,7 @@ impl Drop for Foo {
 }
 
 #[derive(Copy)] //~ ERROR the trait `Copy` may not be implemented
-struct Bar<T>;
+struct Bar<T>(::std::marker::PhantomData<T>);
 
 #[unsafe_destructor]
 impl<T> Drop for Bar<T> {
diff --git a/src/test/compile-fail/generic-impl-less-params-with-defaults.rs b/src/test/compile-fail/generic-impl-less-params-with-defaults.rs
index 02f09749d61..9fea5e609d1 100644
--- a/src/test/compile-fail/generic-impl-less-params-with-defaults.rs
+++ b/src/test/compile-fail/generic-impl-less-params-with-defaults.rs
@@ -8,10 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Foo<A, B, C = (A, B)>;
+use std::marker;
+
+struct Foo<A, B, C = (A, B)>(
+    marker::PhantomData<(A,B,C)>);
 
 impl<A, B, C = (A, B)> Foo<A, B, C> {
-    fn new() -> Foo<A, B, C> {Foo}
+    fn new() -> Foo<A, B, C> {Foo(marker::PhantomData)}
 }
 
 fn main() {
diff --git a/src/test/compile-fail/generic-impl-more-params-with-defaults.rs b/src/test/compile-fail/generic-impl-more-params-with-defaults.rs
index d88da2625c1..73c19aa012d 100644
--- a/src/test/compile-fail/generic-impl-more-params-with-defaults.rs
+++ b/src/test/compile-fail/generic-impl-more-params-with-defaults.rs
@@ -8,12 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker;
+
 struct Heap;
 
-struct Vec<T, A = Heap>;
+struct Vec<T, A = Heap>(
+    marker::PhantomData<(T,A)>);
 
 impl<T, A = Heap> Vec<T, A> {
-    fn new() -> Vec<T, A> {Vec}
+    fn new() -> Vec<T, A> {Vec(marker::PhantomData)}
 }
 
 fn main() {
diff --git a/src/test/compile-fail/generic-lifetime-trait-impl.rs b/src/test/compile-fail/generic-lifetime-trait-impl.rs
index fc54002820e..9b9f09f4777 100644
--- a/src/test/compile-fail/generic-lifetime-trait-impl.rs
+++ b/src/test/compile-fail/generic-lifetime-trait-impl.rs
@@ -16,9 +16,12 @@
 //
 // Regression test for issue #16218.
 
-trait Bar<'a> {}
+trait Bar<'a> {
+    fn dummy(&'a self);
+}
 
 trait Foo<'a> {
+    fn dummy(&'a self) { }
     fn bar<'b, T: Bar<'b>>(self) -> &'b str;
 }
 
diff --git a/src/test/compile-fail/generic-type-less-params-with-defaults.rs b/src/test/compile-fail/generic-type-less-params-with-defaults.rs
index f25d8f99b8d..37737fda474 100644
--- a/src/test/compile-fail/generic-type-less-params-with-defaults.rs
+++ b/src/test/compile-fail/generic-type-less-params-with-defaults.rs
@@ -8,9 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker;
+
 struct Heap;
 
-struct Vec<T, A = Heap>;
+struct Vec<T, A = Heap>(
+    marker::PhantomData<(T,A)>);
 
 fn main() {
     let _: Vec; //~ ERROR wrong number of type arguments: expected at least 1, found 0
diff --git a/src/test/compile-fail/generic-type-more-params-with-defaults.rs b/src/test/compile-fail/generic-type-more-params-with-defaults.rs
index 19d303488ac..ad7e4f190c5 100644
--- a/src/test/compile-fail/generic-type-more-params-with-defaults.rs
+++ b/src/test/compile-fail/generic-type-more-params-with-defaults.rs
@@ -8,9 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker;
+
 struct Heap;
 
-struct Vec<T, A = Heap>;
+struct Vec<T, A = Heap>(
+    marker::PhantomData<(T,A)>);
 
 fn main() {
     let _: Vec<isize, Heap, bool>;
diff --git a/src/test/compile-fail/generic-type-params-name-repr.rs b/src/test/compile-fail/generic-type-params-name-repr.rs
index 3e34344d78b..a452cd35f94 100644
--- a/src/test/compile-fail/generic-type-params-name-repr.rs
+++ b/src/test/compile-fail/generic-type-params-name-repr.rs
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker;
+
 struct A;
 struct B;
 struct C;
-struct Foo<T = A, U = B, V = C>;
+struct Foo<T = A, U = B, V = C>(marker::PhantomData<(T,U,V)>);
 
-struct Hash<T>;
-struct HashMap<K, V, H = Hash<K>>;
+struct Hash<T>(marker::PhantomData<T>);
+struct HashMap<K, V, H = Hash<K>>(marker::PhantomData<(K,V,H)>);
 
 fn main() {
     // Ensure that the printed type doesn't include the default type params...
diff --git a/src/test/compile-fail/issue-11515.rs b/src/test/compile-fail/issue-11515.rs
index f0089b0ae5b..4ff574e939d 100644
--- a/src/test/compile-fail/issue-11515.rs
+++ b/src/test/compile-fail/issue-11515.rs
@@ -10,7 +10,7 @@
 
 #![feature(box_syntax)]
 
-struct Test<'s> {
+struct Test {
     func: Box<FnMut()+'static>
 }
 
diff --git a/src/test/compile-fail/issue-13853-2.rs b/src/test/compile-fail/issue-13853-2.rs
index ea0d880f4a1..dc697e4784f 100644
--- a/src/test/compile-fail/issue-13853-2.rs
+++ b/src/test/compile-fail/issue-13853-2.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait FromStructReader<'a> { }
+use std::marker::PhantomFn;
+
+trait FromStructReader<'a> : PhantomFn<(Self,&'a ())> { }
 trait ResponseHook {
      fn get<'a, T: FromStructReader<'a>>(&'a self);
 }
diff --git a/src/test/compile-fail/issue-13853-3.rs b/src/test/compile-fail/issue-13853-3.rs
index f10c47b594e..7ca158c3e32 100644
--- a/src/test/compile-fail/issue-13853-3.rs
+++ b/src/test/compile-fail/issue-13853-3.rs
@@ -10,6 +10,8 @@
 
 #![crate_type = "lib"]
 
+use std::marker::PhantomData;
+
 enum NodeContents<'a> {
     Children(Vec<Node<'a>>),
 }
@@ -22,11 +24,12 @@ impl<'a> Drop for NodeContents<'a> {
 
 struct Node<'a> {
     contents: NodeContents<'a>,
+    marker: PhantomData<&'a ()>,
 }
 
 impl<'a> Node<'a> {
     fn noName(contents: NodeContents<'a>) -> Node<'a> {
-        Node{  contents: contents,}
+        Node { contents: contents, marker: PhantomData }
     }
 }
 
diff --git a/src/test/compile-fail/issue-13853.rs b/src/test/compile-fail/issue-13853.rs
index 251da2c6b3e..cd3f337c4ab 100644
--- a/src/test/compile-fail/issue-13853.rs
+++ b/src/test/compile-fail/issue-13853.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Node {
+use std::marker::MarkerTrait;
+
+trait Node : MarkerTrait {
     fn zomg();
 }
 
diff --git a/src/test/compile-fail/issue-14285.rs b/src/test/compile-fail/issue-14285.rs
index cbf4412a81d..3a5df9e805b 100644
--- a/src/test/compile-fail/issue-14285.rs
+++ b/src/test/compile-fail/issue-14285.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo {}
+trait Foo {
+    fn dummy(&self) { }
+}
 
 struct A;
 
diff --git a/src/test/compile-fail/issue-14853.rs b/src/test/compile-fail/issue-14853.rs
index 51deb99a4f2..0b846651acf 100644
--- a/src/test/compile-fail/issue-14853.rs
+++ b/src/test/compile-fail/issue-14853.rs
@@ -9,8 +9,9 @@
 // except according to those terms.
 
 use std::fmt::Debug;
+use std::marker::MarkerTrait;
 
-trait Str {}
+trait Str : MarkerTrait {}
 
 trait Something {
     fn yay<T: Debug>(_: Option<Self>, thing: &[T]);
diff --git a/src/test/compile-fail/issue-16747.rs b/src/test/compile-fail/issue-16747.rs
index 814b885e3aa..a213234b89b 100644
--- a/src/test/compile-fail/issue-16747.rs
+++ b/src/test/compile-fail/issue-16747.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait ListItem<'a> {
+use std::marker::MarkerTrait;
+
+trait ListItem<'a> : MarkerTrait {
     fn list_name() -> &'a str;
 }
 
diff --git a/src/test/compile-fail/issue-17431-4.rs b/src/test/compile-fail/issue-17431-4.rs
index 1e27f025564..22aaa796ad0 100644
--- a/src/test/compile-fail/issue-17431-4.rs
+++ b/src/test/compile-fail/issue-17431-4.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Foo<T> { foo: Option<Option<Foo<T>>> }
+use std::marker;
+
+struct Foo<T> { foo: Option<Option<Foo<T>>>, marker: marker::PhantomData<T> }
 //~^ ERROR illegal recursive struct type; wrap the inner value in a box to make it representable
 
 impl<T> Foo<T> { fn bar(&self) {} }
diff --git a/src/test/compile-fail/issue-17431-5.rs b/src/test/compile-fail/issue-17431-5.rs
index d22d79ecaa5..cc9cc2e3c03 100644
--- a/src/test/compile-fail/issue-17431-5.rs
+++ b/src/test/compile-fail/issue-17431-5.rs
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker;
+
 struct Foo { foo: Bar<Foo> }
-struct Bar<T> { x: Bar<Foo> }
+struct Bar<T> { x: Bar<Foo> , marker: marker::PhantomData<T> }
 //~^ ERROR illegal recursive struct type; wrap the inner value in a box to make it representable
 
 impl Foo { fn foo(&self) {} }
diff --git a/src/test/compile-fail/issue-17551.rs b/src/test/compile-fail/issue-17551.rs
index e037ba92b4a..5781cb74117 100644
--- a/src/test/compile-fail/issue-17551.rs
+++ b/src/test/compile-fail/issue-17551.rs
@@ -10,9 +10,11 @@
 
 #![feature(unboxed_closures)]
 
-struct B<T>;
+use std::marker;
+
+struct B<T>(marker::PhantomData<T>);
 
 fn main() {
-    let foo = B; //~ ERROR: unable to infer enough type information
+    let foo = B(marker::PhantomData); //~ ERROR unable to infer enough type information
     let closure = || foo;
 }
diff --git a/src/test/compile-fail/issue-17904-2.rs b/src/test/compile-fail/issue-17904-2.rs
new file mode 100644
index 00000000000..a33ec23a16a
--- /dev/null
+++ b/src/test/compile-fail/issue-17904-2.rs
@@ -0,0 +1,16 @@
+// Copyright 2014 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.
+
+// Test that we can parse a unit struct with a where clause, even if
+// it leads to a error later on since `T` is unused.
+
+struct Foo<T> where T: Copy; //~ ERROR parameter `T` is never used
+
+fn main() {}
diff --git a/src/test/compile-fail/issue-18107.rs b/src/test/compile-fail/issue-18107.rs
index 91689988f58..d5fb22bdebd 100644
--- a/src/test/compile-fail/issue-18107.rs
+++ b/src/test/compile-fail/issue-18107.rs
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker::MarkerTrait;
 
-
-pub trait AbstractRenderer {}
+pub trait AbstractRenderer : MarkerTrait {}
 
 fn _create_render(_: &()) ->
     AbstractRenderer
diff --git a/src/test/compile-fail/issue-18611.rs b/src/test/compile-fail/issue-18611.rs
index a662e9ca98e..e81a576fa63 100644
--- a/src/test/compile-fail/issue-18611.rs
+++ b/src/test/compile-fail/issue-18611.rs
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker::MarkerTrait;
+
 fn add_state(op: <isize as HasState>::State) {
 //~^ ERROR the trait `HasState` is not implemented for the type `isize`
 }
 
-trait HasState {
+trait HasState : MarkerTrait {
     type State;
 }
 
diff --git a/src/test/compile-fail/issue-18783.rs b/src/test/compile-fail/issue-18783.rs
index 5ddf06add9d..13908bda9d8 100644
--- a/src/test/compile-fail/issue-18783.rs
+++ b/src/test/compile-fail/issue-18783.rs
@@ -26,6 +26,7 @@ fn ufcs() {
 
     Push::push(&c, box || y = 0);
     Push::push(&c, box || y = 0);
+//~^ ERROR cannot borrow `y` as mutable more than once at a time
 }
 
 trait Push<'c> {
diff --git a/src/test/compile-fail/issue-18819.rs b/src/test/compile-fail/issue-18819.rs
index 3a9de741043..951d78410b8 100644
--- a/src/test/compile-fail/issue-18819.rs
+++ b/src/test/compile-fail/issue-18819.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo {
+use std::marker::MarkerTrait;
+
+trait Foo : MarkerTrait {
     type Item;
 }
 
diff --git a/src/test/compile-fail/issue-19660.rs b/src/test/compile-fail/issue-19660.rs
index 14601e67a77..77aba7335bd 100644
--- a/src/test/compile-fail/issue-19660.rs
+++ b/src/test/compile-fail/issue-19660.rs
@@ -13,8 +13,12 @@
 #![feature(lang_items, start, no_std)]
 #![no_std]
 
+#[lang="phantom_fn"]
+trait PhantomFn<A:?Sized,R:?Sized=()> { }
+impl<A:?Sized, R:?Sized, U:?Sized> PhantomFn<A,R> for U { }
+
 #[lang = "sized"]
-trait Sized {}
+trait Sized : PhantomFn<Self> {}
 
 #[start]
 fn main(_: int, _: *const *const u8) -> int {
diff --git a/src/test/compile-fail/issue-2063.rs b/src/test/compile-fail/issue-2063.rs
index 00607f85034..aed395d17ea 100644
--- a/src/test/compile-fail/issue-2063.rs
+++ b/src/test/compile-fail/issue-2063.rs
@@ -12,10 +12,11 @@
 // cause compiler to loop.  Note that no instances
 // of such a type could ever be constructed.
 
+use std::marker::MarkerTrait;
 
 struct t(Box<t>); //~ ERROR this type cannot be instantiated
 
-trait to_str_2 {
+trait to_str_2 : MarkerTrait {
     fn my_to_string() -> String;
 }
 
diff --git a/src/test/compile-fail/issue-20831-debruijn.rs b/src/test/compile-fail/issue-20831-debruijn.rs
index aaf45f27398..5b623ac377b 100644
--- a/src/test/compile-fail/issue-20831-debruijn.rs
+++ b/src/test/compile-fail/issue-20831-debruijn.rs
@@ -13,10 +13,11 @@
 // below. Note that changing to a named lifetime made the problem go
 // away.
 
-use std::ops::{Shl, Shr};
 use std::cell::RefCell;
+use std::marker::MarkerTrait;
+use std::ops::{Shl, Shr};
 
-pub trait Subscriber {
+pub trait Subscriber : MarkerTrait {
     type Input;
 }
 
diff --git a/src/test/compile-fail/issue-21160.rs b/src/test/compile-fail/issue-21160.rs
index 45b7fbbd0b4..557bf518a3c 100644
--- a/src/test/compile-fail/issue-21160.rs
+++ b/src/test/compile-fail/issue-21160.rs
@@ -16,6 +16,6 @@ impl Bar {
 
 #[derive(Hash)]
 struct Foo(Bar);
-//~^ error: the trait `core::hash::Hash<_>` is not implemented for the type `Bar`
+//~^ error: the trait `core::hash::Hash` is not implemented for the type `Bar`
 
 fn main() {}
diff --git a/src/test/compile-fail/issue-2611-4.rs b/src/test/compile-fail/issue-2611-4.rs
index 31796e5e20c..24cc0099b89 100644
--- a/src/test/compile-fail/issue-2611-4.rs
+++ b/src/test/compile-fail/issue-2611-4.rs
@@ -12,7 +12,7 @@
 // than the trait method it's implementing
 
 trait A {
-  fn b<C,D>(x: C) -> C;
+  fn b<C,D>(&self, x: C) -> C;
 }
 
 struct E {
@@ -20,7 +20,7 @@ struct E {
 }
 
 impl A for E {
-    fn b<F: Sync, G>(_x: F) -> F { panic!() }
+    fn b<F: Sync, G>(&self, _x: F) -> F { panic!() }
     //~^ ERROR `F : core::marker::Sync` appears on the impl method
 }
 
diff --git a/src/test/compile-fail/issue-3008-3.rs b/src/test/compile-fail/issue-3008-3.rs
index a338a01690d..af6cee1f107 100644
--- a/src/test/compile-fail/issue-3008-3.rs
+++ b/src/test/compile-fail/issue-3008-3.rs
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker;
+
 enum E1 { V1(E2<E1>), }
-enum E2<T> { V2(E2<E1>), }
+enum E2<T> { V2(E2<E1>, marker::PhantomData<T>), }
 //~^ ERROR illegal recursive enum type; wrap the inner value in a box to make it representable
 
 impl E1 { fn foo(&self) {} }
diff --git a/src/test/compile-fail/issue-4972.rs b/src/test/compile-fail/issue-4972.rs
index 9a398796d2a..f384dba7c9e 100644
--- a/src/test/compile-fail/issue-4972.rs
+++ b/src/test/compile-fail/issue-4972.rs
@@ -11,7 +11,9 @@
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 
-trait MyTrait { }
+trait MyTrait {
+    fn dummy(&self) {}
+}
 
 pub enum TraitWrapper {
     A(Box<MyTrait+'static>),
diff --git a/src/test/compile-fail/issue-5035-2.rs b/src/test/compile-fail/issue-5035-2.rs
index 9e324cdd61e..d316b44794a 100644
--- a/src/test/compile-fail/issue-5035-2.rs
+++ b/src/test/compile-fail/issue-5035-2.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait I {}
+use std::marker::MarkerTrait;
+
+trait I : MarkerTrait {}
 type K = I+'static;
 
 fn foo(_x: K) {} //~ ERROR: the trait `core::marker::Sized` is not implemented
diff --git a/src/test/compile-fail/issue-5543.rs b/src/test/compile-fail/issue-5543.rs
index cf98f1572e5..4d721ad7666 100644
--- a/src/test/compile-fail/issue-5543.rs
+++ b/src/test/compile-fail/issue-5543.rs
@@ -10,7 +10,7 @@
 
 #![feature(box_syntax)]
 
-trait Foo {}
+trait Foo { fn foo(&self) {} }
 impl Foo for u8 {}
 
 fn main() {
diff --git a/src/test/compile-fail/issue-5883.rs b/src/test/compile-fail/issue-5883.rs
index 9ff957b6e6d..b0db9906195 100644
--- a/src/test/compile-fail/issue-5883.rs
+++ b/src/test/compile-fail/issue-5883.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait A {}
+use std::marker::MarkerTrait;
+
+trait A : MarkerTrait {}
 
 struct Struct {
     r: A+'static
@@ -20,6 +22,6 @@ fn new_struct(r: A+'static)
     Struct { r: r }
 }
 
-trait Curve {}
+trait Curve : MarkerTrait {}
 enum E {X(Curve+'static)}
 fn main() {}
diff --git a/src/test/compile-fail/issue-6458.rs b/src/test/compile-fail/issue-6458.rs
index efa3100360b..0bf9a3c2d48 100644
--- a/src/test/compile-fail/issue-6458.rs
+++ b/src/test/compile-fail/issue-6458.rs
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub struct TypeWithState<State>;
+use std::marker;
+
+pub struct TypeWithState<State>(marker::PhantomData<State>);
 pub struct MyState;
 
 pub fn foo<State>(_: TypeWithState<State>) {}
 
 pub fn bar() {
-   foo(TypeWithState);  //~ ERROR type annotations required
+   foo(TypeWithState(marker::PhantomData));  //~ ERROR type annotations required
 }
 
 fn main() {
diff --git a/src/test/compile-fail/issue-7575.rs b/src/test/compile-fail/issue-7575.rs
index 9e6000c050a..b6643f43952 100644
--- a/src/test/compile-fail/issue-7575.rs
+++ b/src/test/compile-fail/issue-7575.rs
@@ -10,12 +10,14 @@
 
 // Test the mechanism for warning about possible missing `self` declarations.
 
+use std::marker::MarkerTrait;
+
 trait CtxtFn {
     fn f8(self, usize) -> usize;
     fn f9(usize) -> usize; //~ NOTE candidate
 }
 
-trait OtherTrait {
+trait OtherTrait : MarkerTrait {
     fn f9(usize) -> usize; //~ NOTE candidate
 }
 
@@ -24,7 +26,7 @@ trait OtherTrait {
 // declaration to match against, so we wind up prisizeing it as a
 // candidate. This seems not unreasonable -- perhaps the user meant to
 // implement it, after all.
-trait UnusedTrait {
+trait UnusedTrait : MarkerTrait {
     fn f9(usize) -> usize; //~ NOTE candidate
 }
 
@@ -52,7 +54,7 @@ impl Myisize {
     }
 }
 
-trait ManyImplTrait {
+trait ManyImplTrait : MarkerTrait {
     fn is_str() -> bool { //~ NOTE candidate
         false
     }
diff --git a/src/test/compile-fail/issue-8727.rs b/src/test/compile-fail/issue-8727.rs
index d1a86d334cb..72da6dcaa6c 100644
--- a/src/test/compile-fail/issue-8727.rs
+++ b/src/test/compile-fail/issue-8727.rs
@@ -13,16 +13,12 @@
 // Verify the compiler fails with an error on infinite function
 // recursions.
 
-struct Data(Box<Option<Data>>);
-
-fn generic<T>( _ : Vec<(Data,T)> ) {
-    let rec : Vec<(Data,(bool,T))> = Vec::new();
-    generic( rec );
+fn generic<T>() {
+    generic::<Option<T>>();
 }
 
 
 fn main () {
     // Use generic<T> at least once to trigger instantiation.
-    let input : Vec<(Data,())> = Vec::new();
-    generic(input);
+    generic::<i32>();
 }
diff --git a/src/test/compile-fail/kindck-copy.rs b/src/test/compile-fail/kindck-copy.rs
index 56f83d93008..74e372e41eb 100644
--- a/src/test/compile-fail/kindck-copy.rs
+++ b/src/test/compile-fail/kindck-copy.rs
@@ -10,12 +10,12 @@
 
 // Test which of the builtin types are considered POD.
 
-
+use std::marker::MarkerTrait;
 use std::rc::Rc;
 
 fn assert_copy<T:Copy>() { }
 
-trait Dummy { }
+trait Dummy : MarkerTrait { }
 
 #[derive(Copy)]
 struct MyStruct {
diff --git a/src/test/compile-fail/kindck-impl-type-params-2.rs b/src/test/compile-fail/kindck-impl-type-params-2.rs
index 2731be7308a..b575144f637 100644
--- a/src/test/compile-fail/kindck-impl-type-params-2.rs
+++ b/src/test/compile-fail/kindck-impl-type-params-2.rs
@@ -10,7 +10,9 @@
 
 #![feature(box_syntax)]
 
-trait Foo {
+use std::marker::MarkerTrait;
+
+trait Foo : MarkerTrait {
 }
 
 impl<T:Copy> Foo for T {
diff --git a/src/test/compile-fail/kindck-impl-type-params.rs b/src/test/compile-fail/kindck-impl-type-params.rs
index d5276efa8be..dffc8fa2abd 100644
--- a/src/test/compile-fail/kindck-impl-type-params.rs
+++ b/src/test/compile-fail/kindck-impl-type-params.rs
@@ -13,40 +13,44 @@
 
 #![feature(box_syntax)]
 
-struct S<T>;
+use std::marker;
 
-trait Gettable<T> {}
+struct S<T>(marker::PhantomData<T>);
+
+trait Gettable<T> {
+    fn get(&self) -> T { panic!() }
+}
 
 impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
 
 fn f<T>(val: T) {
-    let t: S<T> = S;
+    let t: S<T> = S(marker::PhantomData);
     let a = &t as &Gettable<T>;
     //~^ ERROR the trait `core::marker::Send` is not implemented
     //~^^ ERROR the trait `core::marker::Copy` is not implemented
 }
 
 fn g<T>(val: T) {
-    let t: S<T> = S;
+    let t: S<T> = S(marker::PhantomData);
     let a: &Gettable<T> = &t;
     //~^ ERROR the trait `core::marker::Send` is not implemented
     //~^^ ERROR the trait `core::marker::Copy` is not implemented
 }
 
 fn foo<'a>() {
-    let t: S<&'a isize> = S;
+    let t: S<&'a isize> = S(marker::PhantomData);
     let a = &t as &Gettable<&'a isize>;
-    //~^ ERROR the type `&'a isize` does not fulfill the required lifetime
+    //~^ ERROR cannot infer
 }
 
 fn foo2<'a>() {
-    let t: Box<S<String>> = box S;
+    let t: Box<S<String>> = box S(marker::PhantomData);
     let a = t as Box<Gettable<String>>;
     //~^ ERROR the trait `core::marker::Copy` is not implemented
 }
 
 fn foo3<'a>() {
-    let t: Box<S<String>> = box S;
+    let t: Box<S<String>> = box S(marker::PhantomData);
     let a: Box<Gettable<String>> = t;
     //~^ ERROR the trait `core::marker::Copy` is not implemented
 }
diff --git a/src/test/compile-fail/kindck-inherited-copy-bound.rs b/src/test/compile-fail/kindck-inherited-copy-bound.rs
index e146cac21a3..0072b1228af 100644
--- a/src/test/compile-fail/kindck-inherited-copy-bound.rs
+++ b/src/test/compile-fail/kindck-inherited-copy-bound.rs
@@ -15,6 +15,7 @@
 use std::any::Any;
 
 trait Foo : Copy {
+    fn foo(&self) {}
 }
 
 impl<T:Copy> Foo for T {
diff --git a/src/test/compile-fail/kindck-send-object.rs b/src/test/compile-fail/kindck-send-object.rs
index 570f7ad7fe3..0c68401bb2b 100644
--- a/src/test/compile-fail/kindck-send-object.rs
+++ b/src/test/compile-fail/kindck-send-object.rs
@@ -12,8 +12,10 @@
 // in this file all test the "kind" violates detected during kindck.
 // See all `regions-bounded-by-send.rs`
 
+use std::marker::MarkerTrait;
+
 fn assert_send<T:Send>() { }
-trait Dummy { }
+trait Dummy : MarkerTrait { }
 trait Message : Send { }
 
 // careful with object types, who knows what they close over...
diff --git a/src/test/compile-fail/kindck-send-object1.rs b/src/test/compile-fail/kindck-send-object1.rs
index 48d5215b708..f86eac8b16b 100644
--- a/src/test/compile-fail/kindck-send-object1.rs
+++ b/src/test/compile-fail/kindck-send-object1.rs
@@ -12,8 +12,10 @@
 // is broken into two parts because some errors occur in distinct
 // phases in the compiler. See kindck-send-object2.rs as well!
 
+use std::marker::MarkerTrait;
+
 fn assert_send<T:Send+'static>() { }
-trait Dummy { }
+trait Dummy : MarkerTrait { }
 
 // careful with object types, who knows what they close over...
 fn test51<'a>() {
diff --git a/src/test/compile-fail/kindck-send-object2.rs b/src/test/compile-fail/kindck-send-object2.rs
index d3d166e2a69..08516e67318 100644
--- a/src/test/compile-fail/kindck-send-object2.rs
+++ b/src/test/compile-fail/kindck-send-object2.rs
@@ -10,8 +10,10 @@
 
 // Continue kindck-send-object1.rs.
 
+use std::marker::MarkerTrait;
+
 fn assert_send<T:Send>() { }
-trait Dummy { }
+trait Dummy : MarkerTrait { }
 
 fn test50() {
     assert_send::<&'static Dummy>(); //~ ERROR the trait `core::marker::Sync` is not implemented
diff --git a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs
index 04c5b223cb8..66d8927ee51 100644
--- a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs
+++ b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs
@@ -10,7 +10,9 @@
 
 // ignore-tidy-linelength
 
-struct Bar<'x, 'y, 'z> { bar: &'y i32, baz: i32 }
+use std::marker::PhantomData;
+
+struct Bar<'x, 'y, 'z> { bar: &'y i32, baz: i32, marker: PhantomData<(&'x(),&'y(),&'z())> }
 fn bar1<'a>(x: &Bar) -> (&'a i32, &'a i32, &'a i32) {
 //~^ HELP: consider using an explicit lifetime parameter as shown: fn bar1<'b, 'c, 'a>(x: &'a Bar<'b, 'a, 'c>) -> (&'a i32, &'a i32, &'a i32)
     (x.bar, &x.baz, &x.baz)
diff --git a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs
index c60e321219b..a85776a938b 100644
--- a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs
+++ b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs
@@ -10,7 +10,9 @@
 
 // ignore-tidy-linelength
 
-struct Foo<'x> { bar: isize }
+use std::marker::PhantomData;
+
+struct Foo<'x> { bar: isize, marker: PhantomData<&'x ()> }
 fn foo1<'a>(x: &Foo) -> &'a isize {
 //~^ HELP: consider using an explicit lifetime parameter as shown: fn foo1<'a>(x: &'a Foo) -> &'a isize
     &x.bar //~ ERROR: cannot infer
diff --git a/src/test/compile-fail/lint-missing-doc.rs b/src/test/compile-fail/lint-missing-doc.rs
index 3b96fd64fa2..73a58741bbb 100644
--- a/src/test/compile-fail/lint-missing-doc.rs
+++ b/src/test/compile-fail/lint-missing-doc.rs
@@ -47,20 +47,26 @@ fn foo3() {}
 /// dox
 pub trait A {
     /// dox
-    fn foo();
+    fn foo(&self);
     /// dox
-    fn foo_with_impl() {}
+    fn foo_with_impl(&self) {}
 }
+
 #[allow(missing_docs)]
 trait B {
-    fn foo();
-    fn foo_with_impl() {}
+    fn foo(&self);
+    fn foo_with_impl(&self) {}
 }
+
 pub trait C { //~ ERROR: missing documentation
-    fn foo(); //~ ERROR: missing documentation
-    fn foo_with_impl() {} //~ ERROR: missing documentation
+    fn foo(&self); //~ ERROR: missing documentation
+    fn foo_with_impl(&self) {} //~ ERROR: missing documentation
+}
+
+#[allow(missing_docs)]
+pub trait D {
+    fn dummy(&self) { }
 }
-#[allow(missing_docs)] pub trait D {}
 
 impl Foo {
     pub fn foo() {}
diff --git a/src/test/compile-fail/lint-non-camel-case-types.rs b/src/test/compile-fail/lint-non-camel-case-types.rs
index 70d6b240985..9f58d5791cb 100644
--- a/src/test/compile-fail/lint-non-camel-case-types.rs
+++ b/src/test/compile-fail/lint-non-camel-case-types.rs
@@ -30,6 +30,7 @@ enum Foo5 {
 }
 
 trait foo6 { //~ ERROR trait `foo6` should have a camel case name such as `Foo6`
+    fn dummy(&self) { }
 }
 
 fn f<ty>(_: ty) {} //~ ERROR type parameter `ty` should have a camel case name such as `Ty`
diff --git a/src/test/compile-fail/lint-stability.rs b/src/test/compile-fail/lint-stability.rs
index f9cdfa4f7d6..88f2cbdea6d 100644
--- a/src/test/compile-fail/lint-stability.rs
+++ b/src/test/compile-fail/lint-stability.rs
@@ -341,7 +341,9 @@ mod this_crate {
 
     #[unstable(feature = "test_feature")]
     #[deprecated(since = "1.0.0")]
-    pub trait DeprecatedTrait {}
+    pub trait DeprecatedTrait {
+        fn dummy(&self) { }
+    }
 
     struct S;
 
diff --git a/src/test/compile-fail/lint-visible-private-types.rs b/src/test/compile-fail/lint-visible-private-types.rs
index 8cf375f80fb..918b4ee209c 100644
--- a/src/test/compile-fail/lint-visible-private-types.rs
+++ b/src/test/compile-fail/lint-visible-private-types.rs
@@ -12,8 +12,10 @@
 #![allow(dead_code)]
 #![crate_type="lib"]
 
-struct Private<T>;
-pub struct Public<T>;
+use std::marker;
+
+struct Private<T>(marker::PhantomData<T>);
+pub struct Public<T>(marker::PhantomData<T>);
 
 impl Private<Public<isize>> {
     pub fn a(&self) -> Private<isize> { panic!() }
@@ -103,7 +105,7 @@ impl PrivTrait for (Private<isize>,) {
     fn bar(&self) -> Private<isize> { panic!() }
 }
 
-pub trait ParamTrait<T> {
+pub trait ParamTrait<T> : marker::MarkerTrait {
     fn foo() -> T;
 }
 
diff --git a/src/test/compile-fail/liveness-use-after-send.rs b/src/test/compile-fail/liveness-use-after-send.rs
index a49339ecd7f..03d8d62e0b4 100644
--- a/src/test/compile-fail/liveness-use-after-send.rs
+++ b/src/test/compile-fail/liveness-use-after-send.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker;
+
 fn send<T:Send + std::fmt::Debug>(ch: _chan<T>, data: T) {
     println!("{:?}", ch);
     println!("{:?}", data);
@@ -15,7 +17,7 @@ fn send<T:Send + std::fmt::Debug>(ch: _chan<T>, data: T) {
 }
 
 #[derive(Debug)]
-struct _chan<T>(isize);
+struct _chan<T>(isize, marker::PhantomData<T>);
 
 // Tests that "log(debug, message);" is flagged as using
 // message after the send deinitializes it
diff --git a/src/test/compile-fail/map-types.rs b/src/test/compile-fail/map-types.rs
index ba2205f5868..6e8719eeace 100644
--- a/src/test/compile-fail/map-types.rs
+++ b/src/test/compile-fail/map-types.rs
@@ -14,7 +14,10 @@ extern crate collections;
 
 use std::collections::HashMap;
 
-trait Map<K, V> {}
+trait Map<K, V>
+{
+    fn get(&self, k: K) -> V { panic!() }
+}
 
 impl<K, V> Map<K, V> for HashMap<K, V> {}
 
diff --git a/src/test/compile-fail/method-ambig-one-trait-coerce.rs b/src/test/compile-fail/method-ambig-one-trait-coerce.rs
deleted file mode 100644
index cb5da4bb547..00000000000
--- a/src/test/compile-fail/method-ambig-one-trait-coerce.rs
+++ /dev/null
@@ -1,50 +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.
-
-// Test that when we pick a trait based on coercion, versus subtyping,
-// we consider all possible coercions equivalent and don't try to pick
-// a best one.
-
-trait Object { }
-
-trait foo {
-    fn foo(self) -> isize;
-}
-
-impl foo for Box<Object+'static> {
-    fn foo(self) -> isize {1}
-}
-
-impl foo for Box<Object+Send> {
-    fn foo(self) -> isize {2}
-}
-
-fn test1(x: Box<Object+Send+Sync>) {
-    // FIXME(#18737) -- we ought to consider this to be ambiguous,
-    // since we could coerce to either impl. However, what actually
-    // happens is that we consider both impls applicable because of
-    // incorrect subtyping relation. We then decide to call this a
-    // call to the `foo` trait, leading to the following error
-    // message.
-
-    x.foo(); //~ ERROR `foo` is not implemented
-}
-
-fn test2(x: Box<Object+Send>) {
-    // Not ambiguous because it is a precise match:
-    x.foo();
-}
-
-fn test3(x: Box<Object+'static>) {
-    // Not ambiguous because it is a precise match:
-    x.foo();
-}
-
-fn main() { }
diff --git a/src/test/parse-fail/mod_file_disambig.rs b/src/test/compile-fail/mod_file_disambig.rs
index 48bd00a3ee0..48bd00a3ee0 100644
--- a/src/test/parse-fail/mod_file_disambig.rs
+++ b/src/test/compile-fail/mod_file_disambig.rs
diff --git a/src/test/parse-fail/mod_file_not_owning.rs b/src/test/compile-fail/mod_file_not_owning.rs
index adbcedd91f2..adbcedd91f2 100644
--- a/src/test/parse-fail/mod_file_not_owning.rs
+++ b/src/test/compile-fail/mod_file_not_owning.rs
diff --git a/src/test/compile-fail/object-does-not-impl-trait.rs b/src/test/compile-fail/object-does-not-impl-trait.rs
index cfaf149a49c..607ab13d122 100644
--- a/src/test/compile-fail/object-does-not-impl-trait.rs
+++ b/src/test/compile-fail/object-does-not-impl-trait.rs
@@ -11,8 +11,9 @@
 // Test that an object type `Box<Foo>` is not considered to implement the
 // trait `Foo`. Issue #5087.
 
+use std::marker::MarkerTrait;
 
-trait Foo {}
+trait Foo : MarkerTrait {}
 fn take_foo<F:Foo>(f: F) {}
 fn take_object(f: Box<Foo>) { take_foo(f); }
 //~^ ERROR the trait `Foo` is not implemented
diff --git a/src/test/compile-fail/object-lifetime-default-mybox.rs b/src/test/compile-fail/object-lifetime-default-mybox.rs
index c107c8d131d..23ddea4499a 100644
--- a/src/test/compile-fail/object-lifetime-default-mybox.rs
+++ b/src/test/compile-fail/object-lifetime-default-mybox.rs
@@ -37,7 +37,6 @@ fn load1<'a,'b>(a: &'a MyBox<SomeTrait>,
     a
       //~^ ERROR cannot infer
       //~| ERROR mismatched types
-      //~| ERROR mismatched types
 }
 
 fn main() {
diff --git a/src/test/compile-fail/object-safety-issue-22040.rs b/src/test/compile-fail/object-safety-issue-22040.rs
new file mode 100644
index 00000000000..edf32131b68
--- /dev/null
+++ b/src/test/compile-fail/object-safety-issue-22040.rs
@@ -0,0 +1,50 @@
+// Copyright 2015 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.
+
+// Regression test for #22040.
+
+use std::fmt::Debug;
+
+trait Expr: Debug + PartialEq {
+    fn print_element_count(&self);
+}
+
+//#[derive(PartialEq)]
+#[derive(Debug)]
+struct SExpr<'x> {
+    elements: Vec<Box<Expr+ 'x>>,
+}
+
+impl<'x> PartialEq for SExpr<'x> {
+    fn eq(&self, other:&SExpr<'x>) -> bool {
+        println!("L1: {} L2: {}", self.elements.len(), other.elements.len());
+        let result = self.elements.len() == other.elements.len();
+
+        println!("Got compare {}", result);
+        return result;
+    }
+}
+
+impl <'x> SExpr<'x> {
+    fn new() -> SExpr<'x> { return SExpr{elements: Vec::new(),}; }
+}
+
+impl <'x> Expr for SExpr<'x> {
+    fn print_element_count(&self) {
+        println!("element count: {}", self.elements.len());
+    }
+}
+
+fn main() {
+    let a: Box<Expr> = Box::new(SExpr::new()); //~ ERROR trait `Expr` is not object-safe
+    let b: Box<Expr> = Box::new(SExpr::new()); //~ ERROR trait `Expr` is not object-safe
+
+    assert_eq!(a , b);
+}
diff --git a/src/test/compile-fail/object-safety-no-static.rs b/src/test/compile-fail/object-safety-no-static.rs
index 6a010d49692..aae829ec7b5 100644
--- a/src/test/compile-fail/object-safety-no-static.rs
+++ b/src/test/compile-fail/object-safety-no-static.rs
@@ -11,7 +11,7 @@
 // Check that we correctly prevent users from making trait objects
 // from traits with static methods.
 
-trait Foo {
+trait Foo : ::std::marker::MarkerTrait {
     fn foo();
 }
 
diff --git a/src/test/compile-fail/object-safety-phantom-fn.rs b/src/test/compile-fail/object-safety-phantom-fn.rs
new file mode 100644
index 00000000000..1c95ee43d27
--- /dev/null
+++ b/src/test/compile-fail/object-safety-phantom-fn.rs
@@ -0,0 +1,34 @@
+// Copyright 2014 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.
+
+// Check that `Self` appearing in a phantom fn does not make a trait not object safe.
+
+#![feature(rustc_attrs)]
+#![allow(dead_code)]
+
+use std::marker::PhantomFn;
+
+trait Baz : PhantomFn<Self> {
+}
+
+trait Bar<T> : PhantomFn<(Self, T)> {
+}
+
+fn make_bar<T:Bar<u32>>(t: &T) -> &Bar<u32> {
+    t
+}
+
+fn make_baz<T:Baz>(t: &T) -> &Baz {
+    t
+}
+
+#[rustc_error]
+fn main() { //~ ERROR compilation successful
+}
diff --git a/src/test/compile-fail/object-safety-supertrait-mentions-Self.rs b/src/test/compile-fail/object-safety-supertrait-mentions-Self.rs
new file mode 100644
index 00000000000..d3f9dc73020
--- /dev/null
+++ b/src/test/compile-fail/object-safety-supertrait-mentions-Self.rs
@@ -0,0 +1,32 @@
+// Copyright 2014 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.
+
+// Check that we correctly prevent users from making trait objects
+// form traits that make use of `Self` in an argument or return position.
+
+trait Bar<T> {
+    fn bar(&self, x: &T);
+}
+
+trait Baz : Bar<Self> {
+}
+
+fn make_bar<T:Bar<u32>>(t: &T) -> &Bar<u32> {
+    t
+}
+
+fn make_baz<T:Baz>(t: &T) -> &Baz {
+    t
+        //~^ ERROR `Baz` is not object-safe
+        //~| NOTE the trait cannot use `Self` as a type parameter in the supertrait listing
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/on-unimplemented-bad-anno.rs b/src/test/compile-fail/on-unimplemented-bad-anno.rs
index dda534cc489..7538b1c85e5 100644
--- a/src/test/compile-fail/on-unimplemented-bad-anno.rs
+++ b/src/test/compile-fail/on-unimplemented-bad-anno.rs
@@ -13,8 +13,12 @@
 
 #![allow(unused)]
 
+use std::marker;
+
 #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}`"]
-trait Foo<Bar, Baz, Quux>{}
+trait Foo<Bar, Baz, Quux>
+    : marker::PhantomFn<(Self,Bar,Baz,Quux)>
+{}
 
 #[rustc_on_unimplemented="a collection of type `{Self}` cannot be built from an iterator over elements of type `{A}`"]
 trait MyFromIterator<A> {
@@ -23,15 +27,21 @@ trait MyFromIterator<A> {
 }
 
 #[rustc_on_unimplemented] //~ ERROR this attribute must have a value
-trait BadAnnotation1 {}
+trait BadAnnotation1
+    : marker::MarkerTrait
+{}
 
 #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{C}>`"]
 //~^ ERROR there is no type parameter C on trait BadAnnotation2
-trait BadAnnotation2<A,B> {}
+trait BadAnnotation2<A,B>
+    : marker::PhantomFn<(Self,A,B)>
+{}
 
 #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{}>`"]
 //~^ only named substitution parameters are allowed
-trait BadAnnotation3<A,B> {}
+trait BadAnnotation3<A,B>
+    : marker::PhantomFn<(Self,A,B)>
+{}
 
 pub fn main() {
 }
diff --git a/src/test/compile-fail/on-unimplemented.rs b/src/test/compile-fail/on-unimplemented.rs
index 7b406afcf1f..2447d086422 100644
--- a/src/test/compile-fail/on-unimplemented.rs
+++ b/src/test/compile-fail/on-unimplemented.rs
@@ -11,8 +11,12 @@
 
 #![feature(on_unimplemented)]
 
+use std::marker;
+
 #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}`"]
-trait Foo<Bar, Baz, Quux>{}
+trait Foo<Bar, Baz, Quux>
+    : marker::PhantomFn<(Self,Bar,Baz,Quux)>
+{}
 
 fn foobar<U: Clone, T: Foo<u8, U, u32>>() -> T {
 
diff --git a/src/test/compile-fail/orphan-check-diagnostics.rs b/src/test/compile-fail/orphan-check-diagnostics.rs
index ff5c101b917..8201565c331 100644
--- a/src/test/compile-fail/orphan-check-diagnostics.rs
+++ b/src/test/compile-fail/orphan-check-diagnostics.rs
@@ -15,7 +15,7 @@ extern crate orphan_check_diagnostics;
 
 use orphan_check_diagnostics::RemoteTrait;
 
-trait LocalTrait {}
+trait LocalTrait { fn dummy(&self) { } }
 
 impl<T> RemoteTrait for T where T: LocalTrait {}
 //~^ ERROR type parameter `T` must be used as the type parameter for some local type
diff --git a/src/test/compile-fail/priv-in-bad-locations.rs b/src/test/compile-fail/priv-in-bad-locations.rs
index db649ed0cc6..43d112b8aa0 100644
--- a/src/test/compile-fail/priv-in-bad-locations.rs
+++ b/src/test/compile-fail/priv-in-bad-locations.rs
@@ -14,7 +14,7 @@ pub extern {
 }
 
 trait A {
-    fn foo() {}
+    fn foo(&self) {}
 }
 
 struct B;
@@ -22,7 +22,7 @@ struct B;
 pub impl B {} //~ ERROR: unnecessary visibility
 
 pub impl A for B { //~ ERROR: unnecessary visibility
-    pub fn foo() {} //~ ERROR: unnecessary visibility
+    pub fn foo(&self) {} //~ ERROR: unnecessary visibility
 }
 
 pub fn main() {}
diff --git a/src/test/compile-fail/privacy-ns2.rs b/src/test/compile-fail/privacy-ns2.rs
index 7fe0574ab7d..67bb566ea68 100644
--- a/src/test/compile-fail/privacy-ns2.rs
+++ b/src/test/compile-fail/privacy-ns2.rs
@@ -17,7 +17,9 @@
 
 // public type, private value
 pub mod foo1 {
-    pub trait Bar {
+    use std::marker::MarkerTrait;
+
+    pub trait Bar : MarkerTrait {
     }
     pub struct Baz;
 
@@ -39,7 +41,7 @@ fn test_list1() {
 
 // private type, public value
 pub mod foo2 {
-    trait Bar {
+    trait Bar : ::std::marker::MarkerTrait {
     }
     pub struct Baz;
 
@@ -60,7 +62,7 @@ fn test_list2() {
 
 // neither public
 pub mod foo3 {
-    trait Bar {
+    trait Bar : ::std::marker::MarkerTrait {
     }
     pub struct Baz;
 
diff --git a/src/test/compile-fail/privacy1.rs b/src/test/compile-fail/privacy1.rs
index 7ebbcc2809a..1ae79adbad7 100644
--- a/src/test/compile-fail/privacy1.rs
+++ b/src/test/compile-fail/privacy1.rs
@@ -11,11 +11,15 @@
 #![feature(lang_items, start, no_std)]
 #![no_std] // makes debugging this test *a lot* easier (during resolve)
 
+#[lang="phantom_fn"]
+pub trait PhantomFn<A:?Sized,R:?Sized=()> { }
+impl<A:?Sized, R:?Sized, U:?Sized> PhantomFn<A,R> for U { }
+
 #[lang="sized"]
-pub trait Sized {}
+pub trait Sized : PhantomFn<Self> {}
 
 #[lang="copy"]
-pub trait Copy {}
+pub trait Copy : PhantomFn<Self> {}
 
 mod bar {
     // shouldn't bring in too much
diff --git a/src/test/compile-fail/privacy4.rs b/src/test/compile-fail/privacy4.rs
index bcb46663aa8..adce93af079 100644
--- a/src/test/compile-fail/privacy4.rs
+++ b/src/test/compile-fail/privacy4.rs
@@ -11,8 +11,12 @@
 #![feature(lang_items, start, no_std)]
 #![no_std] // makes debugging this test *a lot* easier (during resolve)
 
-#[lang = "sized"] pub trait Sized {}
-#[lang="copy"] pub trait Copy {}
+#[lang="phantom_fn"]
+pub trait PhantomFn<A:?Sized,R:?Sized=()> { }
+impl<A:?Sized, R:?Sized, U:?Sized> PhantomFn<A,R> for U { }
+
+#[lang = "sized"] pub trait Sized : PhantomFn<Self> {}
+#[lang="copy"] pub trait Copy : PhantomFn<Self> {}
 
 // Test to make sure that private items imported through globs remain private
 // when  they're used.
diff --git a/src/test/compile-fail/region-object-lifetime-in-coercion.rs b/src/test/compile-fail/region-object-lifetime-in-coercion.rs
index 20cc624ab19..2da414befd8 100644
--- a/src/test/compile-fail/region-object-lifetime-in-coercion.rs
+++ b/src/test/compile-fail/region-object-lifetime-in-coercion.rs
@@ -13,7 +13,7 @@
 
 #![feature(box_syntax)]
 
-trait Foo {}
+trait Foo : ::std::marker::MarkerTrait {}
 impl<'a> Foo for &'a [u8] {}
 
 fn a(v: &[u8]) -> Box<Foo + 'static> {
diff --git a/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs b/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs
index fa26c9c54c8..6aa0cc003ce 100644
--- a/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs
+++ b/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs
@@ -15,15 +15,12 @@
 
 #![allow(dead_code)]
 
-use std::mem::transmute;
-use std::ops::Deref;
+use std::marker::PhantomFn;
 
 ///////////////////////////////////////////////////////////////////////////
 
-pub trait TheTrait {
+pub trait TheTrait: PhantomFn<Self, Self> {
     type TheAssocType;
-
-    fn dummy(&self) { }
 }
 
 pub trait TheSubTrait : TheTrait {
diff --git a/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs b/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs
index 7d955065ff4..9736910d7b5 100644
--- a/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs
+++ b/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs
@@ -14,12 +14,12 @@
 #![allow(dead_code)]
 #![feature(rustc_attrs)]
 
+use std::marker::PhantomFn;
+
 ///////////////////////////////////////////////////////////////////////////
 
-pub trait TheTrait<'b> {
+pub trait TheTrait<'b> : PhantomFn<&'b Self,Self> {
     type TheAssocType;
-
-    fn dummy(&'b self) { }
 }
 
 pub struct TheType<'b> {
diff --git a/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs b/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs
index 6ee65fbdf91..da7546ce21c 100644
--- a/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs
+++ b/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs
@@ -15,15 +15,12 @@
 
 #![allow(dead_code)]
 
-use std::mem::transmute;
-use std::ops::Deref;
+use std::marker::PhantomFn;
 
 ///////////////////////////////////////////////////////////////////////////
 
-pub trait TheTrait {
+pub trait TheTrait: PhantomFn<Self, Self> {
     type TheAssocType;
-
-    fn dummy(&self) { }
 }
 
 pub struct TheType<'b> {
diff --git a/src/test/compile-fail/regions-assoc-type-outlives-container.rs b/src/test/compile-fail/regions-assoc-type-outlives-container.rs
index 49a0726fa3b..e1e72e6f56e 100644
--- a/src/test/compile-fail/regions-assoc-type-outlives-container.rs
+++ b/src/test/compile-fail/regions-assoc-type-outlives-container.rs
@@ -13,16 +13,14 @@
 // outlive the location in which the type appears. Issue #22246.
 
 #![allow(dead_code)]
+#![feature(rustc_attrs)]
 
-use std::mem::transmute;
-use std::ops::Deref;
+use std::marker::PhantomFn;
 
 ///////////////////////////////////////////////////////////////////////////
 
-pub trait TheTrait {
+pub trait TheTrait: PhantomFn<Self, Self> {
     type TheAssocType;
-
-    fn dummy(&self) { }
 }
 
 pub struct TheType<'b> {
diff --git a/src/test/compile-fail/regions-assoc-type-region-bound-in-trait-not-met.rs b/src/test/compile-fail/regions-assoc-type-region-bound-in-trait-not-met.rs
index f833361e3b5..f921eccef1f 100644
--- a/src/test/compile-fail/regions-assoc-type-region-bound-in-trait-not-met.rs
+++ b/src/test/compile-fail/regions-assoc-type-region-bound-in-trait-not-met.rs
@@ -11,7 +11,10 @@
 // Test that the compiler checks that arbitrary region bounds declared
 // in the trait must be satisfied on the impl. Issue #20890.
 
-trait Foo<'a> { type Value: 'a; }
+trait Foo<'a> {
+    type Value: 'a;
+    fn dummy(&'a self) { }
+}
 
 impl<'a> Foo<'a> for &'a i16 {
     // OK.
diff --git a/src/test/compile-fail/regions-assoc-type-static-bound-in-trait-not-met.rs b/src/test/compile-fail/regions-assoc-type-static-bound-in-trait-not-met.rs
index 0871d8b01f6..1cf83b8ac58 100644
--- a/src/test/compile-fail/regions-assoc-type-static-bound-in-trait-not-met.rs
+++ b/src/test/compile-fail/regions-assoc-type-static-bound-in-trait-not-met.rs
@@ -11,7 +11,10 @@
 // Test that the compiler checks that the 'static bound declared in
 // the trait must be satisfied on the impl. Issue #20890.
 
-trait Foo { type Value: 'static; }
+trait Foo {
+    type Value: 'static;
+    fn dummy(&self) { }
+}
 
 impl<'a> Foo for &'a i32 {
     //~^ ERROR cannot infer
diff --git a/src/test/compile-fail/regions-bound-missing-bound-in-impl.rs b/src/test/compile-fail/regions-bound-missing-bound-in-impl.rs
index a3c38dff6b0..278ccd3c119 100644
--- a/src/test/compile-fail/regions-bound-missing-bound-in-impl.rs
+++ b/src/test/compile-fail/regions-bound-missing-bound-in-impl.rs
@@ -21,10 +21,9 @@ pub trait Foo<'a, 't> {
     fn has_bound<'b:'a>(self, b: Inv<'b>);
     fn wrong_bound1<'b,'c,'d:'a+'b>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>);
     fn okay_bound<'b,'c,'d:'a+'b+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>);
-    fn another_bound<'x: 'a>(self, x: Inv<'x>);
+    fn another_bound<'x: 'a>(self, x: Inv<'x>, y: Inv<'t>);
 }
 
-
 impl<'a, 't> Foo<'a, 't> for &'a isize {
     fn no_bound<'b:'a>(self, b: Inv<'b>) {
         //~^ ERROR lifetime parameters or bounds on method `no_bound` do not match
@@ -51,7 +50,7 @@ impl<'a, 't> Foo<'a, 't> for &'a isize {
     fn okay_bound<'b,'c,'e:'b+'c>(self, b: Inv<'b>, c: Inv<'c>, e: Inv<'e>) {
     }
 
-    fn another_bound<'x: 't>(self, x: Inv<'x>) {}
+    fn another_bound<'x: 't>(self, x: Inv<'x>, y: Inv<'t>) {}
 }
 
 fn main() { }
diff --git a/src/test/compile-fail/regions-bounded-method-type-parameters-trait-bound.rs b/src/test/compile-fail/regions-bounded-method-type-parameters-trait-bound.rs
index 74c2c6e584b..f13d8a60894 100644
--- a/src/test/compile-fail/regions-bounded-method-type-parameters-trait-bound.rs
+++ b/src/test/compile-fail/regions-bounded-method-type-parameters-trait-bound.rs
@@ -8,16 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(lang_items, no_std)]
-#![no_std]
-
 // Check that explicit region bounds are allowed on the various
 // nominal types (but not on other types) and that they are type
 // checked.
 
-#[lang="sized"]
-trait Sized { }
-
 struct Inv<'a> { // invariant w/r/t 'a
     x: &'a mut &'a isize
 }
diff --git a/src/test/compile-fail/regions-close-associated-type-into-object.rs b/src/test/compile-fail/regions-close-associated-type-into-object.rs
index 8a03f36972d..979c1e997d0 100644
--- a/src/test/compile-fail/regions-close-associated-type-into-object.rs
+++ b/src/test/compile-fail/regions-close-associated-type-into-object.rs
@@ -10,7 +10,9 @@
 
 #![feature(box_syntax)]
 
-trait X {}
+use std::marker::MarkerTrait;
+
+trait X : MarkerTrait {}
 
 trait Iter {
     type Item: X;
diff --git a/src/test/compile-fail/regions-close-object-into-object-1.rs b/src/test/compile-fail/regions-close-object-into-object-1.rs
index 7a0e3cf4611..7bbce7dad53 100644
--- a/src/test/compile-fail/regions-close-object-into-object-1.rs
+++ b/src/test/compile-fail/regions-close-object-into-object-1.rs
@@ -11,13 +11,16 @@
 #![feature(box_syntax)]
 #![allow(warnings)]
 
-trait A<T> {}
+use std::marker::PhantomFn;
+
+trait A<T> : PhantomFn<(Self,T)> { }
 struct B<'a, T>(&'a (A<T>+'a));
 
-trait X {}
+trait X : ::std::marker::MarkerTrait {}
+
 impl<'a, T> X for B<'a, T> {}
 
-fn f<'a, T, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
+fn f<'a, T:'static, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
     box B(&*v) as Box<X> //~ ERROR `*v` does not live long enough
 }
 
diff --git a/src/test/compile-fail/regions-close-object-into-object-2.rs b/src/test/compile-fail/regions-close-object-into-object-2.rs
index 7861fb95fef..6de49020a6f 100644
--- a/src/test/compile-fail/regions-close-object-into-object-2.rs
+++ b/src/test/compile-fail/regions-close-object-into-object-2.rs
@@ -10,10 +10,12 @@
 
 #![feature(box_syntax)]
 
-trait A<T> {}
+use std::marker::PhantomFn;
+
+trait A<T> : PhantomFn<(Self,T)> { }
 struct B<'a, T>(&'a (A<T>+'a));
 
-trait X {}
+trait X : PhantomFn<Self> {}
 impl<'a, T> X for B<'a, T> {}
 
 fn g<'a, T: 'static>(v: Box<A<T>+'a>) -> Box<X+'static> {
diff --git a/src/test/compile-fail/regions-close-object-into-object-3.rs b/src/test/compile-fail/regions-close-object-into-object-3.rs
index 31354de2a27..e22d0c7d0a4 100644
--- a/src/test/compile-fail/regions-close-object-into-object-3.rs
+++ b/src/test/compile-fail/regions-close-object-into-object-3.rs
@@ -11,10 +11,12 @@
 #![feature(box_syntax)]
 #![allow(warnings)]
 
-trait A<T> {}
+use std::marker::PhantomFn;
+
+trait A<T> : PhantomFn<(Self,T)> {}
 struct B<'a, T>(&'a (A<T>+'a));
 
-trait X {}
+trait X : PhantomFn<Self> {}
 impl<'a, T> X for B<'a, T> {}
 
 fn h<'a, T, U>(v: Box<A<U>+'static>) -> Box<X+'static> {
diff --git a/src/test/compile-fail/regions-close-object-into-object-4.rs b/src/test/compile-fail/regions-close-object-into-object-4.rs
index c60975f97e1..147a575d38c 100644
--- a/src/test/compile-fail/regions-close-object-into-object-4.rs
+++ b/src/test/compile-fail/regions-close-object-into-object-4.rs
@@ -10,10 +10,12 @@
 
 #![feature(box_syntax)]
 
-trait A<T> {}
+use std::marker::PhantomFn;
+
+trait A<T> : PhantomFn<(Self,T)> {}
 struct B<'a, T>(&'a (A<T>+'a));
 
-trait X {}
+trait X : PhantomFn<Self> {}
 impl<'a, T> X for B<'a, T> {}
 
 fn i<'a, T, U>(v: Box<A<U>+'a>) -> Box<X+'static> {
diff --git a/src/test/compile-fail/regions-close-object-into-object-5.rs b/src/test/compile-fail/regions-close-object-into-object-5.rs
new file mode 100644
index 00000000000..bdc52eca2cb
--- /dev/null
+++ b/src/test/compile-fail/regions-close-object-into-object-5.rs
@@ -0,0 +1,30 @@
+// Copyright 2014 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.
+
+#![feature(box_syntax)]
+#![allow(warnings)]
+
+trait A<T>
+{
+    fn get(&self) -> T { panic!() }
+}
+
+struct B<'a, T>(&'a (A<T>+'a));
+
+trait X { fn foo(&self) {} }
+
+impl<'a, T> X for B<'a, T> {}
+
+fn f<'a, T, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
+    box B(&*v) as Box<X> //~ ERROR the parameter type `T` may not live long enough
+}
+
+fn main() {}
+
diff --git a/src/test/compile-fail/regions-close-over-borrowed-ref-in-obj.rs b/src/test/compile-fail/regions-close-over-borrowed-ref-in-obj.rs
index 25b8137d29c..2341d2397c9 100644
--- a/src/test/compile-fail/regions-close-over-borrowed-ref-in-obj.rs
+++ b/src/test/compile-fail/regions-close-over-borrowed-ref-in-obj.rs
@@ -10,7 +10,9 @@
 
 #![feature(box_syntax)]
 
-trait Foo { }
+use std::marker::MarkerTrait;
+
+trait Foo : MarkerTrait { }
 
 impl<'a> Foo for &'a isize { }
 
diff --git a/src/test/compile-fail/regions-close-param-into-object.rs b/src/test/compile-fail/regions-close-param-into-object.rs
index 74b36958c92..655ac6f66c9 100644
--- a/src/test/compile-fail/regions-close-param-into-object.rs
+++ b/src/test/compile-fail/regions-close-param-into-object.rs
@@ -10,7 +10,7 @@
 
 #![feature(box_syntax)]
 
-trait X {}
+trait X { fn foo(&self) {} }
 
 fn p1<T>(v: T) -> Box<X+'static>
     where T : X
diff --git a/src/test/compile-fail/regions-infer-contravariance-due-to-decl.rs b/src/test/compile-fail/regions-infer-contravariance-due-to-decl.rs
index 6c5e90a54de..b7ef19d1e3b 100644
--- a/src/test/compile-fail/regions-infer-contravariance-due-to-decl.rs
+++ b/src/test/compile-fail/regions-infer-contravariance-due-to-decl.rs
@@ -20,7 +20,7 @@ use std::marker;
 // Contravariant<'foo> <: Contravariant<'static> because
 // 'foo <= 'static
 struct Contravariant<'a> {
-    marker: marker::ContravariantLifetime<'a>
+    marker: marker::PhantomData<&'a()>
 }
 
 fn use_<'short,'long>(c: Contravariant<'short>,
diff --git a/src/test/compile-fail/regions-infer-covariance-due-to-decl.rs b/src/test/compile-fail/regions-infer-covariance-due-to-decl.rs
index d8e31fa1374..0d3d9dacbd6 100644
--- a/src/test/compile-fail/regions-infer-covariance-due-to-decl.rs
+++ b/src/test/compile-fail/regions-infer-covariance-due-to-decl.rs
@@ -17,7 +17,7 @@
 use std::marker;
 
 struct Covariant<'a> {
-    marker: marker::CovariantLifetime<'a>
+    marker: marker::PhantomData<fn(&'a ())>
 }
 
 fn use_<'short,'long>(c: Covariant<'long>,
diff --git a/src/test/compile-fail/regions-infer-invariance-due-to-decl.rs b/src/test/compile-fail/regions-infer-invariance-due-to-decl.rs
index e88c96de9e4..8c191fbd5bb 100644
--- a/src/test/compile-fail/regions-infer-invariance-due-to-decl.rs
+++ b/src/test/compile-fail/regions-infer-invariance-due-to-decl.rs
@@ -11,7 +11,7 @@
 use std::marker;
 
 struct invariant<'a> {
-    marker: marker::InvariantLifetime<'a>
+    marker: marker::PhantomData<*mut &'a()>
 }
 
 fn to_same_lifetime<'r>(b_isize: invariant<'r>) {
diff --git a/src/test/compile-fail/required-lang-item.rs b/src/test/compile-fail/required-lang-item.rs
index 7d252604883..1b749faf1b8 100644
--- a/src/test/compile-fail/required-lang-item.rs
+++ b/src/test/compile-fail/required-lang-item.rs
@@ -11,7 +11,11 @@
 #![feature(lang_items, no_std)]
 #![no_std]
 
-#[lang="sized"] pub trait Sized {}
+#[lang="phantom_fn"]
+pub trait PhantomFn<T:?Sized> { }
+impl<T:?Sized, U:?Sized> PhantomFn<T> for U { }
+
+#[lang="sized"] pub trait Sized : PhantomFn<Self> {}
 
 // error-pattern:requires `start` lang_item
 
diff --git a/src/test/compile-fail/shadowed-type-parameter.rs b/src/test/compile-fail/shadowed-type-parameter.rs
index 1a3d7821159..1f72db1e894 100644
--- a/src/test/compile-fail/shadowed-type-parameter.rs
+++ b/src/test/compile-fail/shadowed-type-parameter.rs
@@ -12,19 +12,21 @@
 
 #![feature(box_syntax)]
 
-struct Foo<T>;
+struct Foo<T>(T);
 
 impl<T> Foo<T> {
     fn shadow_in_method<T>(&self) {}
     //~^ ERROR type parameter `T` shadows another type parameter
 
     fn not_shadow_in_item<U>(&self) {
-        struct Bar<T, U>; // not a shadow, separate item
+        struct Bar<T, U>(T,U); // not a shadow, separate item
         fn foo<T, U>() {} // same
     }
 }
 
 trait Bar<T> {
+    fn dummy(&self) -> T;
+
     fn shadow_in_required<T>(&self);
     //~^ ERROR type parameter `T` shadows another type parameter
 
diff --git a/src/test/compile-fail/slice-1.rs b/src/test/compile-fail/slice-1.rs
index 23ad5b09950..3b992e3bcc3 100644
--- a/src/test/compile-fail/slice-1.rs
+++ b/src/test/compile-fail/slice-1.rs
@@ -9,14 +9,12 @@
 // except according to those terms.
 
 // Test slicing &expr[] is deprecated and gives a helpful error message.
-//
-// ignore-test
 
 struct Foo;
 
 fn main() {
     let x = Foo;
-    &x[]; //~ WARNING deprecated slicing syntax: `[]`
-          //~^ NOTE use `&expr[..]` to construct a slice of the whole of expr
-          //~^^ ERROR cannot index a value of type `Foo`
+    &x[];
+    //~^ WARN obsolete syntax
+    //~| ERROR cannot index
 }
diff --git a/src/test/compile-fail/slightly-nice-generic-literal-messages.rs b/src/test/compile-fail/slightly-nice-generic-literal-messages.rs
index 1203d622348..3c1c3796a24 100644
--- a/src/test/compile-fail/slightly-nice-generic-literal-messages.rs
+++ b/src/test/compile-fail/slightly-nice-generic-literal-messages.rs
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Foo<T,U>(T);
+use std::marker;
+
+struct Foo<T,U>(T, marker::PhantomData<U>);
 
 fn main() {
-    match Foo(1.1) {
+    match Foo(1.1, marker::PhantomData) {
         1 => {}
     //~^ ERROR mismatched types
     //~| expected `Foo<_, _>`
diff --git a/src/test/compile-fail/staticness-mismatch.rs b/src/test/compile-fail/staticness-mismatch.rs
index bf4e46cace3..2dfc9b79ee2 100644
--- a/src/test/compile-fail/staticness-mismatch.rs
+++ b/src/test/compile-fail/staticness-mismatch.rs
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
 trait foo {
+    fn dummy(&self) { }
     fn bar();
 }
 
diff --git a/src/test/compile-fail/trait-as-struct-constructor.rs b/src/test/compile-fail/trait-as-struct-constructor.rs
index a1fcab002e1..fff14414094 100644
--- a/src/test/compile-fail/trait-as-struct-constructor.rs
+++ b/src/test/compile-fail/trait-as-struct-constructor.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait TraitNotAStruct { }
+trait TraitNotAStruct : ::std::marker::MarkerTrait { }
 
 fn main() {
     TraitNotAStruct{ value: 0 };
diff --git a/src/test/compile-fail/trait-bounds-cant-coerce.rs b/src/test/compile-fail/trait-bounds-cant-coerce.rs
index 79174552ae0..3129dceffbb 100644
--- a/src/test/compile-fail/trait-bounds-cant-coerce.rs
+++ b/src/test/compile-fail/trait-bounds-cant-coerce.rs
@@ -10,6 +10,7 @@
 
 
 trait Foo {
+    fn dummy(&self) { }
 }
 
 fn a(_x: Box<Foo+Send>) {
diff --git a/src/test/compile-fail/trait-bounds-impl-comparison-1.rs b/src/test/compile-fail/trait-bounds-impl-comparison-1.rs
index 477bd4f5be9..34e06cc9365 100644
--- a/src/test/compile-fail/trait-bounds-impl-comparison-1.rs
+++ b/src/test/compile-fail/trait-bounds-impl-comparison-1.rs
@@ -11,7 +11,10 @@
 // Make sure rustc checks the type parameter bounds in implementations of traits,
 // see #2687
 
-trait A {}
+use std::marker;
+
+trait A : marker::PhantomFn<Self> {
+}
 
 trait B: A {}
 
@@ -62,15 +65,16 @@ impl Foo for isize {
     //~^ ERROR the requirement `T : C` appears on the impl
 }
 
-
-trait Getter<T> { }
+trait Getter<T> {
+    fn get(&self) -> T { loop { } }
+}
 
 trait Trait {
-    fn method<G:Getter<isize>>();
+    fn method<G:Getter<isize>>(&self);
 }
 
 impl Trait for usize {
-    fn method<G: Getter<usize>>() {}
+    fn method<G: Getter<usize>>(&self) {}
     //~^ G : Getter<usize>` appears on the impl method but not on the corresponding trait method
 }
 
diff --git a/src/test/compile-fail/trait-bounds-impl-comparison-2.rs b/src/test/compile-fail/trait-bounds-impl-comparison-2.rs
index 8ad19116e7b..284c4fac953 100644
--- a/src/test/compile-fail/trait-bounds-impl-comparison-2.rs
+++ b/src/test/compile-fail/trait-bounds-impl-comparison-2.rs
@@ -14,7 +14,9 @@ trait Iterator<A> {
     fn next(&mut self) -> Option<A>;
 }
 
-trait IteratorUtil<A> {
+trait IteratorUtil<A>
+    : ::std::marker::PhantomFn<(),A>
+{
     fn zip<B, U: Iterator<U>>(self, other: U) -> ZipIterator<Self, U>;
 }
 
diff --git a/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs b/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs
index 434d803d718..448b186f6a5 100644
--- a/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs
+++ b/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 trait Foo {
+    fn dummy(&self) { }
 }
 
 // This should emit the less confusing error, not the more confusing one.
diff --git a/src/test/compile-fail/trait-bounds-on-structs-and-enums-locals.rs b/src/test/compile-fail/trait-bounds-on-structs-and-enums-locals.rs
index 118dfeb37c2..df44e847c50 100644
--- a/src/test/compile-fail/trait-bounds-on-structs-and-enums-locals.rs
+++ b/src/test/compile-fail/trait-bounds-on-structs-and-enums-locals.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Trait {}
+trait Trait {
+    fn dummy(&self) { }
+}
 
 struct Foo<T:Trait> {
     x: T,
diff --git a/src/test/compile-fail/trait-bounds-on-structs-and-enums-static.rs b/src/test/compile-fail/trait-bounds-on-structs-and-enums-static.rs
index d5369817e9a..18871d0d386 100644
--- a/src/test/compile-fail/trait-bounds-on-structs-and-enums-static.rs
+++ b/src/test/compile-fail/trait-bounds-on-structs-and-enums-static.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Trait {}
+trait Trait {
+    fn dummy(&self) { }
+}
 
 struct Foo<T:Trait> {
     x: T,
diff --git a/src/test/compile-fail/trait-bounds-on-structs-and-enums.rs b/src/test/compile-fail/trait-bounds-on-structs-and-enums.rs
index 490ee0e8ad6..8dfdb2f205d 100644
--- a/src/test/compile-fail/trait-bounds-on-structs-and-enums.rs
+++ b/src/test/compile-fail/trait-bounds-on-structs-and-enums.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Trait {}
+use std::marker::MarkerTrait;
+
+trait Trait : MarkerTrait {}
 
 struct Foo<T:Trait> {
     x: T,
@@ -51,15 +53,15 @@ enum MoreBadness<V> {
     EvenMoreBadness(Bar<V>),
 }
 
-trait PolyTrait<T> {
-    fn whatever() {}
+trait PolyTrait<T>
+{
+    fn whatever(&self, t: T) {}
 }
 
 struct Struct;
 
 impl PolyTrait<Foo<usize>> for Struct {
 //~^ ERROR not implemented
-    fn whatever() {}
 }
 
 fn main() {
diff --git a/src/test/compile-fail/trait-bounds-sugar.rs b/src/test/compile-fail/trait-bounds-sugar.rs
index 3d264e681a3..e4058a0943a 100644
--- a/src/test/compile-fail/trait-bounds-sugar.rs
+++ b/src/test/compile-fail/trait-bounds-sugar.rs
@@ -10,8 +10,9 @@
 
 // Tests for "default" bounds inferred for traits with no bounds list.
 
+use std::marker::MarkerTrait;
 
-trait Foo {}
+trait Foo : MarkerTrait {}
 
 fn a(_x: Box<Foo+Send>) {
 }
diff --git a/src/test/compile-fail/trait-impl-1.rs b/src/test/compile-fail/trait-impl-1.rs
index dadcbd5bce7..2f4793b4d88 100644
--- a/src/test/compile-fail/trait-impl-1.rs
+++ b/src/test/compile-fail/trait-impl-1.rs
@@ -12,7 +12,9 @@
 // trait impl is only applied to a trait object, not concrete types which implement
 // the trait.
 
-trait T {}
+use std::marker::MarkerTrait;
+
+trait T : MarkerTrait {}
 
 impl<'a> T+'a {
     fn foo(&self) {}
diff --git a/src/test/compile-fail/trait-object-safety.rs b/src/test/compile-fail/trait-object-safety.rs
index 761bcd4968a..d45d13556e1 100644
--- a/src/test/compile-fail/trait-object-safety.rs
+++ b/src/test/compile-fail/trait-object-safety.rs
@@ -12,6 +12,7 @@
 
 trait Tr {
     fn foo();
+    fn bar(&self) { }
 }
 
 struct St;
diff --git a/src/test/compile-fail/trait-static-method-generic-inference.rs b/src/test/compile-fail/trait-static-method-generic-inference.rs
index 651f663fc99..0e357d9d4d5 100644
--- a/src/test/compile-fail/trait-static-method-generic-inference.rs
+++ b/src/test/compile-fail/trait-static-method-generic-inference.rs
@@ -16,6 +16,7 @@
 mod base {
     pub trait HasNew<T> {
         fn new() -> T;
+        fn dummy(&self) { }
     }
 
     pub struct Foo {
diff --git a/src/test/compile-fail/type-parameter-defaults-referencing-Self-ppaux.rs b/src/test/compile-fail/type-parameter-defaults-referencing-Self-ppaux.rs
new file mode 100644
index 00000000000..8ff514e04e3
--- /dev/null
+++ b/src/test/compile-fail/type-parameter-defaults-referencing-Self-ppaux.rs
@@ -0,0 +1,26 @@
+// Copyright 2015 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.
+
+// Test a default that references `Self` which is then used in an
+// object type. Issue #18956. In this case, the value is supplied by
+// the user, but pretty-printing the type during the error message
+// caused an ICE.
+
+trait MyAdd<Rhs=Self> { fn add(&self, other: &Rhs) -> Self; }
+
+impl MyAdd for i32 {
+    fn add(&self, other: &i32) -> i32 { *self + *other }
+}
+
+fn main() {
+    let x = 5;
+    let y = x as MyAdd<i32>;
+    //~^ ERROR as `MyAdd<i32>`
+}
diff --git a/src/test/compile-fail/type-parameter-defaults-referencing-Self.rs b/src/test/compile-fail/type-parameter-defaults-referencing-Self.rs
new file mode 100644
index 00000000000..9982d485024
--- /dev/null
+++ b/src/test/compile-fail/type-parameter-defaults-referencing-Self.rs
@@ -0,0 +1,23 @@
+// Copyright 2015 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.
+
+// Test a default that references `Self` which is then used in an object type.
+// Issue #18956.
+
+#![feature(default_type_params)]
+
+trait Foo<T=Self> {
+    fn method(&self);
+}
+
+fn foo(x: &Foo) { }
+//~^ ERROR the type parameter `T` must be explicitly specified
+
+fn main() { }
diff --git a/src/test/compile-fail/typeck-negative-impls-builtin.rs b/src/test/compile-fail/typeck-negative-impls-builtin.rs
index 9da79b11cf0..557fb2f4f88 100644
--- a/src/test/compile-fail/typeck-negative-impls-builtin.rs
+++ b/src/test/compile-fail/typeck-negative-impls-builtin.rs
@@ -12,7 +12,9 @@
 
 struct TestType;
 
-trait TestTrait {}
+trait TestTrait {
+    fn dummy(&self) { }
+}
 
 impl !TestTrait for TestType {}
 //~^ ERROR  negative impls are currently allowed just for `Send` and `Sync`
diff --git a/src/test/compile-fail/typeck_type_placeholder_mismatch.rs b/src/test/compile-fail/typeck_type_placeholder_mismatch.rs
index a34be63ba6b..1daea8f915b 100644
--- a/src/test/compile-fail/typeck_type_placeholder_mismatch.rs
+++ b/src/test/compile-fail/typeck_type_placeholder_mismatch.rs
@@ -11,14 +11,16 @@
 // This test checks that genuine type errors with partial
 // type hints are understandable.
 
-struct Foo<T>;
-struct Bar<U>;
+use std::marker::PhantomData;
+
+struct Foo<T>(PhantomData<T>);
+struct Bar<U>(PhantomData<U>);
 
 pub fn main() {
 }
 
 fn test1() {
-    let x: Foo<_> = Bar::<usize>;
+    let x: Foo<_> = Bar::<usize>(PhantomData);
     //~^ ERROR mismatched types
     //~| expected `Foo<_>`
     //~| found `Bar<usize>`
@@ -28,7 +30,7 @@ fn test1() {
 }
 
 fn test2() {
-    let x: Foo<_> = Bar::<usize>;
+    let x: Foo<_> = Bar::<usize>(PhantomData);
     //~^ ERROR mismatched types
     //~| expected `Foo<_>`
     //~| found `Bar<usize>`
diff --git a/src/test/compile-fail/ufcs-qpath-missing-params.rs b/src/test/compile-fail/ufcs-qpath-missing-params.rs
index 5fa66eb98e1..f4e18265fd9 100644
--- a/src/test/compile-fail/ufcs-qpath-missing-params.rs
+++ b/src/test/compile-fail/ufcs-qpath-missing-params.rs
@@ -12,6 +12,5 @@ use std::borrow::IntoCow;
 
 fn main() {
     <String as IntoCow>::into_cow("foo".to_string());
-    //~^ ERROR wrong number of type arguments: expected 2, found 0
+    //~^ ERROR wrong number of type arguments: expected 1, found 0
 }
-
diff --git a/src/test/compile-fail/unboxed-closure-feature-gate.rs b/src/test/compile-fail/unboxed-closure-feature-gate.rs
index 3536244f011..74a6f869f63 100644
--- a/src/test/compile-fail/unboxed-closure-feature-gate.rs
+++ b/src/test/compile-fail/unboxed-closure-feature-gate.rs
@@ -11,8 +11,12 @@
 // Check that parenthetical notation is feature-gated except with the
 // `Fn` traits.
 
+use std::marker;
+
 trait Foo<A> {
     type Output;
+
+    fn dummy(&self, a: A) { }
 }
 
 fn main() {
diff --git a/src/test/compile-fail/unboxed-closure-sugar-default.rs b/src/test/compile-fail/unboxed-closure-sugar-default.rs
index 870377bc1ad..831db98941c 100644
--- a/src/test/compile-fail/unboxed-closure-sugar-default.rs
+++ b/src/test/compile-fail/unboxed-closure-sugar-default.rs
@@ -19,7 +19,7 @@ trait Foo<T,V=T> {
     fn dummy(&self, t: T, v: V);
 }
 
-trait Eq<X: ?Sized> { }
+trait Eq<X: ?Sized> { fn same_types(&self, x: &X) -> bool { true } }
 impl<X: ?Sized> Eq<X> for X { }
 fn eq<A: ?Sized,B: ?Sized>() where A : Eq<B> { }
 
diff --git a/src/test/compile-fail/unboxed-closure-sugar-equiv.rs b/src/test/compile-fail/unboxed-closure-sugar-equiv.rs
index dc5576aee65..6d315c1b7a9 100644
--- a/src/test/compile-fail/unboxed-closure-sugar-equiv.rs
+++ b/src/test/compile-fail/unboxed-closure-sugar-equiv.rs
@@ -16,12 +16,14 @@
 #![feature(unboxed_closures)]
 #![allow(dead_code)]
 
+use std::marker::PhantomFn;
+
 trait Foo<T> {
     type Output;
     fn dummy(&self, t: T, u: Self::Output);
 }
 
-trait Eq<X: ?Sized> { }
+trait Eq<X: ?Sized> : PhantomFn<(Self,X)> { }
 impl<X: ?Sized> Eq<X> for X { }
 fn eq<A: ?Sized,B: ?Sized +Eq<A>>() { }
 
diff --git a/src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs b/src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs
index d2f781bba11..bd3530e6e30 100644
--- a/src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs
+++ b/src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs
@@ -16,12 +16,14 @@
 #![feature(unboxed_closures)]
 #![allow(dead_code)]
 
+use std::marker;
+
 trait Foo<T> {
     type Output;
     fn dummy(&self, t: T);
 }
 
-trait Eq<X: ?Sized> { }
+trait Eq<X: ?Sized> : marker::PhantomFn<(Self, X)> { }
 impl<X: ?Sized> Eq<X> for X { }
 fn eq<A: ?Sized,B: ?Sized +Eq<A>>() { }
 
diff --git a/src/test/compile-fail/unboxed-closure-sugar-region.rs b/src/test/compile-fail/unboxed-closure-sugar-region.rs
index 75688e44e80..057b496bd43 100644
--- a/src/test/compile-fail/unboxed-closure-sugar-region.rs
+++ b/src/test/compile-fail/unboxed-closure-sugar-region.rs
@@ -22,7 +22,7 @@ trait Foo<'a,T> {
     fn dummy(&'a self) -> &'a (T,Self::Output);
 }
 
-trait Eq<X: ?Sized> { }
+trait Eq<X: ?Sized> { fn is_of_eq_type(&self, x: &X) -> bool { true } }
 impl<X: ?Sized> Eq<X> for X { }
 fn eq<A: ?Sized,B: ?Sized +Eq<A>>() { }
 
diff --git a/src/test/compile-fail/unboxed-closures-recursive-fn-using-fn-mut.rs b/src/test/compile-fail/unboxed-closures-recursive-fn-using-fn-mut.rs
index 215b2c6798e..713b64b1349 100644
--- a/src/test/compile-fail/unboxed-closures-recursive-fn-using-fn-mut.rs
+++ b/src/test/compile-fail/unboxed-closures-recursive-fn-using-fn-mut.rs
@@ -10,7 +10,7 @@
 
 #![feature(core,unboxed_closures)]
 
-use std::marker::CovariantType;
+use std::marker::PhantomData;
 
 // A erroneous variant of `run-pass/unboxed_closures-infer-recursive-fn.rs`
 // where we attempt to perform mutation in the recursive function. This fails to compile
@@ -18,12 +18,12 @@ use std::marker::CovariantType;
 
 struct YCombinator<F,A,R> {
     func: F,
-    marker: CovariantType<(A,R)>,
+    marker: PhantomData<(A,R)>,
 }
 
 impl<F,A,R> YCombinator<F,A,R> {
     fn new(f: F) -> YCombinator<F,A,R> {
-        YCombinator { func: f, marker: CovariantType }
+        YCombinator { func: f, marker: PhantomData }
     }
 }
 
diff --git a/src/test/compile-fail/unnecessary-private.rs b/src/test/compile-fail/unnecessary-private.rs
index e3707292f24..964db6e9a45 100644
--- a/src/test/compile-fail/unnecessary-private.rs
+++ b/src/test/compile-fail/unnecessary-private.rs
@@ -13,10 +13,10 @@ fn main() {
     pub struct A; //~ ERROR: visibility has no effect
     pub enum B {} //~ ERROR: visibility has no effect
     pub trait C { //~ ERROR: visibility has no effect
-        pub fn foo() {} //~ ERROR: visibility has no effect
+        pub fn foo(&self) {} //~ ERROR: visibility has no effect
     }
     impl A {
-        pub fn foo() {} //~ ERROR: visibility has no effect
+        pub fn foo(&self) {} //~ ERROR: visibility has no effect
     }
 
     struct D {
diff --git a/src/test/compile-fail/unsized-inherent-impl-self-type.rs b/src/test/compile-fail/unsized-inherent-impl-self-type.rs
index 8740346a217..a03c76b12dd 100644
--- a/src/test/compile-fail/unsized-inherent-impl-self-type.rs
+++ b/src/test/compile-fail/unsized-inherent-impl-self-type.rs
@@ -12,7 +12,7 @@
 
 // impl - struct
 
-struct S5<Y>;
+struct S5<Y>(Y);
 
 impl<X: ?Sized> S5<X> { //~ ERROR not implemented
 }
diff --git a/src/test/compile-fail/unsized-trait-impl-self-type.rs b/src/test/compile-fail/unsized-trait-impl-self-type.rs
index 3dd55b0ba7d..08df1d9b7b8 100644
--- a/src/test/compile-fail/unsized-trait-impl-self-type.rs
+++ b/src/test/compile-fail/unsized-trait-impl-self-type.rs
@@ -12,9 +12,10 @@
 
 // impl - struct
 trait T3<Z: ?Sized> {
+    fn foo(&self, z: &Z);
 }
 
-struct S5<Y>;
+struct S5<Y>(Y);
 
 impl<X: ?Sized> T3<X> for S5<X> { //~ ERROR not implemented
 }
diff --git a/src/test/compile-fail/unsized-trait-impl-trait-arg.rs b/src/test/compile-fail/unsized-trait-impl-trait-arg.rs
index ac8043d6852..4723dfeaeb9 100644
--- a/src/test/compile-fail/unsized-trait-impl-trait-arg.rs
+++ b/src/test/compile-fail/unsized-trait-impl-trait-arg.rs
@@ -12,8 +12,9 @@
 
 // impl - unbounded
 trait T2<Z> {
+    fn foo(&self, z: Z);
 }
-struct S4<Y: ?Sized>;
+struct S4<Y: ?Sized>(Box<Y>);
 impl<X: ?Sized> T2<X> for S4<X> {
     //~^ ERROR `core::marker::Sized` is not implemented for the type `X`
 }
diff --git a/src/test/compile-fail/unsized3.rs b/src/test/compile-fail/unsized3.rs
index 4fc76c99c60..de1cbab82b2 100644
--- a/src/test/compile-fail/unsized3.rs
+++ b/src/test/compile-fail/unsized3.rs
@@ -10,6 +10,7 @@
 
 // Test sized-ness checking in substitution within fn bodies..
 
+use std::marker;
 
 // Unbounded.
 fn f1<X: ?Sized>(x: &X) {
@@ -20,7 +21,9 @@ fn f2<X>(x: &X) {
 }
 
 // Bounded.
-trait T {}
+trait T {
+    fn foo(&self) { }
+}
 fn f3<X: ?Sized + T>(x: &X) {
     f4::<X>(x);
     //~^ ERROR the trait `core::marker::Sized` is not implemented
diff --git a/src/test/compile-fail/unsized6.rs b/src/test/compile-fail/unsized6.rs
index 217d1f44d84..f31a6ffdc0d 100644
--- a/src/test/compile-fail/unsized6.rs
+++ b/src/test/compile-fail/unsized6.rs
@@ -10,8 +10,9 @@
 
 // Test `?Sized` local variables.
 
+use std::marker;
 
-trait T {}
+trait T : marker::MarkerTrait { }
 
 fn f1<X: ?Sized>(x: &X) {
     let _: X; // <-- this is OK, no bindings created, no initializer.
diff --git a/src/test/compile-fail/unsized7.rs b/src/test/compile-fail/unsized7.rs
index 6fc547c0b8e..6ea3d0720ee 100644
--- a/src/test/compile-fail/unsized7.rs
+++ b/src/test/compile-fail/unsized7.rs
@@ -10,13 +10,17 @@
 
 // Test sized-ness checking in substitution in impls.
 
-trait T {}
+use std::marker::MarkerTrait;
+
+trait T : MarkerTrait {}
 
 // I would like these to fail eventually.
 // impl - bounded
 trait T1<Z: T> {
+    fn dummy(&self) -> Z;
 }
-struct S3<Y: ?Sized>;
+
+struct S3<Y: ?Sized>(Box<Y>);
 impl<X: ?Sized + T> T1<X> for S3<X> {
     //~^ ERROR `core::marker::Sized` is not implemented for the type `X`
 }
diff --git a/src/test/compile-fail/unused-attr.rs b/src/test/compile-fail/unused-attr.rs
index 2d4bc0c857a..af242b96a84 100644
--- a/src/test/compile-fail/unused-attr.rs
+++ b/src/test/compile-fail/unused-attr.rs
@@ -52,9 +52,9 @@ struct Foo {
 #[foo] //~ ERROR unused attribute
 trait Baz {
     #[foo] //~ ERROR unused attribute
-    fn blah();
+    fn blah(&self);
     #[foo] //~ ERROR unused attribute
-    fn blah2() {}
+    fn blah2(&self) {}
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/useless-priv.rs b/src/test/compile-fail/useless-priv.rs
index d8531f4543d..b1120e54434 100644
--- a/src/test/compile-fail/useless-priv.rs
+++ b/src/test/compile-fail/useless-priv.rs
@@ -12,12 +12,14 @@ struct A { pub i: isize }
 pub enum C { pub Variant }      //~ ERROR: unnecessary `pub`
 
 pub trait E {
-    pub fn foo() {}             //~ ERROR: unnecessary visibility
+    pub fn foo(&self) {}         //~ ERROR: unnecessary visibility
+}
+trait F {
+    pub fn foo(&self) {}     //~ ERROR: unnecessary visibility
 }
-trait F { pub fn foo() {} }     //~ ERROR: unnecessary visibility
 
 impl E for A {
-    pub fn foo() {}             //~ ERROR: unnecessary visibility
+    pub fn foo(&self) {}             //~ ERROR: unnecessary visibility
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/useless-priv2.rs b/src/test/compile-fail/useless-priv2.rs
index 7125a66b294..a404d09248f 100644
--- a/src/test/compile-fail/useless-priv2.rs
+++ b/src/test/compile-fail/useless-priv2.rs
@@ -9,8 +9,10 @@
 // except according to those terms.
 
 pub trait E {
-    pub fn foo();               //~ ERROR: unnecessary visibility
+    pub fn foo(&self);               //~ ERROR: unnecessary visibility
+}
+trait F {
+    pub fn foo(&self);               //~ ERROR: unnecessary visibility
 }
-trait F { pub fn foo(); }       //~ ERROR: unnecessary visibility
 
 fn main() {}
diff --git a/src/test/compile-fail/variance-contravariant-arg-object.rs b/src/test/compile-fail/variance-contravariant-arg-object.rs
new file mode 100644
index 00000000000..3330e1d0d51
--- /dev/null
+++ b/src/test/compile-fail/variance-contravariant-arg-object.rs
@@ -0,0 +1,31 @@
+// Copyright 2015 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.
+
+#![allow(dead_code)]
+
+trait Get<T> : 'static {
+    fn get(&self, t: T);
+}
+
+fn get_min_from_max<'min, 'max>(v: Box<Get<&'max i32>>)
+                                -> Box<Get<&'min i32>>
+    where 'max : 'min
+{
+    v //~ ERROR mismatched types
+}
+
+fn get_max_from_min<'min, 'max, G>(v: Box<Get<&'min i32>>)
+                                   -> Box<Get<&'max i32>>
+    where 'max : 'min
+{
+    v
+}
+
+fn main() { }
diff --git a/src/test/compile-fail/variance-contravariant-arg-trait-match.rs b/src/test/compile-fail/variance-contravariant-arg-trait-match.rs
new file mode 100644
index 00000000000..caaad4014ad
--- /dev/null
+++ b/src/test/compile-fail/variance-contravariant-arg-trait-match.rs
@@ -0,0 +1,31 @@
+// Copyright 2015 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.
+
+#![allow(dead_code)]
+
+trait Get<T> {
+    fn get(&self, t: T);
+}
+
+fn get_min_from_max<'min, 'max, G>()
+    where 'max : 'min, G : Get<&'max i32>
+{
+    impls_get::<G,&'min i32>() //~ ERROR mismatched types
+}
+
+fn get_max_from_min<'min, 'max, G>()
+    where 'max : 'min, G : Get<&'min i32>
+{
+    impls_get::<G,&'max i32>()
+}
+
+fn impls_get<G,T>() where G : Get<T> { }
+
+fn main() { }
diff --git a/src/test/compile-fail/variance-contravariant-self-trait-match.rs b/src/test/compile-fail/variance-contravariant-self-trait-match.rs
new file mode 100644
index 00000000000..013511ed517
--- /dev/null
+++ b/src/test/compile-fail/variance-contravariant-self-trait-match.rs
@@ -0,0 +1,31 @@
+// Copyright 2015 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.
+
+#![allow(dead_code)]
+
+trait Get {
+    fn get(&self);
+}
+
+fn get_min_from_max<'min, 'max, G>()
+    where 'max : 'min, G : 'max, &'max G : Get
+{
+    impls_get::<&'min G>(); //~ ERROR mismatched types
+}
+
+fn get_max_from_min<'min, 'max, G>()
+    where 'max : 'min, G : 'max, &'min G : Get
+{
+    impls_get::<&'max G>();
+}
+
+fn impls_get<G>() where G : Get { }
+
+fn main() { }
diff --git a/src/test/compile-fail/variance-covariant-arg-object.rs b/src/test/compile-fail/variance-covariant-arg-object.rs
new file mode 100644
index 00000000000..828c987c082
--- /dev/null
+++ b/src/test/compile-fail/variance-covariant-arg-object.rs
@@ -0,0 +1,31 @@
+// Copyright 2015 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.
+
+#![allow(dead_code)]
+
+trait Get<T> : 'static {
+    fn get(&self) -> T;
+}
+
+fn get_min_from_max<'min, 'max>(v: Box<Get<&'max i32>>)
+                                -> Box<Get<&'min i32>>
+    where 'max : 'min
+{
+    v
+}
+
+fn get_max_from_min<'min, 'max, G>(v: Box<Get<&'min i32>>)
+                                   -> Box<Get<&'max i32>>
+    where 'max : 'min
+{
+    v //~ ERROR mismatched types
+}
+
+fn main() { }
diff --git a/src/test/compile-fail/variance-covariant-arg-trait-match.rs b/src/test/compile-fail/variance-covariant-arg-trait-match.rs
new file mode 100644
index 00000000000..17761b9c0b1
--- /dev/null
+++ b/src/test/compile-fail/variance-covariant-arg-trait-match.rs
@@ -0,0 +1,31 @@
+// Copyright 2015 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.
+
+#![allow(dead_code)]
+
+trait Get<T> {
+    fn get(&self) -> T;
+}
+
+fn get_min_from_max<'min, 'max, G>()
+    where 'max : 'min, G : Get<&'max i32>
+{
+    impls_get::<G,&'min i32>()
+}
+
+fn get_max_from_min<'min, 'max, G>()
+    where 'max : 'min, G : Get<&'min i32>
+{
+    impls_get::<G,&'max i32>() //~ ERROR mismatched types
+}
+
+fn impls_get<G,T>() where G : Get<T> { }
+
+fn main() { }
diff --git a/src/test/compile-fail/variance-covariant-self-trait-match.rs b/src/test/compile-fail/variance-covariant-self-trait-match.rs
new file mode 100644
index 00000000000..4e94a3eeb46
--- /dev/null
+++ b/src/test/compile-fail/variance-covariant-self-trait-match.rs
@@ -0,0 +1,31 @@
+// Copyright 2015 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.
+
+#![allow(dead_code)]
+
+trait Get {
+    fn get() -> Self;
+}
+
+fn get_min_from_max<'min, 'max, G>()
+    where 'max : 'min, G : 'max, &'max G : Get
+{
+    impls_get::<&'min G>();
+}
+
+fn get_max_from_min<'min, 'max, G>()
+    where 'max : 'min, G : 'max, &'min G : Get
+{
+    impls_get::<&'max G>(); //~ ERROR mismatched types
+}
+
+fn impls_get<G>() where G : Get { }
+
+fn main() { }
diff --git a/src/test/compile-fail/variance-deprecated-markers.rs b/src/test/compile-fail/variance-deprecated-markers.rs
new file mode 100644
index 00000000000..8f9d24cb132
--- /dev/null
+++ b/src/test/compile-fail/variance-deprecated-markers.rs
@@ -0,0 +1,35 @@
+// Copyright 2015 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.
+
+// Test that the deprecated markers still have their old effect.
+
+#![feature(rustc_attrs)]
+
+use std::marker;
+
+#[rustc_variance]
+struct A<T>(marker::CovariantType<T>); //~ ERROR types=[[+];[];[]]
+
+#[rustc_variance]
+struct B<T>(marker::ContravariantType<T>); //~ ERROR types=[[-];[];[]]
+
+#[rustc_variance]
+struct C<T>(marker::InvariantType<T>); //~ ERROR types=[[o];[];[]]
+
+#[rustc_variance]
+struct D<'a>(marker::CovariantLifetime<'a>); //~ ERROR regions=[[+];[];[]]
+
+#[rustc_variance]
+struct E<'a>(marker::ContravariantLifetime<'a>); //~ ERROR regions=[[-];[];[]]
+
+#[rustc_variance]
+struct F<'a>(marker::InvariantLifetime<'a>); //~ ERROR regions=[[o];[];[]]
+
+fn main() { }
diff --git a/src/test/compile-fail/variance-invariant-arg-object.rs b/src/test/compile-fail/variance-invariant-arg-object.rs
new file mode 100644
index 00000000000..9edb510b826
--- /dev/null
+++ b/src/test/compile-fail/variance-invariant-arg-object.rs
@@ -0,0 +1,31 @@
+// Copyright 2015 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.
+
+#![allow(dead_code)]
+
+trait Get<T> : 'static {
+    fn get(&self, t: T) -> T;
+}
+
+fn get_min_from_max<'min, 'max>(v: Box<Get<&'max i32>>)
+                                -> Box<Get<&'min i32>>
+    where 'max : 'min
+{
+    v //~ ERROR mismatched types
+}
+
+fn get_max_from_min<'min, 'max, G>(v: Box<Get<&'min i32>>)
+                                   -> Box<Get<&'max i32>>
+    where 'max : 'min
+{
+    v //~ ERROR mismatched types
+}
+
+fn main() { }
diff --git a/src/test/compile-fail/variance-invariant-arg-trait-match.rs b/src/test/compile-fail/variance-invariant-arg-trait-match.rs
new file mode 100644
index 00000000000..45fed0b083d
--- /dev/null
+++ b/src/test/compile-fail/variance-invariant-arg-trait-match.rs
@@ -0,0 +1,31 @@
+// Copyright 2015 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.
+
+#![allow(dead_code)]
+
+trait Get<T> {
+    fn get(&self, t: T) -> T;
+}
+
+fn get_min_from_max<'min, 'max, G>()
+    where 'max : 'min, G : Get<&'max i32>
+{
+    impls_get::<G,&'min i32>() //~ ERROR mismatched types
+}
+
+fn get_max_from_min<'min, 'max, G>()
+    where 'max : 'min, G : Get<&'min i32>
+{
+    impls_get::<G,&'max i32>() //~ ERROR mismatched types
+}
+
+fn impls_get<G,T>() where G : Get<T> { }
+
+fn main() { }
diff --git a/src/test/compile-fail/variance-invariant-self-trait-match.rs b/src/test/compile-fail/variance-invariant-self-trait-match.rs
new file mode 100644
index 00000000000..b46cd302ae5
--- /dev/null
+++ b/src/test/compile-fail/variance-invariant-self-trait-match.rs
@@ -0,0 +1,31 @@
+// Copyright 2015 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.
+
+#![allow(dead_code)]
+
+trait Get {
+    fn get(&self) -> Self;
+}
+
+fn get_min_from_max<'min, 'max, G>()
+    where 'max : 'min, &'max G : Get
+{
+    impls_get::<&'min G>(); //~ ERROR mismatched types
+}
+
+fn get_max_from_min<'min, 'max, G>()
+    where 'max : 'min, &'min G : Get
+{
+    impls_get::<&'max G>(); //~ ERROR mismatched types
+}
+
+fn impls_get<G>() where G : Get { }
+
+fn main() { }
diff --git a/src/test/compile-fail/variance-issue-20533.rs b/src/test/compile-fail/variance-issue-20533.rs
new file mode 100644
index 00000000000..0254f56bd1a
--- /dev/null
+++ b/src/test/compile-fail/variance-issue-20533.rs
@@ -0,0 +1,54 @@
+// Copyright 2015 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.
+
+// Regression test for issue #20533. At some point, only 1 out of the
+// 3 errors below were being reported.
+
+use std::marker::PhantomData;
+
+fn foo<'a, T>(_x: &'a T) -> PhantomData<&'a ()> {
+    PhantomData
+}
+
+struct Wrap<T>(T);
+
+fn bar<'a, T>(_x: &'a T) -> Wrap<PhantomData<&'a ()>> {
+    Wrap(PhantomData)
+}
+
+struct Baked<'a>(PhantomData<&'a ()>);
+
+fn baz<'a, T>(_x: &'a T) -> Baked<'a> {
+    Baked(PhantomData)
+}
+
+struct AffineU32(u32);
+
+fn main() {
+    {
+        let a = AffineU32(1_u32);
+        let x = foo(&a);
+        drop(a); //~ ERROR cannot move out of `a`
+        drop(x);
+    }
+    {
+        let a = AffineU32(1_u32);
+        let x = bar(&a);
+        drop(a); //~ ERROR cannot move out of `a`
+        drop(x);
+    }
+    {
+        let a = AffineU32(1_u32);
+        let x = baz(&a);
+        drop(a); //~ ERROR cannot move out of `a`
+        drop(x);
+    }
+}
+
diff --git a/src/test/compile-fail/variance-regions-direct.rs b/src/test/compile-fail/variance-regions-direct.rs
index d70305d1106..da4d6c75227 100644
--- a/src/test/compile-fail/variance-regions-direct.rs
+++ b/src/test/compile-fail/variance-regions-direct.rs
@@ -60,6 +60,7 @@ struct Test6<'a, 'b> { //~ ERROR regions=[[-, o];[];[]]
 
 #[rustc_variance]
 struct Test7<'a> { //~ ERROR regions=[[*];[];[]]
+    //~^ ERROR parameter `'a` is never used
     x: isize
 }
 
diff --git a/src/test/compile-fail/variance-regions-indirect.rs b/src/test/compile-fail/variance-regions-indirect.rs
index 4bb329d6304..9beb90d0b24 100644
--- a/src/test/compile-fail/variance-regions-indirect.rs
+++ b/src/test/compile-fail/variance-regions-indirect.rs
@@ -16,6 +16,7 @@
 
 #[rustc_variance]
 enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR regions=[[+, -, o, *];[];[]]
+    //~^ ERROR parameter `'d` is never used
     Test8A(extern "Rust" fn(&'a isize)),
     Test8B(&'b [isize]),
     Test8C(&'b mut &'c str),
@@ -23,16 +24,19 @@ enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR regions=[[+, -, o, *];[];[]]
 
 #[rustc_variance]
 struct Derived1<'w, 'x:'y, 'y, 'z> { //~ ERROR regions=[[*, o, -, +];[];[]]
+    //~^ ERROR parameter `'w` is never used
     f: Base<'z, 'y, 'x, 'w>
 }
 
 #[rustc_variance] // Combine - and + to yield o
 struct Derived2<'a, 'b:'a, 'c> { //~ ERROR regions=[[o, o, *];[];[]]
+    //~^ ERROR parameter `'c` is never used
     f: Base<'a, 'a, 'b, 'c>
 }
 
 #[rustc_variance] // Combine + and o to yield o (just pay attention to 'a here)
 struct Derived3<'a:'b, 'b, 'c> { //~ ERROR regions=[[o, -, *];[];[]]
+    //~^ ERROR parameter `'c` is never used
     f: Base<'a, 'b, 'a, 'c>
 }
 
diff --git a/src/test/run-pass/regions-infer-bivariance.rs b/src/test/compile-fail/variance-regions-unused-direct.rs
index a3288e2e1b9..396e7765206 100644
--- a/src/test/run-pass/regions-infer-bivariance.rs
+++ b/src/test/compile-fail/variance-regions-unused-direct.rs
@@ -8,21 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// Test that a type whose lifetime parameters is never used is
-// inferred to be bivariant.
+// Test that disallow lifetime parameters that are unused.
 
 use std::marker;
 
-struct Bivariant<'a>;
+struct Bivariant<'a>; //~ ERROR parameter `'a` is never used
 
-fn use1<'short,'long>(c: Bivariant<'short>,
-                      _where:Option<&'short &'long ()>) {
-    let _: Bivariant<'long> = c;
+struct Struct<'a, 'd> { //~ ERROR parameter `'d` is never used
+    field: &'a [i32]
 }
 
-fn use2<'short,'long>(c: Bivariant<'long>,
-                      _where:Option<&'short &'long ()>) {
-    let _: Bivariant<'short> = c;
+trait Trait<'a, 'd> { //~ ERROR parameter `'d` is never used
+    fn method(&'a self);
 }
 
-pub fn main() {}
+fn main() {}
diff --git a/src/test/run-pass/export-non-interference.rs b/src/test/compile-fail/variance-regions-unused-indirect.rs
index 94652e30fe6..2d234ed7b57 100644
--- a/src/test/run-pass/export-non-interference.rs
+++ b/src/test/compile-fail/variance-regions-unused-indirect.rs
@@ -8,7 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// Test that disallow lifetime parameters that are unused.
 
-enum list_cell<T> { cons(Box<list_cell<T>>), nil }
+enum Foo<'a> { //~ ERROR parameter `'a` is never used
+    Foo1(Bar<'a>)
+}
 
-pub fn main() { }
+enum Bar<'a> { //~ ERROR parameter `'a` is never used
+    Bar1(Foo<'a>)
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/variance-trait-bounds.rs b/src/test/compile-fail/variance-trait-bounds.rs
new file mode 100644
index 00000000000..88b50058b65
--- /dev/null
+++ b/src/test/compile-fail/variance-trait-bounds.rs
@@ -0,0 +1,65 @@
+// Copyright 2014 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.
+
+#![deny(bivariance)]
+#![allow(dead_code)]
+#![feature(rustc_attrs)]
+
+// Check that bounds on type parameters (other than `Self`) do not
+// influence variance.
+
+#[rustc_variance]
+trait Getter<T> { //~ ERROR types=[[+];[-];[]]
+    fn get(&self) -> T;
+}
+
+#[rustc_variance]
+trait Setter<T> { //~ ERROR types=[[-];[-];[]]
+    fn get(&self, T);
+}
+
+#[rustc_variance]
+struct TestStruct<U,T:Setter<U>> { //~ ERROR types=[[+, +];[];[]]
+    t: T, u: U
+}
+
+#[rustc_variance]
+enum TestEnum<U,T:Setter<U>> {//~ ERROR types=[[*, +];[];[]]
+    //~^ ERROR parameter `U` is never used
+    Foo(T)
+}
+
+#[rustc_variance]
+trait TestTrait<U,T:Setter<U>> { //~ ERROR types=[[-, +];[-];[]]
+    fn getter(&self, u: U) -> T;
+}
+
+#[rustc_variance]
+trait TestTrait2<U> : Getter<U> { //~ ERROR types=[[+];[-];[]]
+}
+
+#[rustc_variance]
+trait TestTrait3<U> { //~ ERROR types=[[-];[-];[]]
+    fn getter<T:Getter<U>>(&self);
+}
+
+#[rustc_variance]
+struct TestContraStruct<U,T:Setter<U>> { //~ ERROR types=[[*, +];[];[]]
+    //~^ ERROR parameter `U` is never used
+    t: T
+}
+
+#[rustc_variance]
+struct TestBox<U,T:Getter<U>+Setter<U>> { //~ ERROR types=[[*, +];[];[]]
+    //~^ ERROR parameter `U` is never used
+    t: T
+}
+
+pub fn main() { }
diff --git a/src/test/compile-fail/variance-trait-object-bound.rs b/src/test/compile-fail/variance-trait-object-bound.rs
index 965b9430a5e..f0ca1edd563 100644
--- a/src/test/compile-fail/variance-trait-object-bound.rs
+++ b/src/test/compile-fail/variance-trait-object-bound.rs
@@ -18,7 +18,7 @@
 
 use std::mem;
 
-trait T { fn foo(); }
+trait T { fn foo(&self); }
 
 #[rustc_variance]
 struct TOption<'a> { //~ ERROR regions=[[-];[];[]]
diff --git a/src/test/compile-fail/variance-types-bounds.rs b/src/test/compile-fail/variance-types-bounds.rs
new file mode 100644
index 00000000000..d53e4cd7610
--- /dev/null
+++ b/src/test/compile-fail/variance-types-bounds.rs
@@ -0,0 +1,76 @@
+// 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.
+
+// Test that we correctly infer variance for type parameters in
+// various types and traits.
+
+#![feature(rustc_attrs)]
+
+#[rustc_variance]
+struct TestImm<A, B> { //~ ERROR types=[[+, +];[];[]]
+    x: A,
+    y: B,
+}
+
+#[rustc_variance]
+struct TestMut<A, B:'static> { //~ ERROR types=[[+, o];[];[]]
+    x: A,
+    y: &'static mut B,
+}
+
+#[rustc_variance]
+struct TestIndirect<A:'static, B:'static> { //~ ERROR types=[[+, o];[];[]]
+    m: TestMut<A, B>
+}
+
+#[rustc_variance]
+struct TestIndirect2<A:'static, B:'static> { //~ ERROR types=[[o, o];[];[]]
+    n: TestMut<A, B>,
+    m: TestMut<B, A>
+}
+
+#[rustc_variance]
+trait Getter<A> { //~ ERROR types=[[+];[-];[]]
+    fn get(&self) -> A;
+}
+
+#[rustc_variance]
+trait Setter<A> { //~ ERROR types=[[-];[o];[]]
+    fn set(&mut self, a: A);
+}
+
+#[rustc_variance]
+trait GetterSetter<A> { //~ ERROR types=[[o];[o];[]]
+    fn get(&self) -> A;
+    fn set(&mut self, a: A);
+}
+
+#[rustc_variance]
+trait GetterInTypeBound<A> { //~ ERROR types=[[-];[-];[]]
+    // Here, the use of `A` in the method bound *does* affect
+    // variance.  Think of it as if the method requested a dictionary
+    // for `T:Getter<A>`.  Since this dictionary is an input, it is
+    // contravariant, and the Getter is covariant w/r/t A, yielding an
+    // overall contravariant result.
+    fn do_it<T:Getter<A>>(&self);
+}
+
+#[rustc_variance]
+trait SetterInTypeBound<A> { //~ ERROR types=[[+];[-];[]]
+    fn do_it<T:Setter<A>>(&self);
+}
+
+#[rustc_variance]
+struct TestObject<A, R> { //~ ERROR types=[[-, +];[];[]]
+    n: Box<Setter<A>+Send>,
+    m: Box<Getter<R>+Send>,
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/variance-types.rs b/src/test/compile-fail/variance-types.rs
new file mode 100644
index 00000000000..e407ebe345a
--- /dev/null
+++ b/src/test/compile-fail/variance-types.rs
@@ -0,0 +1,52 @@
+// Copyright 2014 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.
+
+#![deny(bivariance)]
+#![allow(dead_code)]
+#![feature(rustc_attrs)]
+
+use std::cell::Cell;
+
+// Check that a type parameter which is only used in a trait bound is
+// not considered bivariant.
+
+#[rustc_variance]
+struct InvariantMut<'a,A:'a,B:'a> { //~ ERROR types=[[o, o];[];[]], regions=[[-];[];[]]
+    t: &'a mut (A,B)
+}
+
+#[rustc_variance]
+struct InvariantCell<A> { //~ ERROR types=[[o];[];[]]
+    t: Cell<A>
+}
+
+#[rustc_variance]
+struct InvariantIndirect<A> { //~ ERROR types=[[o];[];[]]
+    t: InvariantCell<A>
+}
+
+#[rustc_variance]
+struct Covariant<A> { //~ ERROR types=[[+];[];[]]
+    t: A, u: fn() -> A
+}
+
+#[rustc_variance]
+struct Contravariant<A> { //~ ERROR types=[[-];[];[]]
+    t: fn(A)
+}
+
+#[rustc_variance]
+enum Enum<A,B,C> { //~ ERROR types=[[+, -, o];[];[]]
+    Foo(Covariant<A>),
+    Bar(Contravariant<B>),
+    Zed(Covariant<C>,Contravariant<C>)
+}
+
+pub fn main() { }
diff --git a/src/test/compile-fail/variance-unused-region-param.rs b/src/test/compile-fail/variance-unused-region-param.rs
new file mode 100644
index 00000000000..5f504226370
--- /dev/null
+++ b/src/test/compile-fail/variance-unused-region-param.rs
@@ -0,0 +1,17 @@
+// 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.
+
+// Test that we report an error for unused type parameters in types.
+
+struct SomeStruct<'a> { x: u32 } //~ ERROR parameter `'a` is never used
+enum SomeEnum<'a> { Nothing } //~ ERROR parameter `'a` is never used
+trait SomeTrait<'a> { fn foo(&self); } //~ ERROR parameter `'a` is never used
+
+fn main() {}
diff --git a/src/test/compile-fail/variance-unused-type-param.rs b/src/test/compile-fail/variance-unused-type-param.rs
new file mode 100644
index 00000000000..2e867ec3c93
--- /dev/null
+++ b/src/test/compile-fail/variance-unused-type-param.rs
@@ -0,0 +1,36 @@
+// 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.
+
+#![allow(dead_code)]
+
+// Test that we report an error for unused type parameters in types and traits,
+// and that we offer a helpful suggestion.
+
+struct SomeStruct<A> { x: u32 }
+//~^ ERROR parameter `A` is never used
+//~| HELP PhantomData
+
+enum SomeEnum<A> { Nothing }
+//~^ ERROR parameter `A` is never used
+//~| HELP PhantomData
+
+trait SomeTrait<A> { fn foo(&self); }
+//~^ ERROR parameter `A` is never used
+//~| HELP PhantomFn
+
+// Here T might *appear* used, but in fact it isn't.
+enum ListCell<T> {
+//~^ ERROR parameter `T` is never used
+//~| HELP PhantomData
+    Cons(Box<ListCell<T>>),
+    Nil
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/variance-use-contravariant-struct-1.rs b/src/test/compile-fail/variance-use-contravariant-struct-1.rs
new file mode 100644
index 00000000000..d2fd2978750
--- /dev/null
+++ b/src/test/compile-fail/variance-use-contravariant-struct-1.rs
@@ -0,0 +1,26 @@
+// Copyright 2015 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.
+
+// Test various uses of structs with distint variances to make sure
+// they permit lifetimes to be approximated as expected.
+
+#![feature(rustc_attrs)]
+
+struct SomeStruct<T>(fn(T));
+
+fn foo<'min,'max>(v: SomeStruct<&'max ()>)
+                  -> SomeStruct<&'min ()>
+    where 'max : 'min
+{
+    v //~ ERROR mismatched types
+}
+
+#[rustc_error]
+fn main() { }
diff --git a/src/test/compile-fail/variance-use-contravariant-struct-2.rs b/src/test/compile-fail/variance-use-contravariant-struct-2.rs
new file mode 100644
index 00000000000..b38fd0e9ffc
--- /dev/null
+++ b/src/test/compile-fail/variance-use-contravariant-struct-2.rs
@@ -0,0 +1,27 @@
+// Copyright 2015 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.
+
+// Test various uses of structs with distint variances to make sure
+// they permit lifetimes to be approximated as expected.
+
+#![allow(dead_code)]
+#![feature(rustc_attrs)]
+
+struct SomeStruct<T>(fn(T));
+
+fn bar<'min,'max>(v: SomeStruct<&'min ()>)
+                  -> SomeStruct<&'max ()>
+    where 'max : 'min
+{
+    v
+}
+
+#[rustc_error]
+fn main() { } //~ ERROR compilation successful
diff --git a/src/test/compile-fail/variance-use-covariant-struct-1.rs b/src/test/compile-fail/variance-use-covariant-struct-1.rs
new file mode 100644
index 00000000000..2631cfc05e8
--- /dev/null
+++ b/src/test/compile-fail/variance-use-covariant-struct-1.rs
@@ -0,0 +1,23 @@
+// Copyright 2015 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.
+
+// Test that a covariant struct does not permit the lifetime of a
+// reference to be enlarged.
+
+struct SomeStruct<T>(T);
+
+fn foo<'min,'max>(v: SomeStruct<&'min ()>)
+                  -> SomeStruct<&'max ()>
+    where 'max : 'min
+{
+    v //~ ERROR mismatched types
+}
+
+fn main() { }
diff --git a/src/test/compile-fail/variance-use-covariant-struct-2.rs b/src/test/compile-fail/variance-use-covariant-struct-2.rs
new file mode 100644
index 00000000000..d8e1a5f5f1c
--- /dev/null
+++ b/src/test/compile-fail/variance-use-covariant-struct-2.rs
@@ -0,0 +1,26 @@
+// Copyright 2015 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.
+
+// Test that a covariant struct permits the lifetime of a reference to
+// be shortened.
+
+#![allow(dead_code)]
+#![feature(rustc_attrs)]
+
+struct SomeStruct<T>(T);
+
+fn foo<'min,'max>(v: SomeStruct<&'max ()>)
+                  -> SomeStruct<&'min ()>
+    where 'max : 'min
+{
+    v
+}
+
+#[rustc_error] fn main() { } //~ ERROR compilation successful
diff --git a/src/test/compile-fail/variance-use-invariant-struct-1.rs b/src/test/compile-fail/variance-use-invariant-struct-1.rs
new file mode 100644
index 00000000000..c89436b2094
--- /dev/null
+++ b/src/test/compile-fail/variance-use-invariant-struct-1.rs
@@ -0,0 +1,33 @@
+// Copyright 2015 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.
+
+// Test various uses of structs with distint variances to make sure
+// they permit lifetimes to be approximated as expected.
+
+#![feature(rustc_attrs)]
+
+struct SomeStruct<T>(*mut T);
+
+fn foo<'min,'max>(v: SomeStruct<&'max ()>)
+                  -> SomeStruct<&'min ()>
+    where 'max : 'min
+{
+    v //~ ERROR mismatched types
+}
+
+fn bar<'min,'max>(v: SomeStruct<&'min ()>)
+                  -> SomeStruct<&'max ()>
+    where 'max : 'min
+{
+    v //~ ERROR mismatched types
+}
+
+#[rustc_error]
+fn main() { }
diff --git a/src/test/compile-fail/visible-private-types-generics.rs b/src/test/compile-fail/visible-private-types-generics.rs
index 7ff18f8e088..1f2205b5c71 100644
--- a/src/test/compile-fail/visible-private-types-generics.rs
+++ b/src/test/compile-fail/visible-private-types-generics.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo {}
+trait Foo {
+    fn dummy(&self) { }
+}
 
 pub fn f<
     T
diff --git a/src/test/compile-fail/visible-private-types-supertrait.rs b/src/test/compile-fail/visible-private-types-supertrait.rs
index dc6d446154a..9d9eae4a075 100644
--- a/src/test/compile-fail/visible-private-types-supertrait.rs
+++ b/src/test/compile-fail/visible-private-types-supertrait.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo {}
+trait Foo {
+    fn dummy(&self) { }
+}
 
 pub trait Bar : Foo {} //~ ERROR private trait in exported type
 
diff --git a/src/test/compile-fail/where-clause-method-substituion.rs b/src/test/compile-fail/where-clause-method-substituion.rs
index a5108f005dc..bf614e6eb51 100644
--- a/src/test/compile-fail/where-clause-method-substituion.rs
+++ b/src/test/compile-fail/where-clause-method-substituion.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo<T> {}
+trait Foo<T> {
+    fn dummy(&self, t: T) { }
+}
 
 trait Bar<A> {
     fn method<B>(&self) where A: Foo<B>;
diff --git a/src/test/compile-fail/where-clauses-not-parameter.rs b/src/test/compile-fail/where-clauses-not-parameter.rs
index 313ae273c07..7968cc37090 100644
--- a/src/test/compile-fail/where-clauses-not-parameter.rs
+++ b/src/test/compile-fail/where-clauses-not-parameter.rs
@@ -21,7 +21,7 @@ fn test2() -> bool where Option<isize> : Eq {}
 
 #[derive(PartialEq)]
 //~^ ERROR cannot bound type `isize`, where clause bounds
-enum Foo<T> where isize : Eq { MkFoo }
+enum Foo<T> where isize : Eq { MkFoo(T) }
 //~^ ERROR cannot bound type `isize`, where clause bounds
 
 fn test3<T: Eq>() -> bool where Option<Foo<T>> : Eq {}
@@ -31,7 +31,7 @@ fn test4() -> bool where Option<Foo<isize>> : Eq {}
 
 trait Baz<T> where isize : Eq {
     //~^ ERROR cannot bound type `isize`, where clause bounds may only
-    fn baz() where String : Eq; //~ ERROR cannot bound type `collections::string::String`
+    fn baz(&self, t: T) where String : Eq; //~ ERROR cannot bound type `collections::string::String`
     //~^ ERROR cannot bound type `isize`, where clause
 }
 
diff --git a/src/test/debuginfo/type-names.rs b/src/test/debuginfo/type-names.rs
index a592484f1a4..bf26fc23d3c 100644
--- a/src/test/debuginfo/type-names.rs
+++ b/src/test/debuginfo/type-names.rs
@@ -177,10 +177,11 @@
 #![omit_gdb_pretty_printer_section]
 
 use self::Enum1::{Variant1_1, Variant1_2};
+use std::marker::PhantomData;
 use std::ptr;
 
 struct Struct1;
-struct GenericStruct<T1, T2>;
+struct GenericStruct<T1, T2>(PhantomData<(T1,T2)>);
 
 enum Enum1 {
     Variant1_1,
@@ -207,8 +208,8 @@ mod Mod1 {
     }
 }
 
-trait Trait1 { }
-trait Trait2<T1, T2> { }
+trait Trait1 { fn dummy(&self) { } }
+trait Trait2<T1, T2> { fn dummy(&self, _: T1, _:T2) { } }
 
 impl Trait1 for isize {}
 impl<T1, T2> Trait2<T1, T2> for isize {}
@@ -240,8 +241,10 @@ fn main() {
 
     // Structs
     let simple_struct = Struct1;
-    let generic_struct1: GenericStruct<Mod1::Struct2, Mod1::Mod2::Struct3> = GenericStruct;
-    let generic_struct2: GenericStruct<Struct1, extern "fastcall" fn(isize) -> usize> = GenericStruct;
+    let generic_struct1: GenericStruct<Mod1::Struct2, Mod1::Mod2::Struct3> =
+        GenericStruct(PhantomData);
+    let generic_struct2: GenericStruct<Struct1, extern "fastcall" fn(isize) -> usize> =
+        GenericStruct(PhantomData);
     let mod_struct = Mod1::Struct2;
 
     // Enums
@@ -262,10 +265,10 @@ fn main() {
 
     // References
     let ref1 = (&Struct1, 0i32);
-    let ref2 = (&GenericStruct::<char, Struct1>, 0i32);
+    let ref2 = (&GenericStruct::<char, Struct1>(PhantomData), 0i32);
 
     let mut mut_struct1 = Struct1;
-    let mut mut_generic_struct = GenericStruct::<Mod1::Enum2, f64>;
+    let mut mut_generic_struct = GenericStruct::<Mod1::Enum2, f64>(PhantomData);
     let mut_ref1 = (&mut mut_struct1, 0i32);
     let mut_ref2 = (&mut mut_generic_struct, 0i32);
 
diff --git a/src/test/compile-fail/ascii-only-character-escape.rs b/src/test/parse-fail/ascii-only-character-escape.rs
index 1ba25a827a5..1ba25a827a5 100644
--- a/src/test/compile-fail/ascii-only-character-escape.rs
+++ b/src/test/parse-fail/ascii-only-character-escape.rs
diff --git a/src/test/compile-fail/attr-before-eof.rs b/src/test/parse-fail/attr-before-eof.rs
index e34756229bd..e34756229bd 100644
--- a/src/test/compile-fail/attr-before-eof.rs
+++ b/src/test/parse-fail/attr-before-eof.rs
diff --git a/src/test/compile-fail/attr-before-ext.rs b/src/test/parse-fail/attr-before-ext.rs
index 098c5aaec54..098c5aaec54 100644
--- a/src/test/compile-fail/attr-before-ext.rs
+++ b/src/test/parse-fail/attr-before-ext.rs
diff --git a/src/test/compile-fail/attr-before-let.rs b/src/test/parse-fail/attr-before-let.rs
index b4a90e35c40..b4a90e35c40 100644
--- a/src/test/compile-fail/attr-before-let.rs
+++ b/src/test/parse-fail/attr-before-let.rs
diff --git a/src/test/compile-fail/attr-before-stmt.rs b/src/test/parse-fail/attr-before-stmt.rs
index ec837cd6de3..ec837cd6de3 100644
--- a/src/test/compile-fail/attr-before-stmt.rs
+++ b/src/test/parse-fail/attr-before-stmt.rs
diff --git a/src/test/compile-fail/attr-dangling-in-fn.rs b/src/test/parse-fail/attr-dangling-in-fn.rs
index 384622fb168..384622fb168 100644
--- a/src/test/compile-fail/attr-dangling-in-fn.rs
+++ b/src/test/parse-fail/attr-dangling-in-fn.rs
diff --git a/src/test/compile-fail/attr-dangling-in-mod.rs b/src/test/parse-fail/attr-dangling-in-mod.rs
index 59a922ebee1..59a922ebee1 100644
--- a/src/test/compile-fail/attr-dangling-in-mod.rs
+++ b/src/test/parse-fail/attr-dangling-in-mod.rs
diff --git a/src/test/compile-fail/attr.rs b/src/test/parse-fail/attr.rs
index 4bd61412731..4bd61412731 100644
--- a/src/test/compile-fail/attr.rs
+++ b/src/test/parse-fail/attr.rs
diff --git a/src/test/compile-fail/attrs-after-extern-mod.rs b/src/test/parse-fail/attrs-after-extern-mod.rs
index df747618696..df747618696 100644
--- a/src/test/compile-fail/attrs-after-extern-mod.rs
+++ b/src/test/parse-fail/attrs-after-extern-mod.rs
diff --git a/src/test/compile-fail/bad-char-literals.rs b/src/test/parse-fail/bad-char-literals.rs
index 2a358ae8307..2a358ae8307 100644
--- a/src/test/compile-fail/bad-char-literals.rs
+++ b/src/test/parse-fail/bad-char-literals.rs
diff --git a/src/test/compile-fail/bad-lit-suffixes.rs b/src/test/parse-fail/bad-lit-suffixes.rs
index d10337e768c..d10337e768c 100644
--- a/src/test/compile-fail/bad-lit-suffixes.rs
+++ b/src/test/parse-fail/bad-lit-suffixes.rs
diff --git a/src/test/compile-fail/bad-value-ident-false.rs b/src/test/parse-fail/bad-value-ident-false.rs
index ca10bdd9848..ca10bdd9848 100644
--- a/src/test/compile-fail/bad-value-ident-false.rs
+++ b/src/test/parse-fail/bad-value-ident-false.rs
diff --git a/src/test/compile-fail/bad-value-ident-true.rs b/src/test/parse-fail/bad-value-ident-true.rs
index 4508d5219a2..4508d5219a2 100644
--- a/src/test/compile-fail/bad-value-ident-true.rs
+++ b/src/test/parse-fail/bad-value-ident-true.rs
diff --git a/src/test/compile-fail/doc-before-attr.rs b/src/test/parse-fail/doc-before-attr.rs
index bb44a6a8abb..bb44a6a8abb 100644
--- a/src/test/compile-fail/doc-before-attr.rs
+++ b/src/test/parse-fail/doc-before-attr.rs
diff --git a/src/test/compile-fail/doc-before-eof.rs b/src/test/parse-fail/doc-before-eof.rs
index e6dd4102462..e6dd4102462 100644
--- a/src/test/compile-fail/doc-before-eof.rs
+++ b/src/test/parse-fail/doc-before-eof.rs
diff --git a/src/test/compile-fail/doc-before-extern-rbrace.rs b/src/test/parse-fail/doc-before-extern-rbrace.rs
index 5afd1b2c6b8..5afd1b2c6b8 100644
--- a/src/test/compile-fail/doc-before-extern-rbrace.rs
+++ b/src/test/parse-fail/doc-before-extern-rbrace.rs
diff --git a/src/test/compile-fail/doc-before-macro.rs b/src/test/parse-fail/doc-before-macro.rs
index 8dc6c546500..8dc6c546500 100644
--- a/src/test/compile-fail/doc-before-macro.rs
+++ b/src/test/parse-fail/doc-before-macro.rs
diff --git a/src/test/compile-fail/doc-before-rbrace.rs b/src/test/parse-fail/doc-before-rbrace.rs
index 6d05064277d..6d05064277d 100644
--- a/src/test/compile-fail/doc-before-rbrace.rs
+++ b/src/test/parse-fail/doc-before-rbrace.rs
diff --git a/src/test/compile-fail/doc-before-semi.rs b/src/test/parse-fail/doc-before-semi.rs
index 8b0300edce0..8b0300edce0 100644
--- a/src/test/compile-fail/doc-before-semi.rs
+++ b/src/test/parse-fail/doc-before-semi.rs
diff --git a/src/test/compile-fail/extern-crate-as-no-string-help.rs b/src/test/parse-fail/extern-crate-as-no-string-help.rs
index 5cc52f6f6db..5cc52f6f6db 100644
--- a/src/test/compile-fail/extern-crate-as-no-string-help.rs
+++ b/src/test/parse-fail/extern-crate-as-no-string-help.rs
diff --git a/src/test/compile-fail/generic-non-trailing-defaults.rs b/src/test/parse-fail/generic-non-trailing-defaults.rs
index 0cfb05b9332..0cfb05b9332 100644
--- a/src/test/compile-fail/generic-non-trailing-defaults.rs
+++ b/src/test/parse-fail/generic-non-trailing-defaults.rs
diff --git a/src/test/compile-fail/int-literal-too-large-span.rs b/src/test/parse-fail/int-literal-too-large-span.rs
index 8a496c934b9..8a496c934b9 100644
--- a/src/test/compile-fail/int-literal-too-large-span.rs
+++ b/src/test/parse-fail/int-literal-too-large-span.rs
diff --git a/src/test/compile-fail/issue-10412.rs b/src/test/parse-fail/issue-10412.rs
index 8a99633b4fc..8a99633b4fc 100644
--- a/src/test/compile-fail/issue-10412.rs
+++ b/src/test/parse-fail/issue-10412.rs
diff --git a/src/test/compile-fail/issue-12560-1.rs b/src/test/parse-fail/issue-12560-1.rs
index ea2043e6703..ea2043e6703 100644
--- a/src/test/compile-fail/issue-12560-1.rs
+++ b/src/test/parse-fail/issue-12560-1.rs
diff --git a/src/test/compile-fail/issue-14182.rs b/src/test/parse-fail/issue-14182.rs
index 364951a4fea..364951a4fea 100644
--- a/src/test/compile-fail/issue-14182.rs
+++ b/src/test/parse-fail/issue-14182.rs
diff --git a/src/test/compile-fail/issue-17383.rs b/src/test/parse-fail/issue-17383.rs
index c71e0ecd494..c71e0ecd494 100644
--- a/src/test/compile-fail/issue-17383.rs
+++ b/src/test/parse-fail/issue-17383.rs
diff --git a/src/test/compile-fail/issue-17718-const-mut.rs b/src/test/parse-fail/issue-17718-const-mut.rs
index 5177ebbc188..5177ebbc188 100644
--- a/src/test/compile-fail/issue-17718-const-mut.rs
+++ b/src/test/parse-fail/issue-17718-const-mut.rs
diff --git a/src/test/compile-fail/issue-1802-2.rs b/src/test/parse-fail/issue-1802-2.rs
index f6da2fc82c3..f6da2fc82c3 100644
--- a/src/test/compile-fail/issue-1802-2.rs
+++ b/src/test/parse-fail/issue-1802-2.rs
diff --git a/src/test/compile-fail/issue-5544-a.rs b/src/test/parse-fail/issue-5544-a.rs
index 95a4f36d171..95a4f36d171 100644
--- a/src/test/compile-fail/issue-5544-a.rs
+++ b/src/test/parse-fail/issue-5544-a.rs
diff --git a/src/test/compile-fail/issue-5544-b.rs b/src/test/parse-fail/issue-5544-b.rs
index afff5984b46..afff5984b46 100644
--- a/src/test/compile-fail/issue-5544-b.rs
+++ b/src/test/parse-fail/issue-5544-b.rs
diff --git a/src/test/compile-fail/issue-8537.rs b/src/test/parse-fail/issue-8537.rs
index 52cf420a9ff..52cf420a9ff 100644
--- a/src/test/compile-fail/issue-8537.rs
+++ b/src/test/parse-fail/issue-8537.rs
diff --git a/src/test/compile-fail/keyword-as-as-identifier.rs b/src/test/parse-fail/keyword-as-as-identifier.rs
index f307b12f66e..f307b12f66e 100644
--- a/src/test/compile-fail/keyword-as-as-identifier.rs
+++ b/src/test/parse-fail/keyword-as-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-break-as-identifier.rs b/src/test/parse-fail/keyword-break-as-identifier.rs
index 1e2725eb2fe..1e2725eb2fe 100644
--- a/src/test/compile-fail/keyword-break-as-identifier.rs
+++ b/src/test/parse-fail/keyword-break-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-else-as-identifier.rs b/src/test/parse-fail/keyword-else-as-identifier.rs
index 101fd938dcb..101fd938dcb 100644
--- a/src/test/compile-fail/keyword-else-as-identifier.rs
+++ b/src/test/parse-fail/keyword-else-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-enum-as-identifier.rs b/src/test/parse-fail/keyword-enum-as-identifier.rs
index ed504cc7b7f..ed504cc7b7f 100644
--- a/src/test/compile-fail/keyword-enum-as-identifier.rs
+++ b/src/test/parse-fail/keyword-enum-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-extern-as-identifier.rs b/src/test/parse-fail/keyword-extern-as-identifier.rs
index 3260506b3e1..3260506b3e1 100644
--- a/src/test/compile-fail/keyword-extern-as-identifier.rs
+++ b/src/test/parse-fail/keyword-extern-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-fn-as-identifier.rs b/src/test/parse-fail/keyword-fn-as-identifier.rs
index 8c98da229c8..8c98da229c8 100644
--- a/src/test/compile-fail/keyword-fn-as-identifier.rs
+++ b/src/test/parse-fail/keyword-fn-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-for-as-identifier.rs b/src/test/parse-fail/keyword-for-as-identifier.rs
index 196a3390676..196a3390676 100644
--- a/src/test/compile-fail/keyword-for-as-identifier.rs
+++ b/src/test/parse-fail/keyword-for-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-if-as-identifier.rs b/src/test/parse-fail/keyword-if-as-identifier.rs
index 05f82ec790c..05f82ec790c 100644
--- a/src/test/compile-fail/keyword-if-as-identifier.rs
+++ b/src/test/parse-fail/keyword-if-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-impl-as-identifier.rs b/src/test/parse-fail/keyword-impl-as-identifier.rs
index 1dd21800345..1dd21800345 100644
--- a/src/test/compile-fail/keyword-impl-as-identifier.rs
+++ b/src/test/parse-fail/keyword-impl-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-let-as-identifier.rs b/src/test/parse-fail/keyword-let-as-identifier.rs
index 0069a26a40b..0069a26a40b 100644
--- a/src/test/compile-fail/keyword-let-as-identifier.rs
+++ b/src/test/parse-fail/keyword-let-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-loop-as-identifier.rs b/src/test/parse-fail/keyword-loop-as-identifier.rs
index 6e469e8c0b4..6e469e8c0b4 100644
--- a/src/test/compile-fail/keyword-loop-as-identifier.rs
+++ b/src/test/parse-fail/keyword-loop-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-match-as-identifier.rs b/src/test/parse-fail/keyword-match-as-identifier.rs
index 9155ebc71fa..9155ebc71fa 100644
--- a/src/test/compile-fail/keyword-match-as-identifier.rs
+++ b/src/test/parse-fail/keyword-match-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-mod-as-identifier.rs b/src/test/parse-fail/keyword-mod-as-identifier.rs
index 02f57e937dd..02f57e937dd 100644
--- a/src/test/compile-fail/keyword-mod-as-identifier.rs
+++ b/src/test/parse-fail/keyword-mod-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-pub-as-identifier.rs b/src/test/parse-fail/keyword-pub-as-identifier.rs
index aa679741c1c..aa679741c1c 100644
--- a/src/test/compile-fail/keyword-pub-as-identifier.rs
+++ b/src/test/parse-fail/keyword-pub-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-return-as-identifier.rs b/src/test/parse-fail/keyword-return-as-identifier.rs
index c5676445917..c5676445917 100644
--- a/src/test/compile-fail/keyword-return-as-identifier.rs
+++ b/src/test/parse-fail/keyword-return-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-self-as-identifier.rs b/src/test/parse-fail/keyword-self-as-identifier.rs
index 8bb52142287..8bb52142287 100644
--- a/src/test/compile-fail/keyword-self-as-identifier.rs
+++ b/src/test/parse-fail/keyword-self-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-static-as-identifier.rs b/src/test/parse-fail/keyword-static-as-identifier.rs
index 7268c4f387e..7268c4f387e 100644
--- a/src/test/compile-fail/keyword-static-as-identifier.rs
+++ b/src/test/parse-fail/keyword-static-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-struct-as-identifier.rs b/src/test/parse-fail/keyword-struct-as-identifier.rs
index bd42eac0ecb..bd42eac0ecb 100644
--- a/src/test/compile-fail/keyword-struct-as-identifier.rs
+++ b/src/test/parse-fail/keyword-struct-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-super-as-identifier.rs b/src/test/parse-fail/keyword-super-as-identifier.rs
index 0378c326a89..0378c326a89 100644
--- a/src/test/compile-fail/keyword-super-as-identifier.rs
+++ b/src/test/parse-fail/keyword-super-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-super.rs b/src/test/parse-fail/keyword-super.rs
index 0c94f76f1f6..0c94f76f1f6 100644
--- a/src/test/compile-fail/keyword-super.rs
+++ b/src/test/parse-fail/keyword-super.rs
diff --git a/src/test/compile-fail/keyword-trait-as-identifier.rs b/src/test/parse-fail/keyword-trait-as-identifier.rs
index 95c0d174c33..95c0d174c33 100644
--- a/src/test/compile-fail/keyword-trait-as-identifier.rs
+++ b/src/test/parse-fail/keyword-trait-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-type-as-identifier.rs b/src/test/parse-fail/keyword-type-as-identifier.rs
index 0aaa2a63c7c..0aaa2a63c7c 100644
--- a/src/test/compile-fail/keyword-type-as-identifier.rs
+++ b/src/test/parse-fail/keyword-type-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-unsafe-as-identifier.rs b/src/test/parse-fail/keyword-unsafe-as-identifier.rs
index 1b631eb877d..1b631eb877d 100644
--- a/src/test/compile-fail/keyword-unsafe-as-identifier.rs
+++ b/src/test/parse-fail/keyword-unsafe-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-use-as-identifier.rs b/src/test/parse-fail/keyword-use-as-identifier.rs
index e82afd54442..e82afd54442 100644
--- a/src/test/compile-fail/keyword-use-as-identifier.rs
+++ b/src/test/parse-fail/keyword-use-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-while-as-identifier.rs b/src/test/parse-fail/keyword-while-as-identifier.rs
index 95cea65c610..95cea65c610 100644
--- a/src/test/compile-fail/keyword-while-as-identifier.rs
+++ b/src/test/parse-fail/keyword-while-as-identifier.rs
diff --git a/src/test/compile-fail/keyword.rs b/src/test/parse-fail/keyword.rs
index 64eac47e69b..64eac47e69b 100644
--- a/src/test/compile-fail/keyword.rs
+++ b/src/test/parse-fail/keyword.rs
diff --git a/src/test/compile-fail/keywords-followed-by-double-colon.rs b/src/test/parse-fail/keywords-followed-by-double-colon.rs
index f69b041597e..f69b041597e 100644
--- a/src/test/compile-fail/keywords-followed-by-double-colon.rs
+++ b/src/test/parse-fail/keywords-followed-by-double-colon.rs
diff --git a/src/test/compile-fail/lex-bad-numeric-literals.rs b/src/test/parse-fail/lex-bad-numeric-literals.rs
index 9a490be6a01..9a490be6a01 100644
--- a/src/test/compile-fail/lex-bad-numeric-literals.rs
+++ b/src/test/parse-fail/lex-bad-numeric-literals.rs
diff --git a/src/test/compile-fail/lex-bare-cr-string-literal-doc-comment.rs b/src/test/parse-fail/lex-bare-cr-string-literal-doc-comment.rs
index c1e5121d6dd..c1e5121d6dd 100644
--- a/src/test/compile-fail/lex-bare-cr-string-literal-doc-comment.rs
+++ b/src/test/parse-fail/lex-bare-cr-string-literal-doc-comment.rs
diff --git a/src/test/compile-fail/lifetime-no-keyword.rs b/src/test/parse-fail/lifetime-no-keyword.rs
index 8ffbcd90df8..8ffbcd90df8 100644
--- a/src/test/compile-fail/lifetime-no-keyword.rs
+++ b/src/test/parse-fail/lifetime-no-keyword.rs
diff --git a/src/test/compile-fail/lifetime-obsoleted-self.rs b/src/test/parse-fail/lifetime-obsoleted-self.rs
index 766922f2f88..766922f2f88 100644
--- a/src/test/compile-fail/lifetime-obsoleted-self.rs
+++ b/src/test/parse-fail/lifetime-obsoleted-self.rs
diff --git a/src/test/compile-fail/macros-no-semicolon-items.rs b/src/test/parse-fail/macros-no-semicolon-items.rs
index 314292085df..314292085df 100644
--- a/src/test/compile-fail/macros-no-semicolon-items.rs
+++ b/src/test/parse-fail/macros-no-semicolon-items.rs
diff --git a/src/test/compile-fail/no-binary-float-literal.rs b/src/test/parse-fail/no-binary-float-literal.rs
index 2e207f90d36..2e207f90d36 100644
--- a/src/test/compile-fail/no-binary-float-literal.rs
+++ b/src/test/parse-fail/no-binary-float-literal.rs
diff --git a/src/test/compile-fail/no-hex-float-literal.rs b/src/test/parse-fail/no-hex-float-literal.rs
index 4abb6093b24..4abb6093b24 100644
--- a/src/test/compile-fail/no-hex-float-literal.rs
+++ b/src/test/parse-fail/no-hex-float-literal.rs
diff --git a/src/test/compile-fail/no-unsafe-self.rs b/src/test/parse-fail/no-unsafe-self.rs
index 0bf73bbdfe3..0bf73bbdfe3 100644
--- a/src/test/compile-fail/no-unsafe-self.rs
+++ b/src/test/parse-fail/no-unsafe-self.rs
diff --git a/src/test/compile-fail/non-str-meta.rs b/src/test/parse-fail/non-str-meta.rs
index 752f72f0b08..752f72f0b08 100644
--- a/src/test/compile-fail/non-str-meta.rs
+++ b/src/test/parse-fail/non-str-meta.rs
diff --git a/src/test/compile-fail/obsolete-for-sized.rs b/src/test/parse-fail/obsolete-for-sized.rs
index 1b86d08a50d..1b86d08a50d 100644
--- a/src/test/compile-fail/obsolete-for-sized.rs
+++ b/src/test/parse-fail/obsolete-for-sized.rs
diff --git a/src/test/compile-fail/obsolete-proc.rs b/src/test/parse-fail/obsolete-proc.rs
index 5208cdb6ad2..5208cdb6ad2 100644
--- a/src/test/compile-fail/obsolete-proc.rs
+++ b/src/test/parse-fail/obsolete-proc.rs
diff --git a/src/test/compile-fail/qquote-1.rs b/src/test/parse-fail/qquote-1.rs
index deae9a83866..deae9a83866 100644
--- a/src/test/compile-fail/qquote-1.rs
+++ b/src/test/parse-fail/qquote-1.rs
diff --git a/src/test/compile-fail/qquote-2.rs b/src/test/parse-fail/qquote-2.rs
index 978287a681e..978287a681e 100644
--- a/src/test/compile-fail/qquote-2.rs
+++ b/src/test/parse-fail/qquote-2.rs
diff --git a/src/test/compile-fail/regions-fn-bound.rs b/src/test/parse-fail/regions-fn-bound.rs
index c2b52b79f6c..c2b52b79f6c 100644
--- a/src/test/compile-fail/regions-fn-bound.rs
+++ b/src/test/parse-fail/regions-fn-bound.rs
diff --git a/src/test/compile-fail/require-parens-for-chained-comparison.rs b/src/test/parse-fail/require-parens-for-chained-comparison.rs
index f2705f58331..f2705f58331 100644
--- a/src/test/compile-fail/require-parens-for-chained-comparison.rs
+++ b/src/test/parse-fail/require-parens-for-chained-comparison.rs
diff --git a/src/test/compile-fail/struct-no-fields-2.rs b/src/test/parse-fail/struct-no-fields-2.rs
index 4f973f81b16..4f973f81b16 100644
--- a/src/test/compile-fail/struct-no-fields-2.rs
+++ b/src/test/parse-fail/struct-no-fields-2.rs
diff --git a/src/test/compile-fail/struct-no-fields-3.rs b/src/test/parse-fail/struct-no-fields-3.rs
index e594683feed..e594683feed 100644
--- a/src/test/compile-fail/struct-no-fields-3.rs
+++ b/src/test/parse-fail/struct-no-fields-3.rs
diff --git a/src/test/compile-fail/struct-no-fields-4.rs b/src/test/parse-fail/struct-no-fields-4.rs
index 60a0a85d0ab..60a0a85d0ab 100644
--- a/src/test/compile-fail/struct-no-fields-4.rs
+++ b/src/test/parse-fail/struct-no-fields-4.rs
diff --git a/src/test/compile-fail/struct-no-fields-5.rs b/src/test/parse-fail/struct-no-fields-5.rs
index 940fa9c7f27..940fa9c7f27 100644
--- a/src/test/compile-fail/struct-no-fields-5.rs
+++ b/src/test/parse-fail/struct-no-fields-5.rs
diff --git a/src/test/compile-fail/struct-variant-no-fields.rs b/src/test/parse-fail/struct-variant-no-fields.rs
index 41dbbeefc0a..41dbbeefc0a 100644
--- a/src/test/compile-fail/struct-variant-no-fields.rs
+++ b/src/test/parse-fail/struct-variant-no-fields.rs
diff --git a/src/test/compile-fail/struct-variant-no-pub.rs b/src/test/parse-fail/struct-variant-no-pub.rs
index e62b39ad5aa..e62b39ad5aa 100644
--- a/src/test/compile-fail/struct-variant-no-pub.rs
+++ b/src/test/parse-fail/struct-variant-no-pub.rs
diff --git a/src/test/compile-fail/syntax-trait-polarity.rs b/src/test/parse-fail/syntax-trait-polarity.rs
index 1ab79f5c80e..1ab79f5c80e 100644
--- a/src/test/compile-fail/syntax-trait-polarity.rs
+++ b/src/test/parse-fail/syntax-trait-polarity.rs
diff --git a/src/test/compile-fail/tag-variant-disr-non-nullary.rs b/src/test/parse-fail/tag-variant-disr-non-nullary.rs
index 207bbe9a446..207bbe9a446 100644
--- a/src/test/compile-fail/tag-variant-disr-non-nullary.rs
+++ b/src/test/parse-fail/tag-variant-disr-non-nullary.rs
diff --git a/src/test/compile-fail/trailing-carriage-return-in-string.rs b/src/test/parse-fail/trailing-carriage-return-in-string.rs
index 81098333261..81098333261 100644
--- a/src/test/compile-fail/trailing-carriage-return-in-string.rs
+++ b/src/test/parse-fail/trailing-carriage-return-in-string.rs
diff --git a/src/test/compile-fail/trailing-plus-in-bounds.rs b/src/test/parse-fail/trailing-plus-in-bounds.rs
index e8f9ed4d2cf..e8f9ed4d2cf 100644
--- a/src/test/compile-fail/trailing-plus-in-bounds.rs
+++ b/src/test/parse-fail/trailing-plus-in-bounds.rs
diff --git a/src/test/compile-fail/trait-bounds-not-on-impl.rs b/src/test/parse-fail/trait-bounds-not-on-impl.rs
index a034352c4a6..a034352c4a6 100644
--- a/src/test/compile-fail/trait-bounds-not-on-impl.rs
+++ b/src/test/parse-fail/trait-bounds-not-on-impl.rs
diff --git a/src/test/compile-fail/type-parameters-in-field-exprs.rs b/src/test/parse-fail/type-parameters-in-field-exprs.rs
index 54ddb3e19fa..54ddb3e19fa 100644
--- a/src/test/compile-fail/type-parameters-in-field-exprs.rs
+++ b/src/test/parse-fail/type-parameters-in-field-exprs.rs
diff --git a/src/test/compile-fail/unsized2.rs b/src/test/parse-fail/unsized2.rs
index b2eb2064aeb..b2eb2064aeb 100644
--- a/src/test/compile-fail/unsized2.rs
+++ b/src/test/parse-fail/unsized2.rs
diff --git a/src/test/compile-fail/virtual-structs.rs b/src/test/parse-fail/virtual-structs.rs
index 3b3c7d5a30f..3b3c7d5a30f 100644
--- a/src/test/compile-fail/virtual-structs.rs
+++ b/src/test/parse-fail/virtual-structs.rs
diff --git a/src/test/compile-fail/where-clauses-no-bounds-or-predicates.rs b/src/test/parse-fail/where-clauses-no-bounds-or-predicates.rs
index b96c7c2de6b..b96c7c2de6b 100644
--- a/src/test/compile-fail/where-clauses-no-bounds-or-predicates.rs
+++ b/src/test/parse-fail/where-clauses-no-bounds-or-predicates.rs
diff --git a/src/test/pretty/empty-impl.rs b/src/test/pretty/empty-impl.rs
index f22f1b40952..f5205de5c1f 100644
--- a/src/test/pretty/empty-impl.rs
+++ b/src/test/pretty/empty-impl.rs
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait X { }
+trait X { fn dummy(&self) { } }
 impl X for uint { }
 
-trait Y { }
+trait Y { fn dummy(&self) { } }
 impl Y for uint { }
diff --git a/src/test/pretty/path-type-bounds.rs b/src/test/pretty/path-type-bounds.rs
index e27a3365a41..9e1f2aa8bfe 100644
--- a/src/test/pretty/path-type-bounds.rs
+++ b/src/test/pretty/path-type-bounds.rs
@@ -11,7 +11,9 @@
 // pp-exact
 
 
-trait Tr { }
+trait Tr {
+    fn dummy(&self) { }
+}
 impl Tr for int { }
 
 fn foo<'a>(x: Box<Tr+ Sync + 'a>) -> Box<Tr+ Sync + 'a> { x }
diff --git a/src/test/run-fail/bug-811.rs b/src/test/run-fail/bug-811.rs
index e46564f8076..4ad81197286 100644
--- a/src/test/run-fail/bug-811.rs
+++ b/src/test/run-fail/bug-811.rs
@@ -9,6 +9,9 @@
 // except according to those terms.
 
 // error-pattern:quux
+
+use std::marker::PhantomData;
+
 fn test00_start(ch: chan_t<int>, message: int) { send(ch, message); }
 
 type task_id = int;
@@ -17,6 +20,7 @@ type port_id = int;
 struct chan_t<T> {
     task: task_id,
     port: port_id,
+    marker: PhantomData<*mut T>,
 }
 
 fn send<T:Send>(_ch: chan_t<T>, _data: T) { panic!(); }
diff --git a/src/test/run-make/rustdoc-json/foo.rs b/src/test/run-make/rustdoc-json/foo.rs
index d57a7164cdb..3bd56c14193 100644
--- a/src/test/run-make/rustdoc-json/foo.rs
+++ b/src/test/run-make/rustdoc-json/foo.rs
@@ -21,5 +21,5 @@ pub mod bar {
     }
 
     /// *wow*
-    pub trait Doge { }
+    pub trait Doge { fn dummy(&self) { } }
 }
diff --git a/src/test/run-make/rustdoc-negative-impl/foo.rs b/src/test/run-make/rustdoc-negative-impl/foo.rs
index b5fcbf46c5c..6c56bcc9be6 100644
--- a/src/test/run-make/rustdoc-negative-impl/foo.rs
+++ b/src/test/run-make/rustdoc-negative-impl/foo.rs
@@ -13,7 +13,7 @@
 // @matches foo/struct.Alpha.html '//pre' "pub struct Alpha"
 pub struct Alpha;
 // @matches foo/struct.Bravo.html '//pre' "pub struct Bravo<B>"
-pub struct Bravo<B>;
+pub struct Bravo<B>(B);
 
 // @matches foo/struct.Alpha.html '//*[@class="impl"]//code' "impl !Send for Alpha"
 impl !Send for Alpha {}
diff --git a/src/test/run-make/rustdoc-search-index/index.rs b/src/test/run-make/rustdoc-search-index/index.rs
index dd68f2d6f1d..42469a21f22 100644
--- a/src/test/run-make/rustdoc-search-index/index.rs
+++ b/src/test/run-make/rustdoc-search-index/index.rs
@@ -21,6 +21,6 @@ mod private {
     }
 
     pub trait PrivateTrait {
-        fn trait_method() {} // @!has - priv_method
+        fn trait_method(&self) {} // @!has - priv_method
     }
 }
diff --git a/src/test/run-make/rustdoc-smoke/foo.rs b/src/test/run-make/rustdoc-smoke/foo.rs
index 0438c9aba35..f6b73021beb 100644
--- a/src/test/run-make/rustdoc-smoke/foo.rs
+++ b/src/test/run-make/rustdoc-smoke/foo.rs
@@ -26,7 +26,7 @@ pub mod bar {
 
     /// *wow*
     // @has foo/bar/trait.Doge.html
-    pub trait Doge { }
+    pub trait Doge { fn dummy(&self) { } }
 
     // @has foo/bar/struct.Foo.html
     pub struct Foo { x: int, y: uint }
diff --git a/src/test/run-make/rustdoc-viewpath-self/foo.rs b/src/test/run-make/rustdoc-viewpath-self/foo.rs
index da8f7393023..6fd47d84c30 100644
--- a/src/test/run-make/rustdoc-viewpath-self/foo.rs
+++ b/src/test/run-make/rustdoc-viewpath-self/foo.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 pub mod io {
-    pub trait Reader { }
+    pub trait Reader { fn dummy(&self) { } }
 }
 
 pub enum Maybe<A> {
diff --git a/src/test/run-make/rustdoc-where/foo.rs b/src/test/run-make/rustdoc-where/foo.rs
index 68fde60564e..91a7e1c9fd4 100644
--- a/src/test/run-make/rustdoc-where/foo.rs
+++ b/src/test/run-make/rustdoc-where/foo.rs
@@ -8,30 +8,33 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub trait MyTrait {}
+pub trait MyTrait { fn dummy(&self) { } }
 
 // @has foo/struct.Alpha.html '//pre' "pub struct Alpha<A> where A: MyTrait"
-pub struct Alpha<A> where A: MyTrait;
+pub struct Alpha<A>(A) where A: MyTrait;
 // @has foo/trait.Bravo.html '//pre' "pub trait Bravo<B> where B: MyTrait"
-pub trait Bravo<B> where B: MyTrait {}
+pub trait Bravo<B> where B: MyTrait { fn get(&self, B: B); }
 // @has foo/fn.charlie.html '//pre' "pub fn charlie<C>() where C: MyTrait"
 pub fn charlie<C>() where C: MyTrait {}
 
-pub struct Delta<D>;
+pub struct Delta<D>(D);
+
 // @has foo/struct.Delta.html '//*[@class="impl"]//code' \
 //          "impl<D> Delta<D> where D: MyTrait"
 impl<D> Delta<D> where D: MyTrait {
     pub fn delta() {}
 }
 
-pub struct Echo<E>;
+pub struct Echo<E>(E);
+
 // @has foo/struct.Echo.html '//*[@class="impl"]//code' \
 //          "impl<E> MyTrait for Echo<E> where E: MyTrait"
 // @has foo/trait.MyTrait.html '//*[@id="implementors-list"]//code' \
 //          "impl<E> MyTrait for Echo<E> where E: MyTrait"
 impl<E> MyTrait for Echo<E> where E: MyTrait {}
 
-pub enum Foxtrot<F> {}
+pub enum Foxtrot<F> { Foxtrot1(F) }
+
 // @has foo/enum.Foxtrot.html '//*[@class="impl"]//code' \
 //          "impl<F> MyTrait for Foxtrot<F> where F: MyTrait"
 // @has foo/trait.MyTrait.html '//*[@id="implementors-list"]//code' \
diff --git a/src/test/run-make/save-analysis/foo.rs b/src/test/run-make/save-analysis/foo.rs
index db70a245232..38381da3670 100644
--- a/src/test/run-make/save-analysis/foo.rs
+++ b/src/test/run-make/save-analysis/foo.rs
@@ -34,7 +34,7 @@ use std::mem::size_of;
 static uni: &'static str = "Les Miséééééééérables";
 static yy: usize = 25;
 
-static bob: Option<std::vec::CowVec<'static, isize>> = None;
+static bob: Option<&'static [isize]> = None;
 
 // buglink test - see issue #1337.
 
@@ -99,6 +99,7 @@ struct some_fields {
 type SF = some_fields;
 
 trait SuperTrait {
+    fn dummy(&self) { }
 }
 
 trait SomeTrait: SuperTrait {
diff --git a/src/test/run-make/simd-ffi/simd.rs b/src/test/run-make/simd-ffi/simd.rs
index 834a2adf01f..f418d5d1fb7 100755
--- a/src/test/run-make/simd-ffi/simd.rs
+++ b/src/test/run-make/simd-ffi/simd.rs
@@ -70,10 +70,14 @@ pub fn bar(a: i32x4, b: i32x4) -> i32x4 {
 }
 
 #[lang = "sized"]
-trait Sized {}
+pub trait Sized : PhantomFn<Self> {}
 
 #[lang = "copy"]
-trait Copy {}
+pub trait Copy : PhantomFn<Self> {}
+
+#[lang="phantom_fn"]
+pub trait PhantomFn<A:?Sized,R:?Sized=()> { }
+impl<A:?Sized, R:?Sized, U:?Sized> PhantomFn<A,R> for U { }
 
 mod core {
     pub mod marker {
diff --git a/src/test/run-make/symbols-are-reasonable/lib.rs b/src/test/run-make/symbols-are-reasonable/lib.rs
index 1e0570c95ac..e1f36ecda53 100644
--- a/src/test/run-make/symbols-are-reasonable/lib.rs
+++ b/src/test/run-make/symbols-are-reasonable/lib.rs
@@ -11,7 +11,7 @@
 pub static X: &'static str = "foobarbaz";
 pub static Y: &'static [u8] = include_bytes!("lib.rs");
 
-trait Foo {}
+trait Foo { fn dummy(&self) { } }
 impl Foo for uint {}
 
 pub fn dummy() {
diff --git a/src/test/run-make/target-specs/foo.rs b/src/test/run-make/target-specs/foo.rs
index 365fc039a4e..acda8705b19 100644
--- a/src/test/run-make/target-specs/foo.rs
+++ b/src/test/run-make/target-specs/foo.rs
@@ -11,11 +11,15 @@
 #![feature(lang_items, no_std)]
 #![no_std]
 
+#[lang="phantom_fn"]
+trait PhantomFn<A:?Sized,R:?Sized=()> { }
+impl<A:?Sized, R:?Sized, U:?Sized> PhantomFn<A,R> for U { }
+
 #[lang="copy"]
-trait Copy { }
+trait Copy : PhantomFn<Self> { }
 
 #[lang="sized"]
-trait Sized { }
+trait Sized : PhantomFn<Self>  { }
 
 #[lang="start"]
 fn start(_main: *const u8, _argc: int, _argv: *const *const u8) -> int { 0 }
diff --git a/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs b/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs
index 195055f12d1..aecec44f6fd 100644
--- a/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs
+++ b/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs
@@ -25,7 +25,7 @@ impl Drop for Foo {
 }
 
 
-trait Trait {}
+trait Trait { fn dummy(&self) { } }
 impl Trait for Foo {}
 
 pub fn main() {
diff --git a/src/test/run-pass-valgrind/dst-dtor-1.rs b/src/test/run-pass-valgrind/dst-dtor-1.rs
index 47e2a18a999..c49a684de94 100644
--- a/src/test/run-pass-valgrind/dst-dtor-1.rs
+++ b/src/test/run-pass-valgrind/dst-dtor-1.rs
@@ -19,7 +19,7 @@ impl Drop for Foo {
     }
 }
 
-trait Trait {}
+trait Trait { fn dummy(&self) { } }
 impl Trait for Foo {}
 
 struct Fat<T: ?Sized> {
diff --git a/src/test/run-pass/associated-types-basic.rs b/src/test/run-pass/associated-types-basic.rs
index 3314b613201..f5521f7da85 100644
--- a/src/test/run-pass/associated-types-basic.rs
+++ b/src/test/run-pass/associated-types-basic.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo {
+use std::marker::MarkerTrait;
+
+trait Foo : MarkerTrait {
     type T;
 }
 
diff --git a/src/test/run-pass/associated-types-conditional-dispatch.rs b/src/test/run-pass/associated-types-conditional-dispatch.rs
index f21b7183d70..aa65b0ed10b 100644
--- a/src/test/run-pass/associated-types-conditional-dispatch.rs
+++ b/src/test/run-pass/associated-types-conditional-dispatch.rs
@@ -14,6 +14,7 @@
 // `Target=[A]`, then the impl marked with `(*)` is seen to conflict
 // with all the others.
 
+use std::marker::PhantomData;
 use std::ops::Deref;
 
 pub trait MyEq<U: ?Sized=Self> {
@@ -41,7 +42,8 @@ impl<'a, A, B, Lhs> MyEq<[B; 0]> for Lhs
 }
 
 struct DerefWithHelper<H, T> {
-    pub helper: H
+    pub helper: H,
+    pub marker: PhantomData<T>,
 }
 
 trait Helper<T> {
@@ -63,7 +65,8 @@ impl<T, H: Helper<T>> Deref for DerefWithHelper<H, T> {
 }
 
 pub fn check<T: MyEq>(x: T, y: T) -> bool {
-    let d: DerefWithHelper<Option<T>, T> = DerefWithHelper { helper: Some(x) };
+    let d: DerefWithHelper<Option<T>, T> = DerefWithHelper { helper: Some(x),
+                                                             marker: PhantomData };
     d.eq(&y)
 }
 
diff --git a/src/test/run-pass/associated-types-issue-20371.rs b/src/test/run-pass/associated-types-issue-20371.rs
index d35b7331d4d..40ef7f3531c 100644
--- a/src/test/run-pass/associated-types-issue-20371.rs
+++ b/src/test/run-pass/associated-types-issue-20371.rs
@@ -11,6 +11,8 @@
 // Test that we are able to have an impl that defines an associated type
 // before the actual trait.
 
+use std::marker::MarkerTrait;
+
 impl X for f64 { type Y = int; }
-trait X {type Y; }
+trait X : MarkerTrait { type Y; }
 fn main() {}
diff --git a/src/test/run-pass/associated-types-issue-21212.rs b/src/test/run-pass/associated-types-issue-21212.rs
index ced44250e4d..3c91577362a 100644
--- a/src/test/run-pass/associated-types-issue-21212.rs
+++ b/src/test/run-pass/associated-types-issue-21212.rs
@@ -20,7 +20,8 @@ pub trait Parser {
         panic!()
     }
 }
-impl <P> Parser for P  {
+
+impl <P> Parser for P {
     type Input = ();
 }
 
diff --git a/src/test/run-pass/associated-types-nested-projections.rs b/src/test/run-pass/associated-types-nested-projections.rs
index e3227613159..2ee8ef0d3dd 100644
--- a/src/test/run-pass/associated-types-nested-projections.rs
+++ b/src/test/run-pass/associated-types-nested-projections.rs
@@ -10,11 +10,12 @@
 
 // Test that we can resolve nested projection types. Issue #20666.
 
+use std::marker::MarkerTrait;
 use std::slice;
 
-trait Bound {}
+trait Bound : MarkerTrait {}
 
-impl<'a> Bound for &'a int {}
+impl<'a> Bound for &'a i32 {}
 
 trait IntoIterator {
     type Iter: Iterator;
diff --git a/src/test/run-pass/associated-types-normalize-in-bounds-binding.rs b/src/test/run-pass/associated-types-normalize-in-bounds-binding.rs
index dd5814f875b..de96af83f59 100644
--- a/src/test/run-pass/associated-types-normalize-in-bounds-binding.rs
+++ b/src/test/run-pass/associated-types-normalize-in-bounds-binding.rs
@@ -13,7 +13,9 @@
 
 #![allow(dead_code)]
 
-pub trait Integral {
+use std::marker::MarkerTrait;
+
+pub trait Integral : MarkerTrait {
     type Opposite;
 }
 
@@ -27,6 +29,8 @@ impl Integral for u32 {
 
 pub trait FnLike<A> {
     type R;
+
+    fn dummy(&self, a: A) -> Self::R { loop { } }
 }
 
 fn foo<T>()
diff --git a/src/test/run-pass/associated-types-normalize-in-bounds-ufcs.rs b/src/test/run-pass/associated-types-normalize-in-bounds-ufcs.rs
index 1d264655bc4..8617750ca53 100644
--- a/src/test/run-pass/associated-types-normalize-in-bounds-ufcs.rs
+++ b/src/test/run-pass/associated-types-normalize-in-bounds-ufcs.rs
@@ -11,15 +11,17 @@
 // Test that we normalize associated types that appear in bounds; if
 // we didn't, the call to `self.split2()` fails to type check.
 
-struct Splits<'a, T, P>;
-struct SplitsN<I>;
+use std::marker::PhantomData;
+
+struct Splits<'a, T:'a, P>(PhantomData<(&'a T, P)>);
+struct SplitsN<I>(PhantomData<I>);
 
 trait SliceExt2 {
     type Item;
 
     fn split2<'a, P>(&'a self, pred: P) -> Splits<'a, Self::Item, P>
         where P: FnMut(&Self::Item) -> bool;
-    fn splitn2<'a, P>(&'a self, n: uint, pred: P) -> SplitsN<Splits<'a, Self::Item, P>>
+    fn splitn2<'a, P>(&'a self, n: u32, pred: P) -> SplitsN<Splits<'a, Self::Item, P>>
         where P: FnMut(&Self::Item) -> bool;
 }
 
@@ -30,7 +32,7 @@ impl<T> SliceExt2 for [T] {
         loop {}
     }
 
-    fn splitn2<P>(&self, n: uint, pred: P) -> SplitsN<Splits<T, P>> where P: FnMut(&T) -> bool {
+    fn splitn2<P>(&self, n: u32, pred: P) -> SplitsN<Splits<T, P>> where P: FnMut(&T) -> bool {
         SliceExt2::split2(self, pred);
         loop {}
     }
diff --git a/src/test/run-pass/associated-types-normalize-in-bounds.rs b/src/test/run-pass/associated-types-normalize-in-bounds.rs
index 742bab0578e..94cfcb83653 100644
--- a/src/test/run-pass/associated-types-normalize-in-bounds.rs
+++ b/src/test/run-pass/associated-types-normalize-in-bounds.rs
@@ -11,15 +11,17 @@
 // Test that we normalize associated types that appear in bounds; if
 // we didn't, the call to `self.split2()` fails to type check.
 
-struct Splits<'a, T, P>;
-struct SplitsN<I>;
+use std::marker::PhantomData;
+
+struct Splits<'a, T, P>(PhantomData<(&'a(),T,P)>);
+struct SplitsN<I>(PhantomData<I>);
 
 trait SliceExt2 {
     type Item;
 
     fn split2<'a, P>(&'a self, pred: P) -> Splits<'a, Self::Item, P>
         where P: FnMut(&Self::Item) -> bool;
-    fn splitn2<'a, P>(&'a self, n: uint, pred: P) -> SplitsN<Splits<'a, Self::Item, P>>
+    fn splitn2<'a, P>(&'a self, n: usize, pred: P) -> SplitsN<Splits<'a, Self::Item, P>>
         where P: FnMut(&Self::Item) -> bool;
 }
 
@@ -30,7 +32,7 @@ impl<T> SliceExt2 for [T] {
         loop {}
     }
 
-    fn splitn2<P>(&self, n: uint, pred: P) -> SplitsN<Splits<T, P>> where P: FnMut(&T) -> bool {
+    fn splitn2<P>(&self, n: usize, pred: P) -> SplitsN<Splits<T, P>> where P: FnMut(&T) -> bool {
         self.split2(pred);
         loop {}
     }
diff --git a/src/test/run-pass/associated-types-normalize-unifield-struct.rs b/src/test/run-pass/associated-types-normalize-unifield-struct.rs
index 5aafe93067c..2288e19aae0 100644
--- a/src/test/run-pass/associated-types-normalize-unifield-struct.rs
+++ b/src/test/run-pass/associated-types-normalize-unifield-struct.rs
@@ -13,7 +13,10 @@
 
 
 pub trait OffsetState: Sized {}
-pub trait Offset { type State: OffsetState; }
+pub trait Offset {
+    type State: OffsetState;
+    fn dummy(&self) { }
+}
 
 #[derive(Copy)] pub struct X;
 impl Offset for X { type State = Y; }
diff --git a/src/test/run-pass/associated-types-projection-from-known-type-in-impl.rs b/src/test/run-pass/associated-types-projection-from-known-type-in-impl.rs
index 0a1a8589dec..c65d2db9b0c 100644
--- a/src/test/run-pass/associated-types-projection-from-known-type-in-impl.rs
+++ b/src/test/run-pass/associated-types-projection-from-known-type-in-impl.rs
@@ -13,6 +13,8 @@
 trait Int
 {
     type T;
+
+    fn dummy(&self) { }
 }
 
 trait NonZero
diff --git a/src/test/run-pass/associated-types-projection-in-object-type.rs b/src/test/run-pass/associated-types-projection-in-object-type.rs
index 44dd49b7297..a9c34a605ce 100644
--- a/src/test/run-pass/associated-types-projection-in-object-type.rs
+++ b/src/test/run-pass/associated-types-projection-in-object-type.rs
@@ -18,6 +18,8 @@ use std::cell::RefCell;
 
 pub trait Subscriber {
     type Input;
+
+    fn dummy(&self) { }
 }
 
 pub trait Publisher<'a> {
diff --git a/src/test/run-pass/associated-types-projection-in-supertrait.rs b/src/test/run-pass/associated-types-projection-in-supertrait.rs
index e6fec675b03..4d2358fae27 100644
--- a/src/test/run-pass/associated-types-projection-in-supertrait.rs
+++ b/src/test/run-pass/associated-types-projection-in-supertrait.rs
@@ -14,6 +14,8 @@
 trait A
 {
     type TA;
+
+    fn dummy(&self) { }
 }
 
 trait B<TB>
diff --git a/src/test/run-pass/associated-types-projection-in-where-clause.rs b/src/test/run-pass/associated-types-projection-in-where-clause.rs
index 10a459f3c36..3f3f4fbd1d6 100644
--- a/src/test/run-pass/associated-types-projection-in-where-clause.rs
+++ b/src/test/run-pass/associated-types-projection-in-where-clause.rs
@@ -13,6 +13,8 @@
 trait Int
 {
     type T;
+
+    fn dummy(&self) { }
 }
 
 trait NonZero
diff --git a/src/test/run-pass/associated-types-ref-in-struct-literal.rs b/src/test/run-pass/associated-types-ref-in-struct-literal.rs
index 022c8f4cd01..67fe11d8fed 100644
--- a/src/test/run-pass/associated-types-ref-in-struct-literal.rs
+++ b/src/test/run-pass/associated-types-ref-in-struct-literal.rs
@@ -12,6 +12,8 @@
 
 pub trait Foo {
     type Bar;
+
+    fn dummy(&self) { }
 }
 
 impl Foo for int {
diff --git a/src/test/run-pass/associated-types-resolve-lifetime.rs b/src/test/run-pass/associated-types-resolve-lifetime.rs
index e7a8061a346..a4b0b1a6e03 100644
--- a/src/test/run-pass/associated-types-resolve-lifetime.rs
+++ b/src/test/run-pass/associated-types-resolve-lifetime.rs
@@ -15,6 +15,8 @@ trait Get<T> {
 trait Trait<'a> {
     type T: 'static;
     type U: Get<&'a int>;
+
+    fn dummy(&'a self) { }
 }
 
 fn main() {}
diff --git a/src/test/run-pass/associated-types-struct-field-named.rs b/src/test/run-pass/associated-types-struct-field-named.rs
index 1ded34ff3ff..8667f6c8430 100644
--- a/src/test/run-pass/associated-types-struct-field-named.rs
+++ b/src/test/run-pass/associated-types-struct-field-named.rs
@@ -13,6 +13,8 @@
 
 pub trait UnifyKey {
     type Value;
+
+    fn dummy(&self) { }
 }
 
 pub struct Node<K:UnifyKey> {
diff --git a/src/test/run-pass/associated-types-struct-field-numbered.rs b/src/test/run-pass/associated-types-struct-field-numbered.rs
index 3669dec4fbd..9503f78a71b 100644
--- a/src/test/run-pass/associated-types-struct-field-numbered.rs
+++ b/src/test/run-pass/associated-types-struct-field-numbered.rs
@@ -13,6 +13,8 @@
 
 pub trait UnifyKey {
     type Value;
+
+    fn dummy(&self) { }
 }
 
 pub struct Node<K:UnifyKey>(K, K::Value);
diff --git a/src/test/run-pass/associated-types-sugar-path.rs b/src/test/run-pass/associated-types-sugar-path.rs
index 3b70e941ac5..c068065ac6a 100644
--- a/src/test/run-pass/associated-types-sugar-path.rs
+++ b/src/test/run-pass/associated-types-sugar-path.rs
@@ -31,8 +31,9 @@ pub fn bar<T: Foo>(a: T, x: T::A) -> T::A {
 // Using a type via an impl.
 trait C {
     fn f();
+    fn g(&self) { }
 }
-struct B<X>;
+struct B<X>(X);
 impl<T: Foo> C for B<T> {
     fn f() {
         let x: T::A = panic!();
diff --git a/src/test/run-pass/bitv-perf-test.rs b/src/test/run-pass/bitv-perf-test.rs
index b6d428924e3..7bb9f042fe8 100644
--- a/src/test/run-pass/bitv-perf-test.rs
+++ b/src/test/run-pass/bitv-perf-test.rs
@@ -13,11 +13,11 @@
 #![feature(box_syntax)]
 
 extern crate collections;
-use std::collections::Bitv;
+use std::collections::BitVec;
 
 fn bitv_test() {
-    let mut v1 = box Bitv::from_elem(31, false);
-    let v2 = box Bitv::from_elem(31, true);
+    let mut v1 = box BitVec::from_elem(31, false);
+    let v2 = box BitVec::from_elem(31, true);
     v1.union(&*v2);
 }
 
diff --git a/src/test/run-pass/borrowck-trait-lifetime.rs b/src/test/run-pass/borrowck-trait-lifetime.rs
index b39f03a93c9..a2b0fa56635 100644
--- a/src/test/run-pass/borrowck-trait-lifetime.rs
+++ b/src/test/run-pass/borrowck-trait-lifetime.rs
@@ -12,8 +12,11 @@
 // to the same lifetime on a trait succeeds. See issue #10766.
 
 #![allow(dead_code)]
+
+use std::marker;
+
 fn main() {
-    trait T {}
+    trait T { fn foo(&self) {} }
 
     fn f<'a, V: T>(v: &'a V) -> &'a T {
         v as &'a T
diff --git a/src/test/run-pass/bug-7295.rs b/src/test/run-pass/bug-7295.rs
index ea711d78dd2..143ebfdabfa 100644
--- a/src/test/run-pass/bug-7295.rs
+++ b/src/test/run-pass/bug-7295.rs
@@ -9,10 +9,10 @@
 // except according to those terms.
 
 pub trait Foo<T> {
-    fn func1<U>(&self, t: U);
+    fn func1<U>(&self, t: U, w: T);
 
-    fn func2<U>(&self, t: U) {
-        self.func1(t);
+    fn func2<U>(&self, t: U, w: T) {
+        self.func1(t, w);
     }
 }
 
diff --git a/src/test/run-pass/builtin-superkinds-in-metadata.rs b/src/test/run-pass/builtin-superkinds-in-metadata.rs
index c115415bb9b..7eaed910124 100644
--- a/src/test/run-pass/builtin-superkinds-in-metadata.rs
+++ b/src/test/run-pass/builtin-superkinds-in-metadata.rs
@@ -16,6 +16,7 @@
 extern crate trait_superkinds_in_metadata;
 use trait_superkinds_in_metadata::{RequiresRequiresShareAndSend, RequiresShare};
 use trait_superkinds_in_metadata::{RequiresCopy};
+use std::marker;
 
 #[derive(Copy)]
 struct X<T>(T);
diff --git a/src/test/run-pass/builtin-superkinds-phantom-typaram.rs b/src/test/run-pass/builtin-superkinds-phantom-typaram.rs
index 7e1b2821937..964c28dc945 100644
--- a/src/test/run-pass/builtin-superkinds-phantom-typaram.rs
+++ b/src/test/run-pass/builtin-superkinds-phantom-typaram.rs
@@ -12,10 +12,12 @@
 // super-builtin-kind of a trait, if the type parameter is never used,
 // the type can implement the trait anyway.
 
+use std::marker;
+
 trait Foo : Send { }
 
-struct X<T>(());
+struct X<T> { marker: marker::PhantomData<T> }
 
-impl <T> Foo for X<T> { }
+impl<T:Send> Foo for X<T> { }
 
 pub fn main() { }
diff --git a/src/test/run-pass/c-stack-returning-int64.rs b/src/test/run-pass/c-stack-returning-int64.rs
index 22c322b86c9..6246ee9c6c4 100644
--- a/src/test/run-pass/c-stack-returning-int64.rs
+++ b/src/test/run-pass/c-stack-returning-int64.rs
@@ -24,12 +24,12 @@ mod mlibc {
 }
 
 fn atol(s: String) -> int {
-    let c = CString::from_slice(s.as_bytes());
+    let c = CString::new(s).unwrap();
     unsafe { mlibc::atol(c.as_ptr()) as int }
 }
 
 fn atoll(s: String) -> i64 {
-    let c = CString::from_slice(s.as_bytes());
+    let c = CString::new(s).unwrap();
     unsafe { mlibc::atoll(c.as_ptr()) as i64 }
 }
 
diff --git a/src/test/run-pass/class-typarams.rs b/src/test/run-pass/class-typarams.rs
index 68457095944..b56a749d33b 100644
--- a/src/test/run-pass/class-typarams.rs
+++ b/src/test/run-pass/class-typarams.rs
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker::PhantomData;
+
 struct cat<U> {
     meows : uint,
-
     how_hungry : int,
+    m: PhantomData<U>
 }
 
 impl<U> cat<U> {
@@ -22,7 +24,8 @@ impl<U> cat<U> {
 fn cat<U>(in_x : uint, in_y : int) -> cat<U> {
     cat {
         meows: in_x,
-        how_hungry: in_y
+        how_hungry: in_y,
+        m: PhantomData
     }
 }
 
diff --git a/src/test/run-pass/const-polymorphic-paths.rs b/src/test/run-pass/const-polymorphic-paths.rs
index f8f92a56adb..dce12030f79 100644
--- a/src/test/run-pass/const-polymorphic-paths.rs
+++ b/src/test/run-pass/const-polymorphic-paths.rs
@@ -11,7 +11,7 @@
 #![feature(macro_rules)]
 
 use std::borrow::{Cow, IntoCow};
-use std::collections::Bitv;
+use std::collections::BitVec;
 use std::default::Default;
 use std::iter::FromIterator;
 use std::ops::Add;
@@ -63,8 +63,8 @@ tests! {
     Vec::<()>::new, fn() -> Vec<()>, ();
     Vec::with_capacity, fn(uint) -> Vec<()>, (5);
     Vec::<()>::with_capacity, fn(uint) -> Vec<()>, (5);
-    Bitv::from_fn, fn(uint, fn(uint) -> bool) -> Bitv, (5, odd);
-    Bitv::from_fn::<fn(uint) -> bool>, fn(uint, fn(uint) -> bool) -> Bitv, (5, odd);
+    BitVec::from_fn, fn(uint, fn(uint) -> bool) -> BitVec, (5, odd);
+    BitVec::from_fn::<fn(uint) -> bool>, fn(uint, fn(uint) -> bool) -> BitVec, (5, odd);
 
     // Inherent non-static method.
     Vec::map_in_place, fn(Vec<u8>, fn(u8) -> i8) -> Vec<i8>, (vec![b'f', b'o', b'o'], u8_as_i8);
@@ -100,8 +100,8 @@ tests! {
     Add::add, fn(i32, i32) -> i32, (5, 6);
     <i32 as Add<_>>::add, fn(i32, i32) -> i32, (5, 6);
     <i32 as Add<i32>>::add, fn(i32, i32) -> i32, (5, 6);
-    <String as IntoCow<_, _>>::into_cow, fn(String) -> Cow<'static, String, str>,
+    <String as IntoCow<_>>::into_cow, fn(String) -> Cow<'static, str>,
         ("foo".to_string());
-    <String as IntoCow<'static, _, _>>::into_cow, fn(String) -> Cow<'static, String, str>,
+    <String as IntoCow<'static, _>>::into_cow, fn(String) -> Cow<'static, str>,
         ("foo".to_string());
 }
diff --git a/src/test/run-pass/deriving-hash.rs b/src/test/run-pass/deriving-hash.rs
index 02ab7e5db5b..5fe7c8bb94b 100644
--- a/src/test/run-pass/deriving-hash.rs
+++ b/src/test/run-pass/deriving-hash.rs
@@ -17,7 +17,7 @@ struct Person {
     phone: uint,
 }
 
-fn hash<T: Hash<SipHasher>>(t: &T) -> u64 {
+fn hash<T: Hash>(t: &T) -> u64 {
     std::hash::hash::<T, SipHasher>(t)
 }
 
diff --git a/src/test/run-pass/deriving-meta-multiple.rs b/src/test/run-pass/deriving-meta-multiple.rs
index f45dce9da63..62ec2f8e590 100644
--- a/src/test/run-pass/deriving-meta-multiple.rs
+++ b/src/test/run-pass/deriving-meta-multiple.rs
@@ -20,7 +20,7 @@ struct Foo {
     baz: int
 }
 
-fn hash<T: Hash<SipHasher>>(_t: &T) {}
+fn hash<T: Hash>(_t: &T) {}
 
 pub fn main() {
     let a = Foo {bar: 4, baz: -3};
diff --git a/src/test/run-pass/deriving-meta.rs b/src/test/run-pass/deriving-meta.rs
index d6a2fad08ed..82cf9db3232 100644
--- a/src/test/run-pass/deriving-meta.rs
+++ b/src/test/run-pass/deriving-meta.rs
@@ -17,7 +17,7 @@ struct Foo {
     baz: int
 }
 
-fn hash<T: Hash<SipHasher>>(_t: &T) {}
+fn hash<T: Hash>(_t: &T) {}
 
 pub fn main() {
     let a = Foo {bar: 4, baz: -3};
diff --git a/src/test/run-pass/dst-coercions.rs b/src/test/run-pass/dst-coercions.rs
index dbad546ce1a..30ed0b8e402 100644
--- a/src/test/run-pass/dst-coercions.rs
+++ b/src/test/run-pass/dst-coercions.rs
@@ -11,7 +11,7 @@
 // Test coercions involving DST and/or raw pointers
 
 struct S;
-trait T {}
+trait T { fn dummy(&self) { } }
 impl T for S {}
 
 pub fn main() {
diff --git a/src/test/run-pass/enum-null-pointer-opt.rs b/src/test/run-pass/enum-null-pointer-opt.rs
index 797c26556aa..023376ce473 100644
--- a/src/test/run-pass/enum-null-pointer-opt.rs
+++ b/src/test/run-pass/enum-null-pointer-opt.rs
@@ -16,7 +16,7 @@ use std::mem::size_of;
 use std::rc::Rc;
 use std::sync::Arc;
 
-trait Trait {}
+trait Trait { fn dummy(&self) { } }
 
 fn main() {
     // Functions
diff --git a/src/test/run-pass/explicit-self-generic.rs b/src/test/run-pass/explicit-self-generic.rs
index 066a5f9580a..382c5c58e92 100644
--- a/src/test/run-pass/explicit-self-generic.rs
+++ b/src/test/run-pass/explicit-self-generic.rs
@@ -15,21 +15,19 @@
 struct LM { resize_at: uint, size: uint }
 
 enum HashMap<K,V> {
-    HashMap_(LM)
+    HashMap_(LM, Vec<(K,V)>)
 }
 
-impl<K,V> Copy for HashMap<K,V> {}
-
 fn linear_map<K,V>() -> HashMap<K,V> {
     HashMap::HashMap_(LM{
         resize_at: 32,
-        size: 0})
+        size: 0}, Vec::new())
 }
 
 impl<K,V> HashMap<K,V> {
     pub fn len(&mut self) -> uint {
         match *self {
-            HashMap::HashMap_(l) => l.size
+            HashMap::HashMap_(ref l, _) => l.size
         }
     }
 }
diff --git a/src/test/run-pass/foreign-fn-linkname.rs b/src/test/run-pass/foreign-fn-linkname.rs
index 592ab7d0e6e..24b711328a1 100644
--- a/src/test/run-pass/foreign-fn-linkname.rs
+++ b/src/test/run-pass/foreign-fn-linkname.rs
@@ -24,7 +24,7 @@ mod mlibc {
 
 fn strlen(str: String) -> uint {
     // C string is terminated with a zero
-    let s = CString::from_slice(str.as_bytes());
+    let s = CString::new(str).unwrap();
     unsafe {
         mlibc::my_strlen(s.as_ptr()) as uint
     }
diff --git a/src/test/run-pass/generic-default-type-params-cross-crate.rs b/src/test/run-pass/generic-default-type-params-cross-crate.rs
index ed8c6e73255..bf02b82d1a0 100644
--- a/src/test/run-pass/generic-default-type-params-cross-crate.rs
+++ b/src/test/run-pass/generic-default-type-params-cross-crate.rs
@@ -12,13 +12,13 @@
 
 extern crate default_type_params_xc;
 
-struct Vec<T, A = default_type_params_xc::Heap>;
+struct Vec<T, A = default_type_params_xc::Heap>(Option<(T,A)>);
 
 struct Foo;
 
 fn main() {
-    let _a = Vec::<int>;
-    let _b = Vec::<int, default_type_params_xc::FakeHeap>;
-    let _c = default_type_params_xc::FakeVec::<int>;
-    let _d = default_type_params_xc::FakeVec::<int, Foo>;
+    let _a = Vec::<int>(None);
+    let _b = Vec::<int, default_type_params_xc::FakeHeap>(None);
+    let _c = default_type_params_xc::FakeVec::<int> { f: None };
+    let _d = default_type_params_xc::FakeVec::<int, Foo> { f: None };
 }
diff --git a/src/test/run-pass/hrtb-opt-in-copy.rs b/src/test/run-pass/hrtb-opt-in-copy.rs
index 9c9f95f61e9..7b16bb867e7 100644
--- a/src/test/run-pass/hrtb-opt-in-copy.rs
+++ b/src/test/run-pass/hrtb-opt-in-copy.rs
@@ -18,7 +18,7 @@
 
 #![allow(dead_code)]
 
-use std::marker;
+use std::marker::PhantomData;
 
 #[derive(Copy)]
 struct Foo<T> { x: T }
@@ -26,7 +26,7 @@ struct Foo<T> { x: T }
 type Ty<'tcx> = &'tcx TyS<'tcx>;
 
 enum TyS<'tcx> {
-    Boop(marker::InvariantLifetime<'tcx>)
+    Boop(PhantomData<*mut &'tcx ()>)
 }
 
 #[derive(Copy)]
diff --git a/src/test/run-pass/inner-static.rs b/src/test/run-pass/inner-static.rs
index f9b430c1553..e4026a8fd01 100644
--- a/src/test/run-pass/inner-static.rs
+++ b/src/test/run-pass/inner-static.rs
@@ -13,9 +13,9 @@
 extern crate inner_static;
 
 pub fn main() {
-    let a = inner_static::A::<()>;
-    let b = inner_static::B::<()>;
-    let c = inner_static::test::A::<()>;
+    let a = inner_static::A::<()> { v: () };
+    let b = inner_static::B::<()> { v: () };
+    let c = inner_static::test::A::<()> { v: () };
     assert_eq!(a.bar(), 2);
     assert_eq!(b.bar(), 4);
     assert_eq!(c.bar(), 6);
diff --git a/src/test/run-pass/issue-10456.rs b/src/test/run-pass/issue-10456.rs
index b714d87f4ef..da73c4b27ac 100644
--- a/src/test/run-pass/issue-10456.rs
+++ b/src/test/run-pass/issue-10456.rs
@@ -14,7 +14,9 @@ pub trait Bar {
     fn bar(&self);
 }
 
-pub trait Baz {}
+pub trait Baz {
+    fn baz(&self) { }
+}
 
 impl<T: Baz> Bar for T {
     fn bar(&self) {}
diff --git a/src/test/run-pass/issue-10802.rs b/src/test/run-pass/issue-10802.rs
index de2b4c51e52..174a69e1135 100644
--- a/src/test/run-pass/issue-10802.rs
+++ b/src/test/run-pass/issue-10802.rs
@@ -29,7 +29,7 @@ impl Drop for DroppableEnum {
     }
 }
 
-trait MyTrait { }
+trait MyTrait { fn dummy(&self) { } }
 impl MyTrait for Box<DroppableStruct> {}
 impl MyTrait for Box<DroppableEnum> {}
 
diff --git a/src/test/run-pass/issue-10902.rs b/src/test/run-pass/issue-10902.rs
index 324a1701b2f..7fab6662ee0 100644
--- a/src/test/run-pass/issue-10902.rs
+++ b/src/test/run-pass/issue-10902.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 pub mod two_tuple {
-    pub trait T {}
+    pub trait T { fn dummy(&self) { } }
     pub struct P<'a>(&'a (T + 'a), &'a (T + 'a));
     pub fn f<'a>(car: &'a T, cdr: &'a T) -> P<'a> {
         P(car, cdr)
@@ -17,7 +17,7 @@ pub mod two_tuple {
 }
 
 pub mod two_fields {
-    pub trait T {}
+    pub trait T { fn dummy(&self) { } }
     pub struct P<'a> { car: &'a (T + 'a), cdr: &'a (T + 'a) }
     pub fn f<'a>(car: &'a T, cdr: &'a T) -> P<'a> {
         P{ car: car, cdr: cdr }
diff --git a/src/test/run-pass/issue-11205.rs b/src/test/run-pass/issue-11205.rs
index d7c6c1b1bb2..1325b51a54f 100644
--- a/src/test/run-pass/issue-11205.rs
+++ b/src/test/run-pass/issue-11205.rs
@@ -12,7 +12,7 @@
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-trait Foo {}
+trait Foo { fn dummy(&self) { } }
 impl Foo for int {}
 fn foo(_: [&Foo; 2]) {}
 fn foos(_: &[&Foo]) {}
diff --git a/src/test/run-pass/issue-11384.rs b/src/test/run-pass/issue-11384.rs
index a511149b05e..26634fabf5a 100644
--- a/src/test/run-pass/issue-11384.rs
+++ b/src/test/run-pass/issue-11384.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Common {}
+trait Common { fn dummy(&self) { } }
 
 impl<'t, T> Common for (T, &'t T) {}
 
diff --git a/src/test/run-pass/issue-11612.rs b/src/test/run-pass/issue-11612.rs
index fa25d25df05..3c69377b375 100644
--- a/src/test/run-pass/issue-11612.rs
+++ b/src/test/run-pass/issue-11612.rs
@@ -12,7 +12,7 @@
 // We weren't updating the auto adjustments with all the resolved
 // type information after type check.
 
-trait A {}
+trait A { fn dummy(&self) { } }
 
 struct B<'a, T:'a> {
     f: &'a T
diff --git a/src/test/run-pass/issue-11677.rs b/src/test/run-pass/issue-11677.rs
index 6fa45058694..7cccac4483d 100644
--- a/src/test/run-pass/issue-11677.rs
+++ b/src/test/run-pass/issue-11677.rs
@@ -14,13 +14,18 @@
 
 // this code used to cause an ICE
 
-trait X<T> {}
+use std::marker;
+
+trait X<T> {
+    fn dummy(&self) -> T { panic!() }
+}
 
 struct S<T> {f: Box<X<T>+'static>,
              g: Box<X<T>+'static>}
 
 struct F;
-impl X<int> for F {}
+impl X<int> for F {
+}
 
 fn main() {
   S {f: box F, g: box F};
diff --git a/src/test/run-pass/issue-11736.rs b/src/test/run-pass/issue-11736.rs
index d9bae6886fa..b901e95ff55 100644
--- a/src/test/run-pass/issue-11736.rs
+++ b/src/test/run-pass/issue-11736.rs
@@ -10,13 +10,13 @@
 
 extern crate collections;
 
-use std::collections::Bitv;
+use std::collections::BitVec;
 use std::num::Float;
 
 fn main() {
     // Generate sieve of Eratosthenes for n up to 1e6
     let n = 1000000_usize;
-    let mut sieve = Bitv::from_elem(n+1, true);
+    let mut sieve = BitVec::from_elem(n+1, true);
     let limit: uint = (n as f32).sqrt() as uint;
     for i in 2..limit+1 {
         if sieve[i] {
diff --git a/src/test/run-pass/issue-13105.rs b/src/test/run-pass/issue-13105.rs
index 7fab36bd64e..64807dc44e0 100644
--- a/src/test/run-pass/issue-13105.rs
+++ b/src/test/run-pass/issue-13105.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo {
+use std::marker::MarkerTrait;
+
+trait Foo : MarkerTrait {
     fn quux(u8) {}
 }
 
diff --git a/src/test/run-pass/issue-14399.rs b/src/test/run-pass/issue-14399.rs
index 7e533c2cf86..db7eacce9d1 100644
--- a/src/test/run-pass/issue-14399.rs
+++ b/src/test/run-pass/issue-14399.rs
@@ -19,7 +19,7 @@
 #[derive(Clone)]
 struct B1;
 
-trait A {}
+trait A { fn foo(&self) {} }
 impl A for B1 {}
 
 fn main() {
diff --git a/src/test/run-pass/issue-14589.rs b/src/test/run-pass/issue-14589.rs
index d9763baa826..71d88ee6215 100644
--- a/src/test/run-pass/issue-14589.rs
+++ b/src/test/run-pass/issue-14589.rs
@@ -17,17 +17,18 @@
 fn main() {
     send::<Box<Foo>>(box Output(0));
     Test::<Box<Foo>>::foo(box Output(0));
-    Test::<Box<Foo>>.send(box Output(0));
+    Test::<Box<Foo>>::new().send(box Output(0));
 }
 
 fn send<T>(_: T) {}
 
-struct Test<T>;
+struct Test<T> { marker: std::marker::PhantomData<T> }
 impl<T> Test<T> {
+    fn new() -> Test<T> { Test { marker: ::std::marker::PhantomData } }
     fn foo(_: T) {}
     fn send(&self, _: T) {}
 }
 
-trait Foo {}
+trait Foo { fn dummy(&self) { }}
 struct Output(int);
 impl Foo for Output {}
diff --git a/src/test/run-pass/issue-14958.rs b/src/test/run-pass/issue-14958.rs
index 814a743648d..6335f79be6c 100644
--- a/src/test/run-pass/issue-14958.rs
+++ b/src/test/run-pass/issue-14958.rs
@@ -10,7 +10,7 @@
 
 #![feature(unboxed_closures)]
 
-trait Foo {}
+trait Foo { fn dummy(&self) { }}
 
 struct Bar;
 
diff --git a/src/test/run-pass/issue-14959.rs b/src/test/run-pass/issue-14959.rs
index 33281d7d78f..53d0f7dae05 100644
--- a/src/test/run-pass/issue-14959.rs
+++ b/src/test/run-pass/issue-14959.rs
@@ -12,8 +12,8 @@
 
 use std::ops::Fn;
 
-trait Response {}
-trait Request {}
+trait Response { fn dummy(&self) { } }
+trait Request { fn dummy(&self) { } }
 trait Ingot<R, S> {
     fn enter(&mut self, _: &mut R, _: &mut S, a: &mut Alloy) -> Status;
 }
@@ -21,7 +21,7 @@ trait Ingot<R, S> {
 #[allow(dead_code)]
 struct HelloWorld;
 
-struct SendFile<'a>;
+struct SendFile;
 struct Alloy;
 enum Status {
     Continue
@@ -33,7 +33,7 @@ impl Alloy {
     }
 }
 
-impl<'a, 'b> Fn<(&'b mut (Response+'b),)> for SendFile<'a> {
+impl<'b> Fn<(&'b mut (Response+'b),)> for SendFile {
     type Output = ();
 
     extern "rust-call" fn call(&self, (_res,): (&'b mut (Response+'b),)) {}
diff --git a/src/test/run-pass/issue-15858.rs b/src/test/run-pass/issue-15858.rs
index c75c6725461..6a4f78442d1 100644
--- a/src/test/run-pass/issue-15858.rs
+++ b/src/test/run-pass/issue-15858.rs
@@ -12,21 +12,21 @@
 
 static mut DROP_RAN: bool = false;
 
-trait Bar<'b> {
+trait Bar {
     fn do_something(&mut self);
 }
 
-struct BarImpl<'b>;
+struct BarImpl;
 
-impl<'b> Bar<'b> for BarImpl<'b> {
+impl Bar for BarImpl {
     fn do_something(&mut self) {}
 }
 
 
-struct Foo<B>;
+struct Foo<B>(B);
 
 #[unsafe_destructor]
-impl<'b, B: Bar<'b>> Drop for Foo<B> {
+impl<B: Bar> Drop for Foo<B> {
     fn drop(&mut self) {
         unsafe {
             DROP_RAN = true;
@@ -37,7 +37,7 @@ impl<'b, B: Bar<'b>> Drop for Foo<B> {
 
 fn main() {
     {
-       let _x: Foo<BarImpl> = Foo;
+       let _x: Foo<BarImpl> = Foo(BarImpl);
     }
     unsafe {
         assert_eq!(DROP_RAN, true);
diff --git a/src/test/run-pass/issue-16596.rs b/src/test/run-pass/issue-16596.rs
index e01de3a3262..1ba7b142e5e 100644
--- a/src/test/run-pass/issue-16596.rs
+++ b/src/test/run-pass/issue-16596.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait MatrixRow {}
+trait MatrixRow { fn dummy(&self) { }}
 
 struct Mat;
 
diff --git a/src/test/run-pass/issue-16643.rs b/src/test/run-pass/issue-16643.rs
index b118c9573cd..4e57c55c5f7 100644
--- a/src/test/run-pass/issue-16643.rs
+++ b/src/test/run-pass/issue-16643.rs
@@ -13,5 +13,5 @@
 extern crate "issue-16643" as i;
 
 pub fn main() {
-    i::TreeBuilder::<uint>.process_token();
+    i::TreeBuilder { h: 3u }.process_token();
 }
diff --git a/src/test/run-pass/issue-17662.rs b/src/test/run-pass/issue-17662.rs
index 45e70f59f33..7bd41cc5b52 100644
--- a/src/test/run-pass/issue-17662.rs
+++ b/src/test/run-pass/issue-17662.rs
@@ -12,12 +12,14 @@
 
 extern crate "issue-17662" as i;
 
-struct Bar<'a>;
+use std::marker;
+
+struct Bar<'a> { m: marker::PhantomData<&'a ()> }
 
 impl<'a> i::Foo<'a, uint> for Bar<'a> {
     fn foo(&self) -> uint { 5_usize }
 }
 
 pub fn main() {
-    assert_eq!(i::foo(&Bar), 5);
+    assert_eq!(i::foo(&Bar { m: marker::PhantomData }), 5);
 }
diff --git a/src/test/run-pass/issue-17732.rs b/src/test/run-pass/issue-17732.rs
index b4bd55da597..de9611f2592 100644
--- a/src/test/run-pass/issue-17732.rs
+++ b/src/test/run-pass/issue-17732.rs
@@ -10,8 +10,9 @@
 
 trait Person {
     type string;
+    fn dummy(&self) { }
 }
 
-struct Someone<P: Person>;
+struct Someone<P: Person>(std::marker::PhantomData<P>);
 
 fn main() {}
diff --git a/src/test/run-pass/issue-17771.rs b/src/test/run-pass/issue-17771.rs
index 1e9550acef4..2f1b0342b8e 100644
--- a/src/test/run-pass/issue-17771.rs
+++ b/src/test/run-pass/issue-17771.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Aaa {}
+trait Aaa { fn dummy(&self) { } }
 
 impl<'a> Aaa for &'a mut (Aaa + 'a) {}
 
diff --git a/src/test/run-pass/issue-17816.rs b/src/test/run-pass/issue-17816.rs
index f8fbd680dcb..a976eccf89e 100644
--- a/src/test/run-pass/issue-17816.rs
+++ b/src/test/run-pass/issue-17816.rs
@@ -10,9 +10,11 @@
 
 #![feature(unboxed_closures)]
 
+use std::marker::PhantomData;
+
 fn main() {
-    struct Symbol<'a, F: Fn(Vec<&'a str>) -> &'a str> { function: F }
+    struct Symbol<'a, F: Fn(Vec<&'a str>) -> &'a str> { function: F, marker: PhantomData<&'a ()> }
     let f = |x: Vec<&str>| -> &str "foobar";
-    let sym = Symbol { function: f };
+    let sym = Symbol { function: f, marker: PhantomData };
     (sym.function)(vec![]);
 }
diff --git a/src/test/run-pass/issue-17904.rs b/src/test/run-pass/issue-17904.rs
index 3ce347d67e3..58a0872a571 100644
--- a/src/test/run-pass/issue-17904.rs
+++ b/src/test/run-pass/issue-17904.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Foo<T> where T: Copy;
+// Test that we can parse where clauses on various forms of tuple
+// structs.
+
 struct Bar<T>(T) where T: Copy;
 struct Bleh<T, U>(T, U) where T: Copy, U: Sized;
 struct Baz<T> where T: Copy {
diff --git a/src/test/run-pass/issue-18232.rs b/src/test/run-pass/issue-18232.rs
index 15cf5870d40..67b3239d351 100644
--- a/src/test/run-pass/issue-18232.rs
+++ b/src/test/run-pass/issue-18232.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Cursor<'a>;
+struct Cursor<'a>(::std::marker::PhantomData<&'a ()>);
 
 trait CursorNavigator {
     fn init_cursor<'a, 'b:'a>(&'a self, cursor: &mut Cursor<'b>) -> bool;
@@ -23,7 +23,7 @@ impl CursorNavigator for SimpleNavigator {
 }
 
 fn main() {
-    let mut c = Cursor;
+    let mut c = Cursor(::std::marker::PhantomData);
     let n = SimpleNavigator;
     n.init_cursor(&mut c);
 }
diff --git a/src/test/run-pass/issue-18906.rs b/src/test/run-pass/issue-18906.rs
index 11ffb4198da..16dd84315ed 100644
--- a/src/test/run-pass/issue-18906.rs
+++ b/src/test/run-pass/issue-18906.rs
@@ -24,7 +24,7 @@ fn bar<K, Q>(k: &K, q: &Q) where K: Borrow<Q>, Q: Foo {
     q.foo(k.borrow())
 }
 
-struct MyTree<K>;
+struct MyTree<K>(K);
 
 impl<K> MyTree<K> {
     // This caused a failure in #18906
diff --git a/src/test/run-pass/issue-19121.rs b/src/test/run-pass/issue-19121.rs
index d95f74ef2a2..222f67af437 100644
--- a/src/test/run-pass/issue-19121.rs
+++ b/src/test/run-pass/issue-19121.rs
@@ -13,6 +13,8 @@
 
 trait Foo {
     type A;
+
+    fn dummy(&self) { }
 }
 
 fn bar(x: &Foo) {}
diff --git a/src/test/run-pass/issue-19129-2.rs b/src/test/run-pass/issue-19129-2.rs
index d6b3a1908b8..cf0f48e025a 100644
--- a/src/test/run-pass/issue-19129-2.rs
+++ b/src/test/run-pass/issue-19129-2.rs
@@ -11,7 +11,7 @@
 trait Trait<Input> {
     type Output;
 
-    fn method() -> bool { false }
+    fn method(&self, i: Input) -> bool { false }
 }
 
 fn main() {}
diff --git a/src/test/run-pass/issue-19135.rs b/src/test/run-pass/issue-19135.rs
index 031a63ba474..5e6dd567d63 100644
--- a/src/test/run-pass/issue-19135.rs
+++ b/src/test/run-pass/issue-19135.rs
@@ -10,13 +10,15 @@
 
 #![feature(unboxed_closures)]
 
+use std::marker::PhantomData;
+
 #[derive(Debug)]
-struct LifetimeStruct<'a>;
+struct LifetimeStruct<'a>(PhantomData<&'a ()>);
 
 fn main() {
     takes_hrtb_closure(|lts| println!("{:?}", lts));
 }
 
 fn takes_hrtb_closure<F: for<'a>FnMut(LifetimeStruct<'a>)>(mut f: F) {
-    f(LifetimeStruct);
+    f(LifetimeStruct(PhantomData));
 }
diff --git a/src/test/run-pass/issue-19358.rs b/src/test/run-pass/issue-19358.rs
index ff657376ecc..8b5269ab92f 100644
--- a/src/test/run-pass/issue-19358.rs
+++ b/src/test/run-pass/issue-19358.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Trait {}
+trait Trait { fn dummy(&self) { } }
 
 #[derive(Debug)]
 struct Foo<T: Trait> {
diff --git a/src/test/run-pass/issue-19398.rs b/src/test/run-pass/issue-19398.rs
index 1196162568a..e603167b26b 100644
--- a/src/test/run-pass/issue-19398.rs
+++ b/src/test/run-pass/issue-19398.rs
@@ -9,11 +9,11 @@
 // except according to those terms.
 
 trait T {
-    unsafe extern "Rust" fn foo();
+    unsafe extern "Rust" fn foo(&self);
 }
 
 impl T for () {
-    unsafe extern "Rust" fn foo() {}
+    unsafe extern "Rust" fn foo(&self) {}
 }
 
 fn main() {}
diff --git a/src/test/run-pass/issue-19479.rs b/src/test/run-pass/issue-19479.rs
index 91bc645b2d4..38a7af3a695 100644
--- a/src/test/run-pass/issue-19479.rs
+++ b/src/test/run-pass/issue-19479.rs
@@ -8,12 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Base {}
+trait Base {
+    fn dummy(&self) { }
+}
 trait AssocA {
     type X: Base;
+    fn dummy(&self) { }
 }
 trait AssocB {
     type Y: Base;
+    fn dummy(&self) { }
 }
 impl<T: AssocA> AssocB for T {
     type Y = <T as AssocA>::X;
diff --git a/src/test/run-pass/issue-19631.rs b/src/test/run-pass/issue-19631.rs
index 43116f63641..7bb0d055b84 100644
--- a/src/test/run-pass/issue-19631.rs
+++ b/src/test/run-pass/issue-19631.rs
@@ -10,6 +10,7 @@
 
 trait PoolManager {
     type C;
+    fn dummy(&self) { }
 }
 
 struct InnerPool<M> {
diff --git a/src/test/run-pass/issue-19632.rs b/src/test/run-pass/issue-19632.rs
index 01a073a6889..4339339d74c 100644
--- a/src/test/run-pass/issue-19632.rs
+++ b/src/test/run-pass/issue-19632.rs
@@ -10,6 +10,7 @@
 
 trait PoolManager {
     type C;
+    fn dummy(&self) { }
 }
 
 struct InnerPool<M: PoolManager> {
diff --git a/src/test/run-pass/issue-20055-box-trait.rs b/src/test/run-pass/issue-20055-box-trait.rs
index 836e78b5b51..572a0d82528 100644
--- a/src/test/run-pass/issue-20055-box-trait.rs
+++ b/src/test/run-pass/issue-20055-box-trait.rs
@@ -16,7 +16,9 @@
 // whichever arm is run, and subsequently dropped at the end of the
 // statement surrounding the `match`.
 
-trait Boo { }
+trait Boo {
+    fn dummy(&self) { }
+}
 
 impl Boo for [i8; 1] { }
 impl Boo for [i8; 2] { }
diff --git a/src/test/run-pass/issue-20343.rs b/src/test/run-pass/issue-20343.rs
index 79034a4a4a6..2f9e8feed24 100644
--- a/src/test/run-pass/issue-20343.rs
+++ b/src/test/run-pass/issue-20343.rs
@@ -16,7 +16,7 @@ struct B { b: u32 }
 struct C;
 struct D;
 
-trait T<A> {}
+trait T<A> { fn dummy(&self, a: A) { } }
 impl<A> T<A> for () {}
 
 impl B {
diff --git a/src/test/run-pass/issue-20763-1.rs b/src/test/run-pass/issue-20763-1.rs
index 911ee715da2..97c06ac9826 100644
--- a/src/test/run-pass/issue-20763-1.rs
+++ b/src/test/run-pass/issue-20763-1.rs
@@ -8,7 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait T0 { type O; }
+trait T0 {
+    type O;
+    fn dummy(&self) { }
+}
 
 struct S<A>(A);
 impl<A> T0 for S<A> { type O = A; }
diff --git a/src/test/run-pass/issue-20763-2.rs b/src/test/run-pass/issue-20763-2.rs
index a17c7b6ade4..d9701763571 100644
--- a/src/test/run-pass/issue-20763-2.rs
+++ b/src/test/run-pass/issue-20763-2.rs
@@ -8,7 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait T0 { type O; }
+trait T0 {
+    type O;
+    fn dummy(&self) { }
+}
 
 struct S<A>(A);
 impl<A> T0 for S<A> { type O = A; }
diff --git a/src/test/run-pass/issue-21363.rs b/src/test/run-pass/issue-21363.rs
index 2fc1d9fd643..71bb3d39fe1 100644
--- a/src/test/run-pass/issue-21363.rs
+++ b/src/test/run-pass/issue-21363.rs
@@ -12,6 +12,7 @@
 
 trait Iterator {
     type Item;
+    fn dummy(&self) { }
 }
 
 impl<'a, T> Iterator for &'a mut (Iterator<Item=T> + 'a) {
diff --git a/src/test/run-pass/issue-21909.rs b/src/test/run-pass/issue-21909.rs
index 5bbc90b2606..55b61dd1945 100644
--- a/src/test/run-pass/issue-21909.rs
+++ b/src/test/run-pass/issue-21909.rs
@@ -8,11 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait A<X> {}
+trait A<X> {
+    fn dummy(&self, arg: X);
+}
 
 trait B {
     type X;
     type Y: A<Self::X>;
+
+    fn dummy(&self);
 }
 
 fn main () { }
diff --git a/src/test/run-pass/issue-2311-2.rs b/src/test/run-pass/issue-2311-2.rs
index e0b98ab1965..5529d51b408 100644
--- a/src/test/run-pass/issue-2311-2.rs
+++ b/src/test/run-pass/issue-2311-2.rs
@@ -8,7 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait clam<A> { }
+trait clam<A> {
+    fn get(self) -> A;
+}
+
 struct foo<A> {
     x: A,
 }
diff --git a/src/test/run-pass/issue-2311.rs b/src/test/run-pass/issue-2311.rs
index dc873ed08d7..b6b3114e2a4 100644
--- a/src/test/run-pass/issue-2311.rs
+++ b/src/test/run-pass/issue-2311.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait clam<A> { }
+trait clam<A> { fn get(self) -> A; }
 trait foo<A> {
    fn bar<B,C:clam<A>>(&self, c: C) -> B;
 }
diff --git a/src/test/run-pass/issue-2312.rs b/src/test/run-pass/issue-2312.rs
index 8c597552d75..3f273b56efd 100644
--- a/src/test/run-pass/issue-2312.rs
+++ b/src/test/run-pass/issue-2312.rs
@@ -10,7 +10,7 @@
 
 // Testing that the B's are resolved
 
-trait clam<A> { }
+trait clam<A> { fn get(self) -> A; }
 
 struct foo(int);
 
diff --git a/src/test/run-pass/issue-2383.rs b/src/test/run-pass/issue-2383.rs
index b8136323df6..a5a05283f80 100644
--- a/src/test/run-pass/issue-2383.rs
+++ b/src/test/run-pass/issue-2383.rs
@@ -10,9 +10,9 @@
 // except according to those terms.
 
 extern crate collections;
-use std::collections::RingBuf;
+use std::collections::VecDeque;
 
 pub fn main() {
-    let mut q = RingBuf::new();
+    let mut q = VecDeque::new();
     q.push_front(10);
 }
diff --git a/src/test/run-pass/issue-2611-3.rs b/src/test/run-pass/issue-2611-3.rs
index 2608c89d155..c005699ce30 100644
--- a/src/test/run-pass/issue-2611-3.rs
+++ b/src/test/run-pass/issue-2611-3.rs
@@ -12,7 +12,7 @@
 // than the traits require.
 
 trait A {
-  fn b<C:Sync,D>(x: C) -> C;
+  fn b<C:Sync,D>(&self, x: C) -> C;
 }
 
 struct E {
@@ -20,7 +20,7 @@ struct E {
 }
 
 impl A for E {
-  fn b<F,G>(_x: F) -> F { panic!() }
+  fn b<F,G>(&self, _x: F) -> F { panic!() }
   //~^ ERROR in method `b`, type parameter 0 has 1 bound, but
 }
 
diff --git a/src/test/run-pass/issue-2734.rs b/src/test/run-pass/issue-2734.rs
index 7ca439a1a19..a7b53db6b05 100644
--- a/src/test/run-pass/issue-2734.rs
+++ b/src/test/run-pass/issue-2734.rs
@@ -11,7 +11,9 @@
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-trait hax { }
+trait hax {
+    fn dummy(&self) { }
+}
 impl<A> hax for A { }
 
 fn perform_hax<T: 'static>(x: Box<T>) -> Box<hax+'static> {
diff --git a/src/test/run-pass/issue-2735.rs b/src/test/run-pass/issue-2735.rs
index 962359537bf..1594b94879c 100644
--- a/src/test/run-pass/issue-2735.rs
+++ b/src/test/run-pass/issue-2735.rs
@@ -11,7 +11,9 @@
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-trait hax { }
+trait hax {
+    fn dummy(&self) { }
+}
 impl<A> hax for A { }
 
 fn perform_hax<T: 'static>(x: Box<T>) -> Box<hax+'static> {
diff --git a/src/test/run-pass/issue-4107.rs b/src/test/run-pass/issue-4107.rs
index 2ed662e9f2d..d660f300ada 100644
--- a/src/test/run-pass/issue-4107.rs
+++ b/src/test/run-pass/issue-4107.rs
@@ -9,14 +9,14 @@
 // except according to those terms.
 
 pub fn main() {
-    let _id: &Mat2<f64> = &Matrix::identity();
+    let _id: &Mat2<f64> = &Matrix::identity(1.0);
 }
 
-pub trait Index<Index,Result> { }
+pub trait Index<Index,Result> { fn get(&self, Index) -> Result { panic!() } }
 pub trait Dimensional<T>: Index<uint, T> { }
 
-pub struct Mat2<T> { x: () }
-pub struct Vec2<T> { x: () }
+pub struct Mat2<T> { x: T }
+pub struct Vec2<T> { x: T }
 
 impl<T> Dimensional<Vec2<T>> for Mat2<T> { }
 impl<T> Index<uint, Vec2<T>> for Mat2<T> { }
@@ -25,9 +25,9 @@ impl<T> Dimensional<T> for Vec2<T> { }
 impl<T> Index<uint, T> for Vec2<T> { }
 
 pub trait Matrix<T,V>: Dimensional<V> {
-    fn identity() -> Self;
+    fn identity(t:T) -> Self;
 }
 
 impl<T> Matrix<T, Vec2<T>> for Mat2<T> {
-    fn identity() -> Mat2<T> { Mat2{ x: () } }
+    fn identity(t:T) -> Mat2<T> { Mat2{ x: t } }
 }
diff --git a/src/test/run-pass/issue-5192.rs b/src/test/run-pass/issue-5192.rs
index bb79cd4d046..a6f3771bf62 100644
--- a/src/test/run-pass/issue-5192.rs
+++ b/src/test/run-pass/issue-5192.rs
@@ -12,6 +12,7 @@
 #![feature(box_syntax)]
 
 pub trait EventLoop {
+    fn dummy(&self) { }
 }
 
 pub struct UvEventLoop {
diff --git a/src/test/run-pass/issue-5708.rs b/src/test/run-pass/issue-5708.rs
index fd39bcc6b61..59bca87bed0 100644
--- a/src/test/run-pass/issue-5708.rs
+++ b/src/test/run-pass/issue-5708.rs
@@ -48,7 +48,9 @@ pub fn main() {
 
 
 // minimal
-pub trait MyTrait<T> { }
+pub trait MyTrait<T> {
+    fn dummy(&self, t: T) -> T { panic!() }
+}
 
 pub struct MyContainer<'a, T> {
     foos: Vec<&'a (MyTrait<T>+'a)> ,
diff --git a/src/test/run-pass/issue-6128.rs b/src/test/run-pass/issue-6128.rs
index d96862b588f..1746a6281dc 100644
--- a/src/test/run-pass/issue-6128.rs
+++ b/src/test/run-pass/issue-6128.rs
@@ -17,6 +17,7 @@ use std::collections::HashMap;
 
 trait Graph<Node, Edge> {
     fn f(&self, Edge);
+    fn g(&self, Node);
 
 }
 
@@ -24,6 +25,9 @@ impl<E> Graph<int, E> for HashMap<int, int> {
     fn f(&self, _e: E) {
         panic!();
     }
+    fn g(&self, _e: int) {
+        panic!();
+    }
 }
 
 pub fn main() {
diff --git a/src/test/run-pass/issue-6318.rs b/src/test/run-pass/issue-6318.rs
index 1d8fe8bfce8..6e608d34bd5 100644
--- a/src/test/run-pass/issue-6318.rs
+++ b/src/test/run-pass/issue-6318.rs
@@ -15,7 +15,9 @@ pub enum Thing {
     A(Box<Foo+'static>)
 }
 
-pub trait Foo {}
+pub trait Foo {
+    fn dummy(&self) { }
+}
 
 pub struct Struct;
 
diff --git a/src/test/run-pass/issue-7575.rs b/src/test/run-pass/issue-7575.rs
index 225213db6a4..77cfc7f0cf6 100644
--- a/src/test/run-pass/issue-7575.rs
+++ b/src/test/run-pass/issue-7575.rs
@@ -10,6 +10,7 @@
 
 trait Foo {
     fn new() -> bool { false }
+    fn dummy(&self) { }
 }
 
 trait Bar {
diff --git a/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs b/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs
index b6dfbb1ca42..736860947f2 100644
--- a/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs
+++ b/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs
@@ -19,7 +19,10 @@
 
 pub fn main() {}
 
-trait A {}
+trait A {
+    fn dummy(&self) { }
+}
+
 impl<T: 'static> A for T {}
 
 fn owned2<T: 'static>(a: Box<T>) { a as Box<A>; }
diff --git a/src/test/run-pass/issue-7911.rs b/src/test/run-pass/issue-7911.rs
index 86948ebcb91..3eb593708be 100644
--- a/src/test/run-pass/issue-7911.rs
+++ b/src/test/run-pass/issue-7911.rs
@@ -14,7 +14,9 @@
 // with different mutability in macro in two methods
 
 #![allow(unused_variable)] // unused foobar_immut + foobar_mut
-trait FooBar {}
+trait FooBar {
+    fn dummy(&self) { }
+}
 struct Bar(i32);
 struct Foo { bar: Bar }
 
diff --git a/src/test/run-pass/issue-8248.rs b/src/test/run-pass/issue-8248.rs
index 377b9ce262c..7bc8dbe616f 100644
--- a/src/test/run-pass/issue-8248.rs
+++ b/src/test/run-pass/issue-8248.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait A {}
+trait A {
+    fn dummy(&self) { }
+}
 struct B;
 impl A for B {}
 
diff --git a/src/test/run-pass/issue-8249.rs b/src/test/run-pass/issue-8249.rs
index 44f07def531..83c9e9bf450 100644
--- a/src/test/run-pass/issue-8249.rs
+++ b/src/test/run-pass/issue-8249.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait A {}
+trait A {
+    fn dummy(&self) { }
+}
 struct B;
 impl A for B {}
 
diff --git a/src/test/run-pass/issue-9719.rs b/src/test/run-pass/issue-9719.rs
index 8fc86eb49e7..aa1e65efaa4 100644
--- a/src/test/run-pass/issue-9719.rs
+++ b/src/test/run-pass/issue-9719.rs
@@ -13,7 +13,9 @@ mod a {
         A(T),
     }
 
-    pub trait X {}
+    pub trait X {
+        fn dummy(&self) { }
+    }
     impl X for int {}
 
     pub struct Z<'a>(Enum<&'a (X+'a)>);
@@ -21,7 +23,9 @@ mod a {
 }
 
 mod b {
-    trait X {}
+    trait X {
+        fn dummy(&self) { }
+    }
     impl X for int {}
     struct Y<'a>{
         x:Option<&'a (X+'a)>,
diff --git a/src/test/run-pass/lint-cstack.rs b/src/test/run-pass/lint-cstack.rs
index 2194453aac2..f180ffcd4e8 100644
--- a/src/test/run-pass/lint-cstack.rs
+++ b/src/test/run-pass/lint-cstack.rs
@@ -15,7 +15,7 @@ extern {
 }
 
 trait A {
-    fn foo() {
+    fn foo(&self) {
         unsafe {
             rust_get_test_int();
         }
diff --git a/src/test/run-pass/method-early-bound-lifetimes-on-self.rs b/src/test/run-pass/method-early-bound-lifetimes-on-self.rs
index 25ce0d774eb..cec9753a2fe 100644
--- a/src/test/run-pass/method-early-bound-lifetimes-on-self.rs
+++ b/src/test/run-pass/method-early-bound-lifetimes-on-self.rs
@@ -13,7 +13,11 @@
 
 #![allow(dead_code)]
 
-struct Cursor<'a>;
+use std::marker;
+
+struct Cursor<'a> {
+    m: marker::PhantomData<&'a ()>
+}
 
 trait CursorNavigator {
     fn init_cursor<'a, 'b:'a>(&'a self, cursor: &mut Cursor<'b>) -> bool;
@@ -28,7 +32,7 @@ impl CursorNavigator for SimpleNavigator {
 }
 
 fn main() {
-    let mut c = Cursor;
+    let mut c = Cursor { m: marker::PhantomData };
     let n = SimpleNavigator;
     n.init_cursor(&mut c);
 }
diff --git a/src/test/run-pass/method-recursive-blanket-impl.rs b/src/test/run-pass/method-recursive-blanket-impl.rs
index 338bd89ab5c..15eb2ae2e4b 100644
--- a/src/test/run-pass/method-recursive-blanket-impl.rs
+++ b/src/test/run-pass/method-recursive-blanket-impl.rs
@@ -17,16 +17,16 @@ use std::marker::Sized;
 
 // Note: this must be generic for the problem to show up
 trait Foo<A> {
-    fn foo(&self);
+    fn foo(&self, a: A);
 }
 
 impl Foo<u8> for [u8] {
-    fn foo(&self) {}
+    fn foo(&self, a: u8) {}
 }
 
 impl<'a, A, T> Foo<A> for &'a T where T: Foo<A> {
-    fn foo(&self) {
-        Foo::foo(*self)
+    fn foo(&self, a: A) {
+        Foo::foo(*self, a)
     }
 }
 
diff --git a/src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs b/src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs
index eb17aa78bd9..1164ef1a3c9 100644
--- a/src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs
+++ b/src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs
@@ -8,8 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker::MarkerTrait;
 
-trait Serializer {
+trait Serializer : MarkerTrait {
 }
 
 trait Serializable {
diff --git a/src/test/run-pass/overloaded-autoderef-vtable.rs b/src/test/run-pass/overloaded-autoderef-vtable.rs
index be2b309b821..d50f2efe0e7 100644
--- a/src/test/run-pass/overloaded-autoderef-vtable.rs
+++ b/src/test/run-pass/overloaded-autoderef-vtable.rs
@@ -11,7 +11,8 @@
 use std::ops::Deref;
 
 struct DerefWithHelper<H, T> {
-    helper: H
+    helper: H,
+    value: T
 }
 
 trait Helper<T> {
@@ -39,6 +40,7 @@ impl Foo {
 }
 
 pub fn main() {
-    let x: DerefWithHelper<Option<Foo>, Foo> = DerefWithHelper { helper: Some(Foo {x: 5}) };
+    let x: DerefWithHelper<Option<Foo>, Foo> =
+        DerefWithHelper { helper: Some(Foo {x: 5}), value: Foo { x: 2 } };
     assert!(x.foo() == 5);
 }
diff --git a/src/test/run-pass/overloaded-calls-param-vtables.rs b/src/test/run-pass/overloaded-calls-param-vtables.rs
index 2838909c1be..2ef9e08134c 100644
--- a/src/test/run-pass/overloaded-calls-param-vtables.rs
+++ b/src/test/run-pass/overloaded-calls-param-vtables.rs
@@ -12,10 +12,11 @@
 
 #![feature(unboxed_closures)]
 
+use std::marker::PhantomData;
 use std::ops::Fn;
 use std::ops::Add;
 
-struct G<A>;
+struct G<A>(PhantomData<A>);
 
 impl<'a, A: Add<i32, Output=i32>> Fn<(A,)> for G<A> {
     type Output = i32;
@@ -27,5 +28,5 @@ impl<'a, A: Add<i32, Output=i32>> Fn<(A,)> for G<A> {
 
 fn main() {
     // ICE trigger
-    G(1_i32);
+    (G(PhantomData))(1_i32);
 }
diff --git a/src/test/run-pass/parameterized-trait-with-bounds.rs b/src/test/run-pass/parameterized-trait-with-bounds.rs
index 840e58848a7..061c9168955 100644
--- a/src/test/run-pass/parameterized-trait-with-bounds.rs
+++ b/src/test/run-pass/parameterized-trait-with-bounds.rs
@@ -11,12 +11,12 @@
 #![allow(dead_code)]
 
 
-trait A<T> {}
-trait B<T, U> {}
-trait C<'a, U> {}
+trait A<T> { fn get(self) -> T; }
+trait B<T, U> { fn get(self) -> (T,U); }
+trait C<'a, U> { fn get(self) -> &'a U; }
 
 mod foo {
-    pub trait D<'a, T> {}
+    pub trait D<'a, T> { fn get(self) -> &'a T; }
 }
 
 fn foo1<T>(_: &(A<T> + Send)) {}
diff --git a/src/test/run-pass/privacy-ns.rs b/src/test/run-pass/privacy-ns.rs
index f3380352f5f..e9b8e694d60 100644
--- a/src/test/run-pass/privacy-ns.rs
+++ b/src/test/run-pass/privacy-ns.rs
@@ -19,6 +19,7 @@
 // public type, private value
 pub mod foo1 {
     pub trait Bar {
+        fn dummy(&self) { }
     }
     pub struct Baz;
 
@@ -50,6 +51,7 @@ fn test_glob1() {
 // private type, public value
 pub mod foo2 {
     trait Bar {
+        fn dummy(&self) { }
     }
     pub struct Baz;
 
@@ -81,6 +83,7 @@ fn test_glob2() {
 // public type, public value
 pub mod foo3 {
     pub trait Bar {
+        fn dummy(&self) { }
     }
     pub struct Baz;
 
diff --git a/src/test/run-pass/regions-assoc-type-static-bound.rs b/src/test/run-pass/regions-assoc-type-static-bound.rs
index 6b629a9035d..80ae371e509 100644
--- a/src/test/run-pass/regions-assoc-type-static-bound.rs
+++ b/src/test/run-pass/regions-assoc-type-static-bound.rs
@@ -11,7 +11,10 @@
 // Test that the compiler considers the 'static bound declared in the
 // trait. Issue #20890.
 
-trait Foo { type Value: 'static; }
+trait Foo {
+    type Value: 'static;
+    fn dummy(&self) { }
+}
 
 fn require_static<T: 'static>() {}
 
diff --git a/src/test/run-pass/regions-bound-lists-feature-gate-2.rs b/src/test/run-pass/regions-bound-lists-feature-gate-2.rs
index 0a95a89d57c..a06e0f6da78 100644
--- a/src/test/run-pass/regions-bound-lists-feature-gate-2.rs
+++ b/src/test/run-pass/regions-bound-lists-feature-gate-2.rs
@@ -12,7 +12,9 @@
 
 #![feature(issue_5723_bootstrap)]
 
-trait Foo { }
+trait Foo {
+    fn dummy(&self) { }
+}
 
 fn foo<'a, 'b, 'c:'a+'b, 'd>() {
 }
diff --git a/src/test/run-pass/regions-bound-lists-feature-gate.rs b/src/test/run-pass/regions-bound-lists-feature-gate.rs
index c5baecf7272..996583dc6de 100644
--- a/src/test/run-pass/regions-bound-lists-feature-gate.rs
+++ b/src/test/run-pass/regions-bound-lists-feature-gate.rs
@@ -12,8 +12,9 @@
 
 #![feature(issue_5723_bootstrap)]
 
-
-trait Foo { }
+trait Foo {
+    fn dummy(&self) { }
+}
 
 fn foo<'a>(x: Box<Foo + 'a>) {
 }
diff --git a/src/test/run-pass/regions-early-bound-lifetime-in-assoc-fn.rs b/src/test/run-pass/regions-early-bound-lifetime-in-assoc-fn.rs
index 978383c2447..bdc0d41c94e 100644
--- a/src/test/run-pass/regions-early-bound-lifetime-in-assoc-fn.rs
+++ b/src/test/run-pass/regions-early-bound-lifetime-in-assoc-fn.rs
@@ -14,6 +14,8 @@
 // lifetime parameters must be early bound in the type of the
 // associated item.
 
+use std::marker;
+
 pub enum Value<'v> {
     A(&'v str),
     B,
@@ -23,7 +25,9 @@ pub trait Decoder<'v> {
     fn read(&mut self) -> Value<'v>;
 }
 
-pub trait Decodable<'v, D: Decoder<'v>> {
+pub trait Decodable<'v, D: Decoder<'v>>
+    : marker::PhantomFn<(), &'v int>
+{
     fn decode(d: &mut D) -> Self;
 }
 
diff --git a/src/test/run-pass/regions-early-bound-trait-param.rs b/src/test/run-pass/regions-early-bound-trait-param.rs
index 6fcfaf58a02..3f434a4838d 100644
--- a/src/test/run-pass/regions-early-bound-trait-param.rs
+++ b/src/test/run-pass/regions-early-bound-trait-param.rs
@@ -53,11 +53,11 @@ fn field_invoke2<'l, 'm, 'n>(x: &'n Struct2<'l,'m>) -> int {
     x.f.short()
 }
 
-trait MakerTrait<'o> {
+trait MakerTrait {
     fn mk() -> Self;
 }
 
-fn make_val<'p, T:MakerTrait<'p>>() -> T {
+fn make_val<T:MakerTrait>() -> T {
     MakerTrait::mk()
 }
 
@@ -80,7 +80,7 @@ impl<'s> Trait<'s> for (int,int) {
     }
 }
 
-impl<'t> MakerTrait<'t> for Box<Trait<'t>+'static> {
+impl<'t> MakerTrait for Box<Trait<'t>+'static> {
     fn mk() -> Box<Trait<'t>+'static> { box() (4,5) as Box<Trait> }
 }
 
diff --git a/src/test/run-pass/regions-issue-21422.rs b/src/test/run-pass/regions-issue-21422.rs
new file mode 100644
index 00000000000..c59bf15afc3
--- /dev/null
+++ b/src/test/run-pass/regions-issue-21422.rs
@@ -0,0 +1,25 @@
+// Copyright 2015 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.
+
+// Regression test for issue #21422, which was related to failing to
+// add inference constraints that the operands of a binary operator
+// should outlive the binary operation itself.
+
+pub struct P<'a> {
+    _ptr: *const &'a u8,
+}
+
+impl <'a> PartialEq for P<'a> {
+    fn eq(&self, other: &P<'a>) -> bool {
+        (self as *const _) == (other as *const _)
+    }
+}
+
+fn main() {}
diff --git a/src/test/run-pass/regions-no-bound-in-argument-cleanup.rs b/src/test/run-pass/regions-no-bound-in-argument-cleanup.rs
index d3464f01203..5964ac65d5f 100644
--- a/src/test/run-pass/regions-no-bound-in-argument-cleanup.rs
+++ b/src/test/run-pass/regions-no-bound-in-argument-cleanup.rs
@@ -10,7 +10,9 @@
 
 #![feature(unsafe_destructor)]
 
-pub struct Foo<T>;
+use std::marker;
+
+pub struct Foo<T>(marker::PhantomData<T>);
 
 impl<T> Iterator for Foo<T> {
     type Item = T;
diff --git a/src/test/run-pass/regions-no-variance-from-fn-generics.rs b/src/test/run-pass/regions-no-variance-from-fn-generics.rs
index a35ab1bfc0c..80c478afa64 100644
--- a/src/test/run-pass/regions-no-variance-from-fn-generics.rs
+++ b/src/test/run-pass/regions-no-variance-from-fn-generics.rs
@@ -12,7 +12,9 @@
 // should not upset the variance inference for actual occurrences of
 // that lifetime in type expressions.
 
-pub trait HasLife<'a> { }
+pub trait HasLife<'a> {
+    fn dummy(&'a self) { } // just to induce a variance on 'a
+}
 
 trait UseLife01 {
     fn refs<'a, H: HasLife<'a>>(&'a self) -> H;
@@ -23,7 +25,11 @@ trait UseLife02 {
 }
 
 
-pub trait HasType<T> { }
+pub trait HasType<T>
+{
+    fn dummy(&self, t: T) -> T { panic!() }
+}
+
 
 trait UseLife03<T> {
     fn refs<'a, H: HasType<&'a T>>(&'a self) -> H;
diff --git a/src/test/run-pass/regions-refcell.rs b/src/test/run-pass/regions-refcell.rs
index 10c9aef7c3b..a224017780e 100644
--- a/src/test/run-pass/regions-refcell.rs
+++ b/src/test/run-pass/regions-refcell.rs
@@ -19,7 +19,7 @@ use std::cell::RefCell;
 #[cfg(cannot_use_this_yet)]
 fn foo<'a>(map: RefCell<HashMap<&'static str, &'a [u8]>>) {
     let one = [1_usize];
-    assert_eq!(map.borrow().get("one"), Some(&one[]));
+    assert_eq!(map.borrow().get("one"), Some(&one[..]));
 }
 
 #[cfg(cannot_use_this_yet_either)]
@@ -45,9 +45,9 @@ fn main() {
     let one = [1u8];
     let two = [2u8];
     let mut map = HashMap::new();
-    map.insert("zero", &zer[]);
-    map.insert("one",  &one[]);
-    map.insert("two",  &two[]);
+    map.insert("zero", &zer[..]);
+    map.insert("one",  &one[..]);
+    map.insert("two",  &two[..]);
     let map = RefCell::new(map);
     foo(map);
 }
diff --git a/src/test/run-pass/rename-directory.rs b/src/test/run-pass/rename-directory.rs
index a21b5aa1dab..abe6ffe7d4c 100644
--- a/src/test/run-pass/rename-directory.rs
+++ b/src/test/run-pass/rename-directory.rs
@@ -31,12 +31,12 @@ fn rename_directory() {
         let test_file = &old_path.join("temp.txt");
 
         /* Write the temp input file */
-        let fromp = CString::from_slice(test_file.as_vec());
-        let modebuf = CString::from_slice(b"w+b");
+        let fromp = CString::new(test_file.as_vec()).unwrap();
+        let modebuf = CString::new(b"w+b").unwrap();
         let ostream = libc::fopen(fromp.as_ptr(), modebuf.as_ptr());
         assert!((ostream as uint != 0_usize));
         let s = "hello".to_string();
-        let buf = CString::from_slice(b"hello");
+        let buf = CString::new(b"hello").unwrap();
         let write_len = libc::fwrite(buf.as_ptr() as *mut _,
                                      1_usize as libc::size_t,
                                      (s.len() + 1_usize) as libc::size_t,
diff --git a/src/test/run-pass/self-impl.rs b/src/test/run-pass/self-impl.rs
index 40a4dc52a70..af2b2de8ab8 100644
--- a/src/test/run-pass/self-impl.rs
+++ b/src/test/run-pass/self-impl.rs
@@ -29,6 +29,7 @@ pub struct Baz<X> {
 
 trait Bar<X> {
     fn bar(x: Self, y: &Self, z: Box<Self>) -> Self;
+    fn dummy(&self, x: X) { }
 }
 
 impl Bar<int> for Box<Baz<int>> {
diff --git a/src/test/run-pass/send_str_hashmap.rs b/src/test/run-pass/send_str_hashmap.rs
index c58654670d1..33e4fa85bcb 100644
--- a/src/test/run-pass/send_str_hashmap.rs
+++ b/src/test/run-pass/send_str_hashmap.rs
@@ -13,7 +13,7 @@ extern crate collections;
 use std::collections::HashMap;
 use std::borrow::{Cow, IntoCow};
 
-type SendStr = Cow<'static, String, str>;
+type SendStr = Cow<'static, str>;
 
 pub fn main() {
     let mut map: HashMap<SendStr, uint> = HashMap::new();
diff --git a/src/test/run-pass/send_str_treemap.rs b/src/test/run-pass/send_str_treemap.rs
index 438724a2b06..3390369242d 100644
--- a/src/test/run-pass/send_str_treemap.rs
+++ b/src/test/run-pass/send_str_treemap.rs
@@ -13,7 +13,7 @@ extern crate collections;
 use self::collections::BTreeMap;
 use std::borrow::{Cow, IntoCow};
 
-type SendStr = Cow<'static, String, str>;
+type SendStr = Cow<'static, str>;
 
 pub fn main() {
     let mut map: BTreeMap<SendStr, uint> = BTreeMap::new();
diff --git a/src/test/run-pass/simple-match-generic-tag.rs b/src/test/run-pass/simple-match-generic-tag.rs
index 7ed8cb434ca..2217dddbd21 100644
--- a/src/test/run-pass/simple-match-generic-tag.rs
+++ b/src/test/run-pass/simple-match-generic-tag.rs
@@ -8,11 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
-
-enum opt<T> { none, }
+enum opt<T> { none, some(T) }
 
 pub fn main() {
     let x = opt::none::<int>;
-    match x { opt::none::<int> => { println!("hello world"); } }
+    match x {
+        opt::none::<int> => { println!("hello world"); }
+        opt::some(_) => { }
+    }
 }
diff --git a/src/test/run-pass/syntax-trait-polarity.rs b/src/test/run-pass/syntax-trait-polarity.rs
index 3344844d49f..340ad2a531a 100644
--- a/src/test/run-pass/syntax-trait-polarity.rs
+++ b/src/test/run-pass/syntax-trait-polarity.rs
@@ -10,17 +10,17 @@
 
 #![feature(optin_builtin_traits)]
 
-use std::marker::Send;
+use std::marker::{MarkerTrait, Send};
 
 struct TestType;
 
 impl TestType {}
 
-trait TestTrait {}
+trait TestTrait : MarkerTrait {}
 
 impl !Send for TestType {}
 
-struct TestType2<T>;
+struct TestType2<T>(T);
 
 impl<T> TestType2<T> {}
 
diff --git a/src/test/run-pass/trailing-comma.rs b/src/test/run-pass/trailing-comma.rs
index b5ae259bc63..76c62a83e75 100644
--- a/src/test/run-pass/trailing-comma.rs
+++ b/src/test/run-pass/trailing-comma.rs
@@ -12,7 +12,7 @@
 
 fn f<T,>(_: T,) {}
 
-struct Foo<T,>;
+struct Foo<T,>(T);
 
 struct Bar;
 
@@ -34,7 +34,7 @@ pub fn main() {
     let [_, _, .., _,] = [1, 1, 1, 1,];
     let [_, _, _.., _,] = [1, 1, 1, 1,];
 
-    let x: Foo<int,> = Foo::<int,>;
+    let x: Foo<int,> = Foo::<int,>(1);
 
     Bar::f(0,);
     Bar.g(0,);
diff --git a/src/test/run-pass/trait-bounds-basic.rs b/src/test/run-pass/trait-bounds-basic.rs
index d03496403ad..ed25bf8b02e 100644
--- a/src/test/run-pass/trait-bounds-basic.rs
+++ b/src/test/run-pass/trait-bounds-basic.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 
-trait Foo {
+trait Foo : ::std::marker::MarkerTrait {
 }
 
 fn b(_x: Box<Foo+Send>) {
diff --git a/src/test/run-pass/trait-bounds-on-structs-and-enums.rs b/src/test/run-pass/trait-bounds-on-structs-and-enums.rs
index e3234f03754..976120908b2 100644
--- a/src/test/run-pass/trait-bounds-on-structs-and-enums.rs
+++ b/src/test/run-pass/trait-bounds-on-structs-and-enums.rs
@@ -8,10 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait U {}
-trait T<X: U> {}
+trait U : ::std::marker::MarkerTrait {}
+trait T<X: U> { fn get(self) -> X; }
 
-trait S2<Y: U> {
+trait S2<Y: U> : ::std::marker::MarkerTrait {
     fn m(x: Box<T<Y>+'static>) {}
 }
 
diff --git a/src/test/run-pass/trait-bounds-recursion.rs b/src/test/run-pass/trait-bounds-recursion.rs
index 49f8999cd45..7135dad7d19 100644
--- a/src/test/run-pass/trait-bounds-recursion.rs
+++ b/src/test/run-pass/trait-bounds-recursion.rs
@@ -10,17 +10,17 @@
 
 trait I { fn i(&self) -> Self; }
 
-trait A<T:I> {
+trait A<T:I> : ::std::marker::MarkerTrait {
     fn id(x:T) -> T { x.i() }
 }
 
-trait J<T> { fn j(&self) -> Self; }
+trait J<T> { fn j(&self) -> T; }
 
-trait B<T:J<T>> {
+trait B<T:J<T>> : ::std::marker::MarkerTrait {
     fn id(x:T) -> T { x.j() }
 }
 
-trait C {
+trait C : ::std::marker::MarkerTrait {
     fn id<T:J<T>>(x:T) -> T { x.j() }
 }
 
diff --git a/src/test/run-pass/trait-default-method-bound-subst4.rs b/src/test/run-pass/trait-default-method-bound-subst4.rs
index 3efe2507470..383849ca512 100644
--- a/src/test/run-pass/trait-default-method-bound-subst4.rs
+++ b/src/test/run-pass/trait-default-method-bound-subst4.rs
@@ -11,6 +11,7 @@
 
 trait A<T> {
     fn g(&self, x: uint) -> uint { x }
+    fn h(&self, x: T) { }
 }
 
 impl<T> A<T> for int { }
diff --git a/src/test/run-pass/trait-impl.rs b/src/test/run-pass/trait-impl.rs
index 16ef315c206..325fba8a0ee 100644
--- a/src/test/run-pass/trait-impl.rs
+++ b/src/test/run-pass/trait-impl.rs
@@ -16,7 +16,9 @@ use traitimpl::Bar;
 
 static mut COUNT: uint = 1;
 
-trait T {}
+trait T {
+    fn t(&self) {}
+}
 
 impl<'a> T+'a {
     fn foo(&self) {
diff --git a/src/test/run-pass/trait-inheritance-num2.rs b/src/test/run-pass/trait-inheritance-num2.rs
index 1e6e7227a06..f89eea46090 100644
--- a/src/test/run-pass/trait-inheritance-num2.rs
+++ b/src/test/run-pass/trait-inheritance-num2.rs
@@ -14,8 +14,7 @@
 use std::cmp::{PartialEq, PartialOrd};
 use std::num::NumCast;
 
-pub trait TypeExt {}
-
+pub trait TypeExt : ::std::marker::MarkerTrait { }
 
 impl TypeExt for u8 {}
 impl TypeExt for u16 {}
diff --git a/src/test/run-pass/trait-inheritance-static2.rs b/src/test/run-pass/trait-inheritance-static2.rs
index 3b454aad03e..8f3b325a513 100644
--- a/src/test/run-pass/trait-inheritance-static2.rs
+++ b/src/test/run-pass/trait-inheritance-static2.rs
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub trait MyEq { }
+pub trait MyEq : ::std::marker::MarkerTrait { }
 
-pub trait MyNum {
+pub trait MyNum : ::std::marker::MarkerTrait {
     fn from_int(int) -> Self;
 }
 
diff --git a/src/test/run-pass/trait-object-generics.rs b/src/test/run-pass/trait-object-generics.rs
index 76352c799a0..6f89490716f 100644
--- a/src/test/run-pass/trait-object-generics.rs
+++ b/src/test/run-pass/trait-object-generics.rs
@@ -13,11 +13,14 @@
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
+use std::marker;
+
 pub trait Trait2<A> {
-    fn doit(&self);
+    fn doit(&self) -> A;
 }
 
 pub struct Impl<A1, A2, A3> {
+    m1: marker::PhantomData<(A1,A2,A3)>,
     /*
      * With A2 we get the ICE:
      * task <unnamed> failed at 'index out of bounds: the len is 1 but the index is 1',
@@ -28,13 +31,13 @@ pub struct Impl<A1, A2, A3> {
 
 impl<A1, A2, A3> Impl<A1, A2, A3> {
     pub fn step(&self) {
-        self.t.doit()
+        self.t.doit();
     }
 }
 
 // test for #8601
 
-enum Type<T> { Constant }
+enum Type<T> { Constant(T) }
 
 trait Trait<K,V> {
     fn method(&self,Type<(K,V)>) -> int;
@@ -46,5 +49,5 @@ impl<V> Trait<u8,V> for () {
 
 pub fn main() {
     let a = box() () as Box<Trait<u8, u8>>;
-    assert_eq!(a.method(Type::Constant), 0);
+    assert_eq!(a.method(Type::Constant((1u8, 2u8))), 0);
 }
diff --git a/src/test/run-pass/trait-static-method-overwriting.rs b/src/test/run-pass/trait-static-method-overwriting.rs
index a8cea24db0c..10439d5c86a 100644
--- a/src/test/run-pass/trait-static-method-overwriting.rs
+++ b/src/test/run-pass/trait-static-method-overwriting.rs
@@ -10,7 +10,7 @@
 // except according to those terms.
 
 mod base {
-    pub trait HasNew<T> {
+    pub trait HasNew {
         fn new() -> Self;
     }
 
@@ -18,7 +18,7 @@ mod base {
         dummy: (),
     }
 
-    impl ::base::HasNew<Foo> for Foo {
+    impl ::base::HasNew for Foo {
         fn new() -> Foo {
             println!("Foo");
             Foo { dummy: () }
@@ -29,7 +29,7 @@ mod base {
         dummy: (),
     }
 
-    impl ::base::HasNew<Bar> for Bar {
+    impl ::base::HasNew for Bar {
         fn new() -> Bar {
             println!("Bar");
             Bar { dummy: () }
@@ -38,6 +38,6 @@ mod base {
 }
 
 pub fn main() {
-    let _f: base::Foo = base::HasNew::<base::Foo>::new();
-    let _b: base::Bar = base::HasNew::<base::Bar>::new();
+    let _f: base::Foo = base::HasNew::new();
+    let _b: base::Bar = base::HasNew::new();
 }
diff --git a/src/test/run-pass/traits-issue-22019.rs b/src/test/run-pass/traits-issue-22019.rs
index 5d3195e1937..7e0f60d55a8 100644
--- a/src/test/run-pass/traits-issue-22019.rs
+++ b/src/test/run-pass/traits-issue-22019.rs
@@ -23,18 +23,18 @@ pub type Node<'a> = &'a CFGNode;
 
 pub trait GraphWalk<'c, N> {
     /// Returns all the nodes in this graph.
-    fn nodes(&'c self) where [N]:ToOwned<Vec<N>>;
+    fn nodes(&'c self) where [N]:ToOwned<Owned=Vec<N>>;
 }
 
 impl<'g> GraphWalk<'g, Node<'g>> for u32
 {
-    fn nodes(&'g self) where [Node<'g>]:ToOwned<Vec<Node<'g>>>
+    fn nodes(&'g self) where [Node<'g>]:ToOwned<Owned=Vec<Node<'g>>>
     { loop { } }
 }
 
 impl<'h> GraphWalk<'h, Node<'h>> for u64
 {
-    fn nodes(&'h self) where [Node<'h>]:ToOwned<Vec<Node<'h>>>
+    fn nodes(&'h self) where [Node<'h>]:ToOwned<Owned=Vec<Node<'h>>>
     { loop { } }
 }
 
diff --git a/src/test/run-pass/unboxed-closures-infer-recursive-fn.rs b/src/test/run-pass/unboxed-closures-infer-recursive-fn.rs
index 1f9b821178c..2d1ba7f39b2 100644
--- a/src/test/run-pass/unboxed-closures-infer-recursive-fn.rs
+++ b/src/test/run-pass/unboxed-closures-infer-recursive-fn.rs
@@ -10,7 +10,7 @@
 
 #![feature(core,unboxed_closures)]
 
-use std::marker::CovariantType;
+use std::marker::PhantomData;
 
 // Test that we are able to infer a suitable kind for a "recursive"
 // closure.  As far as I can tell, coding up a recursive closure
@@ -20,12 +20,12 @@ use std::marker::CovariantType;
 
 struct YCombinator<F,A,R> {
     func: F,
-    marker: CovariantType<(A,R)>,
+    marker: PhantomData<(A,R)>,
 }
 
 impl<F,A,R> YCombinator<F,A,R> {
     fn new(f: F) -> YCombinator<F,A,R> {
-        YCombinator { func: f, marker: CovariantType }
+        YCombinator { func: f, marker: PhantomData }
     }
 }
 
diff --git a/src/test/run-pass/unique-object-move.rs b/src/test/run-pass/unique-object-move.rs
index cec523a0671..f01a56142e0 100644
--- a/src/test/run-pass/unique-object-move.rs
+++ b/src/test/run-pass/unique-object-move.rs
@@ -13,7 +13,7 @@
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-pub trait EventLoop { }
+pub trait EventLoop { fn foo(&self) {} }
 
 pub struct UvEventLoop {
     uvio: int
diff --git a/src/test/run-pass/unsized.rs b/src/test/run-pass/unsized.rs
index e6dd8d46952..ae175d27b0a 100644
--- a/src/test/run-pass/unsized.rs
+++ b/src/test/run-pass/unsized.rs
@@ -12,17 +12,19 @@
 
 // Test syntax checks for `?Sized` syntax.
 
-trait T1 {}
-pub trait T2 {}
-trait T3<X: T1> : T2 {}
-trait T4<X: ?Sized> {}
-trait T5<X: ?Sized, Y> {}
-trait T6<Y, X: ?Sized> {}
-trait T7<X: ?Sized, Y: ?Sized> {}
-trait T8<X: ?Sized+T2> {}
-trait T9<X: T2 + ?Sized> {}
-struct S1<X: ?Sized>;
-enum E<X: ?Sized> {}
+use std::marker::{PhantomData, PhantomFn};
+
+trait T1 : PhantomFn<Self> { }
+pub trait T2 : PhantomFn<Self> { }
+trait T3<X: T1> : T2 + PhantomFn<X> { }
+trait T4<X: ?Sized> : PhantomFn<(Self,X)> {}
+trait T5<X: ?Sized, Y> : PhantomFn<(Self,X,Y)> {}
+trait T6<Y, X: ?Sized> : PhantomFn<(Self,X,Y)> {}
+trait T7<X: ?Sized, Y: ?Sized> : PhantomFn<(Self,X,Y)> {}
+trait T8<X: ?Sized+T2> : PhantomFn<(Self,X)> {}
+trait T9<X: T2 + ?Sized> : PhantomFn<(Self,X)> {}
+struct S1<X: ?Sized>(PhantomData<X>);
+enum E<X: ?Sized> { E1(PhantomData<X>) }
 impl <X: ?Sized> T1 for S1<X> {}
 fn f<X: ?Sized>() {}
 type TT<T: ?Sized> = T;
diff --git a/src/test/run-pass/unsized2.rs b/src/test/run-pass/unsized2.rs
index 285100dd719..10b2f2fb709 100644
--- a/src/test/run-pass/unsized2.rs
+++ b/src/test/run-pass/unsized2.rs
@@ -15,6 +15,8 @@
 
 // Test sized-ness checking in substitution.
 
+use std::marker;
+
 // Unbounded.
 fn f1<X: ?Sized>(x: &X) {
     f1::<X>(x);
@@ -25,7 +27,7 @@ fn f2<X>(x: &X) {
 }
 
 // Bounded.
-trait T {}
+trait T { fn dummy(&self) { } }
 fn f3<X: T+?Sized>(x: &X) {
     f3::<X>(x);
 }
@@ -66,20 +68,24 @@ fn f7<X: ?Sized+T3>(x: &X) {
 }
 
 trait T4<X> {
-    fn m1(x: &T4<X>);
-    fn m2(x: &T5<X>);
+    fn dummy(&self) { }
+    fn m1(x: &T4<X>, y: X);
+    fn m2(x: &T5<X>, y: X);
 }
 trait T5<X: ?Sized> {
+    fn dummy(&self) { }
     // not an error (for now)
     fn m1(x: &T4<X>);
     fn m2(x: &T5<X>);
 }
 
 trait T6<X: T> {
+    fn dummy(&self) { }
     fn m1(x: &T4<X>);
     fn m2(x: &T5<X>);
 }
 trait T7<X: ?Sized+T> {
+    fn dummy(&self) { }
     // not an error (for now)
     fn m1(x: &T4<X>);
     fn m2(x: &T5<X>);
diff --git a/src/test/run-pass/variadic-ffi.rs b/src/test/run-pass/variadic-ffi.rs
index a729fedb271..5a476ed9ee2 100644
--- a/src/test/run-pass/variadic-ffi.rs
+++ b/src/test/run-pass/variadic-ffi.rs
@@ -29,11 +29,11 @@ pub fn main() {
 
     unsafe {
         // Call with just the named parameter
-        let c = CString::from_slice(b"Hello World\n");
+        let c = CString::new(b"Hello World\n").unwrap();
         check("Hello World\n", |s| sprintf(s, c.as_ptr()));
 
         // Call with variable number of arguments
-        let c = CString::from_slice(b"%d %f %c %s\n");
+        let c = CString::new(b"%d %f %c %s\n").unwrap();
         check("42 42.500000 a %d %f %c %s\n\n", |s| {
             sprintf(s, c.as_ptr(), 42, 42.5f64, 'a' as c_int, c.as_ptr());
         });
@@ -44,11 +44,11 @@ pub fn main() {
         // A function that takes a function pointer
         unsafe fn call(p: unsafe extern fn(*mut c_char, *const c_char, ...) -> c_int) {
             // Call with just the named parameter
-            let c = CString::from_slice(b"Hello World\n");
+            let c = CString::new(b"Hello World\n").unwrap();
             check("Hello World\n", |s| sprintf(s, c.as_ptr()));
 
             // Call with variable number of arguments
-            let c = CString::from_slice(b"%d %f %c %s\n");
+            let c = CString::new(b"%d %f %c %s\n").unwrap();
             check("42 42.500000 a %d %f %c %s\n\n", |s| {
                 sprintf(s, c.as_ptr(), 42, 42.5f64, 'a' as c_int, c.as_ptr());
             });
diff --git a/src/test/run-pass/variance-intersection-of-ref-and-opt-ref.rs b/src/test/run-pass/variance-intersection-of-ref-and-opt-ref.rs
new file mode 100644
index 00000000000..948d68e0ccd
--- /dev/null
+++ b/src/test/run-pass/variance-intersection-of-ref-and-opt-ref.rs
@@ -0,0 +1,34 @@
+// Copyright 2015 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.
+
+// Elaborated version of the opening example from RFC 738. This failed
+// to compile before variance because invariance of `Option` prevented
+// us from approximating the lifetimes of `field1` and `field2` to a
+// common intersection.
+
+#![allow(dead_code)]
+
+struct List<'l> {
+    field1: &'l i32,
+    field2: Option<&'l i32>,
+}
+
+fn foo(field1: &i32, field2: Option<&i32>) -> i32 {
+    let list = List { field1: field1, field2: field2 };
+    *list.field1 + list.field2.cloned().unwrap_or(0)
+}
+
+fn main() {
+    let x = 22;
+    let y = Some(3);
+    let z = None;
+    assert_eq!(foo(&x, y.as_ref()), 25);
+    assert_eq!(foo(&x, z.as_ref()), 22);
+}
diff --git a/src/test/run-pass/variance-trait-matching.rs b/src/test/run-pass/variance-trait-matching.rs
new file mode 100644
index 00000000000..10441bee3cb
--- /dev/null
+++ b/src/test/run-pass/variance-trait-matching.rs
@@ -0,0 +1,49 @@
+// Copyright 2015 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.
+
+#![allow(dead_code)]
+
+// Get<T> is covariant in T
+trait Get<T> {
+    fn get(&self) -> T;
+}
+
+struct Cloner<T:Clone> {
+    t: T
+}
+
+impl<T:Clone> Get<T> for Cloner<T> {
+    fn get(&self) -> T {
+        self.t.clone()
+    }
+}
+
+fn get<'a, G>(get: &G) -> i32
+    where G : Get<&'a i32>
+{
+    // This call only type checks if we can use `G : Get<&'a i32>` as
+    // evidence that `G : Get<&'b i32>` where `'a : 'b`.
+    pick(get, &22)
+}
+
+fn pick<'b, G>(get: &'b G, if_odd: &'b i32) -> i32
+    where G : Get<&'b i32>
+{
+    let v = *get.get();
+    if v % 2 != 0 { v } else { *if_odd }
+}
+
+fn main() {
+    let x = Cloner { t: &23 };
+    let y = get(&x);
+    assert_eq!(y, 23);
+}
+
+
diff --git a/src/test/run-pass/variance-vec-covariant.rs b/src/test/run-pass/variance-vec-covariant.rs
new file mode 100644
index 00000000000..caec6df5a4d
--- /dev/null
+++ b/src/test/run-pass/variance-vec-covariant.rs
@@ -0,0 +1,28 @@
+// Copyright 2015 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.
+
+// Test that vec is now covariant in its argument type.
+
+#![allow(dead_code)]
+
+fn foo<'a,'b>(v1: Vec<&'a i32>, v2: Vec<&'b i32>) -> i32 {
+    bar(v1, v2).cloned().unwrap_or(0) // only type checks if we can intersect 'a and 'b
+}
+
+fn bar<'c>(v1: Vec<&'c i32>, v2: Vec<&'c i32>) -> Option<&'c i32> {
+    v1.get(0).cloned().or_else(|| v2.get(0).cloned())
+}
+
+fn main() {
+    let x = 22;
+    let y = 44;
+    assert_eq!(foo(vec![&x], vec![&y]), 22);
+    assert_eq!(foo(vec![&y], vec![&x]), 44);
+}
diff --git a/src/test/run-pass/visible-private-types-feature-gate.rs b/src/test/run-pass/visible-private-types-feature-gate.rs
index 9518671b479..46e93b25697 100644
--- a/src/test/run-pass/visible-private-types-feature-gate.rs
+++ b/src/test/run-pass/visible-private-types-feature-gate.rs
@@ -10,7 +10,7 @@
 
 #![feature(visible_private_types)]
 
-trait Foo {}
+trait Foo { fn dummy(&self) { } }
 
 pub trait Bar : Foo {}
 
diff --git a/src/test/run-pass/where-clause-bounds-inconsistency.rs b/src/test/run-pass/where-clause-bounds-inconsistency.rs
index a1a61127f68..3374f47ed5f 100644
--- a/src/test/run-pass/where-clause-bounds-inconsistency.rs
+++ b/src/test/run-pass/where-clause-bounds-inconsistency.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Bound {}
+trait Bound {
+    fn dummy(&self) { }
+}
 
 trait Trait {
     fn a<T>(&self, T) where T: Bound;
diff --git a/src/test/run-pass/where-clause-early-bound-lifetimes.rs b/src/test/run-pass/where-clause-early-bound-lifetimes.rs
index cade99b83a2..4a149d4d3df 100644
--- a/src/test/run-pass/where-clause-early-bound-lifetimes.rs
+++ b/src/test/run-pass/where-clause-early-bound-lifetimes.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait TheTrait { }
+trait TheTrait { fn dummy(&self) { } }
 
 impl TheTrait for &'static int { }
 
diff --git a/src/test/run-pass/where-clause-method-substituion.rs b/src/test/run-pass/where-clause-method-substituion.rs
index b391df8500b..ecc210ea579 100644
--- a/src/test/run-pass/where-clause-method-substituion.rs
+++ b/src/test/run-pass/where-clause-method-substituion.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo<T> {}
+trait Foo<T> { fn dummy(&self, arg: T) { } }
 
 trait Bar<A> {
     fn method<B>(&self) where A: Foo<B>;
@@ -19,7 +19,7 @@ struct X;
 
 impl Foo<S> for X {}
 
-impl Bar<X> for int {
+impl Bar<X> for i32 {
     fn method<U>(&self) where X: Foo<U> {
     }
 }
diff --git a/src/test/run-pass/where-for-self.rs b/src/test/run-pass/where-for-self.rs
index 5d426793c2e..1fd223b0dd3 100644
--- a/src/test/run-pass/where-for-self.rs
+++ b/src/test/run-pass/where-for-self.rs
@@ -11,13 +11,19 @@
 // Test that we can quantify lifetimes outside a constraint (i.e., including
 // the self type) in a where clause.
 
+use std::marker::PhantomFn;
+
 static mut COUNT: u32 = 1;
 
-trait Bar<'a> {
+trait Bar<'a>
+    : PhantomFn<&'a ()>
+{
     fn bar(&self);
 }
 
-trait Baz<'a> {
+trait Baz<'a>
+    : PhantomFn<&'a ()>
+{
     fn baz(&self);
 }