about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/doc/guide.md2
-rw-r--r--src/etc/zsh/_rust199
-rw-r--r--src/grammar/verify.rs2
-rw-r--r--src/libcollections/string.rs6
-rw-r--r--src/libcollections/vec.rs80
-rw-r--r--src/libcore/ops.rs105
-rw-r--r--src/libcore/slice.rs58
-rw-r--r--src/libfmt_macros/lib.rs37
-rw-r--r--src/libnative/io/net.rs8
-rw-r--r--src/libnum/bigint.rs62
-rw-r--r--src/libregex/compile.rs4
-rw-r--r--src/libregex/lib.rs2
-rw-r--r--src/libregex/parse.rs26
-rw-r--r--src/libregex/re.rs22
-rw-r--r--src/libregex_macros/lib.rs6
-rw-r--r--src/librustc/back/link.rs28
-rw-r--r--src/librustc/back/lto.rs137
-rw-r--r--src/librustc/back/write.rs69
-rw-r--r--src/librustc/driver/config.rs10
-rw-r--r--src/librustc/driver/driver.rs20
-rw-r--r--src/librustc/lib.rs3
-rw-r--r--src/librustc/lint/builtin.rs13
-rw-r--r--src/librustc/middle/astencode.rs75
-rw-r--r--src/librustc/middle/borrowck/check_loans.rs6
-rw-r--r--src/librustc/middle/borrowck/gather_loans/gather_moves.rs3
-rw-r--r--src/librustc/middle/borrowck/gather_loans/lifetime.rs4
-rw-r--r--src/librustc/middle/borrowck/gather_loans/restrictions.rs3
-rw-r--r--src/librustc/middle/borrowck/mod.rs7
-rw-r--r--src/librustc/middle/cfg/construct.rs7
-rw-r--r--src/librustc/middle/dead.rs4
-rw-r--r--src/librustc/middle/def.rs18
-rw-r--r--src/librustc/middle/expr_use_visitor.rs46
-rw-r--r--src/librustc/middle/freevars.rs190
-rw-r--r--src/librustc/middle/kind.rs13
-rw-r--r--src/librustc/middle/lang_items.rs2
-rw-r--r--src/librustc/middle/liveness.rs70
-rw-r--r--src/librustc/middle/mem_categorization.rs92
-rw-r--r--src/librustc/middle/privacy.rs8
-rw-r--r--src/librustc/middle/resolve.rs371
-rw-r--r--src/librustc/middle/save/mod.rs49
-rw-r--r--src/librustc/middle/save/span_utils.rs2
-rw-r--r--src/librustc/middle/traits/fulfill.rs10
-rw-r--r--src/librustc/middle/traits/mod.rs30
-rw-r--r--src/librustc/middle/traits/select.rs15
-rw-r--r--src/librustc/middle/traits/util.rs22
-rw-r--r--src/librustc/middle/trans/_match.rs66
-rw-r--r--src/librustc/middle/trans/base.rs13
-rw-r--r--src/librustc/middle/trans/callee.rs26
-rw-r--r--src/librustc/middle/trans/closure.rs34
-rw-r--r--src/librustc/middle/trans/common.rs8
-rw-r--r--src/librustc/middle/trans/consts.rs6
-rw-r--r--src/librustc/middle/trans/debuginfo.rs22
-rw-r--r--src/librustc/middle/trans/expr.rs85
-rw-r--r--src/librustc/middle/trans/foreign.rs4
-rw-r--r--src/librustc/middle/trans/intrinsic.rs24
-rw-r--r--src/librustc/middle/trans/meth.rs8
-rw-r--r--src/librustc/middle/ty.rs63
-rw-r--r--src/librustc/middle/ty_fold.rs12
-rw-r--r--src/librustc/middle/typeck/astconv.rs28
-rw-r--r--src/librustc/middle/typeck/check/method.rs28
-rw-r--r--src/librustc/middle/typeck/check/mod.rs284
-rw-r--r--src/librustc/middle/typeck/check/regionck.rs37
-rw-r--r--src/librustc/middle/typeck/check/vtable2.rs6
-rw-r--r--src/librustc/middle/typeck/check/writeback.rs8
-rw-r--r--src/librustc/middle/typeck/collect.rs42
-rw-r--r--src/librustc/middle/typeck/infer/coercion.rs18
-rw-r--r--src/librustc/middle/typeck/infer/test.rs9
-rw-r--r--src/librustc/middle/typeck/mod.rs4
-rw-r--r--src/librustc/plugin/registry.rs6
-rw-r--r--src/librustc/util/ppaux.rs4
-rw-r--r--src/librustc_back/svh.rs2
-rw-r--r--src/librustc_llvm/lib.rs91
-rw-r--r--src/librustdoc/clean/mod.rs38
-rw-r--r--src/librustdoc/fold.rs4
-rw-r--r--src/librustdoc/html/format.rs2
-rw-r--r--src/librustdoc/html/render.rs10
-rw-r--r--src/librustdoc/stability_summary.rs4
-rw-r--r--src/librustrt/c_str.rs17
-rw-r--r--src/librustrt/local_data.rs62
-rw-r--r--src/libserialize/json.rs105
-rw-r--r--src/libstd/macros.rs4
-rw-r--r--src/libstd/rt/backtrace.rs4
-rw-r--r--src/libsyntax/ast.rs14
-rw-r--r--src/libsyntax/codemap.rs45
-rw-r--r--src/libsyntax/diagnostic.rs38
-rw-r--r--src/libsyntax/diagnostics/plugin.rs8
-rw-r--r--src/libsyntax/ext/base.rs108
-rw-r--r--src/libsyntax/ext/build.rs4
-rw-r--r--src/libsyntax/ext/deriving/generic/mod.rs3
-rw-r--r--src/libsyntax/ext/expand.rs33
-rw-r--r--src/libsyntax/ext/format.rs33
-rw-r--r--src/libsyntax/ext/source_util.rs46
-rw-r--r--src/libsyntax/fold.rs30
-rw-r--r--src/libsyntax/lib.rs2
-rw-r--r--src/libsyntax/parse/lexer/mod.rs6
-rw-r--r--src/libsyntax/parse/mod.rs4
-rw-r--r--src/libsyntax/parse/parser.rs183
-rw-r--r--src/libsyntax/parse/token.rs83
-rw-r--r--src/libsyntax/print/pp.rs10
-rw-r--r--src/libsyntax/print/pprust.rs73
-rw-r--r--src/libsyntax/visit.rs5
-rw-r--r--src/libterm/terminfo/parm.rs22
-rw-r--r--src/test/auxiliary/issue_16723_multiple_items_syntax_ext.rs33
-rw-r--r--src/test/auxiliary/macro_crate_test.rs2
-rw-r--r--src/test/auxiliary/xcrate_unit_struct.rs2
-rw-r--r--src/test/compile-fail/borrowck-closures-unique.rs2
-rw-r--r--src/test/compile-fail/borrowck-unboxed-closures.rs8
-rw-r--r--src/test/compile-fail/enum-variant-type-2.rs19
-rw-r--r--src/test/compile-fail/enum-variant-type.rs23
-rw-r--r--src/test/compile-fail/issue-3008-1.rs2
-rw-r--r--src/test/compile-fail/issue-3008-2.rs2
-rw-r--r--src/test/compile-fail/keywords-followed-by-double-colon.rs (renamed from src/test/run-pass/issue-3186.rs)10
-rw-r--r--src/test/compile-fail/qquote-1.rs2
-rw-r--r--src/test/compile-fail/qquote-2.rs2
-rw-r--r--src/test/compile-fail/recursion.rs4
-rw-r--r--src/test/compile-fail/slice-1.rs19
-rw-r--r--src/test/compile-fail/slice-2.rs25
-rw-r--r--src/test/compile-fail/slice-borrow.rs19
-rw-r--r--src/test/compile-fail/slice-mut-2.rs17
-rw-r--r--src/test/compile-fail/slice-mut.rs22
-rw-r--r--src/test/compile-fail/unboxed-closure-sugar-nonexistent-trait.rs18
-rw-r--r--src/test/compile-fail/unboxed-closure-sugar-wrong-trait.rs17
-rw-r--r--src/test/compile-fail/unboxed-closures-wrong-trait.rs2
-rw-r--r--src/test/pretty/tag-blank-lines.rs4
-rw-r--r--src/test/run-fail/issue-2444.rs2
-rw-r--r--src/test/run-pass-fulldeps/issue_16723_multiple_items_syntax_ext.rs31
-rw-r--r--src/test/run-pass-fulldeps/qquote.rs2
-rw-r--r--src/test/run-pass/borrowck-univariant-enum.rs6
-rw-r--r--src/test/run-pass/coerce-to-closure-and-proc.rs10
-rw-r--r--src/test/run-pass/fn-trait-sugar.rs2
-rw-r--r--src/test/run-pass/issue-2804.rs2
-rw-r--r--src/test/run-pass/issue-3874.rs4
-rw-r--r--src/test/run-pass/match-arm-statics.rs6
-rw-r--r--src/test/run-pass/match-range-static.rs2
-rw-r--r--src/test/run-pass/sepcomp-lib-lto.rs (renamed from src/test/compile-fail/sepcomp-lib-lto.rs)5
-rw-r--r--src/test/run-pass/slice-2.rs69
-rw-r--r--src/test/run-pass/slice-fail-1.rs31
-rw-r--r--src/test/run-pass/slice-fail-2.rs35
-rw-r--r--src/test/run-pass/slice.rs70
-rw-r--r--src/test/run-pass/tag-align-dyn-u64.rs4
-rw-r--r--src/test/run-pass/tag-align-shape.rs6
-rw-r--r--src/test/run-pass/tag-align-u64.rs4
-rw-r--r--src/test/run-pass/unboxed-closures-all-traits.rs6
-rw-r--r--src/test/run-pass/unboxed-closures-drop.rs6
-rw-r--r--src/test/run-pass/unboxed-closures-single-word-env.rs6
-rw-r--r--src/test/run-pass/unboxed-closures-unique-type-id.rs3
-rw-r--r--src/test/run-pass/where-clauses-unboxed-closures.rs2
-rw-r--r--src/test/run-pass/xcrate-unit-struct.rs4
148 files changed, 2667 insertions, 1789 deletions
diff --git a/src/doc/guide.md b/src/doc/guide.md
index 2f16c783446..03a73db8aa4 100644
--- a/src/doc/guide.md
+++ b/src/doc/guide.md
@@ -1575,8 +1575,6 @@ we haven't seen before. Here's a simple program that reads some input,
 and then prints it back out:
 
 ```{rust,ignore}
-use std::io;
-
 fn main() {
     println!("Type something!");
 
diff --git a/src/etc/zsh/_rust b/src/etc/zsh/_rust
index b423191d54a..f4e8f6f7873 100644
--- a/src/etc/zsh/_rust
+++ b/src/etc/zsh/_rust
@@ -4,109 +4,166 @@ local -a _rustc_opts_switches _rustc_opts_lint _rustc_opts_debug
 
 typeset -A opt_args
 
+_rustc_debuginfo_levels=(
+    "0[no debug info]"
+    "1[line-tables only (for stacktraces and breakpoints)]"
+    "2[full debug info with variable and type information (same as -g)]"
+)
+
+_rustc_crate_types=(
+    'bin'
+    'lib'
+    'rlib'
+    'dylib'
+    'staticlib'
+)
+
+_rustc_emit_types=(
+    'asm'
+    'bc'
+    'ir'
+    'obj'
+    'link'
+)
+_rustc_pretty_types=(
+    'normal[un-annotated source]'
+    'expanded[crates expanded]'
+    'typed[crates  expanded,  with  type  annotations]'
+    'identified[fully parenthesized, AST nodes and blocks with IDs]'
+    'flowgraph=[graphviz formatted flowgraph for node]:NODEID:'
+)
+_rustc_color_types=(
+    'auto[colorize, if output goes to a tty (default)]'
+    'always[always colorize output]'
+    'never[never colorize output]'
+)
+
+_rustc_opts_vals=(
+    --crate-name='[Specify the name of the crate being built]'
+    --crate-type='[Comma separated list of types of crates for the compiler to emit]:TYPES:_values -s "," "Crate types"  "$_rustc_crate_types[@]"'
+    --emit='[Comma separated list of types of output for the compiler to emit]:TYPES:_values -s "," "Emit Targets" "$_rustc_emit_types[@]"'
+    --debuginfo='[Emit DWARF debug info to the objects created]:LEVEL:_values "Debug Levels" "$_rustc_debuginfo_levels[@]"'
+    --dep-info='[Output dependency info to <filename> after compiling]::FILE:_files -/'
+    --sysroot='[Override the system root]:PATH:_files -/'
+    --cfg='[Configure the compilation environment]:SPEC:'
+    --out-dir='[Write output to compiler-chosen filename in <dir>.  Ignored  if  -o  is  specified. (default the current directory)]:DIR:_files -/'
+    -o'[Write output to <filename>. Ignored if more than one --emit is specified.]:FILENAME:_files'
+    --opt-level='[Optimize with possible levels 0-3]:LEVEL:(0 1 2 3)'
+    --pretty='[Pretty-print the input instead of compiling]::TYPE:_values "TYPES" "$_rustc_pretty_types[@]"'
+    -L'[Add a directory to the library search path]:DIR:_files -/'
+    --target='[Target triple cpu-manufacturer-kernel\[-os\] to compile]:TRIPLE:'
+    --color='[Configure coloring of output]:CONF:_values "COLORS" "$_rustc_color_types[@]"'
+    {-v,--version}'[Print version info and exit]::VERBOSE:(verbose)'
+    --explain='[Provide a detailed explanation of an error message]:OPT:'
+    --extern'[Specify where an external rust library is located]:ARG:'
+)
+
 _rustc_opts_switches=(
-    --ar'[Program to use for managing archives instead of the default.]'
-    -c'[Compile and assemble, but do not link]'
-    --cfg'[Configure the compilation environment]'
-    --crate-id'[Output the crate id and exit]'
-    --crate-file-name'[deprecated in favor of --print-file-name]'
-    --crate-name'[Specify the name of the crate being built]'
-    --crate-type'[Specify the type of crate to crate]'
-    --debuginfo'[Emit DWARF debug info to the objects created: 0 = no debug info, 1 = line-tables only (for stacktraces and breakpoints), 2 = full debug info with variable and type information (same as -g)]'
-    --dep-info'[Output dependency info to <filename> after compiling]'
     -g'[Equivalent to --debuginfo=2]'
     {-h,--help}'[Display this message]'
-    -L'[Add a directory to the library search path]'
-    --linker'[Program to use for linking instead of the default.]'
-    --link-args'[FLAGS is a space-separated list of flags passed to the linker]'
-    --llvm-args'[A list of arguments to pass to llvm, comma separated]'
-    --ls'[List the symbols defined by a library crate]'
     --no-analysis'[Parse and expand the output, but run no analysis or produce output]'
-    --no-rpath'[Disables setting the rpath in libs/exes]'
     --no-trans'[Run all passes except translation; no output]'
     -O'[Equivalent to --opt-level=2]'
-    -o'[Write output to <filename>]'
-    --opt-level'[Optimize with possible levels 0-3]'
-    --out-dir'[Write output to compiler-chosen filename in <dir>]'
     --parse-only'[Parse only; do not compile, assemble, or link]'
-    --passes'[Comma or space separated list of pass names to use]'
-    --pretty'[Pretty-print the input instead of compiling]'
     --print-crate-name'[Output the crate name and exit]'
     --print-file-name'[Output the file(s) that would be written if compilation continued and exit]'
-    --save-temps'[Write intermediate files (.bc, .opt.bc, .o) in addition to normal output]'
-    --sysroot'[Override the system root]'
     --test'[Build a test harness]'
-    --target'[Target triple cpu-manufacturer-kernel\[-os\] to compile]'
-    --target-cpu'[Select target processor (llc -mcpu=help for details)]'
-    --target-feature'[Target specific attributes (llc -mattr=help for details)]'
-    --relocation-model'[Relocation model (llc --help for details)]'
-    {-v,--version}'[Print version info and exit]'
 )
+_rustc_opts_codegen=(
+    'ar=[Path to the archive utility to use when assembling archives.]:BIN:_path_files'
+    'linker=[Path to the linker utility to use when linking libraries, executables, and objects.]:BIN:_path_files'
+    'link-args=[A space-separated list of extra arguments to pass to the linker when the linker is invoked.]:ARGS:'
+    'target-cpu=[Selects a target processor. If the value is "help", then a list of  available  CPUs is printed.]:CPU:'
+    'target-feature=[A space-separated list of features to enable or disable for the target. A preceding "+" enables a feature while a preceding "-" disables it. Available features can be discovered through target-cpu=help.]:FEATURE:'
+    'passes=[A space-separated list of extra LLVM passes to run. A value of "list" will cause rustc to print all known passes and exit. The passes specified are appended at the end of the normal pass manager.]:LIST:'
+    'llvm-args=[A space-separated list of arguments to pass through to LLVM.]:ARGS:'
+    'save-temps[If specified, the compiler will save more files (.bc, .o, .no-opt.bc) generated throughout compilation in the output directory.]'
+    'rpath[If specified, then the rpath value for dynamic libraries will be set in either dynamic library or executable outputs.]'
+    'no-prepopulate-passes[Suppresses pre-population of the LLVM pass manager that is run over the module.]'
+    'no-vectorize-loops[Suppresses running the loop vectorization LLVM pass, regardless of optimization level.]'
+    'no-vectorize-slp[Suppresses running the LLVM SLP vectorization pass, regardless of optimization level.]'
+    'soft-float[Generates software floating point library calls instead of hardware instructions.]'
+    'prefer-dynamic[Prefers dynamic linking to static linking.]'
+    "no-integrated-as[Force usage of an external assembler rather than LLVM's integrated one.]"
+    'no-redzone[disable the use of the redzone]'
+    'relocation-model=[The relocation model to use. (default: pic)]:MODEL:(pic static dynamic-no-pic)'
+    'code-model=[choose the code model to use (llc -code-model for details)]:MODEL:'
+    'metadata=[metadata to mangle symbol names with]:VAL:'
+    'extra-filenames=[extra data to put in each output filename]:VAL:'
+    'codegen-units=[divide crate into N units to optimize in parallel]:N:'
+    'help[Show all codegen options]'
+)
+
 _rustc_opts_lint=(
-    'attribute-usage[detects bad use of attributes]'
-    'ctypes[proper use of libc types in foreign modules]'
-    'dead-assignment[detect assignments that will never be read]'
-    'dead-code[detect piece of code that will never be used]'
-    'default-type-param-usage[prevents explicitly setting a type parameter with a default]'
-    'deprecated[detects use of #\[deprecated\] items]'
+    'help[Show a list of all lints]'
     'experimental[detects use of #\[experimental\] items]'
-    'heap-memory[use of any (~ type or @ type) heap memory]'
+    'heap-memory[use of any (Box type or @ type) heap memory]'
     'managed-heap-memory[use of managed (@ type) heap memory]'
     'missing-doc[detects missing documentation for public members]'
-    'non-camel-case-types[types, variants and traits should have camel case names]'
-    'non-uppercase-pattern-statics[static constants in match patterns should be all caps]'
     'non-uppercase-statics[static constants should have uppercase identifiers]'
     'owned-heap-memory[use of owned (~ type) heap memory]'
+    'unnecessary-qualification[detects unnecessarily qualified names]'
+    'unsafe-block[usage of an `unsafe` block]'
+    'unstable[detects use of #\[unstable\] items (incl. items with no stability attribute)]'
+    'unused-result[unused result of an expression in a statement]'
+    'variant-size-difference[detects enums with widely varying variant sizes]'
+    'ctypes[proper use of libc types in foreign modules]'
+    'dead-assignment[detect assignments that will never be read]'
+    'dead-code[detect piece of code that will never be used]'
+    'deprecated[detects use of #\[deprecated\] items]'
+    'non-camel-case-types[types, variants and traits should have camel case names]'
+    'non-snake-case[methods, functions, lifetime parameters and modules should have snake case names]'
     'path-statement[path statements with no effect]'
+    'raw-pointer-deriving[uses of #\[deriving\] with raw pointers are rarely correct]'
     'type-limits[comparisons made useless by limits of the types involved]'
     'type-overflow[literal out of range for its type]'
-    'unknown-crate-type[unknown crate type found in #\[crate_type\] directive]'
-    'unknown-features[unknown features found in crate-level #\[feature\] directives]'
     'unnecessary-allocation[detects unnecessary allocations that can be eliminated]'
     'unnecessary-parens[`if`, `match`, `while` and `return` do not need parentheses]'
-    'unnecessary-qualification[detects unnecessarily qualified names]'
-    'unnecessary-typecast[detects unnecessary type casts, that can be removed]'
     'unreachable-code[detects unreachable code]'
     'unrecognized-lint[unrecognized lint attribute]'
-    'unsafe-block[usage of an `unsafe` block]'
-    'unstable[detects use of #\[unstable\] items (incl. items with no stability attribute)]'
+    'unsigned-negate[using an unary minus operator on unsigned type]'
+    'unused-attribute[detects attributes that were not used by the compiler]'
     'unused-imports[imports that are never used]'
     'unused-must-use[unused result of a type flagged as #\[must_use\]]'
     "unused-mut[detect mut variables which don't need to be mutable]"
-    'unused-result[unused result of an expression in a statement]'
     'unused-unsafe[unnecessary use of an `unsafe` block]'
     'unused-variable[detect variables which are not used in any way]'
+    'visible-private-types[detect use of private types in exported type signatures]'
     'warnings[mass-change the level for lints which produce warnings]'
     'while-true[suggest using `loop { }` instead of `while true { }`]'
+    'unknown-crate-type[unknown crate type found in #\[crate_type\] directive]'
+    'unknown-features[unknown features found in crate-level #\[feature\] directives]'
+    'bad-style[group of non_camel_case_types, non_snake_case, non_uppercase_statics]'
+    'unused[group of unused_imports, unused_variable, dead_assignment, dead_code, unused_mut, unreachable_code]'
 )
 
 _rustc_opts_debug=(
+    'verbose[in general, enable more debug printouts]'
+    'time-passes[measure time of each rustc pass]'
+    'count-llvm-insns[count where LLVM instrs originate]'
+    'time-llvm-passes[measure time of each LLVM pass]'
+    'trans-stats[gather trans statistics]'
     'asm-comments[generate comments into the assembly (may change behavior)]'
+    'no-verify[skip LLVM verification]'
     'borrowck-stats[gather borrowck statistics]'
-    'count-llvm-insns[count where LLVM instrs originate]'
-    'count-type-sizes[count the sizes of aggregate types]'
-    'debug-info[Produce debug info (experimental)]'
+    'no-landing-pads[omit landing pads for unwinding]'
     'debug-llvm[enable debug output from LLVM]'
-    'extra-debug-info[Extra debugging info (experimental)]'
-    'gc[Garbage collect shared data (experimental)]'
-    'gen-crate-map[Force generation of a toplevel crate map]'
-    'lto[Perform LLVM link-time optimizations]'
+    'show-span[show spans for compiler debugging]'
+    'count-type-sizes[count the sizes of aggregate types]'
     'meta-stats[gather metadata statistics]'
-    "no-integrated-as[Use external assembler rather than LLVM's integrated one]"
-    'no-landing-pads[omit landing pads for unwinding]'
     'no-opt[do not optimize, even if -O is passed]'
-    "no-prepopulate-passes[Don't pre-populate the pass managers with a list of passes, only use the passes from --passes]"
-    "no-vectorize-loops[Don't run the loop vectorization optimization passes]"
-    "no-vectorize-slp[Don't run LLVM's SLP vectorization passes]"
-    'no-verify[skip LLVM verification]'
-    'prefer-dynamic[Prefer dynamic linking to static linking]'
     'print-link-args[Print the arguments passed to the linker]'
+    'gc[Garbage collect shared data (experimental)]'
     'print-llvm-passes[Prints the llvm optimization passes being run]'
-    'soft-float[Generate software floating point library calls]'
-    'time-llvm-passes[measure time of each LLVM pass]'
-    'time-passes[measure time of each rustc pass]'
-    'trans-stats[gather trans statistics]'
-    'verbose[in general, enable more debug printouts]'
+    'lto[Perform LLVM link-time optimizations]'
+    'ast-json[Print the AST as JSON and halt]'
+    'ast-json-noexpand[Print the pre-expansion AST as JSON and halt]'
+    'ls[List the symbols defined by a library crate]'
+    'save-analysis[Write syntax and type analysis information in addition to normal output]'
+    'flowgraph-print-loans[Include loan analysis data in --pretty flowgraph output]'
+    'flowgraph-print-moves[Include move analysis data in --pretty flowgraph output]'
+    'flowgraph-print-assigns[Include assignment analysis data in --pretty flowgraph output]'
+    'flowgraph-print-all[Include all dataflow analysis data in --pretty flowgraph output]'
 )
 
 _rustc_opts_fun_lint(){
@@ -115,14 +172,20 @@ _rustc_opts_fun_lint(){
 }
 
 _rustc_opts_fun_debug(){
-    _describe 'options' _rustc_opts_debug
+    _values 'options' "$_rustc_opts_debug[@]"
+}
+
+_rustc_opts_fun_codegen(){
+    _values 'options' "$_rustc_opts_codegen[@]"
 }
 
 _arguments -s :  \
-    '(-W --warn)'{-W,--warn}'[Set lint warnings]:lint options:_rustc_opts_fun_lint' \
-    '(-A --allow)'{-A,--allow}'[Set lint allowed]:lint options:_rustc_opts_fun_lint' \
-    '(-D --deny)'{-D,--deny}'[Set lint denied]:lint options:_rustc_opts_fun_lint' \
-    '(-F --forbid)'{-F,--forbid}'[Set lint forbidden]:lint options:_rustc_opts_fun_lint' \
+    '(-W --warn)'{-W,--warn=}'[Set lint warnings]:lint options:_rustc_opts_fun_lint' \
+    '(-A --allow)'{-A,--allow=}'[Set lint allowed]:lint options:_rustc_opts_fun_lint' \
+    '(-D --deny)'{-D,--deny=}'[Set lint denied]:lint options:_rustc_opts_fun_lint' \
+    '(-F --forbid)'{-F,--forbid=}'[Set lint forbidden]:lint options:_rustc_opts_fun_lint' \
     '*-Z[Set internal debugging options]:debug options:_rustc_opts_fun_debug' \
+    '*-C[Set internal Codegen options]:codegen options:_rustc_opts_fun_codegen' \
     "$_rustc_opts_switches[@]" \
-    '*::files:_files -g "*.rs"'
+    "$_rustc_opts_vals[@]" \
+    '::files:_files -g "*.rs"'
diff --git a/src/grammar/verify.rs b/src/grammar/verify.rs
index f2ae5a1ea4e..a95eeb3c97d 100644
--- a/src/grammar/verify.rs
+++ b/src/grammar/verify.rs
@@ -211,7 +211,7 @@ fn parse_antlr_token(s: &str, tokens: &HashMap<String, Token>) -> TokenAndSpan {
     let sp = syntax::codemap::Span {
         lo: syntax::codemap::BytePos(from_str::<u32>(start).unwrap() - offset),
         hi: syntax::codemap::BytePos(from_str::<u32>(end).unwrap() + 1),
-        expn_info: None
+        expn_id: syntax::codemap::NO_EXPANSION
     };
 
     TokenAndSpan {
diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs
index 05d91a75041..a12d403603f 100644
--- a/src/libcollections/string.rs
+++ b/src/libcollections/string.rs
@@ -872,7 +872,7 @@ mod tests {
 
     use {Mutable, MutableSeq};
     use str;
-    use str::{Str, StrSlice, Owned, Slice};
+    use str::{Str, StrSlice, Owned};
     use super::String;
     use vec::Vec;
 
@@ -898,10 +898,10 @@ mod tests {
     #[test]
     fn test_from_utf8_lossy() {
         let xs = b"hello";
-        assert_eq!(String::from_utf8_lossy(xs), Slice("hello"));
+        assert_eq!(String::from_utf8_lossy(xs), str::Slice("hello"));
 
         let xs = "ศไทย中华Việt Nam".as_bytes();
-        assert_eq!(String::from_utf8_lossy(xs), Slice("ศไทย中华Việt Nam"));
+        assert_eq!(String::from_utf8_lossy(xs), str::Slice("ศไทย中华Việt Nam"));
 
         let xs = b"Hello\xC2 There\xFF Goodbye";
         assert_eq!(String::from_utf8_lossy(xs),
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index f570573262a..4051f682134 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -20,6 +20,7 @@ use core::default::Default;
 use core::fmt;
 use core::mem;
 use core::num;
+use core::ops;
 use core::ptr;
 use core::raw::Slice as RawSlice;
 use core::uint;
@@ -464,6 +465,47 @@ impl<T> Index<uint,T> for Vec<T> {
     }
 }*/
 
+impl<T> ops::Slice<uint, [T]> for Vec<T> {
+    #[inline]
+    fn as_slice_<'a>(&'a self) -> &'a [T] {
+        self.as_slice()
+    }
+
+    #[inline]
+    fn slice_from_<'a>(&'a self, start: &uint) -> &'a [T] {
+        self.as_slice().slice_from_(start)
+    }
+
+    #[inline]
+    fn slice_to_<'a>(&'a self, end: &uint) -> &'a [T] {
+        self.as_slice().slice_to_(end)
+    }
+    #[inline]
+    fn slice_<'a>(&'a self, start: &uint, end: &uint) -> &'a [T] {
+        self.as_slice().slice_(start, end)
+    }
+}
+
+impl<T> ops::SliceMut<uint, [T]> for Vec<T> {
+    #[inline]
+    fn as_mut_slice_<'a>(&'a mut self) -> &'a mut [T] {
+        self.as_mut_slice()
+    }
+
+    #[inline]
+    fn slice_from_mut_<'a>(&'a mut self, start: &uint) -> &'a mut [T] {
+        self.as_mut_slice().slice_from_mut_(start)
+    }
+
+    #[inline]
+    fn slice_to_mut_<'a>(&'a mut self, end: &uint) -> &'a mut [T] {
+        self.as_mut_slice().slice_to_mut_(end)
+    }
+    #[inline]
+    fn slice_mut_<'a>(&'a mut self, start: &uint, end: &uint) -> &'a mut [T] {
+        self.as_mut_slice().slice_mut_(start, end)
+    }
+}
 impl<T> FromIterator<T> for Vec<T> {
     #[inline]
     fn from_iter<I:Iterator<T>>(mut iterator: I) -> Vec<T> {
@@ -2327,6 +2369,44 @@ mod tests {
         let _ = vec[3];
     }
 
+    // NOTE uncomment after snapshot
+    /*
+    #[test]
+    #[should_fail]
+    fn test_slice_out_of_bounds_1() {
+        let x: Vec<int> = vec![1, 2, 3, 4, 5];
+        x[-1..];
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_slice_out_of_bounds_2() {
+        let x: Vec<int> = vec![1, 2, 3, 4, 5];
+        x[..6];
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_slice_out_of_bounds_3() {
+        let x: Vec<int> = vec![1, 2, 3, 4, 5];
+        x[-1..4];
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_slice_out_of_bounds_4() {
+        let x: Vec<int> = vec![1, 2, 3, 4, 5];
+        x[1..6];
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_slice_out_of_bounds_5() {
+        let x: Vec<int> = vec![1, 2, 3, 4, 5];
+        x[3..2];
+    }
+    */
+
     #[test]
     fn test_swap_remove_empty() {
         let mut vec: Vec<uint> = vec!();
diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs
index 94febf03635..718d3119995 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -638,7 +638,7 @@ shr_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64)
  * ```
  */
 #[lang="index"]
-pub trait Index<Index,Result> {
+pub trait Index<Index, Result> {
     /// The method for the indexing (`Foo[Bar]`) operation
     fn index<'a>(&'a self, index: &Index) -> &'a Result;
 }
@@ -651,7 +651,7 @@ pub trait Index<Index,Result> {
  * # Example
  *
  * A trivial implementation of `IndexMut`. When `Foo[Foo]` happens, it ends up
- * calling `index`, and therefore, `main` prints `Indexing!`.
+ * calling `index_mut`, and therefore, `main` prints `Indexing!`.
  *
  * ```
  * struct Foo;
@@ -669,13 +669,112 @@ pub trait Index<Index,Result> {
  * ```
  */
 #[lang="index_mut"]
-pub trait IndexMut<Index,Result> {
+pub trait IndexMut<Index, Result> {
     /// The method for the indexing (`Foo[Bar]`) operation
     fn index_mut<'a>(&'a mut self, index: &Index) -> &'a mut Result;
 }
 
 /**
  *
+ * The `Slice` trait is used to specify the functionality of slicing operations
+ * like `arr[from..to]` when used in an immutable context.
+ *
+ * # Example
+ *
+ * A trivial implementation of `Slice`. When `Foo[..Foo]` happens, it ends up
+ * calling `slice_to`, and therefore, `main` prints `Slicing!`.
+ *
+ * ```
+ * struct Foo;
+ *
+ * impl ::core::ops::Slice<Foo, Foo> for Foo {
+ *     fn as_slice_<'a>(&'a self) -> &'a Foo {
+ *         println!("Slicing!");
+ *         self
+ *     }
+ *     fn slice_from_<'a>(&'a self, from: &Foo) -> &'a Foo {
+ *         println!("Slicing!");
+ *         self
+ *     }
+ *     fn slice_to_<'a>(&'a self, to: &Foo) -> &'a Foo {
+ *         println!("Slicing!");
+ *         self
+ *     }
+ *     fn slice_<'a>(&'a self, from: &Foo, to: &Foo) -> &'a Foo {
+ *         println!("Slicing!");
+ *         self
+ *     }
+ * }
+ *
+ * fn main() {
+ *     Foo[..Foo];
+ * }
+ * ```
+ */
+// FIXME(#17273) remove the postscript _s
+#[lang="slice"]
+pub trait Slice<Idx, Sized? Result> for Sized? {
+    /// The method for the slicing operation foo[]
+    fn as_slice_<'a>(&'a self) -> &'a Result;
+    /// The method for the slicing operation foo[from..]
+    fn slice_from_<'a>(&'a self, from: &Idx) -> &'a Result;
+    /// The method for the slicing operation foo[..to]
+    fn slice_to_<'a>(&'a self, to: &Idx) -> &'a Result;
+    /// The method for the slicing operation foo[from..to]
+    fn slice_<'a>(&'a self, from: &Idx, to: &Idx) -> &'a Result;
+}
+
+/**
+ *
+ * The `SliceMut` trait is used to specify the functionality of slicing
+ * operations like `arr[from..to]`, when used in a mutable context.
+ *
+ * # Example
+ *
+ * A trivial implementation of `SliceMut`. When `Foo[Foo..]` happens, it ends up
+ * calling `slice_from_mut`, and therefore, `main` prints `Slicing!`.
+ *
+ * ```
+ * struct Foo;
+ *
+ * impl ::core::ops::SliceMut<Foo, Foo> for Foo {
+ *     fn as_mut_slice_<'a>(&'a mut self) -> &'a mut Foo {
+ *         println!("Slicing!");
+ *         self
+ *     }
+ *     fn slice_from_mut_<'a>(&'a mut self, from: &Foo) -> &'a mut Foo {
+ *         println!("Slicing!");
+ *         self
+ *     }
+ *     fn slice_to_mut_<'a>(&'a mut self, to: &Foo) -> &'a mut Foo {
+ *         println!("Slicing!");
+ *         self
+ *     }
+ *     fn slice_mut_<'a>(&'a mut self, from: &Foo, to: &Foo) -> &'a mut Foo {
+ *         println!("Slicing!");
+ *         self
+ *     }
+ * }
+ *
+ * fn main() {
+ *     Foo[mut Foo..];
+ * }
+ * ```
+ */
+// FIXME(#17273) remove the postscript _s
+#[lang="slice_mut"]
+pub trait SliceMut<Idx, Sized? Result> for Sized? {
+    /// The method for the slicing operation foo[]
+    fn as_mut_slice_<'a>(&'a mut self) -> &'a mut Result;
+    /// The method for the slicing operation foo[from..]
+    fn slice_from_mut_<'a>(&'a mut self, from: &Idx) -> &'a mut Result;
+    /// The method for the slicing operation foo[..to]
+    fn slice_to_mut_<'a>(&'a mut self, to: &Idx) -> &'a mut Result;
+    /// The method for the slicing operation foo[from..to]
+    fn slice_mut_<'a>(&'a mut self, from: &Idx, to: &Idx) -> &'a mut Result;
+}
+/**
+ *
  * The `Deref` trait is used to specify the functionality of dereferencing
  * operations like `*v`.
  *
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index 65ad7bb1753..5368cb44502 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -42,6 +42,7 @@ use cmp;
 use default::Default;
 use iter::*;
 use num::{CheckedAdd, Saturating, div_rem};
+use ops;
 use option::{None, Option, Some};
 use ptr;
 use ptr::RawPtr;
@@ -475,6 +476,63 @@ impl<'a,T> ImmutableSlice<'a, T> for &'a [T] {
     }
 }
 
+impl<T> ops::Slice<uint, [T]> for [T] {
+    #[inline]
+    fn as_slice_<'a>(&'a self) -> &'a [T] {
+        self
+    }
+
+    #[inline]
+    fn slice_from_<'a>(&'a self, start: &uint) -> &'a [T] {
+        self.slice_(start, &self.len())
+    }
+
+    #[inline]
+    fn slice_to_<'a>(&'a self, end: &uint) -> &'a [T] {
+        self.slice_(&0, end)
+    }
+    #[inline]
+    fn slice_<'a>(&'a self, start: &uint, end: &uint) -> &'a [T] {
+        assert!(*start <= *end);
+        assert!(*end <= self.len());
+        unsafe {
+            transmute(RawSlice {
+                    data: self.as_ptr().offset(*start as int),
+                    len: (*end - *start)
+                })
+        }
+    }
+}
+
+impl<T> ops::SliceMut<uint, [T]> for [T] {
+    #[inline]
+    fn as_mut_slice_<'a>(&'a mut self) -> &'a mut [T] {
+        self
+    }
+
+    #[inline]
+    fn slice_from_mut_<'a>(&'a mut self, start: &uint) -> &'a mut [T] {
+        let len = &self.len();
+        self.slice_mut_(start, len)
+    }
+
+    #[inline]
+    fn slice_to_mut_<'a>(&'a mut self, end: &uint) -> &'a mut [T] {
+        self.slice_mut_(&0, end)
+    }
+    #[inline]
+    fn slice_mut_<'a>(&'a mut self, start: &uint, end: &uint) -> &'a mut [T] {
+        assert!(*start <= *end);
+        assert!(*end <= self.len());
+        unsafe {
+            transmute(RawSlice {
+                    data: self.as_ptr().offset(*start as int),
+                    len: (*end - *start)
+                })
+        }
+    }
+}
+
 /// Extension methods for vectors such that their elements are
 /// mutable.
 #[experimental = "may merge with other traits; may lose region param; needs review"]
diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs
index 9272369f73c..a9f34e1195c 100644
--- a/src/libfmt_macros/lib.rs
+++ b/src/libfmt_macros/lib.rs
@@ -23,6 +23,7 @@
 
 use std::char;
 use std::str;
+use std::string;
 
 /// A piece is a portion of the format string which represents the next part
 /// to emit. These are emitted as a stream by the `Parser` class.
@@ -32,7 +33,7 @@ pub enum Piece<'a> {
     String(&'a str),
     /// This describes that formatting should process the next argument (as
     /// specified inside) for emission.
-    Argument(Argument<'a>),
+    NextArgument(Argument<'a>),
 }
 
 /// Representation of an argument specification.
@@ -129,7 +130,7 @@ pub struct Parser<'a> {
     input: &'a str,
     cur: str::CharOffsets<'a>,
     /// Error messages accumulated during parsing
-    pub errors: Vec<String>,
+    pub errors: Vec<string::String>,
 }
 
 impl<'a> Iterator<Piece<'a>> for Parser<'a> {
@@ -140,7 +141,7 @@ impl<'a> Iterator<Piece<'a>> for Parser<'a> {
                 if self.consume('{') {
                     Some(String(self.string(pos + 1)))
                 } else {
-                    let ret = Some(Argument(self.argument()));
+                    let ret = Some(NextArgument(self.argument()));
                     self.must_consume('}');
                     ret
                 }
@@ -469,28 +470,28 @@ mod tests {
 
     #[test]
     fn format_nothing() {
-        same("{}", [Argument(Argument {
+        same("{}", [NextArgument(Argument {
             position: ArgumentNext,
             format: fmtdflt(),
         })]);
     }
     #[test]
     fn format_position() {
-        same("{3}", [Argument(Argument {
+        same("{3}", [NextArgument(Argument {
             position: ArgumentIs(3),
             format: fmtdflt(),
         })]);
     }
     #[test]
     fn format_position_nothing_else() {
-        same("{3:}", [Argument(Argument {
+        same("{3:}", [NextArgument(Argument {
             position: ArgumentIs(3),
             format: fmtdflt(),
         })]);
     }
     #[test]
     fn format_type() {
-        same("{3:a}", [Argument(Argument {
+        same("{3:a}", [NextArgument(Argument {
             position: ArgumentIs(3),
             format: FormatSpec {
                 fill: None,
@@ -504,7 +505,7 @@ mod tests {
     }
     #[test]
     fn format_align_fill() {
-        same("{3:>}", [Argument(Argument {
+        same("{3:>}", [NextArgument(Argument {
             position: ArgumentIs(3),
             format: FormatSpec {
                 fill: None,
@@ -515,7 +516,7 @@ mod tests {
                 ty: "",
             },
         })]);
-        same("{3:0<}", [Argument(Argument {
+        same("{3:0<}", [NextArgument(Argument {
             position: ArgumentIs(3),
             format: FormatSpec {
                 fill: Some('0'),
@@ -526,7 +527,7 @@ mod tests {
                 ty: "",
             },
         })]);
-        same("{3:*<abcd}", [Argument(Argument {
+        same("{3:*<abcd}", [NextArgument(Argument {
             position: ArgumentIs(3),
             format: FormatSpec {
                 fill: Some('*'),
@@ -540,7 +541,7 @@ mod tests {
     }
     #[test]
     fn format_counts() {
-        same("{:10s}", [Argument(Argument {
+        same("{:10s}", [NextArgument(Argument {
             position: ArgumentNext,
             format: FormatSpec {
                 fill: None,
@@ -551,7 +552,7 @@ mod tests {
                 ty: "s",
             },
         })]);
-        same("{:10$.10s}", [Argument(Argument {
+        same("{:10$.10s}", [NextArgument(Argument {
             position: ArgumentNext,
             format: FormatSpec {
                 fill: None,
@@ -562,7 +563,7 @@ mod tests {
                 ty: "s",
             },
         })]);
-        same("{:.*s}", [Argument(Argument {
+        same("{:.*s}", [NextArgument(Argument {
             position: ArgumentNext,
             format: FormatSpec {
                 fill: None,
@@ -573,7 +574,7 @@ mod tests {
                 ty: "s",
             },
         })]);
-        same("{:.10$s}", [Argument(Argument {
+        same("{:.10$s}", [NextArgument(Argument {
             position: ArgumentNext,
             format: FormatSpec {
                 fill: None,
@@ -584,7 +585,7 @@ mod tests {
                 ty: "s",
             },
         })]);
-        same("{:a$.b$s}", [Argument(Argument {
+        same("{:a$.b$s}", [NextArgument(Argument {
             position: ArgumentNext,
             format: FormatSpec {
                 fill: None,
@@ -598,7 +599,7 @@ mod tests {
     }
     #[test]
     fn format_flags() {
-        same("{:-}", [Argument(Argument {
+        same("{:-}", [NextArgument(Argument {
             position: ArgumentNext,
             format: FormatSpec {
                 fill: None,
@@ -609,7 +610,7 @@ mod tests {
                 ty: "",
             },
         })]);
-        same("{:+#}", [Argument(Argument {
+        same("{:+#}", [NextArgument(Argument {
             position: ArgumentNext,
             format: FormatSpec {
                 fill: None,
@@ -623,7 +624,7 @@ mod tests {
     }
     #[test]
     fn format_mixture() {
-        same("abcd {3:a} efg", [String("abcd "), Argument(Argument {
+        same("abcd {3:a} efg", [String("abcd "), NextArgument(Argument {
             position: ArgumentIs(3),
             format: FormatSpec {
                 fill: None,
diff --git a/src/libnative/io/net.rs b/src/libnative/io/net.rs
index af7508ccbe9..8418e741167 100644
--- a/src/libnative/io/net.rs
+++ b/src/libnative/io/net.rs
@@ -37,7 +37,7 @@ pub fn ntohs(u: u16) -> u16 {
 }
 
 enum InAddr {
-    InAddr(libc::in_addr),
+    In4Addr(libc::in_addr),
     In6Addr(libc::in6_addr),
 }
 
@@ -48,7 +48,7 @@ fn ip_to_inaddr(ip: rtio::IpAddr) -> InAddr {
                      (b as u32 << 16) |
                      (c as u32 <<  8) |
                      (d as u32 <<  0);
-            InAddr(libc::in_addr {
+            In4Addr(libc::in_addr {
                 s_addr: Int::from_be(ip)
             })
         }
@@ -74,7 +74,7 @@ fn addr_to_sockaddr(addr: rtio::SocketAddr,
                     -> libc::socklen_t {
     unsafe {
         let len = match ip_to_inaddr(addr.ip) {
-            InAddr(inaddr) => {
+            In4Addr(inaddr) => {
                 let storage = storage as *mut _ as *mut libc::sockaddr_in;
                 (*storage).sin_family = libc::AF_INET as libc::sa_family_t;
                 (*storage).sin_port = htons(addr.port);
@@ -723,7 +723,7 @@ impl UdpSocket {
     pub fn set_membership(&mut self, addr: rtio::IpAddr,
                           opt: libc::c_int) -> IoResult<()> {
         match ip_to_inaddr(addr) {
-            InAddr(addr) => {
+            In4Addr(addr) => {
                 let mreq = libc::ip_mreq {
                     imr_multiaddr: addr,
                     // interface == INADDR_ANY
diff --git a/src/libnum/bigint.rs b/src/libnum/bigint.rs
index 3f91ce11915..efa3402073f 100644
--- a/src/libnum/bigint.rs
+++ b/src/libnum/bigint.rs
@@ -618,7 +618,7 @@ impl ToBigUint for BigInt {
     fn to_biguint(&self) -> Option<BigUint> {
         if self.sign == Plus {
             Some(self.data.clone())
-        } else if self.sign == Zero {
+        } else if self.sign == NoSign {
             Some(Zero::zero())
         } else {
             None
@@ -838,7 +838,7 @@ fn get_radix_base(radix: uint) -> (DoubleBigDigit, uint) {
 
 /// A Sign is a `BigInt`'s composing element.
 #[deriving(PartialEq, PartialOrd, Eq, Ord, Clone, Show)]
-pub enum Sign { Minus, Zero, Plus }
+pub enum Sign { Minus, NoSign, Plus }
 
 impl Neg<Sign> for Sign {
     /// Negate Sign value.
@@ -846,7 +846,7 @@ impl Neg<Sign> for Sign {
     fn neg(&self) -> Sign {
         match *self {
           Minus => Plus,
-          Zero  => Zero,
+          NoSign  => NoSign,
           Plus  => Minus
         }
     }
@@ -882,7 +882,7 @@ impl Ord for BigInt {
         if scmp != Equal { return scmp; }
 
         match self.sign {
-            Zero  => Equal,
+            NoSign  => Equal,
             Plus  => self.data.cmp(&other.data),
             Minus => other.data.cmp(&self.data),
         }
@@ -933,11 +933,11 @@ impl Shr<uint, BigInt> for BigInt {
 impl Zero for BigInt {
     #[inline]
     fn zero() -> BigInt {
-        BigInt::from_biguint(Zero, Zero::zero())
+        BigInt::from_biguint(NoSign, Zero::zero())
     }
 
     #[inline]
-    fn is_zero(&self) -> bool { self.sign == Zero }
+    fn is_zero(&self) -> bool { self.sign == NoSign }
 }
 
 impl One for BigInt {
@@ -951,7 +951,7 @@ impl Signed for BigInt {
     #[inline]
     fn abs(&self) -> BigInt {
         match self.sign {
-            Plus | Zero => self.clone(),
+            Plus | NoSign => self.clone(),
             Minus => BigInt::from_biguint(Plus, self.data.clone())
         }
     }
@@ -966,7 +966,7 @@ impl Signed for BigInt {
         match self.sign {
             Plus  => BigInt::from_biguint(Plus, One::one()),
             Minus => BigInt::from_biguint(Minus, One::one()),
-            Zero  => Zero::zero(),
+            NoSign  => Zero::zero(),
         }
     }
 
@@ -981,8 +981,8 @@ impl Add<BigInt, BigInt> for BigInt {
     #[inline]
     fn add(&self, other: &BigInt) -> BigInt {
         match (self.sign, other.sign) {
-            (Zero, _)      => other.clone(),
-            (_,    Zero)   => self.clone(),
+            (NoSign, _)      => other.clone(),
+            (_,    NoSign)   => self.clone(),
             (Plus, Plus)   => BigInt::from_biguint(Plus, self.data + other.data),
             (Plus, Minus)  => self - (-*other),
             (Minus, Plus)  => other - (-*self),
@@ -995,8 +995,8 @@ impl Sub<BigInt, BigInt> for BigInt {
     #[inline]
     fn sub(&self, other: &BigInt) -> BigInt {
         match (self.sign, other.sign) {
-            (Zero, _)    => -other,
-            (_,    Zero) => self.clone(),
+            (NoSign, _)    => -other,
+            (_,    NoSign) => self.clone(),
             (Plus, Plus) => match self.data.cmp(&other.data) {
                 Less    => BigInt::from_biguint(Minus, other.data - self.data),
                 Greater => BigInt::from_biguint(Plus, self.data - other.data),
@@ -1013,7 +1013,7 @@ impl Mul<BigInt, BigInt> for BigInt {
     #[inline]
     fn mul(&self, other: &BigInt) -> BigInt {
         match (self.sign, other.sign) {
-            (Zero, _)     | (_,     Zero)  => Zero::zero(),
+            (NoSign, _)     | (_,     NoSign)  => Zero::zero(),
             (Plus, Plus)  | (Minus, Minus) => {
                 BigInt::from_biguint(Plus, self.data * other.data)
             },
@@ -1087,9 +1087,9 @@ impl Integer for BigInt {
         let d = BigInt::from_biguint(Plus, d_ui);
         let r = BigInt::from_biguint(Plus, r_ui);
         match (self.sign, other.sign) {
-            (_,    Zero)   => fail!(),
-            (Plus, Plus)  | (Zero, Plus)  => ( d,  r),
-            (Plus, Minus) | (Zero, Minus) => (-d,  r),
+            (_,    NoSign)   => fail!(),
+            (Plus, Plus)  | (NoSign, Plus)  => ( d,  r),
+            (Plus, Minus) | (NoSign, Minus) => (-d,  r),
             (Minus, Plus)                 => (-d, -r),
             (Minus, Minus)                => ( d, -r)
         }
@@ -1113,9 +1113,9 @@ impl Integer for BigInt {
         let d = BigInt::from_biguint(Plus, d_ui);
         let m = BigInt::from_biguint(Plus, m_ui);
         match (self.sign, other.sign) {
-            (_,    Zero)   => fail!(),
-            (Plus, Plus)  | (Zero, Plus)  => (d, m),
-            (Plus, Minus) | (Zero, Minus) => if m.is_zero() {
+            (_,    NoSign)   => fail!(),
+            (Plus, Plus)  | (NoSign, Plus)  => (d, m),
+            (Plus, Minus) | (NoSign, Minus) => if m.is_zero() {
                 (-d, Zero::zero())
             } else {
                 (-d - One::one(), m + *other)
@@ -1166,7 +1166,7 @@ impl ToPrimitive for BigInt {
     fn to_i64(&self) -> Option<i64> {
         match self.sign {
             Plus  => self.data.to_i64(),
-            Zero  => Some(0),
+            NoSign  => Some(0),
             Minus => {
                 self.data.to_u64().and_then(|n| {
                     let m: u64 = 1 << 63;
@@ -1186,7 +1186,7 @@ impl ToPrimitive for BigInt {
     fn to_u64(&self) -> Option<u64> {
         match self.sign {
             Plus => self.data.to_u64(),
-            Zero => Some(0),
+            NoSign => Some(0),
             Minus => None
         }
     }
@@ -1272,7 +1272,7 @@ impl ToStrRadix for BigInt {
     fn to_str_radix(&self, radix: uint) -> String {
         match self.sign {
             Plus  => self.data.to_str_radix(radix),
-            Zero  => "0".to_string(),
+            NoSign  => "0".to_string(),
             Minus => format!("-{}", self.data.to_str_radix(radix)),
         }
     }
@@ -1334,7 +1334,7 @@ impl<R: Rng> RandBigInt for R {
             if self.gen() {
                 return self.gen_bigint(bit_size);
             } else {
-                Zero
+                NoSign
             }
         } else if self.gen() {
             Plus
@@ -1385,8 +1385,8 @@ impl BigInt {
     /// The digits are be in base 2^32.
     #[inline]
     pub fn from_biguint(sign: Sign, data: BigUint) -> BigInt {
-        if sign == Zero || data.is_zero() {
-            return BigInt { sign: Zero, data: Zero::zero() };
+        if sign == NoSign || data.is_zero() {
+            return BigInt { sign: NoSign, data: Zero::zero() };
         }
         BigInt { sign: sign, data: data }
     }
@@ -1415,7 +1415,7 @@ impl BigInt {
     pub fn to_biguint(&self) -> Option<BigUint> {
         match self.sign {
             Plus => Some(self.data.clone()),
-            Zero => Some(Zero::zero()),
+            NoSign => Some(Zero::zero()),
             Minus => None
         }
     }
@@ -2288,7 +2288,7 @@ mod biguint_tests {
 mod bigint_tests {
     use Integer;
     use super::{BigDigit, BigUint, ToBigUint};
-    use super::{Sign, Minus, Zero, Plus, BigInt, RandBigInt, ToBigInt};
+    use super::{Sign, Minus, NoSign, Plus, BigInt, RandBigInt, ToBigInt};
 
     use std::cmp::{Less, Equal, Greater};
     use std::i64;
@@ -2307,9 +2307,9 @@ mod bigint_tests {
             assert_eq!(inp, ans);
         }
         check(Plus, 1, Plus, 1);
-        check(Plus, 0, Zero, 0);
+        check(Plus, 0, NoSign, 0);
         check(Minus, 1, Minus, 1);
-        check(Zero, 1, Zero, 0);
+        check(NoSign, 1, NoSign, 0);
     }
 
     #[test]
@@ -2357,8 +2357,8 @@ mod bigint_tests {
 
     #[test]
     fn test_hash() {
-        let a = BigInt::new(Zero, vec!());
-        let b = BigInt::new(Zero, vec!(0));
+        let a = BigInt::new(NoSign, vec!());
+        let b = BigInt::new(NoSign, vec!(0));
         let c = BigInt::new(Plus, vec!(1));
         let d = BigInt::new(Plus, vec!(1,0,0,0,0,0));
         let e = BigInt::new(Plus, vec!(0,0,0,0,0,1));
diff --git a/src/libregex/compile.rs b/src/libregex/compile.rs
index 869dd25e3fa..c4b517c5259 100644
--- a/src/libregex/compile.rs
+++ b/src/libregex/compile.rs
@@ -16,7 +16,7 @@ use std::cmp;
 use parse;
 use parse::{
     Flags, FLAG_EMPTY,
-    Nothing, Literal, Dot, Class, Begin, End, WordBoundary, Capture, Cat, Alt,
+    Nothing, Literal, Dot, AstClass, Begin, End, WordBoundary, Capture, Cat, Alt,
     Rep,
     ZeroOne, ZeroMore, OneMore,
 };
@@ -148,7 +148,7 @@ impl<'r> Compiler<'r> {
             Nothing => {},
             Literal(c, flags) => self.push(OneChar(c, flags)),
             Dot(nl) => self.push(Any(nl)),
-            Class(ranges, flags) =>
+            AstClass(ranges, flags) =>
                 self.push(CharClass(ranges, flags)),
             Begin(flags) => self.push(EmptyBegin(flags)),
             End(flags) => self.push(EmptyEnd(flags)),
diff --git a/src/libregex/lib.rs b/src/libregex/lib.rs
index 4f849a8a67b..9ff65fe3e2a 100644
--- a/src/libregex/lib.rs
+++ b/src/libregex/lib.rs
@@ -425,7 +425,7 @@ pub mod native {
         FLAG_EMPTY, FLAG_NOCASE, FLAG_MULTI, FLAG_DOTNL,
         FLAG_SWAP_GREED, FLAG_NEGATED,
     };
-    pub use re::{Dynamic, Native};
+    pub use re::{Dynamic, ExDynamic, Native, ExNative};
     pub use vm::{
         MatchKind, Exists, Location, Submatches,
         StepState, StepMatchEarlyReturn, StepMatch, StepContinue,
diff --git a/src/libregex/parse.rs b/src/libregex/parse.rs
index 12555b7c443..ad60829c088 100644
--- a/src/libregex/parse.rs
+++ b/src/libregex/parse.rs
@@ -53,7 +53,7 @@ pub enum Ast {
     Nothing,
     Literal(char, Flags),
     Dot(Flags),
-    Class(Vec<(char, char)>, Flags),
+    AstClass(Vec<(char, char)>, Flags),
     Begin(Flags),
     End(Flags),
     WordBoundary(Flags),
@@ -101,7 +101,7 @@ impl Greed {
 /// state.
 #[deriving(Show)]
 enum BuildAst {
-    Ast(Ast),
+    Expr(Ast),
     Paren(Flags, uint, String), // '('
     Bar, // '|'
 }
@@ -152,7 +152,7 @@ impl BuildAst {
 
     fn unwrap(self) -> Result<Ast, Error> {
         match self {
-            Ast(x) => Ok(x),
+            Expr(x) => Ok(x),
             _ => fail!("Tried to unwrap non-AST item: {}", self),
         }
     }
@@ -311,7 +311,7 @@ impl<'a> Parser<'a> {
     }
 
     fn push(&mut self, ast: Ast) {
-        self.stack.push(Ast(ast))
+        self.stack.push(Expr(ast))
     }
 
     fn push_repeater(&mut self, c: char) -> Result<(), Error> {
@@ -388,8 +388,8 @@ impl<'a> Parser<'a> {
             match c {
                 '[' =>
                     match self.try_parse_ascii() {
-                        Some(Class(asciis, flags)) => {
-                            alts.push(Class(asciis, flags ^ negated));
+                        Some(AstClass(asciis, flags)) => {
+                            alts.push(AstClass(asciis, flags ^ negated));
                             continue
                         }
                         Some(ast) =>
@@ -399,8 +399,8 @@ impl<'a> Parser<'a> {
                     },
                 '\\' => {
                     match try!(self.parse_escape()) {
-                        Class(asciis, flags) => {
-                            alts.push(Class(asciis, flags ^ negated));
+                        AstClass(asciis, flags) => {
+                            alts.push(AstClass(asciis, flags ^ negated));
                             continue
                         }
                         Literal(c2, _) => c = c2, // process below
@@ -417,7 +417,7 @@ impl<'a> Parser<'a> {
                 ']' => {
                     if ranges.len() > 0 {
                         let flags = negated | (self.flags & FLAG_NOCASE);
-                        let mut ast = Class(combine_ranges(ranges), flags);
+                        let mut ast = AstClass(combine_ranges(ranges), flags);
                         for alt in alts.into_iter() {
                             ast = Alt(box alt, box ast)
                         }
@@ -485,7 +485,7 @@ impl<'a> Parser<'a> {
             Some(ranges) => {
                 self.chari = closer;
                 let flags = negated | (self.flags & FLAG_NOCASE);
-                Some(Class(combine_ranges(ranges), flags))
+                Some(AstClass(combine_ranges(ranges), flags))
             }
         }
     }
@@ -611,7 +611,7 @@ impl<'a> Parser<'a> {
                 let ranges = perl_unicode_class(c);
                 let mut flags = self.flags & FLAG_NOCASE;
                 if c.is_uppercase() { flags |= FLAG_NEGATED }
-                Ok(Class(ranges, flags))
+                Ok(AstClass(ranges, flags))
             }
             _ => {
                 self.err(format!("Invalid escape sequence '\\\\{}'",
@@ -655,7 +655,7 @@ impl<'a> Parser<'a> {
                                         name).as_slice())
             }
             Some(ranges) => {
-                Ok(Class(ranges, negated | (self.flags & FLAG_NOCASE)))
+                Ok(AstClass(ranges, negated | (self.flags & FLAG_NOCASE)))
             }
         }
     }
@@ -888,7 +888,7 @@ impl<'a> Parser<'a> {
         while i > from {
             i = i - 1;
             match self.stack.pop().unwrap() {
-                Ast(x) => combined = mk(x, combined),
+                Expr(x) => combined = mk(x, combined),
                 _ => {},
             }
         }
diff --git a/src/libregex/re.rs b/src/libregex/re.rs
index 8e4145b2a31..c2578d227ee 100644
--- a/src/libregex/re.rs
+++ b/src/libregex/re.rs
@@ -110,14 +110,14 @@ pub enum Regex {
     // See the comments for the `program` module in `lib.rs` for a more
     // detailed explanation for what `regex!` requires.
     #[doc(hidden)]
-    Dynamic(Dynamic),
+    Dynamic(ExDynamic),
     #[doc(hidden)]
-    Native(Native),
+    Native(ExNative),
 }
 
 #[deriving(Clone)]
 #[doc(hidden)]
-pub struct Dynamic {
+pub struct ExDynamic {
     original: String,
     names: Vec<Option<String>>,
     #[doc(hidden)]
@@ -125,7 +125,7 @@ pub struct Dynamic {
 }
 
 #[doc(hidden)]
-pub struct Native {
+pub struct ExNative {
     #[doc(hidden)]
     pub original: &'static str,
     #[doc(hidden)]
@@ -134,8 +134,8 @@ pub struct Native {
     pub prog: fn(MatchKind, &str, uint, uint) -> Vec<Option<uint>>
 }
 
-impl Clone for Native {
-    fn clone(&self) -> Native { *self }
+impl Clone for ExNative {
+    fn clone(&self) -> ExNative { *self }
 }
 
 impl fmt::Show for Regex {
@@ -156,7 +156,7 @@ impl Regex {
     pub fn new(re: &str) -> Result<Regex, parse::Error> {
         let ast = try!(parse::parse(re));
         let (prog, names) = Program::new(ast);
-        Ok(Dynamic(Dynamic {
+        Ok(Dynamic(ExDynamic {
             original: re.to_string(),
             names: names,
             prog: prog,
@@ -510,8 +510,8 @@ impl Regex {
     /// Returns the original string of this regex.
     pub fn as_str<'a>(&'a self) -> &'a str {
         match *self {
-            Dynamic(Dynamic { ref original, .. }) => original.as_slice(),
-            Native(Native { ref original, .. }) => original.as_slice(),
+            Dynamic(ExDynamic { ref original, .. }) => original.as_slice(),
+            Native(ExNative { ref original, .. }) => original.as_slice(),
         }
     }
 
@@ -915,8 +915,8 @@ fn exec(re: &Regex, which: MatchKind, input: &str) -> CaptureLocs {
 fn exec_slice(re: &Regex, which: MatchKind,
               input: &str, s: uint, e: uint) -> CaptureLocs {
     match *re {
-        Dynamic(Dynamic { ref prog, .. }) => vm::run(which, prog, input, s, e),
-        Native(Native { prog, .. }) => prog(which, input, s, e),
+        Dynamic(ExDynamic { ref prog, .. }) => vm::run(which, prog, input, s, e),
+        Native(ExNative { prog, .. }) => prog(which, input, s, e),
     }
 }
 
diff --git a/src/libregex_macros/lib.rs b/src/libregex_macros/lib.rs
index 12809184003..ae6dd2a4d70 100644
--- a/src/libregex_macros/lib.rs
+++ b/src/libregex_macros/lib.rs
@@ -42,7 +42,7 @@ use regex::Regex;
 use regex::native::{
     OneChar, CharClass, Any, Save, Jump, Split,
     Match, EmptyBegin, EmptyEnd, EmptyWordBoundary,
-    Program, Dynamic, Native,
+    Program, Dynamic, ExDynamic, Native,
     FLAG_NOCASE, FLAG_MULTI, FLAG_DOTNL, FLAG_NEGATED,
 };
 
@@ -91,7 +91,7 @@ fn native(cx: &mut ExtCtxt, sp: codemap::Span, tts: &[ast::TokenTree])
         }
     };
     let prog = match re {
-        Dynamic(Dynamic { ref prog, .. }) => prog.clone(),
+        Dynamic(ExDynamic { ref prog, .. }) => prog.clone(),
         Native(_) => unreachable!(),
     };
 
@@ -322,7 +322,7 @@ fn exec<'t>(which: ::regex::native::MatchKind, input: &'t str,
     }
 }
 
-::regex::native::Native(::regex::native::Native {
+::regex::native::Native(::regex::native::ExNative {
     original: $regex,
     names: CAP_NAMES,
     prog: exec,
diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs
index de1eef1dce3..d31e19b4467 100644
--- a/src/librustc/back/link.rs
+++ b/src/librustc/back/link.rs
@@ -659,19 +659,18 @@ fn link_rlib<'a>(sess: &'a Session,
             ab.add_file(&metadata).unwrap();
             remove(sess, &metadata);
 
-            if sess.opts.cg.codegen_units == 1 {
-                // For LTO purposes, the bytecode of this library is also
-                // inserted into the archive.  We currently do this only when
-                // codegen_units == 1, so we don't have to deal with multiple
-                // bitcode files per crate.
-                //
+            // For LTO purposes, the bytecode of this library is also inserted
+            // into the archive.  If codegen_units > 1, we insert each of the
+            // bitcode files.
+            for i in range(0, sess.opts.cg.codegen_units) {
                 // Note that we make sure that the bytecode filename in the
                 // archive is never exactly 16 bytes long by adding a 16 byte
                 // extension to it. This is to work around a bug in LLDB that
                 // would cause it to crash if the name of a file in an archive
                 // was exactly 16 bytes.
-                let bc_filename = obj_filename.with_extension("bc");
-                let bc_deflated_filename = obj_filename.with_extension("bytecode.deflate");
+                let bc_filename = obj_filename.with_extension(format!("{}.bc", i).as_slice());
+                let bc_deflated_filename = obj_filename.with_extension(
+                    format!("{}.bytecode.deflate", i).as_slice());
 
                 let bc_data = match fs::File::open(&bc_filename).read_to_end() {
                     Ok(buffer) => buffer,
@@ -705,8 +704,13 @@ fn link_rlib<'a>(sess: &'a Session,
 
                 ab.add_file(&bc_deflated_filename).unwrap();
                 remove(sess, &bc_deflated_filename);
-                if !sess.opts.cg.save_temps &&
-                   !sess.opts.output_types.contains(&OutputTypeBitcode) {
+
+                // See the bottom of back::write::run_passes for an explanation
+                // of when we do and don't keep .0.bc files around.
+                let user_wants_numbered_bitcode =
+                        sess.opts.output_types.contains(&OutputTypeBitcode) &&
+                        sess.opts.cg.codegen_units > 1;
+                if !sess.opts.cg.save_temps && !user_wants_numbered_bitcode {
                     remove(sess, &bc_filename);
                 }
             }
@@ -1024,7 +1028,9 @@ fn link_args(cmd: &mut Command,
 
         // Mark all dynamic libraries and executables as compatible with ASLR
         // FIXME #17098: ASLR breaks gdb
-        // cmd.arg("-Wl,--dynamicbase");
+        if sess.opts.debuginfo == NoDebugInfo {
+            cmd.arg("-Wl,--dynamicbase");
+        }
 
         // Mark all dynamic libraries and executables as compatible with the larger 4GiB address
         // space available to x86 Windows binaries on x86_64.
diff --git a/src/librustc/back/lto.rs b/src/librustc/back/lto.rs
index 250557d0af1..cd425b5fec1 100644
--- a/src/librustc/back/lto.rs
+++ b/src/librustc/back/lto.rs
@@ -21,6 +21,7 @@ use util::common::time;
 use libc;
 use flate;
 
+use std::iter;
 use std::mem;
 
 pub fn run(sess: &session::Session, llmod: ModuleRef,
@@ -60,78 +61,84 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
         let file = path.filename_str().unwrap();
         let file = file.slice(3, file.len() - 5); // chop off lib/.rlib
         debug!("reading {}", file);
-        let bc_encoded = time(sess.time_passes(),
-                              format!("read {}.bytecode.deflate", name).as_slice(),
-                              (),
-                              |_| {
-                                  archive.read(format!("{}.bytecode.deflate",
-                                                       file).as_slice())
-                              });
-        let bc_encoded = match bc_encoded {
-            Some(data) => data,
-            None => {
-                sess.fatal(format!("missing compressed bytecode in {} \
-                                    (perhaps it was compiled with -C codegen-units > 1)",
-                                   path.display()).as_slice());
-            },
-        };
-        let bc_extractor = if is_versioned_bytecode_format(bc_encoded) {
-            |_| {
-                // Read the version
-                let version = extract_bytecode_format_version(bc_encoded);
-
-                if version == 1 {
-                    // The only version existing so far
-                    let data_size = extract_compressed_bytecode_size_v1(bc_encoded);
-                    let compressed_data = bc_encoded.slice(
-                        link::RLIB_BYTECODE_OBJECT_V1_DATA_OFFSET,
-                        link::RLIB_BYTECODE_OBJECT_V1_DATA_OFFSET + data_size as uint);
-
-                    match flate::inflate_bytes(compressed_data) {
-                        Some(inflated) => inflated,
+        for i in iter::count(0u, 1) {
+            let bc_encoded = time(sess.time_passes(),
+                                  format!("check for {}.{}.bytecode.deflate", name, i).as_slice(),
+                                  (),
+                                  |_| {
+                                      archive.read(format!("{}.{}.bytecode.deflate",
+                                                           file, i).as_slice())
+                                  });
+            let bc_encoded = match bc_encoded {
+                Some(data) => data,
+                None => {
+                    if i == 0 {
+                        // No bitcode was found at all.
+                        sess.fatal(format!("missing compressed bytecode in {}",
+                                           path.display()).as_slice());
+                    }
+                    // No more bitcode files to read.
+                    break;
+                },
+            };
+            let bc_extractor = if is_versioned_bytecode_format(bc_encoded) {
+                |_| {
+                    // Read the version
+                    let version = extract_bytecode_format_version(bc_encoded);
+
+                    if version == 1 {
+                        // The only version existing so far
+                        let data_size = extract_compressed_bytecode_size_v1(bc_encoded);
+                        let compressed_data = bc_encoded.slice(
+                            link::RLIB_BYTECODE_OBJECT_V1_DATA_OFFSET,
+                            link::RLIB_BYTECODE_OBJECT_V1_DATA_OFFSET + data_size as uint);
+
+                        match flate::inflate_bytes(compressed_data) {
+                            Some(inflated) => inflated,
+                            None => {
+                                sess.fatal(format!("failed to decompress bc of `{}`",
+                                                   name).as_slice())
+                            }
+                        }
+                    } else {
+                        sess.fatal(format!("Unsupported bytecode format version {}",
+                                           version).as_slice())
+                    }
+                }
+            } else {
+                // the object must be in the old, pre-versioning format, so simply
+                // inflate everything and let LLVM decide if it can make sense of it
+                |_| {
+                    match flate::inflate_bytes(bc_encoded) {
+                        Some(bc) => bc,
                         None => {
                             sess.fatal(format!("failed to decompress bc of `{}`",
                                                name).as_slice())
                         }
                     }
-                } else {
-                    sess.fatal(format!("Unsupported bytecode format version {}",
-                                       version).as_slice())
                 }
-            }
-        } else {
-            // the object must be in the old, pre-versioning format, so simply
-            // inflate everything and let LLVM decide if it can make sense of it
-            |_| {
-                match flate::inflate_bytes(bc_encoded) {
-                    Some(bc) => bc,
-                    None => {
-                        sess.fatal(format!("failed to decompress bc of `{}`",
-                                           name).as_slice())
-                    }
+            };
+
+            let bc_decoded = time(sess.time_passes(),
+                                  format!("decode {}.{}.bc", file, i).as_slice(),
+                                  (),
+                                  bc_extractor);
+
+            let ptr = bc_decoded.as_slice().as_ptr();
+            debug!("linking {}, part {}", name, i);
+            time(sess.time_passes(),
+                 format!("ll link {}.{}", name, i).as_slice(),
+                 (),
+                 |()| unsafe {
+                if !llvm::LLVMRustLinkInExternalBitcode(llmod,
+                                                        ptr as *const libc::c_char,
+                                                        bc_decoded.len() as libc::size_t) {
+                    write::llvm_err(sess.diagnostic().handler(),
+                                    format!("failed to load bc of `{}`",
+                                            name.as_slice()));
                 }
-            }
-        };
-
-        let bc_decoded = time(sess.time_passes(),
-                              format!("decode {}.bc", file).as_slice(),
-                              (),
-                              bc_extractor);
-
-        let ptr = bc_decoded.as_slice().as_ptr();
-        debug!("linking {}", name);
-        time(sess.time_passes(),
-             format!("ll link {}", name).as_slice(),
-             (),
-             |()| unsafe {
-            if !llvm::LLVMRustLinkInExternalBitcode(llmod,
-                                                    ptr as *const libc::c_char,
-                                                    bc_decoded.len() as libc::size_t) {
-                write::llvm_err(sess.diagnostic().handler(),
-                                format!("failed to load bc of `{}`",
-                                        name.as_slice()));
-            }
-        });
+            });
+        }
     }
 
     // Internalize everything but the reachable symbols of the current module
diff --git a/src/librustc/back/write.rs b/src/librustc/back/write.rs
index cff5ac5375d..7242c12ae0c 100644
--- a/src/librustc/back/write.rs
+++ b/src/librustc/back/write.rs
@@ -11,7 +11,7 @@
 use back::lto;
 use back::link::{get_cc_prog, remove};
 use driver::driver::{CrateTranslation, ModuleTranslation, OutputFilenames};
-use driver::config::{NoDebugInfo, Passes, AllPasses};
+use driver::config::{NoDebugInfo, Passes, SomePasses, AllPasses};
 use driver::session::Session;
 use driver::config;
 use llvm;
@@ -341,7 +341,7 @@ unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_vo
             let pass_name = pass_name.as_str().expect("got a non-UTF8 pass name from LLVM");
             let enabled = match cgcx.remark {
                 AllPasses => true,
-                Passes(ref v) => v.iter().any(|s| s.as_slice() == pass_name),
+                SomePasses(ref v) => v.iter().any(|s| s.as_slice() == pass_name),
             };
 
             if enabled {
@@ -482,14 +482,14 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
         if config.emit_asm {
             let path = output_names.with_extension(format!("{}.s", name_extra).as_slice());
             with_codegen(tm, llmod, config.no_builtins, |cpm| {
-                write_output_file(cgcx.handler, tm, cpm, llmod, &path, llvm::AssemblyFile);
+                write_output_file(cgcx.handler, tm, cpm, llmod, &path, llvm::AssemblyFileType);
             });
         }
 
         if config.emit_obj {
             let path = output_names.with_extension(format!("{}.o", name_extra).as_slice());
             with_codegen(tm, llmod, config.no_builtins, |cpm| {
-                write_output_file(cgcx.handler, tm, cpm, llmod, &path, llvm::ObjectFile);
+                write_output_file(cgcx.handler, tm, cpm, llmod, &path, llvm::ObjectFileType);
             });
         }
     });
@@ -540,13 +540,12 @@ pub fn run_passes(sess: &Session,
         metadata_config.emit_bc = true;
     }
 
-    // Emit a bitcode file for the crate if we're emitting an rlib.
+    // Emit bitcode files for the crate if we're emitting an rlib.
     // Whenever an rlib is created, the bitcode is inserted into the
     // archive in order to allow LTO against it.
     let needs_crate_bitcode =
             sess.crate_types.borrow().contains(&config::CrateTypeRlib) &&
-            sess.opts.output_types.contains(&OutputTypeExe) &&
-            sess.opts.cg.codegen_units == 1;
+            sess.opts.output_types.contains(&OutputTypeExe);
     if needs_crate_bitcode {
         modules_config.emit_bc = true;
     }
@@ -602,19 +601,8 @@ pub fn run_passes(sess: &Session,
     // Process the work items, optionally using worker threads.
     if sess.opts.cg.codegen_units == 1 {
         run_work_singlethreaded(sess, trans.reachable.as_slice(), work_items);
-
-        if needs_crate_bitcode {
-            // The only bitcode file produced (aside from metadata) was
-            // "crate.0.bc".  Rename to "crate.bc" since that's what
-            // `link_rlib` expects to find.
-            fs::copy(&crate_output.with_extension("0.bc"),
-                     &crate_output.temp_path(OutputTypeBitcode)).unwrap();
-        }
     } else {
         run_work_multithreaded(sess, work_items, sess.opts.cg.codegen_units);
-
-        assert!(!needs_crate_bitcode,
-               "can't produce a crate bitcode file from multiple compilation units");
     }
 
     // All codegen is finished.
@@ -624,14 +612,14 @@ pub fn run_passes(sess: &Session,
 
     // Produce final compile outputs.
 
-    let copy_if_one_unit = |ext: &str, output_type: OutputType| {
+    let copy_if_one_unit = |ext: &str, output_type: OutputType, keep_numbered: bool| {
         // Three cases:
         if sess.opts.cg.codegen_units == 1 {
             // 1) Only one codegen unit.  In this case it's no difficulty
             //    to copy `foo.0.x` to `foo.x`.
             fs::copy(&crate_output.with_extension(ext),
                      &crate_output.path(output_type)).unwrap();
-            if !sess.opts.cg.save_temps {
+            if !sess.opts.cg.save_temps && !keep_numbered {
                 // The user just wants `foo.x`, not `foo.0.x`.
                 remove(sess, &crate_output.with_extension(ext));
             }
@@ -716,17 +704,18 @@ pub fn run_passes(sess: &Session,
     // Flag to indicate whether the user explicitly requested bitcode.
     // Otherwise, we produced it only as a temporary output, and will need
     // to get rid of it.
-    // FIXME: Since we don't support LTO anyway, maybe we can avoid
-    // producing the temporary .0.bc's in the first place?
-    let mut save_bitcode = false;
+    let mut user_wants_bitcode = false;
     for output_type in output_types.iter() {
         match *output_type {
             OutputTypeBitcode => {
-                save_bitcode = true;
-                copy_if_one_unit("0.bc", OutputTypeBitcode);
+                user_wants_bitcode = true;
+                // Copy to .bc, but always keep the .0.bc.  There is a later
+                // check to figure out if we should delete .0.bc files, or keep
+                // them for making an rlib.
+                copy_if_one_unit("0.bc", OutputTypeBitcode, true);
             },
-            OutputTypeLlvmAssembly => { copy_if_one_unit("0.ll", OutputTypeLlvmAssembly); },
-            OutputTypeAssembly => { copy_if_one_unit("0.s", OutputTypeAssembly); },
+            OutputTypeLlvmAssembly => { copy_if_one_unit("0.ll", OutputTypeLlvmAssembly, false); },
+            OutputTypeAssembly => { copy_if_one_unit("0.s", OutputTypeAssembly, false); },
             OutputTypeObject => { link_obj(&crate_output.path(OutputTypeObject)); },
             OutputTypeExe => {
                 // If OutputTypeObject is already in the list, then
@@ -739,7 +728,7 @@ pub fn run_passes(sess: &Session,
             },
         }
     }
-    let save_bitcode = save_bitcode;
+    let user_wants_bitcode = user_wants_bitcode;
 
     // Clean up unwanted temporary files.
 
@@ -755,22 +744,36 @@ pub fn run_passes(sess: &Session,
 
     if !sess.opts.cg.save_temps {
         // Remove the temporary .0.o objects.  If the user didn't
-        // explicitly request bitcode (with --emit=bc), we must remove
-        // .0.bc as well.  (We don't touch the crate.bc that may have been
-        // produced earlier.)
+        // explicitly request bitcode (with --emit=bc), and the bitcode is not
+        // needed for building an rlib, then we must remove .0.bc as well.
+
+        // Specific rules for keeping .0.bc:
+        //  - If we're building an rlib (`needs_crate_bitcode`), then keep
+        //    it.
+        //  - If the user requested bitcode (`user_wants_bitcode`), and
+        //    codegen_units > 1, then keep it.
+        //  - If the user requested bitcode but codegen_units == 1, then we
+        //    can toss .0.bc because we copied it to .bc earlier.
+        //  - If we're not building an rlib and the user didn't request
+        //    bitcode, then delete .0.bc.
+        // If you change how this works, also update back::link::link_rlib,
+        // where .0.bc files are (maybe) deleted after making an rlib.
+        let keep_numbered_bitcode = needs_crate_bitcode ||
+                (user_wants_bitcode && sess.opts.cg.codegen_units > 1);
+
         for i in range(0, trans.modules.len()) {
             if modules_config.emit_obj {
                 let ext = format!("{}.o", i);
                 remove(sess, &crate_output.with_extension(ext.as_slice()));
             }
 
-            if modules_config.emit_bc && !save_bitcode {
+            if modules_config.emit_bc && !keep_numbered_bitcode {
                 let ext = format!("{}.bc", i);
                 remove(sess, &crate_output.with_extension(ext.as_slice()));
             }
         }
 
-        if metadata_config.emit_bc && !save_bitcode {
+        if metadata_config.emit_bc && !user_wants_bitcode {
             remove(sess, &crate_output.with_extension("metadata.bc"));
         }
     }
diff --git a/src/librustc/driver/config.rs b/src/librustc/driver/config.rs
index 309c7a44c5d..72e2d244ad3 100644
--- a/src/librustc/driver/config.rs
+++ b/src/librustc/driver/config.rs
@@ -237,14 +237,14 @@ pub fn debugging_opts_map() -> Vec<(&'static str, &'static str, u64)> {
 
 #[deriving(Clone)]
 pub enum Passes {
-    Passes(Vec<String>),
+    SomePasses(Vec<String>),
     AllPasses,
 }
 
 impl Passes {
     pub fn is_empty(&self) -> bool {
         match *self {
-            Passes(ref v) => v.is_empty(),
+            SomePasses(ref v) => v.is_empty(),
             AllPasses => false,
         }
     }
@@ -276,7 +276,7 @@ macro_rules! cgoptions(
         &[ $( (stringify!($opt), cgsetters::$opt, $desc) ),* ];
 
     mod cgsetters {
-        use super::{CodegenOptions, Passes, AllPasses};
+        use super::{CodegenOptions, Passes, SomePasses, AllPasses};
 
         $(
             pub fn $opt(cg: &mut CodegenOptions, v: Option<&str>) -> bool {
@@ -335,7 +335,7 @@ macro_rules! cgoptions(
                 v => {
                     let mut passes = vec!();
                     if parse_list(&mut passes, v) {
-                        *slot = Passes(passes);
+                        *slot = SomePasses(passes);
                         true
                     } else {
                         false
@@ -389,7 +389,7 @@ cgoptions!(
          "extra data to put in each output filename"),
     codegen_units: uint = (1, parse_uint,
         "divide crate into N units to optimize in parallel"),
-    remark: Passes = (Passes(Vec::new()), parse_passes,
+    remark: Passes = (SomePasses(Vec::new()), parse_passes,
         "print remarks for these optimization passes (space separated, or \"all\")"),
 )
 
diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs
index bb454e07fc1..4ff9133c8a5 100644
--- a/src/librustc/driver/driver.rs
+++ b/src/librustc/driver/driver.rs
@@ -17,7 +17,7 @@ use lint;
 use llvm::{ContextRef, ModuleRef};
 use metadata::common::LinkMeta;
 use metadata::creader;
-use middle::{trans, freevars, stability, kind, ty, typeck, reachable};
+use middle::{trans, stability, kind, ty, typeck, reachable};
 use middle::dependency_format;
 use middle;
 use plugin::load::Plugins;
@@ -378,11 +378,13 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
                           middle::lang_items::collect_language_items(krate, &sess));
 
     let middle::resolve::CrateMap {
-        def_map: def_map,
-        exp_map2: exp_map2,
-        trait_map: trait_map,
-        external_exports: external_exports,
-        last_private_map: last_private_map
+        def_map,
+        freevars,
+        capture_mode_map,
+        exp_map2,
+        trait_map,
+        external_exports,
+        last_private_map
     } =
         time(time_passes, "resolution", (), |_|
              middle::resolve::resolve_crate(&sess, &lang_items, krate));
@@ -401,10 +403,6 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
             plugin::build::find_plugin_registrar(
                 sess.diagnostic(), krate)));
 
-    let (freevars, capture_modes) =
-        time(time_passes, "freevar finding", (), |_|
-             freevars::annotate_freevars(&def_map, krate));
-
     let region_map = time(time_passes, "region resolution", (), |_|
                           middle::region::resolve_crate(&sess, krate));
 
@@ -423,7 +421,7 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
                             named_region_map,
                             ast_map,
                             freevars,
-                            capture_modes,
+                            capture_mode_map,
                             region_map,
                             lang_items,
                             stability_index);
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index c5b9f33be28..2994954c3d7 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -29,7 +29,7 @@ This API is completely unstable and subject to change.
       html_root_url = "http://doc.rust-lang.org/master/")]
 
 #![allow(deprecated)]
-#![feature(macro_rules, globs, struct_variant, managed_boxes, quote)]
+#![feature(macro_rules, globs, struct_variant, quote)]
 #![feature(default_type_params, phase, unsafe_destructor)]
 
 #![allow(unknown_features)] // NOTE: Remove after next snapshot
@@ -93,7 +93,6 @@ pub mod middle {
     pub mod effect;
     pub mod entry;
     pub mod expr_use_visitor;
-    pub mod freevars;
     pub mod graph;
     pub mod intrinsicck;
     pub mod kind;
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index 473c3935769..588e275455a 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -42,7 +42,7 @@ use syntax::abi;
 use syntax::ast_map;
 use syntax::attr::AttrMetaMethods;
 use syntax::attr;
-use syntax::codemap::Span;
+use syntax::codemap::{Span, NO_EXPANSION};
 use syntax::parse::token;
 use syntax::{ast, ast_util, visit};
 use syntax::ptr::P;
@@ -954,8 +954,7 @@ impl LintPass for NonSnakeCase {
         match &p.node {
             &ast::PatIdent(_, ref path1, _) => {
                 match cx.tcx.def_map.borrow().find(&p.id) {
-                    Some(&def::DefLocal(_, _)) | Some(&def::DefBinding(_, _)) |
-                            Some(&def::DefArg(_, _)) => {
+                    Some(&def::DefLocal(_)) => {
                         self.check_snake_case(cx, "variable", path1.node, p.span);
                     }
                     _ => {}
@@ -1297,7 +1296,7 @@ impl LintPass for UnnecessaryAllocation {
         match cx.tcx.adjustments.borrow().find(&e.id) {
             Some(adjustment) => {
                 match *adjustment {
-                    ty::AutoDerefRef(ty::AutoDerefRef { ref autoref, .. }) => {
+                    ty::AdjustDerefRef(ty::AutoDerefRef { ref autoref, .. }) => {
                         match (allocation, autoref) {
                             (VectorAllocation, &Some(ty::AutoPtr(_, _, None))) => {
                                 cx.span_lint(UNNECESSARY_ALLOCATION, e.span,
@@ -1492,7 +1491,7 @@ impl LintPass for Stability {
 
     fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
         // if the expression was produced by a macro expansion,
-        if e.span.expn_info.is_some() { return }
+        if e.span.expn_id != NO_EXPANSION { return }
 
         let id = match e.node {
             ast::ExprPath(..) | ast::ExprStruct(..) => {
@@ -1512,12 +1511,12 @@ impl LintPass for Stability {
                             typeck::MethodStaticUnboxedClosure(def_id) => {
                                 def_id
                             }
-                            typeck::MethodParam(typeck::MethodParam {
+                            typeck::MethodTypeParam(typeck::MethodParam {
                                 trait_ref: ref trait_ref,
                                 method_num: index,
                                 ..
                             }) |
-                            typeck::MethodObject(typeck::MethodObject {
+                            typeck::MethodTraitObject(typeck::MethodObject {
                                 trait_ref: ref trait_ref,
                                 method_num: index,
                                 ..
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index 399313ddd8e..acb4f1be85c 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -18,13 +18,12 @@ use driver::session::Session;
 use metadata::decoder;
 use middle::def;
 use metadata::encoder as e;
-use middle::freevars::{CaptureMode, freevar_entry};
-use middle::freevars;
 use middle::region;
 use metadata::tydecode;
 use metadata::tydecode::{DefIdSource, NominalType, TypeWithId, TypeParameter};
 use metadata::tydecode::{RegionParameter};
 use metadata::tyencode;
+use middle::mem_categorization::Typer;
 use middle::subst;
 use middle::subst::VecPerParamSpace;
 use middle::typeck::{MethodCall, MethodCallee, MethodOrigin};
@@ -42,7 +41,6 @@ use syntax;
 use libc;
 use std::io::Seek;
 use std::mem;
-use std::gc::GC;
 use std::rc::Rc;
 
 use rbml::io::SeekableMemWriter;
@@ -462,8 +460,7 @@ impl tr for def::Def {
           def::DefMod(did) => { def::DefMod(did.tr(dcx)) }
           def::DefForeignMod(did) => { def::DefForeignMod(did.tr(dcx)) }
           def::DefStatic(did, m) => { def::DefStatic(did.tr(dcx), m) }
-          def::DefArg(nid, b) => { def::DefArg(dcx.tr_id(nid), b) }
-          def::DefLocal(nid, b) => { def::DefLocal(dcx.tr_id(nid), b) }
+          def::DefLocal(nid) => { def::DefLocal(dcx.tr_id(nid)) }
           def::DefVariant(e_did, v_did, is_s) => {
             def::DefVariant(e_did.tr(dcx), v_did.tr(dcx), is_s)
           },
@@ -472,11 +469,9 @@ impl tr for def::Def {
           def::DefAssociatedTy(did) => def::DefAssociatedTy(did.tr(dcx)),
           def::DefPrimTy(p) => def::DefPrimTy(p),
           def::DefTyParam(s, did, v) => def::DefTyParam(s, did.tr(dcx), v),
-          def::DefBinding(nid, bm) => def::DefBinding(dcx.tr_id(nid), bm),
           def::DefUse(did) => def::DefUse(did.tr(dcx)),
-          def::DefUpvar(nid1, def, nid2, nid3) => {
+          def::DefUpvar(nid1, nid2, nid3) => {
             def::DefUpvar(dcx.tr_id(nid1),
-                           box(GC) (*def).tr(dcx),
                            dcx.tr_id(nid2),
                            dcx.tr_id(nid3))
           }
@@ -541,36 +536,36 @@ impl tr for ty::TraitStore {
 // ______________________________________________________________________
 // Encoding and decoding of freevar information
 
-fn encode_freevar_entry(rbml_w: &mut Encoder, fv: &freevar_entry) {
+fn encode_freevar_entry(rbml_w: &mut Encoder, fv: &ty::Freevar) {
     (*fv).encode(rbml_w).unwrap();
 }
 
-fn encode_capture_mode(rbml_w: &mut Encoder, cm: CaptureMode) {
+fn encode_capture_mode(rbml_w: &mut Encoder, cm: ast::CaptureClause) {
     cm.encode(rbml_w).unwrap();
 }
 
 trait rbml_decoder_helper {
     fn read_freevar_entry(&mut self, dcx: &DecodeContext)
-                          -> freevar_entry;
-    fn read_capture_mode(&mut self) -> CaptureMode;
+                          -> ty::Freevar;
+    fn read_capture_mode(&mut self) -> ast::CaptureClause;
 }
 
 impl<'a> rbml_decoder_helper for reader::Decoder<'a> {
     fn read_freevar_entry(&mut self, dcx: &DecodeContext)
-                          -> freevar_entry {
-        let fv: freevar_entry = Decodable::decode(self).unwrap();
+                          -> ty::Freevar {
+        let fv: ty::Freevar = Decodable::decode(self).unwrap();
         fv.tr(dcx)
     }
 
-    fn read_capture_mode(&mut self) -> CaptureMode {
-        let cm: CaptureMode = Decodable::decode(self).unwrap();
+    fn read_capture_mode(&mut self) -> ast::CaptureClause {
+        let cm: ast::CaptureClause = Decodable::decode(self).unwrap();
         cm
     }
 }
 
-impl tr for freevar_entry {
-    fn tr(&self, dcx: &DecodeContext) -> freevar_entry {
-        freevar_entry {
+impl tr for ty::Freevar {
+    fn tr(&self, dcx: &DecodeContext) -> ty::Freevar {
+        ty::Freevar {
             def: self.def.tr(dcx),
             span: self.span.tr(dcx),
         }
@@ -646,8 +641,8 @@ impl tr for MethodOrigin {
             typeck::MethodStaticUnboxedClosure(did) => {
                 typeck::MethodStaticUnboxedClosure(did.tr(dcx))
             }
-            typeck::MethodParam(ref mp) => {
-                typeck::MethodParam(
+            typeck::MethodTypeParam(ref mp) => {
+                typeck::MethodTypeParam(
                     typeck::MethodParam {
                         // def-id is already translated when we read it out
                         trait_ref: mp.trait_ref.clone(),
@@ -655,8 +650,8 @@ impl tr for MethodOrigin {
                     }
                 )
             }
-            typeck::MethodObject(ref mo) => {
-                typeck::MethodObject(
+            typeck::MethodTraitObject(ref mo) => {
+                typeck::MethodTraitObject(
                     typeck::MethodObject {
                         trait_ref: mo.trait_ref.clone(),
                         .. *mo
@@ -962,8 +957,8 @@ impl<'a> rbml_writer_helpers for Encoder<'a> {
                     })
                 }
 
-                typeck::MethodParam(ref p) => {
-                    this.emit_enum_variant("MethodParam", 2, 1, |this| {
+                typeck::MethodTypeParam(ref p) => {
+                    this.emit_enum_variant("MethodTypeParam", 2, 1, |this| {
                         this.emit_struct("MethodParam", 2, |this| {
                             try!(this.emit_struct_field("trait_ref", 0, |this| {
                                 Ok(this.emit_trait_ref(ecx, &*p.trait_ref))
@@ -976,8 +971,8 @@ impl<'a> rbml_writer_helpers for Encoder<'a> {
                     })
                 }
 
-                typeck::MethodObject(ref o) => {
-                    this.emit_enum_variant("MethodObject", 3, 1, |this| {
+                typeck::MethodTraitObject(ref o) => {
+                    this.emit_enum_variant("MethodTraitObject", 3, 1, |this| {
                         this.emit_struct("MethodObject", 2, |this| {
                             try!(this.emit_struct_field("trait_ref", 0, |this| {
                                 Ok(this.emit_trait_ref(ecx, &*o.trait_ref))
@@ -1072,13 +1067,13 @@ impl<'a> rbml_writer_helpers for Encoder<'a> {
 
         self.emit_enum("AutoAdjustment", |this| {
             match *adj {
-                ty::AutoAddEnv(store) => {
+                ty::AdjustAddEnv(store) => {
                     this.emit_enum_variant("AutoAddEnv", 0, 1, |this| {
                         this.emit_enum_variant_arg(0, |this| store.encode(this))
                     })
                 }
 
-                ty::AutoDerefRef(ref auto_deref_ref) => {
+                ty::AdjustDerefRef(ref auto_deref_ref) => {
                     this.emit_enum_variant("AutoDerefRef", 1, 1, |this| {
                         this.emit_enum_variant_arg(0,
                             |this| Ok(this.emit_auto_deref_ref(ecx, auto_deref_ref)))
@@ -1292,8 +1287,8 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
         });
 
         for freevar in fv.iter() {
-            match freevars::get_capture_mode(tcx, id) {
-                freevars::CaptureByRef => {
+            match tcx.capture_mode(id) {
+                ast::CaptureByRef => {
                     rbml_w.tag(c::tag_table_upvar_borrow_map, |rbml_w| {
                         rbml_w.id(id);
                         rbml_w.tag(c::tag_table_val, |rbml_w| {
@@ -1374,7 +1369,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
                     })
                 }
             }
-            ty::AutoDerefRef(ref adj) => {
+            ty::AdjustDerefRef(ref adj) => {
                 assert!(!ty::adjust_is_object(adjustment));
                 for autoderef in range(0, adj.autoderefs) {
                     let method_call = MethodCall::autoderef(id, autoderef);
@@ -1505,7 +1500,7 @@ impl<'a> rbml_decoder_decoder_helpers for reader::Decoder<'a> {
     {
         self.read_enum("MethodOrigin", |this| {
             let variants = ["MethodStatic", "MethodStaticUnboxedClosure",
-                            "MethodParam", "MethodObject"];
+                            "MethodTypeParam", "MethodTraitObject"];
             this.read_enum_variant(variants, |this, i| {
                 Ok(match i {
                     0 => {
@@ -1519,8 +1514,8 @@ impl<'a> rbml_decoder_decoder_helpers for reader::Decoder<'a> {
                     }
 
                     2 => {
-                        this.read_struct("MethodParam", 2, |this| {
-                            Ok(typeck::MethodParam(
+                        this.read_struct("MethodTypeParam", 2, |this| {
+                            Ok(typeck::MethodTypeParam(
                                 typeck::MethodParam {
                                     trait_ref: {
                                         this.read_struct_field("trait_ref", 0, |this| {
@@ -1537,8 +1532,8 @@ impl<'a> rbml_decoder_decoder_helpers for reader::Decoder<'a> {
                     }
 
                     3 => {
-                        this.read_struct("MethodObject", 2, |this| {
-                            Ok(typeck::MethodObject(
+                        this.read_struct("MethodTraitObject", 2, |this| {
+                            Ok(typeck::MethodTraitObject(
                                 typeck::MethodObject {
                                     trait_ref: {
                                         this.read_struct_field("trait_ref", 0, |this| {
@@ -1685,14 +1680,14 @@ impl<'a> rbml_decoder_decoder_helpers for reader::Decoder<'a> {
                         let store: ty::TraitStore =
                             this.read_enum_variant_arg(0, |this| Decodable::decode(this)).unwrap();
 
-                        ty::AutoAddEnv(store.tr(dcx))
+                        ty::AdjustAddEnv(store.tr(dcx))
                     }
                     1 => {
                         let auto_deref_ref: ty::AutoDerefRef =
                             this.read_enum_variant_arg(0,
                                 |this| Ok(this.read_auto_deref_ref(dcx))).unwrap();
 
-                        ty::AutoDerefRef(auto_deref_ref)
+                        ty::AdjustDerefRef(auto_deref_ref)
                     }
                     _ => fail!("bad enum variant for ty::AutoAdjustment")
                 })
@@ -2035,7 +2030,7 @@ impl fake_ext_ctxt for parse::ParseSess {
         codemap::Span {
             lo: codemap::BytePos(0),
             hi: codemap::BytePos(0),
-            expn_info: None
+            expn_id: codemap::NO_EXPANSION
         }
     }
     fn ident_of(&self, st: &str) -> ast::Ident {
diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs
index df637e7a052..95009bc2dbf 100644
--- a/src/librustc/middle/borrowck/check_loans.rs
+++ b/src/librustc/middle/borrowck/check_loans.rs
@@ -514,9 +514,9 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
         true
     }
 
-    pub fn is_local_variable_or_arg(&self, cmt: mc::cmt) -> bool {
+    fn is_local_variable_or_arg(&self, cmt: mc::cmt) -> bool {
         match cmt.cat {
-          mc::cat_local(_) | mc::cat_arg(_) => true,
+          mc::cat_local(_) => true,
           _ => false
         }
     }
@@ -775,7 +775,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
                 debug!("mark_variable_as_used_mut(cmt={})", cmt.repr(this.tcx()));
                 match cmt.cat.clone() {
                     mc::cat_copied_upvar(mc::CopiedUpvar { upvar_id: id, .. }) |
-                    mc::cat_local(id) | mc::cat_arg(id) => {
+                    mc::cat_local(id) => {
                         this.tcx().used_mut_nodes.borrow_mut().insert(id);
                         return;
                     }
diff --git a/src/librustc/middle/borrowck/gather_loans/gather_moves.rs b/src/librustc/middle/borrowck/gather_loans/gather_moves.rs
index f58cc950383..25439fce68c 100644
--- a/src/librustc/middle/borrowck/gather_loans/gather_moves.rs
+++ b/src/librustc/middle/borrowck/gather_loans/gather_moves.rs
@@ -147,8 +147,7 @@ fn check_and_get_illegal_move_origin(bccx: &BorrowckCtxt,
         }
 
         mc::cat_rvalue(..) |
-        mc::cat_local(..) |
-        mc::cat_arg(..) => {
+        mc::cat_local(..) => {
             None
         }
 
diff --git a/src/librustc/middle/borrowck/gather_loans/lifetime.rs b/src/librustc/middle/borrowck/gather_loans/lifetime.rs
index e13717e5abd..c0712332525 100644
--- a/src/librustc/middle/borrowck/gather_loans/lifetime.rs
+++ b/src/librustc/middle/borrowck/gather_loans/lifetime.rs
@@ -69,7 +69,6 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> {
             mc::cat_rvalue(..) |
             mc::cat_copied_upvar(..) |                  // L-Local
             mc::cat_local(..) |                         // L-Local
-            mc::cat_arg(..) |                           // L-Local
             mc::cat_upvar(..) |
             mc::cat_deref(_, _, mc::BorrowedPtr(..)) |  // L-Deref-Borrowed
             mc::cat_deref(_, _, mc::Implicit(..)) |
@@ -174,8 +173,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> {
             mc::cat_static_item => {
                 ty::ReStatic
             }
-            mc::cat_local(local_id) |
-            mc::cat_arg(local_id) => {
+            mc::cat_local(local_id) => {
                 ty::ReScope(self.bccx.tcx.region_maps.var_scope(local_id))
             }
             mc::cat_deref(_, _, mc::UnsafePtr(..)) => {
diff --git a/src/librustc/middle/borrowck/gather_loans/restrictions.rs b/src/librustc/middle/borrowck/gather_loans/restrictions.rs
index 90e17e4d79c..e0018919b98 100644
--- a/src/librustc/middle/borrowck/gather_loans/restrictions.rs
+++ b/src/librustc/middle/borrowck/gather_loans/restrictions.rs
@@ -66,8 +66,7 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> {
                 Safe
             }
 
-            mc::cat_local(local_id) |
-            mc::cat_arg(local_id) => {
+            mc::cat_local(local_id) => {
                 // R-Variable, locally declared
                 let lp = Rc::new(LpVar(local_id));
                 SafeIf(lp.clone(), vec![lp])
diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs
index 0d584a7664f..e1e37b3d371 100644
--- a/src/librustc/middle/borrowck/mod.rs
+++ b/src/librustc/middle/borrowck/mod.rs
@@ -321,8 +321,7 @@ pub fn opt_loan_path(cmt: &mc::cmt) -> Option<Rc<LoanPath>> {
             None
         }
 
-        mc::cat_local(id) |
-        mc::cat_arg(id) => {
+        mc::cat_local(id) => {
             Some(Rc::new(LpVar(id)))
         }
 
@@ -425,12 +424,12 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                                adj: &ty::AutoAdjustment)
                                -> mc::cmt {
         let r = match *adj {
-            ty::AutoDerefRef(
+            ty::AdjustDerefRef(
                 ty::AutoDerefRef {
                     autoderefs: autoderefs, ..}) => {
                 self.mc().cat_expr_autoderefd(expr, autoderefs)
             }
-            ty::AutoAddEnv(..) => {
+            ty::AdjustAddEnv(..) => {
                 // no autoderefs
                 self.mc().cat_expr_unadjusted(expr)
             }
diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs
index f1c288ae7a9..b268c2a7a51 100644
--- a/src/librustc/middle/cfg/construct.rs
+++ b/src/librustc/middle/cfg/construct.rs
@@ -424,6 +424,13 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
                 self.call(expr, pred, &**l, Some(&**r).into_iter())
             }
 
+            ast::ExprSlice(ref base, ref start, ref end, _) => {
+                self.call(expr,
+                          pred,
+                          &**base,
+                          start.iter().chain(end.iter()).map(|x| &**x))
+            }
+
             ast::ExprUnary(_, ref e) if self.is_method_call(expr) => {
                 self.call(expr, pred, &**e, None::<ast::Expr>.iter())
             }
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index b75d61100ec..345b8c88372 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -101,12 +101,12 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
                         }
                     }
                     typeck::MethodStaticUnboxedClosure(_) => {}
-                    typeck::MethodParam(typeck::MethodParam {
+                    typeck::MethodTypeParam(typeck::MethodParam {
                         trait_ref: ref trait_ref,
                         method_num: index,
                         ..
                     }) |
-                    typeck::MethodObject(typeck::MethodObject {
+                    typeck::MethodTraitObject(typeck::MethodObject {
                         trait_ref: ref trait_ref,
                         method_num: index,
                         ..
diff --git a/src/librustc/middle/def.rs b/src/librustc/middle/def.rs
index ae45d827def..1863a19b56d 100644
--- a/src/librustc/middle/def.rs
+++ b/src/librustc/middle/def.rs
@@ -12,8 +12,6 @@ use middle::subst::ParamSpace;
 use syntax::ast;
 use syntax::ast_util::local_def;
 
-use std::gc::Gc;
-
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub enum Def {
     DefFn(ast::DefId, ast::FnStyle),
@@ -22,20 +20,18 @@ pub enum Def {
     DefMod(ast::DefId),
     DefForeignMod(ast::DefId),
     DefStatic(ast::DefId, bool /* is_mutbl */),
-    DefArg(ast::NodeId, ast::BindingMode),
-    DefLocal(ast::NodeId, ast::BindingMode),
+    DefLocal(ast::NodeId),
     DefVariant(ast::DefId /* enum */, ast::DefId /* variant */, bool /* is_structure */),
     DefTy(ast::DefId, bool /* is_enum */),
     DefAssociatedTy(ast::DefId),
     DefTrait(ast::DefId),
     DefPrimTy(ast::PrimTy),
     DefTyParam(ParamSpace, ast::DefId, uint),
-    DefBinding(ast::NodeId, ast::BindingMode),
     DefUse(ast::DefId),
-    DefUpvar(ast::NodeId,  // id of closed over var
-             Gc<Def>,     // closed over def
+    DefUpvar(ast::NodeId,  // id of closed over local
              ast::NodeId,  // expr node that creates the closure
-             ast::NodeId), // id for the block/body of the closure expr
+             ast::NodeId), // block node for the closest enclosing proc
+                           // or unboxed closure, DUMMY_NODE_ID otherwise
 
     /// Note that if it's a tuple struct's definition, the node id of the ast::DefId
     /// may either refer to the item definition's id or the StructDef.ctor_id.
@@ -68,11 +64,9 @@ impl Def {
             DefMethod(id, _) => {
                 id
             }
-            DefArg(id, _) |
-            DefLocal(id, _) |
+            DefLocal(id) |
             DefSelfTy(id) |
-            DefUpvar(id, _, _, _) |
-            DefBinding(id, _) |
+            DefUpvar(id, _, _) |
             DefRegion(id) |
             DefTyParamBinder(id) |
             DefLabel(id) => {
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index c8c5284022d..0b4f661a16a 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -16,10 +16,11 @@
 
 use middle::mem_categorization as mc;
 use middle::def;
-use middle::freevars;
+use middle::mem_categorization::Typer;
 use middle::pat_util;
 use middle::ty;
-use middle::typeck::{MethodCall, MethodObject, MethodOrigin, MethodParam};
+use middle::typeck::{MethodCall, MethodObject, MethodTraitObject};
+use middle::typeck::{MethodOrigin, MethodParam, MethodTypeParam};
 use middle::typeck::{MethodStatic, MethodStaticUnboxedClosure};
 use middle::typeck;
 use util::ppaux::Repr;
@@ -177,8 +178,8 @@ impl OverloadedCallType {
             MethodStaticUnboxedClosure(def_id) => {
                 OverloadedCallType::from_unboxed_closure(tcx, def_id)
             }
-            MethodParam(MethodParam { trait_ref: ref trait_ref, .. }) |
-            MethodObject(MethodObject { trait_ref: ref trait_ref, .. }) => {
+            MethodTypeParam(MethodParam { trait_ref: ref trait_ref, .. }) |
+            MethodTraitObject(MethodObject { trait_ref: ref trait_ref, .. }) => {
                 OverloadedCallType::from_trait_id(tcx, trait_ref.def_id)
             }
         }
@@ -316,7 +317,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> {
             ast::ExprPath(..) => { }
 
             ast::ExprUnary(ast::UnDeref, ref base) => {      // *base
-                if !self.walk_overloaded_operator(expr, &**base, None) {
+                if !self.walk_overloaded_operator(expr, &**base, Vec::new()) {
                     self.select_from_expr(&**base);
                 }
             }
@@ -330,12 +331,23 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> {
             }
 
             ast::ExprIndex(ref lhs, ref rhs) => {       // lhs[rhs]
-                if !self.walk_overloaded_operator(expr, &**lhs, Some(&**rhs)) {
+                if !self.walk_overloaded_operator(expr, &**lhs, vec![&**rhs]) {
                     self.select_from_expr(&**lhs);
                     self.consume_expr(&**rhs);
                 }
             }
 
+            ast::ExprSlice(ref base, ref start, ref end, _) => {    // base[start..end]
+                let args = match (start, end) {
+                    (&Some(ref e1), &Some(ref e2)) => vec![&**e1, &**e2],
+                    (&Some(ref e), &None) => vec![&**e],
+                    (&None, &Some(ref e)) => vec![&**e],
+                    (&None, &None) => Vec::new()
+                };
+                let overloaded = self.walk_overloaded_operator(expr, &**base, args);
+                assert!(overloaded);
+            }
+
             ast::ExprCall(ref callee, ref args) => {    // callee(args)
                 self.walk_callee(expr, &**callee);
                 self.consume_exprs(args);
@@ -430,13 +442,13 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> {
             }
 
             ast::ExprUnary(_, ref lhs) => {
-                if !self.walk_overloaded_operator(expr, &**lhs, None) {
+                if !self.walk_overloaded_operator(expr, &**lhs, Vec::new()) {
                     self.consume_expr(&**lhs);
                 }
             }
 
             ast::ExprBinary(_, ref lhs, ref rhs) => {
-                if !self.walk_overloaded_operator(expr, &**lhs, Some(&**rhs)) {
+                if !self.walk_overloaded_operator(expr, &**lhs, vec![&**rhs]) {
                     self.consume_expr(&**lhs);
                     self.consume_expr(&**rhs);
                 }
@@ -673,7 +685,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> {
             None => { }
             Some(adjustment) => {
                 match *adjustment {
-                    ty::AutoAddEnv(..) => {
+                    ty::AdjustAddEnv(..) => {
                         // Creating a closure consumes the input and stores it
                         // into the resulting rvalue.
                         debug!("walk_adjustment(AutoAddEnv)");
@@ -681,7 +693,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> {
                             return_if_err!(self.mc.cat_expr_unadjusted(expr));
                         self.delegate_consume(expr.id, expr.span, cmt_unadjusted);
                     }
-                    ty::AutoDerefRef(ty::AutoDerefRef {
+                    ty::AdjustDerefRef(ty::AutoDerefRef {
                         autoref: ref opt_autoref,
                         autoderefs: n
                     }) => {
@@ -774,7 +786,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> {
     fn walk_overloaded_operator(&mut self,
                                 expr: &ast::Expr,
                                 receiver: &ast::Expr,
-                                rhs: Option<&ast::Expr>)
+                                rhs: Vec<&ast::Expr>)
                                 -> bool
     {
         if !self.typer.is_method_call(expr.id) {
@@ -911,12 +923,12 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> {
         debug!("walk_captures({})", closure_expr.repr(self.tcx()));
 
         let tcx = self.typer.tcx();
-        freevars::with_freevars(tcx, closure_expr.id, |freevars| {
-            match freevars::get_capture_mode(self.tcx(), closure_expr.id) {
-                freevars::CaptureByRef => {
+        ty::with_freevars(tcx, closure_expr.id, |freevars| {
+            match self.tcx().capture_mode(closure_expr.id) {
+                ast::CaptureByRef => {
                     self.walk_by_ref_captures(closure_expr, freevars);
                 }
-                freevars::CaptureByValue => {
+                ast::CaptureByValue => {
                     self.walk_by_value_captures(closure_expr, freevars);
                 }
             }
@@ -925,7 +937,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> {
 
     fn walk_by_ref_captures(&mut self,
                             closure_expr: &ast::Expr,
-                            freevars: &[freevars::freevar_entry]) {
+                            freevars: &[ty::Freevar]) {
         for freevar in freevars.iter() {
             let id_var = freevar.def.def_id().node;
             let cmt_var = return_if_err!(self.cat_captured_var(closure_expr.id,
@@ -950,7 +962,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> {
 
     fn walk_by_value_captures(&mut self,
                               closure_expr: &ast::Expr,
-                              freevars: &[freevars::freevar_entry]) {
+                              freevars: &[ty::Freevar]) {
         for freevar in freevars.iter() {
             let cmt_var = return_if_err!(self.cat_captured_var(closure_expr.id,
                                                                closure_expr.span,
diff --git a/src/librustc/middle/freevars.rs b/src/librustc/middle/freevars.rs
deleted file mode 100644
index 5b7c72208ea..00000000000
--- a/src/librustc/middle/freevars.rs
+++ /dev/null
@@ -1,190 +0,0 @@
-// Copyright 2012-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 pass that annotates for each loops and functions with the free
-// variables that they contain.
-
-#![allow(non_camel_case_types)]
-
-use middle::def;
-use middle::mem_categorization::Typer;
-use middle::resolve;
-use middle::ty;
-use util::nodemap::{NodeMap, NodeSet};
-
-use syntax::ast;
-use syntax::codemap::Span;
-use syntax::visit::Visitor;
-use syntax::visit;
-
-#[deriving(Clone, Decodable, Encodable, Show)]
-pub enum CaptureMode {
-    /// Copy/move the value from this llvm ValueRef into the environment.
-    CaptureByValue,
-
-    /// Access by reference (used for stack closures).
-    CaptureByRef
-}
-
-// A vector of defs representing the free variables referred to in a function.
-// (The def_upvar will already have been stripped).
-#[deriving(Encodable, Decodable)]
-pub struct freevar_entry {
-    pub def: def::Def, //< The variable being accessed free.
-    pub span: Span     //< First span where it is accessed (there can be multiple)
-}
-
-pub type freevar_map = NodeMap<Vec<freevar_entry>>;
-
-pub type CaptureModeMap = NodeMap<CaptureMode>;
-
-struct CollectFreevarsVisitor<'a> {
-    seen: NodeSet,
-    refs: Vec<freevar_entry>,
-    def_map: &'a resolve::DefMap,
-    capture_mode_map: &'a mut CaptureModeMap,
-    depth: uint
-}
-
-impl<'a, 'v> Visitor<'v> for CollectFreevarsVisitor<'a> {
-    fn visit_item(&mut self, _: &ast::Item) {
-        // ignore_item
-    }
-
-    fn visit_expr(&mut self, expr: &ast::Expr) {
-        match expr.node {
-            ast::ExprProc(..) => {
-                self.capture_mode_map.insert(expr.id, CaptureByValue);
-                self.depth += 1;
-                visit::walk_expr(self, expr);
-                self.depth -= 1;
-            }
-            ast::ExprFnBlock(_, _, _) => {
-                // NOTE(stage0): After snapshot, change to:
-                //
-                //let capture_mode = match capture_clause {
-                //    ast::CaptureByValue => CaptureByValue,
-                //    ast::CaptureByRef => CaptureByRef,
-                //};
-                let capture_mode = CaptureByRef;
-                self.capture_mode_map.insert(expr.id, capture_mode);
-                self.depth += 1;
-                visit::walk_expr(self, expr);
-                self.depth -= 1;
-            }
-            ast::ExprUnboxedFn(capture_clause, _, _, _) => {
-                let capture_mode = match capture_clause {
-                    ast::CaptureByValue => CaptureByValue,
-                    ast::CaptureByRef => CaptureByRef,
-                };
-                self.capture_mode_map.insert(expr.id, capture_mode);
-                self.depth += 1;
-                visit::walk_expr(self, expr);
-                self.depth -= 1;
-            }
-            ast::ExprPath(..) => {
-                let mut def = *self.def_map.borrow().find(&expr.id)
-                                                    .expect("path not found");
-                let mut i = 0;
-                while i < self.depth {
-                    match def {
-                        def::DefUpvar(_, inner, _, _) => { def = *inner; }
-                        _ => break
-                    }
-                    i += 1;
-                }
-                if i == self.depth { // Made it to end of loop
-                    let dnum = def.def_id().node;
-                    if !self.seen.contains(&dnum) {
-                        self.refs.push(freevar_entry {
-                            def: def,
-                            span: expr.span,
-                        });
-                        self.seen.insert(dnum);
-                    }
-                }
-            }
-            _ => visit::walk_expr(self, expr)
-        }
-    }
-}
-
-// Searches through part of the AST for all references to locals or
-// upvars in this frame and returns the list of definition IDs thus found.
-// Since we want to be able to collect upvars in some arbitrary piece
-// of the AST, we take a walker function that we invoke with a visitor
-// in order to start the search.
-fn collect_freevars(def_map: &resolve::DefMap,
-                    blk: &ast::Block,
-                    capture_mode_map: &mut CaptureModeMap)
-                    -> Vec<freevar_entry> {
-    let mut v = CollectFreevarsVisitor {
-        seen: NodeSet::new(),
-        refs: Vec::new(),
-        def_map: def_map,
-        capture_mode_map: &mut *capture_mode_map,
-        depth: 1
-    };
-
-    v.visit_block(blk);
-
-    v.refs
-}
-
-struct AnnotateFreevarsVisitor<'a> {
-    def_map: &'a resolve::DefMap,
-    freevars: freevar_map,
-    capture_mode_map: CaptureModeMap,
-}
-
-impl<'a, 'v> Visitor<'v> for AnnotateFreevarsVisitor<'a> {
-    fn visit_fn(&mut self, fk: visit::FnKind<'v>, fd: &'v ast::FnDecl,
-                blk: &'v ast::Block, s: Span, nid: ast::NodeId) {
-        let vars = collect_freevars(self.def_map,
-                                    blk,
-                                    &mut self.capture_mode_map);
-        self.freevars.insert(nid, vars);
-        visit::walk_fn(self, fk, fd, blk, s);
-    }
-}
-
-// Build a map from every function and for-each body to a set of the
-// freevars contained in it. The implementation is not particularly
-// efficient as it fully recomputes the free variables at every
-// node of interest rather than building up the free variables in
-// one pass. This could be improved upon if it turns out to matter.
-pub fn annotate_freevars(def_map: &resolve::DefMap, krate: &ast::Crate)
-                         -> (freevar_map, CaptureModeMap) {
-    let mut visitor = AnnotateFreevarsVisitor {
-        def_map: def_map,
-        freevars: NodeMap::new(),
-        capture_mode_map: NodeMap::new(),
-    };
-    visit::walk_crate(&mut visitor, krate);
-
-    let AnnotateFreevarsVisitor {
-        freevars,
-        capture_mode_map,
-        ..
-    } = visitor;
-    (freevars, capture_mode_map)
-}
-
-pub fn with_freevars<T>(tcx: &ty::ctxt, fid: ast::NodeId, f: |&[freevar_entry]| -> T) -> T {
-    match tcx.freevars.borrow().find(&fid) {
-        None => fail!("with_freevars: {} has no freevars", fid),
-        Some(d) => f(d.as_slice())
-    }
-}
-
-pub fn get_capture_mode<'tcx, T:Typer<'tcx>>(tcx: &T, closure_expr_id: ast::NodeId)
-                                             -> CaptureMode {
-    tcx.capture_mode(closure_expr_id)
-}
diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs
index aeb0c155a3f..4a5b2e01463 100644
--- a/src/librustc/middle/kind.rs
+++ b/src/librustc/middle/kind.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use middle::freevars::freevar_entry;
-use middle::freevars;
 use middle::mem_categorization::Typer;
 use middle::subst;
 use middle::ty;
@@ -146,10 +144,10 @@ fn check_item(cx: &mut Context, item: &Item) {
 fn with_appropriate_checker(cx: &Context,
                             id: NodeId,
                             fn_span: Span,
-                            b: |checker: |&Context, &freevar_entry||) {
+                            b: |checker: |&Context, &ty::Freevar||) {
     fn check_for_uniq(cx: &Context,
                       fn_span: Span,
-                      fv: &freevar_entry,
+                      fv: &ty::Freevar,
                       bounds: ty::BuiltinBounds) {
         // all captured data must be owned, regardless of whether it is
         // moved in or copied in.
@@ -162,7 +160,7 @@ fn with_appropriate_checker(cx: &Context,
     fn check_for_block(cx: &Context,
                        fn_span: Span,
                        fn_id: NodeId,
-                       fv: &freevar_entry,
+                       fv: &ty::Freevar,
                        bounds: ty::BuiltinBounds) {
         let id = fv.def.def_id().node;
         let var_t = ty::node_id_to_type(cx.tcx, id);
@@ -177,7 +175,7 @@ fn with_appropriate_checker(cx: &Context,
                              bounds, Some(var_t));
     }
 
-    fn check_for_bare(cx: &Context, fv: &freevar_entry) {
+    fn check_for_bare(cx: &Context, fv: &ty::Freevar) {
         span_err!(cx.tcx.sess, fv.span, E0143,
                   "can't capture dynamic environment in a fn item; \
                    use the || {} closure form instead", "{ ... }");
@@ -227,7 +225,7 @@ fn check_fn(
 
     // <Check kinds on free variables:
     with_appropriate_checker(cx, fn_id, sp, |chk| {
-        freevars::with_freevars(cx.tcx, fn_id, |freevars| {
+        ty::with_freevars(cx.tcx, fn_id, |freevars| {
             for fv in freevars.iter() {
                 chk(cx, fv);
             }
@@ -274,6 +272,7 @@ pub fn check_expr(cx: &mut Context, e: &Expr) {
 
     visit::walk_expr(cx, e);
 }
+
 fn check_ty(cx: &mut Context, aty: &Ty) {
     match aty.node {
         TyPath(_, _, id) => {
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index 1875c53f074..daba3b701c0 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -247,6 +247,8 @@ lets_do_this! {
     ShrTraitLangItem,                "shr",                     shr_trait;
     IndexTraitLangItem,              "index",                   index_trait;
     IndexMutTraitLangItem,           "index_mut",               index_mut_trait;
+    SliceTraitLangItem,              "slice",                   slice_trait;
+    SliceMutTraitLangItem,           "slice_mut",               slice_mut_trait;
 
     UnsafeTypeLangItem,              "unsafe",                  unsafe_type;
 
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index fee6c77a799..b6893a6a3b4 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -103,7 +103,6 @@
  */
 
 use middle::def::*;
-use middle::freevars;
 use middle::mem_categorization::Typer;
 use middle::pat_util;
 use middle::ty;
@@ -116,6 +115,7 @@ use std::mem::transmute;
 use std::rc::Rc;
 use std::str;
 use std::uint;
+use syntax::ast;
 use syntax::ast::*;
 use syntax::codemap::{BytePos, original_sp, Span};
 use syntax::parse::token::special_idents;
@@ -183,7 +183,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for IrMaps<'a, 'tcx> {
                 b: &'v Block, s: Span, n: NodeId) {
         visit_fn(self, fk, fd, b, s, n);
     }
-    fn visit_local(&mut self, l: &Local) { visit_local(self, l); }
+    fn visit_local(&mut self, l: &ast::Local) { visit_local(self, l); }
     fn visit_expr(&mut self, ex: &Expr) { visit_expr(self, ex); }
     fn visit_arm(&mut self, a: &Arm) { visit_arm(self, a); }
 }
@@ -346,7 +346,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Liveness<'a, 'tcx> {
     fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: &'v Block, s: Span, n: NodeId) {
         check_fn(self, fk, fd, b, s, n);
     }
-    fn visit_local(&mut self, l: &Local) {
+    fn visit_local(&mut self, l: &ast::Local) {
         check_local(self, l);
     }
     fn visit_expr(&mut self, ex: &Expr) {
@@ -408,7 +408,7 @@ fn visit_fn(ir: &mut IrMaps,
     lsets.warn_about_unused_args(decl, entry_ln);
 }
 
-fn visit_local(ir: &mut IrMaps, local: &Local) {
+fn visit_local(ir: &mut IrMaps, local: &ast::Local) {
     pat_util::pat_bindings(&ir.tcx.def_map, &*local.pat, |_, p_id, sp, path1| {
         debug!("adding local variable {}", p_id);
         let name = path1.node;
@@ -437,24 +437,15 @@ fn visit_arm(ir: &mut IrMaps, arm: &Arm) {
     visit::walk_arm(ir, arm);
 }
 
-fn moved_variable_node_id_from_def(def: Def) -> Option<NodeId> {
-    match def {
-        DefBinding(nid, _) |
-        DefArg(nid, _) |
-        DefLocal(nid, _) => Some(nid),
-
-      _ => None
-    }
-}
-
 fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
     match expr.node {
       // live nodes required for uses or definitions of variables:
       ExprPath(_) => {
         let def = ir.tcx.def_map.borrow().get_copy(&expr.id);
         debug!("expr {}: path that leads to {:?}", expr.id, def);
-        if moved_variable_node_id_from_def(def).is_some() {
-            ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
+        match def {
+            DefLocal(..) => ir.add_live_node_for_node(expr.id, ExprNode(expr.span)),
+            _ => {}
         }
         visit::walk_expr(ir, expr);
       }
@@ -468,15 +459,15 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
         // in better error messages than just pointing at the closure
         // construction site.
         let mut call_caps = Vec::new();
-        freevars::with_freevars(ir.tcx, expr.id, |freevars| {
+        ty::with_freevars(ir.tcx, expr.id, |freevars| {
             for fv in freevars.iter() {
-                match moved_variable_node_id_from_def(fv.def) {
-                    Some(rv) => {
+                match fv.def {
+                    DefLocal(rv) => {
                         let fv_ln = ir.add_live_node(FreeVarNode(fv.span));
                         call_caps.push(CaptureInfo {ln: fv_ln,
                                                     var_nid: rv});
                     }
-                    None => {}
+                    _ => {}
                 }
             }
         });
@@ -511,7 +502,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
 
       // otherwise, live nodes are not required:
       ExprIndex(..) | ExprField(..) | ExprTupField(..) | ExprVec(..) |
-      ExprCall(..) | ExprMethodCall(..) | ExprTup(..) |
+      ExprCall(..) | ExprMethodCall(..) | ExprTup(..) | ExprSlice(..) |
       ExprBinary(..) | ExprAddrOf(..) |
       ExprCast(..) | ExprUnary(..) | ExprBreak(_) |
       ExprAgain(_) | ExprLit(_) | ExprRet(..) | ExprBlock(..) |
@@ -913,7 +904,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         }
     }
 
-    fn propagate_through_local(&mut self, local: &Local, succ: LiveNode)
+    fn propagate_through_local(&mut self, local: &ast::Local, succ: LiveNode)
                                -> LiveNode {
         // Note: we mark the variable as defined regardless of whether
         // there is an initializer.  Initially I had thought to only mark
@@ -1184,6 +1175,12 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
             self.propagate_through_expr(&**l, r_succ)
           }
 
+          ExprSlice(ref e1, ref e2, ref e3, _) => {
+            let succ = e3.as_ref().map_or(succ, |e| self.propagate_through_expr(&**e, succ));
+            let succ = e2.as_ref().map_or(succ, |e| self.propagate_through_expr(&**e, succ));
+            self.propagate_through_expr(&**e1, succ)
+          }
+
           ExprAddrOf(_, ref e) |
           ExprCast(ref e, _) |
           ExprUnary(_, ref e) |
@@ -1296,9 +1293,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
 
     fn access_path(&mut self, expr: &Expr, succ: LiveNode, acc: uint)
                    -> LiveNode {
-        let def = self.ir.tcx.def_map.borrow().get_copy(&expr.id);
-        match moved_variable_node_id_from_def(def) {
-          Some(nid) => {
+        match self.ir.tcx.def_map.borrow().get_copy(&expr.id) {
+          DefLocal(nid) => {
             let ln = self.live_node(expr.id, expr.span);
             if acc != 0u {
                 self.init_from_succ(ln, succ);
@@ -1307,7 +1303,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
             }
             ln
           }
-          None => succ
+          _ => succ
         }
     }
 
@@ -1403,7 +1399,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
 // _______________________________________________________________________
 // Checking for error conditions
 
-fn check_local(this: &mut Liveness, local: &Local) {
+fn check_local(this: &mut Liveness, local: &ast::Local) {
     match local.init {
         Some(_) => {
             this.warn_about_unused_or_dead_vars_in_pat(&*local.pat);
@@ -1468,7 +1464,7 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
       ExprWhile(..) | ExprLoop(..) | ExprIndex(..) | ExprField(..) |
       ExprTupField(..) | ExprVec(..) | ExprTup(..) | ExprBinary(..) |
       ExprCast(..) | ExprUnary(..) | ExprRet(..) | ExprBreak(..) |
-      ExprAgain(..) | ExprLit(_) | ExprBlock(..) |
+      ExprAgain(..) | ExprLit(_) | ExprBlock(..) | ExprSlice(..) |
       ExprMac(..) | ExprAddrOf(..) | ExprStruct(..) | ExprRepeat(..) |
       ExprParen(..) | ExprFnBlock(..) | ExprProc(..) | ExprUnboxedFn(..) |
       ExprPath(..) | ExprBox(..) => {
@@ -1520,11 +1516,12 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
                     sp, "not all control paths return a value");
                 if ends_with_stmt {
                     let last_stmt = body.stmts.last().unwrap();
-                    let original_span = original_sp(last_stmt.span, sp);
+                    let original_span = original_sp(self.ir.tcx.sess.codemap(),
+                                                    last_stmt.span, sp);
                     let span_semicolon = Span {
                         lo: original_span.hi - BytePos(1),
                         hi: original_span.hi,
-                        expn_info: original_span.expn_info
+                        expn_id: original_span.expn_id
                     };
                     self.ir.tcx.sess.span_note(
                         span_semicolon, "consider removing this semicolon:");
@@ -1537,7 +1534,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         match expr.node {
           ExprPath(_) => {
             match self.ir.tcx.def_map.borrow().get_copy(&expr.id) {
-              DefLocal(nid, _) => {
+              DefLocal(nid) => {
                 // Assignment to an immutable variable or argument: only legal
                 // if there is no later assignment. If this local is actually
                 // mutable, then check for a reassignment to flag the mutability
@@ -1546,16 +1543,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
                 let var = self.variable(nid, expr.span);
                 self.warn_about_dead_assign(expr.span, expr.id, ln, var);
               }
-              def => {
-                match moved_variable_node_id_from_def(def) {
-                  Some(nid) => {
-                    let ln = self.live_node(expr.id, expr.span);
-                    let var = self.variable(nid, expr.span);
-                    self.warn_about_dead_assign(expr.span, expr.id, ln, var);
-                  }
-                  None => {}
-                }
-              }
+              _ => {}
             }
           }
 
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 17d941b5958..6350fa6a506 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -63,7 +63,6 @@
 #![allow(non_camel_case_types)]
 
 use middle::def;
-use middle::freevars;
 use middle::ty;
 use middle::typeck;
 use util::nodemap::{DefIdMap, NodeMap};
@@ -71,6 +70,7 @@ use util::ppaux::{ty_to_string, Repr};
 
 use syntax::ast::{MutImmutable, MutMutable};
 use syntax::ast;
+use syntax::ast_map;
 use syntax::codemap::Span;
 use syntax::print::pprust;
 use syntax::parse::token;
@@ -85,7 +85,6 @@ pub enum categorization {
     cat_copied_upvar(CopiedUpvar),     // upvar copied into proc env
     cat_upvar(ty::UpvarId, ty::UpvarBorrow), // by ref upvar from stack closure
     cat_local(ast::NodeId),            // local variable
-    cat_arg(ast::NodeId),              // formal argument
     cat_deref(cmt, uint, PointerKind), // deref of a ptr
     cat_interior(cmt, InteriorKind),   // something interior: field, tuple, etc
     cat_downcast(cmt),                 // selects a particular enum variant (*1)
@@ -273,7 +272,7 @@ pub trait Typer<'tcx> {
     fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<ast::NodeId>;
     fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> ty::UpvarBorrow;
     fn capture_mode(&self, closure_expr_id: ast::NodeId)
-                    -> freevars::CaptureMode;
+                    -> ast::CaptureClause;
     fn unboxed_closures<'a>(&'a self)
                         -> &'a RefCell<DefIdMap<ty::UnboxedClosure>>;
 }
@@ -312,28 +311,19 @@ impl MutabilityCategory {
         }
     }
 
-    fn from_def(def: &def::Def) -> MutabilityCategory {
-        match *def {
-            def::DefFn(..) | def::DefStaticMethod(..) | def::DefSelfTy(..) |
-            def::DefMod(..) | def::DefForeignMod(..) | def::DefVariant(..) |
-            def::DefTy(..) | def::DefTrait(..) | def::DefPrimTy(..) |
-            def::DefTyParam(..) | def::DefUse(..) | def::DefStruct(..) |
-            def::DefTyParamBinder(..) | def::DefRegion(..) | def::DefLabel(..) |
-            def::DefMethod(..) | def::DefAssociatedTy(..) => {
-                fail!("no MutabilityCategory for def: {}", *def)
-            }
-
-            def::DefStatic(_, false) => McImmutable,
-            def::DefStatic(_, true) => McDeclared,
-
-            def::DefArg(_, binding_mode) |
-            def::DefBinding(_, binding_mode) |
-            def::DefLocal(_, binding_mode)  => match binding_mode {
-                ast::BindByValue(ast::MutMutable) => McDeclared,
-                _ => McImmutable
+    fn from_local(tcx: &ty::ctxt, id: ast::NodeId) -> MutabilityCategory {
+        match tcx.map.get(id) {
+            ast_map::NodeLocal(p) | ast_map::NodeArg(p) => match p.node {
+                ast::PatIdent(bind_mode, _, _) => {
+                    if bind_mode == ast::BindByValue(ast::MutMutable) {
+                        McDeclared
+                    } else {
+                        McImmutable
+                    }
+                }
+                _ => tcx.sess.span_bug(p.span, "expected identifier pattern")
             },
-
-            def::DefUpvar(_, def, _, _) => MutabilityCategory::from_def(&*def)
+            _ => tcx.sess.span_bug(tcx.map.span(id), "expected identifier pattern")
         }
     }
 
@@ -414,14 +404,14 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
 
             Some(adjustment) => {
                 match *adjustment {
-                    ty::AutoAddEnv(..) => {
+                    ty::AdjustAddEnv(..) => {
                         // Convert a bare fn to a closure by adding NULL env.
                         // Result is an rvalue.
                         let expr_ty = if_ok!(self.expr_ty_adjusted(expr));
                         Ok(self.cat_rvalue_node(expr.id(), expr.span(), expr_ty))
                     }
 
-                    ty::AutoDerefRef(
+                    ty::AdjustDerefRef(
                         ty::AutoDerefRef {
                             autoref: Some(_), ..}) => {
                         // Equivalent to &*expr or something similar.
@@ -430,7 +420,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                         Ok(self.cat_rvalue_node(expr.id(), expr.span(), expr_ty))
                     }
 
-                    ty::AutoDerefRef(
+                    ty::AdjustDerefRef(
                         ty::AutoDerefRef {
                             autoref: None, autoderefs: autoderefs}) => {
                         // Equivalent to *expr or something similar.
@@ -504,7 +494,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
           ast::ExprAssign(..) | ast::ExprAssignOp(..) |
           ast::ExprFnBlock(..) | ast::ExprProc(..) |
           ast::ExprUnboxedFn(..) | ast::ExprRet(..) |
-          ast::ExprUnary(..) |
+          ast::ExprUnary(..) | ast::ExprSlice(..) |
           ast::ExprMethodCall(..) | ast::ExprCast(..) |
           ast::ExprVec(..) | ast::ExprTup(..) | ast::ExprIf(..) |
           ast::ExprBinary(..) | ast::ExprWhile(..) |
@@ -546,30 +536,17 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
               }))
           }
 
-          def::DefStatic(_, _) => {
+          def::DefStatic(_, mutbl) => {
               Ok(Rc::new(cmt_ {
                   id:id,
                   span:span,
                   cat:cat_static_item,
-                  mutbl: MutabilityCategory::from_def(&def),
+                  mutbl: if mutbl { McDeclared } else { McImmutable},
                   ty:expr_ty
               }))
           }
 
-          def::DefArg(vid, _) => {
-            // Idea: make this could be rewritten to model by-ref
-            // stuff as `&const` and `&mut`?
-
-            Ok(Rc::new(cmt_ {
-                id: id,
-                span: span,
-                cat: cat_arg(vid),
-                mutbl: MutabilityCategory::from_def(&def),
-                ty:expr_ty
-            }))
-          }
-
-          def::DefUpvar(var_id, _, fn_node_id, _) => {
+          def::DefUpvar(var_id, fn_node_id, _) => {
               let ty = if_ok!(self.node_ty(fn_node_id));
               match ty::get(ty).sty {
                   ty::ty_closure(ref closure_ty) => {
@@ -597,7 +574,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                                   onceness: closure_ty.onceness,
                                   capturing_proc: fn_node_id,
                               }),
-                              mutbl: MutabilityCategory::from_def(&def),
+                              mutbl: MutabilityCategory::from_local(self.tcx(), var_id),
                               ty:expr_ty
                           }))
                       }
@@ -620,7 +597,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                               onceness: onceness,
                               capturing_proc: fn_node_id,
                           }),
-                          mutbl: MutabilityCategory::from_def(&def),
+                          mutbl: MutabilityCategory::from_local(self.tcx(), var_id),
                           ty: expr_ty
                       }))
                   }
@@ -634,14 +611,12 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
               }
           }
 
-          def::DefLocal(vid, _) |
-          def::DefBinding(vid, _) => {
-            // by-value/by-ref bindings are local variables
+          def::DefLocal(vid) => {
             Ok(Rc::new(cmt_ {
                 id: id,
                 span: span,
                 cat: cat_local(vid),
-                mutbl: MutabilityCategory::from_def(&def),
+                mutbl: MutabilityCategory::from_local(self.tcx(), vid),
                 ty: expr_ty
             }))
           }
@@ -1196,11 +1171,13 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
           cat_rvalue(..) => {
               "non-lvalue".to_string()
           }
-          cat_local(_) => {
-              "local variable".to_string()
-          }
-          cat_arg(..) => {
-              "argument".to_string()
+          cat_local(vid) => {
+              match self.tcx().map.find(vid) {
+                  Some(ast_map::NodeArg(_)) => {
+                      "argument".to_string()
+                  }
+                  _ => "local variable".to_string()
+              }
           }
           cat_deref(ref base, _, pk) => {
               match base.cat {
@@ -1267,7 +1244,6 @@ impl cmt_ {
             cat_static_item |
             cat_copied_upvar(..) |
             cat_local(..) |
-            cat_arg(..) |
             cat_deref(_, _, UnsafePtr(..)) |
             cat_deref(_, _, GcPtr(..)) |
             cat_deref(_, _, BorrowedPtr(..)) |
@@ -1311,7 +1287,6 @@ impl cmt_ {
             cat_rvalue(..) |
             cat_local(..) |
             cat_upvar(..) |
-            cat_arg(_) |
             cat_deref(_, _, UnsafePtr(..)) => { // yes, it's aliasable, but...
                 None
             }
@@ -1363,8 +1338,7 @@ impl Repr for categorization {
             cat_rvalue(..) |
             cat_copied_upvar(..) |
             cat_local(..) |
-            cat_upvar(..) |
-            cat_arg(..) => {
+            cat_upvar(..) => {
                 format!("{:?}", *self)
             }
             cat_deref(ref cmt, derefs, ptr) => {
diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs
index 8aac96a5410..36778e7cfc3 100644
--- a/src/librustc/middle/privacy.rs
+++ b/src/librustc/middle/privacy.rs
@@ -19,8 +19,8 @@ use middle::def;
 use lint;
 use middle::resolve;
 use middle::ty;
-use middle::typeck::{MethodCall, MethodMap, MethodOrigin, MethodParam};
-use middle::typeck::{MethodStatic, MethodStaticUnboxedClosure, MethodObject};
+use middle::typeck::{MethodCall, MethodMap, MethodOrigin, MethodParam, MethodTypeParam};
+use middle::typeck::{MethodStatic, MethodStaticUnboxedClosure, MethodObject, MethodTraitObject};
 use util::nodemap::{NodeMap, NodeSet};
 
 use syntax::ast;
@@ -829,8 +829,8 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
             MethodStaticUnboxedClosure(_) => {}
             // Trait methods are always all public. The only controlling factor
             // is whether the trait itself is accessible or not.
-            MethodParam(MethodParam { trait_ref: ref trait_ref, .. }) |
-            MethodObject(MethodObject { trait_ref: ref trait_ref, .. }) => {
+            MethodTypeParam(MethodParam { trait_ref: ref trait_ref, .. }) |
+            MethodTraitObject(MethodObject { trait_ref: ref trait_ref, .. }) => {
                 self.report_error(self.ensure_public(span, trait_ref.def_id,
                                                      None, "source trait"));
             }
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 6fa33f4b5aa..11ea84c75d3 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -19,7 +19,8 @@ use middle::lang_items::LanguageItems;
 use middle::pat_util::pat_bindings;
 use middle::subst::{ParamSpace, FnSpace, TypeSpace};
 use middle::ty::{ExplicitSelfCategory, StaticExplicitSelfCategory};
-use util::nodemap::{NodeMap, DefIdSet, FnvHashMap};
+use middle::ty::{CaptureModeMap, Freevar, FreevarMap};
+use util::nodemap::{NodeMap, NodeSet, DefIdSet, FnvHashMap};
 
 use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block, Crate, CrateNum};
 use syntax::ast::{DeclItem, DefId, Expr, ExprAgain, ExprBreak, ExprField};
@@ -28,7 +29,7 @@ use syntax::ast::{ExprPath, ExprProc, ExprStruct, ExprUnboxedFn, FnDecl};
 use syntax::ast::{ForeignItem, ForeignItemFn, ForeignItemStatic, Generics};
 use syntax::ast::{Ident, ImplItem, Item, ItemEnum, ItemFn, ItemForeignMod};
 use syntax::ast::{ItemImpl, ItemMac, ItemMod, ItemStatic, ItemStruct};
-use syntax::ast::{ItemTrait, ItemTy, LOCAL_CRATE, Local, Method};
+use syntax::ast::{ItemTrait, ItemTy, LOCAL_CRATE, Local};
 use syntax::ast::{MethodImplItem, Mod, Name, NamedField, NodeId};
 use syntax::ast::{Pat, PatEnum, PatIdent, PatLit};
 use syntax::ast::{PatRange, PatStruct, Path, PathListIdent, PathListMod};
@@ -59,7 +60,6 @@ use syntax::visit::Visitor;
 
 use std::collections::{HashMap, HashSet};
 use std::cell::{Cell, RefCell};
-use std::gc::GC;
 use std::mem::replace;
 use std::rc::{Rc, Weak};
 use std::uint;
@@ -270,16 +270,16 @@ enum TypeParameters<'a> {
         RibKind)
 }
 
-// The rib kind controls the translation of argument or local definitions
-// (`def_arg` or `def_local`) to upvars (`def_upvar`).
+// The rib kind controls the translation of local
+// definitions (`DefLocal`) to upvars (`DefUpvar`).
 
 enum RibKind {
     // No translation needs to be applied.
     NormalRibKind,
 
-    // We passed through a function scope at the given node ID. Translate
-    // upvars as appropriate.
-    FunctionRibKind(NodeId /* func id */, NodeId /* body id */),
+    // We passed through a closure scope at the given node ID.
+    // Translate upvars as appropriate.
+    ClosureRibKind(NodeId /* func id */, NodeId /* body id if proc or unboxed */),
 
     // We passed through an impl or trait and are now in one of its
     // methods. Allow references to ty params that impl or trait
@@ -891,6 +891,9 @@ struct Resolver<'a> {
     primitive_type_table: PrimitiveTypeTable,
 
     def_map: DefMap,
+    freevars: RefCell<FreevarMap>,
+    freevars_seen: RefCell<NodeMap<NodeSet>>,
+    capture_mode_map: RefCell<CaptureModeMap>,
     export_map2: ExportMap2,
     trait_map: TraitMap,
     external_exports: ExternalExports,
@@ -996,6 +999,9 @@ impl<'a> Resolver<'a> {
             primitive_type_table: PrimitiveTypeTable::new(),
 
             def_map: RefCell::new(NodeMap::new()),
+            freevars: RefCell::new(NodeMap::new()),
+            freevars_seen: RefCell::new(NodeMap::new()),
+            capture_mode_map: RefCell::new(NodeMap::new()),
             export_map2: RefCell::new(NodeMap::new()),
             trait_map: NodeMap::new(),
             used_imports: HashSet::new(),
@@ -1523,33 +1529,31 @@ impl<'a> Resolver<'a> {
     }
 
     // Constructs the reduced graph for one variant. Variants exist in the
-    // type and/or value namespaces.
+    // type and value namespaces.
     fn build_reduced_graph_for_variant(&mut self,
                                        variant: &Variant,
                                        item_id: DefId,
                                        parent: ReducedGraphParent,
                                        is_public: bool) {
         let ident = variant.node.name;
-
-        match variant.node.kind {
-            TupleVariantKind(_) => {
-                let child = self.add_child(ident, parent, ForbidDuplicateValues, variant.span);
-                child.define_value(DefVariant(item_id,
-                                              local_def(variant.node.id), false),
-                                   variant.span, is_public);
-            }
+        let is_exported = match variant.node.kind {
+            TupleVariantKind(_) => false,
             StructVariantKind(_) => {
-                let child = self.add_child(ident, parent,
-                                           ForbidDuplicateTypesAndValues,
-                                           variant.span);
-                child.define_type(DefVariant(item_id,
-                                             local_def(variant.node.id), true),
-                                  variant.span, is_public);
-
                 // Not adding fields for variants as they are not accessed with a self receiver
                 self.structs.insert(local_def(variant.node.id), Vec::new());
+                true
             }
-        }
+        };
+
+        let child = self.add_child(ident, parent,
+                                   ForbidDuplicateTypesAndValues,
+                                   variant.span);
+        child.define_value(DefVariant(item_id,
+                                      local_def(variant.node.id), is_exported),
+                           variant.span, is_public);
+        child.define_type(DefVariant(item_id,
+                                     local_def(variant.node.id), is_exported),
+                          variant.span, is_public);
     }
 
     /// Constructs the reduced graph for one 'view item'. View items consist
@@ -1895,8 +1899,7 @@ impl<'a> Resolver<'a> {
                       ignoring {:?}", def);
               // Ignored; handled elsewhere.
           }
-          DefArg(..) | DefLocal(..) | DefPrimTy(..) |
-          DefTyParam(..) | DefBinding(..) |
+          DefLocal(..) | DefPrimTy(..) | DefTyParam(..) |
           DefUse(..) | DefUpvar(..) | DefRegion(..) |
           DefTyParamBinder(..) | DefLabel(..) | DefSelfTy(..) => {
             fail!("didn't expect `{:?}`", def);
@@ -3828,130 +3831,143 @@ impl<'a> Resolver<'a> {
         self.current_module = orig_module;
     }
 
-    /// Wraps the given definition in the appropriate number of `def_upvar`
+    /// Wraps the given definition in the appropriate number of `DefUpvar`
     /// wrappers.
     fn upvarify(&self,
                 ribs: &[Rib],
-                rib_index: uint,
                 def_like: DefLike,
                 span: Span)
                 -> Option<DefLike> {
-        let mut def;
-        let is_ty_param;
-
         match def_like {
-            DlDef(d @ DefLocal(..)) | DlDef(d @ DefUpvar(..)) |
-            DlDef(d @ DefArg(..)) | DlDef(d @ DefBinding(..)) => {
-                def = d;
-                is_ty_param = false;
-            }
-            DlDef(d @ DefTyParam(..)) |
-            DlDef(d @ DefSelfTy(..)) => {
-                def = d;
-                is_ty_param = true;
-            }
-            _ => {
-                return Some(def_like);
-            }
-        }
+            DlDef(d @ DefUpvar(..)) => {
+                self.session.span_bug(span,
+                    format!("unexpected {} in bindings", d).as_slice())
+            }
+            DlDef(d @ DefLocal(_)) => {
+                let node_id = d.def_id().node;
+                let mut def = d;
+                let mut last_proc_body_id = ast::DUMMY_NODE_ID;
+                for rib in ribs.iter() {
+                    match rib.kind {
+                        NormalRibKind => {
+                            // Nothing to do. Continue.
+                        }
+                        ClosureRibKind(function_id, maybe_proc_body) => {
+                            let prev_def = def;
+                            if maybe_proc_body != ast::DUMMY_NODE_ID {
+                                last_proc_body_id = maybe_proc_body;
+                            }
+                            def = DefUpvar(node_id, function_id, last_proc_body_id);
 
-        let mut rib_index = rib_index + 1;
-        while rib_index < ribs.len() {
-            match ribs[rib_index].kind {
-                NormalRibKind => {
-                    // Nothing to do. Continue.
-                }
-                FunctionRibKind(function_id, body_id) => {
-                    if !is_ty_param {
-                        def = DefUpvar(def.def_id().node,
-                                       box(GC) def,
-                                       function_id,
-                                       body_id);
-                    }
-                }
-                MethodRibKind(item_id, _) => {
-                  // If the def is a ty param, and came from the parent
-                  // item, it's ok
-                  match def {
-                    DefTyParam(_, did, _) if {
-                        self.def_map.borrow().find(&did.node).map(|x| *x)
-                            == Some(DefTyParamBinder(item_id))
-                    } => {
-                      // ok
-                    }
+                            let mut seen = self.freevars_seen.borrow_mut();
+                            let seen = seen.find_or_insert(function_id, NodeSet::new());
+                            if seen.contains(&node_id) {
+                                continue;
+                            }
+                            self.freevars.borrow_mut().find_or_insert(function_id, vec![])
+                                         .push(Freevar { def: prev_def, span: span });
+                            seen.insert(node_id);
+                        }
+                        MethodRibKind(item_id, _) => {
+                            // If the def is a ty param, and came from the parent
+                            // item, it's ok
+                            match def {
+                                DefTyParam(_, did, _) if {
+                                    self.def_map.borrow().find_copy(&did.node)
+                                        == Some(DefTyParamBinder(item_id))
+                                } => {} // ok
+                                DefSelfTy(did) if did == item_id => {} // ok
+                                _ => {
+                                    // This was an attempt to access an upvar inside a
+                                    // named function item. This is not allowed, so we
+                                    // report an error.
 
-                    DefSelfTy(did) if {
-                        did == item_id
-                    } => {
-                      // ok
-                    }
+                                    self.resolve_error(
+                                        span,
+                                        "can't capture dynamic environment in a fn item; \
+                                        use the || { ... } closure form instead");
 
-                    _ => {
-                    if !is_ty_param {
-                        // This was an attempt to access an upvar inside a
-                        // named function item. This is not allowed, so we
-                        // report an error.
+                                    return None;
+                                }
+                            }
+                        }
+                        ItemRibKind => {
+                            // This was an attempt to access an upvar inside a
+                            // named function item. This is not allowed, so we
+                            // report an error.
 
-                        self.resolve_error(
-                            span,
-                            "can't capture dynamic environment in a fn item; \
-                            use the || { ... } closure form instead");
-                    } else {
-                        // This was an attempt to use a type parameter outside
-                        // its scope.
+                            self.resolve_error(
+                                span,
+                                "can't capture dynamic environment in a fn item; \
+                                use the || { ... } closure form instead");
 
-                        self.resolve_error(span,
-                                              "can't use type parameters from \
-                                              outer function; try using a local \
-                                              type parameter instead");
-                    }
+                            return None;
+                        }
+                        ConstantItemRibKind => {
+                            // Still doesn't deal with upvars
+                            self.resolve_error(span,
+                                               "attempt to use a non-constant \
+                                                value in a constant");
 
-                    return None;
+                        }
                     }
-                  }
                 }
-                ItemRibKind => {
-                    if !is_ty_param {
-                        // This was an attempt to access an upvar inside a
-                        // named function item. This is not allowed, so we
-                        // report an error.
+                Some(DlDef(def))
+            }
+            DlDef(def @ DefTyParam(..)) |
+            DlDef(def @ DefSelfTy(..)) => {
+                for rib in ribs.iter() {
+                    match rib.kind {
+                        NormalRibKind | ClosureRibKind(..) => {
+                            // Nothing to do. Continue.
+                        }
+                        MethodRibKind(item_id, _) => {
+                            // If the def is a ty param, and came from the parent
+                            // item, it's ok
+                            match def {
+                                DefTyParam(_, did, _) if {
+                                    self.def_map.borrow().find_copy(&did.node)
+                                        == Some(DefTyParamBinder(item_id))
+                                } => {} // ok
+                                DefSelfTy(did) if did == item_id => {} // ok
 
-                        self.resolve_error(
-                            span,
-                            "can't capture dynamic environment in a fn item; \
-                            use the || { ... } closure form instead");
-                    } else {
-                        // This was an attempt to use a type parameter outside
-                        // its scope.
+                                _ => {
+                                    // This was an attempt to use a type parameter outside
+                                    // its scope.
 
-                        self.resolve_error(span,
-                                              "can't use type parameters from \
-                                              outer function; try using a local \
-                                              type parameter instead");
-                    }
+                                    self.resolve_error(span,
+                                                        "can't use type parameters from \
+                                                        outer function; try using a local \
+                                                        type parameter instead");
 
-                    return None;
-                }
-                ConstantItemRibKind => {
-                    if is_ty_param {
-                        // see #9186
-                        self.resolve_error(span,
-                                              "cannot use an outer type \
-                                               parameter in this context");
-                    } else {
-                        // Still doesn't deal with upvars
-                        self.resolve_error(span,
-                                              "attempt to use a non-constant \
-                                               value in a constant");
-                    }
+                                    return None;
+                                }
+                            }
+                        }
+                        ItemRibKind => {
+                            // This was an attempt to use a type parameter outside
+                            // its scope.
+
+                            self.resolve_error(span,
+                                               "can't use type parameters from \
+                                                outer function; try using a local \
+                                                type parameter instead");
 
+                            return None;
+                        }
+                        ConstantItemRibKind => {
+                            // see #9186
+                            self.resolve_error(span,
+                                               "cannot use an outer type \
+                                                parameter in this context");
+
+                        }
+                    }
                 }
+                Some(DlDef(def))
             }
-
-            rib_index += 1;
+            _ => Some(def_like)
         }
-
-        return Some(DlDef(def));
     }
 
     fn search_ribs(&self,
@@ -3959,16 +3975,12 @@ impl<'a> Resolver<'a> {
                    name: Name,
                    span: Span)
                    -> Option<DefLike> {
-        // FIXME #4950: This should not use a while loop.
         // FIXME #4950: Try caching?
 
-        let mut i = ribs.len();
-        while i != 0 {
-            i -= 1;
-            let binding_opt = ribs[i].bindings.borrow().find_copy(&name);
-            match binding_opt {
+        for (i, rib) in ribs.iter().enumerate().rev() {
+            match rib.bindings.borrow().find_copy(&name) {
                 Some(def_like) => {
-                    return self.upvarify(ribs, i, def_like, span);
+                    return self.upvarify(ribs.slice_from(i + 1), def_like, span);
                 }
                 None => {
                     // Continue.
@@ -3976,7 +3988,7 @@ impl<'a> Resolver<'a> {
             }
         }
 
-        return None;
+        None
     }
 
     fn resolve_crate(&mut self, krate: &ast::Crate) {
@@ -4328,6 +4340,34 @@ impl<'a> Resolver<'a> {
                 self.resolve_trait_reference(id, tref, reference_type)
             }
             UnboxedFnTyParamBound(ref unboxed_function) => {
+                match self.resolve_path(unboxed_function.ref_id,
+                                        &unboxed_function.path,
+                                        TypeNS,
+                                        true) {
+                    None => {
+                        let path_str = self.path_idents_to_string(
+                            &unboxed_function.path);
+                        self.resolve_error(unboxed_function.path.span,
+                                           format!("unresolved trait `{}`",
+                                                   path_str).as_slice())
+                    }
+                    Some(def) => {
+                        match def {
+                            (DefTrait(_), _) => {
+                                self.record_def(unboxed_function.ref_id, def);
+                            }
+                            _ => {
+                                let msg =
+                                    format!("`{}` is not a trait",
+                                            self.path_idents_to_string(
+                                                &unboxed_function.path));
+                                self.resolve_error(unboxed_function.path.span,
+                                                   msg.as_slice());
+                            }
+                        }
+                    }
+                }
+
                 for argument in unboxed_function.decl.inputs.iter() {
                     self.resolve_type(&*argument.ty);
                 }
@@ -4471,7 +4511,7 @@ impl<'a> Resolver<'a> {
     // to be NormalRibKind?
     fn resolve_method(&mut self,
                       rib_kind: RibKind,
-                      method: &Method) {
+                      method: &ast::Method) {
         let method_generics = method.pe_generics();
         let type_parameters = HasTypeParameters(method_generics,
                                                 FnSpace,
@@ -4942,22 +4982,7 @@ impl<'a> Resolver<'a> {
                             debug!("(resolving pattern) binding `{}`",
                                    token::get_name(renamed));
 
-                            let def = match mode {
-                                RefutableMode => {
-                                    // For pattern arms, we must use
-                                    // `def_binding` definitions.
-
-                                    DefBinding(pattern.id, binding_mode)
-                                }
-                                LocalIrrefutableMode => {
-                                    // But for locals, we use `def_local`.
-                                    DefLocal(pattern.id, binding_mode)
-                                }
-                                ArgumentIrrefutableMode => {
-                                    // And for function arguments, `def_arg`.
-                                    DefArg(pattern.id, binding_mode)
-                                }
-                            };
+                            let def = DefLocal(pattern.id);
 
                             // Record the definition so that later passes
                             // will be able to distinguish variants from
@@ -5775,10 +5800,24 @@ impl<'a> Resolver<'a> {
                 visit::walk_expr(self, expr);
             }
 
-            ExprFnBlock(_, ref fn_decl, ref block) |
-            ExprProc(ref fn_decl, ref block) |
-            ExprUnboxedFn(_, _, ref fn_decl, ref block) => {
-                self.resolve_function(FunctionRibKind(expr.id, block.id),
+            ExprFnBlock(_, ref fn_decl, ref block) => {
+                // NOTE(stage0): After snapshot, change to:
+                //
+                //self.capture_mode_map.borrow_mut().insert(expr.id, capture_clause);
+                self.capture_mode_map.borrow_mut().insert(expr.id, ast::CaptureByRef);
+                self.resolve_function(ClosureRibKind(expr.id, ast::DUMMY_NODE_ID),
+                                      Some(&**fn_decl), NoTypeParameters,
+                                      &**block);
+            }
+            ExprProc(ref fn_decl, ref block) => {
+                self.capture_mode_map.borrow_mut().insert(expr.id, ast::CaptureByValue);
+                self.resolve_function(ClosureRibKind(expr.id, block.id),
+                                      Some(&**fn_decl), NoTypeParameters,
+                                      &**block);
+            }
+            ExprUnboxedFn(capture_clause, _, ref fn_decl, ref block) => {
+                self.capture_mode_map.borrow_mut().insert(expr.id, capture_clause);
+                self.resolve_function(ClosureRibKind(expr.id, block.id),
                                       Some(&**fn_decl), NoTypeParameters,
                                       &**block);
             }
@@ -6209,6 +6248,8 @@ impl<'a> Resolver<'a> {
 
 pub struct CrateMap {
     pub def_map: DefMap,
+    pub freevars: RefCell<FreevarMap>,
+    pub capture_mode_map: RefCell<CaptureModeMap>,
     pub exp_map2: ExportMap2,
     pub trait_map: TraitMap,
     pub external_exports: ExternalExports,
@@ -6222,13 +6263,13 @@ pub fn resolve_crate(session: &Session,
                   -> CrateMap {
     let mut resolver = Resolver::new(session, krate.span);
     resolver.resolve(krate);
-    let Resolver { def_map, export_map2, trait_map, last_private,
-                   external_exports, .. } = resolver;
     CrateMap {
-        def_map: def_map,
-        exp_map2: export_map2,
-        trait_map: trait_map,
-        external_exports: external_exports,
-        last_private_map: last_private,
+        def_map: resolver.def_map,
+        freevars: resolver.freevars,
+        capture_mode_map: resolver.capture_mode_map,
+        exp_map2: resolver.export_map2,
+        trait_map: resolver.trait_map,
+        external_exports: resolver.external_exports,
+        last_private_map: resolver.last_private,
     }
 }
diff --git a/src/librustc/middle/save/mod.rs b/src/librustc/middle/save/mod.rs
index cab83f4cda2..0f4ed202ec2 100644
--- a/src/librustc/middle/save/mod.rs
+++ b/src/librustc/middle/save/mod.rs
@@ -71,7 +71,7 @@ fn escape(s: String) -> String {
 
 // If the expression is a macro expansion or other generated code, run screaming and don't index.
 fn generated_code(span: Span) -> bool {
-    span.expn_info.is_some() || span  == DUMMY_SP
+    span.expn_id != NO_EXPANSION || span  == DUMMY_SP
 }
 
 struct DxrVisitor<'l, 'tcx: 'l> {
@@ -230,11 +230,9 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
             def::DefAssociatedTy(..) |
             def::DefTrait(_) => Some(recorder::TypeRef),
             def::DefStatic(_, _) |
-            def::DefBinding(_, _) |
-            def::DefArg(_, _) |
-            def::DefLocal(_, _) |
+            def::DefLocal(_) |
             def::DefVariant(_, _, _) |
-            def::DefUpvar(_, _, _, _) => Some(recorder::VarRef),
+            def::DefUpvar(..) => Some(recorder::VarRef),
 
             def::DefFn(_, _) => Some(recorder::FnRef),
 
@@ -739,20 +737,14 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
         let def = def_map.get(&ex.id);
         let sub_span = self.span.span_for_last_ident(ex.span);
         match *def {
-            def::DefLocal(id, _) |
-            def::DefArg(id, _) |
-            def::DefUpvar(id, _, _, _) |
-            def::DefBinding(id, _) => self.fmt.ref_str(recorder::VarRef,
-                                                       ex.span,
-                                                       sub_span,
-                                                       ast_util::local_def(id),
-                                                       self.cur_scope),
-            def::DefStatic(def_id,_) |
-            def::DefVariant(_, def_id, _) => self.fmt.ref_str(recorder::VarRef,
-                                                              ex.span,
-                                                              sub_span,
-                                                              def_id,
-                                                              self.cur_scope),
+            def::DefUpvar(..) |
+            def::DefLocal(..) |
+            def::DefStatic(..) |
+            def::DefVariant(..) => self.fmt.ref_str(recorder::VarRef,
+                                                    ex.span,
+                                                    sub_span,
+                                                    def.def_id(),
+                                                    self.cur_scope),
             def::DefStruct(def_id) => self.fmt.ref_str(recorder::StructRef,
                                                        ex.span,
                                                        sub_span,
@@ -813,8 +805,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
             def::DefStaticMethod(_, _, _) => {
                 self.write_sub_path_trait_truncated(path);
             },
-            def::DefLocal(_, _) |
-            def::DefArg(_, _) |
+            def::DefLocal(_) |
             def::DefStatic(_,_) |
             def::DefStruct(_) |
             def::DefFn(_, _) => self.write_sub_paths_truncated(path),
@@ -904,14 +895,14 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                 };
                 (Some(def_id), decl_id)
             }
-            typeck::MethodParam(ref mp) => {
+            typeck::MethodTypeParam(ref mp) => {
                 // method invoked on a type parameter
                 let trait_item = ty::trait_item(&self.analysis.ty_cx,
                                                 mp.trait_ref.def_id,
                                                 mp.method_num);
                 (None, Some(trait_item.def_id()))
             }
-            typeck::MethodObject(ref mo) => {
+            typeck::MethodTraitObject(ref mo) => {
                 // method invoked on a trait instance
                 let trait_item = ty::trait_item(&self.analysis.ty_cx,
                                                 mo.trait_ref.def_id,
@@ -1382,12 +1373,12 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
             }
             let def = def_map.get(&id);
             match *def {
-                def::DefBinding(id, _)  => self.fmt.variable_str(p.span,
-                                                                 sub_span,
-                                                                 id,
-                                                                 path_to_string(p).as_slice(),
-                                                                 value.as_slice(),
-                                                                 ""),
+                def::DefLocal(id)  => self.fmt.variable_str(p.span,
+                                                            sub_span,
+                                                            id,
+                                                            path_to_string(p).as_slice(),
+                                                            value.as_slice(),
+                                                            ""),
                 def::DefVariant(_,id,_) => self.fmt.ref_str(ref_kind,
                                                             p.span,
                                                             sub_span,
diff --git a/src/librustc/middle/save/span_utils.rs b/src/librustc/middle/save/span_utils.rs
index 57006d5e72b..1086dc608a3 100644
--- a/src/librustc/middle/save/span_utils.rs
+++ b/src/librustc/middle/save/span_utils.rs
@@ -57,7 +57,7 @@ impl<'a> SpanUtils<'a> {
                 Some(Span {
                     lo: base + self.sess.codemap().lookup_byte_offset(sub.lo).pos,
                     hi: base + self.sess.codemap().lookup_byte_offset(sub.hi).pos,
-                    expn_info: None,
+                    expn_id: NO_EXPANSION,
                 })
             }
         }
diff --git a/src/librustc/middle/traits/fulfill.rs b/src/librustc/middle/traits/fulfill.rs
index 22392f3f1c0..e7b1053b358 100644
--- a/src/librustc/middle/traits/fulfill.rs
+++ b/src/librustc/middle/traits/fulfill.rs
@@ -13,10 +13,10 @@ use middle::typeck::infer::{InferCtxt, skolemize};
 use util::nodemap::DefIdMap;
 use util::ppaux::Repr;
 
-use super::Ambiguity;
+use super::CodeAmbiguity;
 use super::Obligation;
 use super::FulfillmentError;
-use super::SelectionError;
+use super::CodeSelectionError;
 use super::select::SelectionContext;
 use super::Unimplemented;
 
@@ -78,7 +78,7 @@ impl FulfillmentContext {
         let errors: Vec<FulfillmentError> =
             self.trait_obligations
             .iter()
-            .map(|o| FulfillmentError::new((*o).clone(), Ambiguity))
+            .map(|o| FulfillmentError::new((*o).clone(), CodeAmbiguity))
             .collect();
 
         if errors.is_empty() {
@@ -129,7 +129,7 @@ impl FulfillmentContext {
 
                         errors.push(FulfillmentError::new(
                             (*obligation).clone(),
-                            SelectionError(selection_err)));
+                            CodeSelectionError(selection_err)));
                         false
                     }
                 }
@@ -237,7 +237,7 @@ impl FulfillmentContext {
             errors.push(
                 FulfillmentError::new(
                     (*obligation).clone(),
-                    SelectionError(Unimplemented)));
+                    CodeSelectionError(Unimplemented)));
         }
 
         if errors.is_empty() {
diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs
index 62b3c982ccd..dde733a6a3e 100644
--- a/src/librustc/middle/traits/mod.rs
+++ b/src/librustc/middle/traits/mod.rs
@@ -97,8 +97,8 @@ pub struct FulfillmentError {
 
 #[deriving(Clone)]
 pub enum FulfillmentErrorCode {
-    SelectionError(SelectionError),
-    Ambiguity,
+    CodeSelectionError(SelectionError),
+    CodeAmbiguity,
 }
 
 /**
@@ -110,7 +110,7 @@ pub enum FulfillmentErrorCode {
  *   to inconclusive type inference.
  * - `Err(e)`: error `e` occurred
  */
-pub type SelectionResult<T> = Result<Option<T>,SelectionError>;
+pub type SelectionResult<T> = Result<Option<T>, SelectionError>;
 
 #[deriving(PartialEq,Eq,Show)]
 pub enum EvaluationResult {
@@ -157,12 +157,12 @@ pub enum EvaluationResult {
  *
  * ### The type parameter `N`
  *
- * See explanation on `VtableImpl`.
+ * See explanation on `VtableImplData`.
  */
 #[deriving(Show,Clone)]
 pub enum Vtable<N> {
     /// Vtable identifying a particular impl.
-    VtableImpl(VtableImpl<N>),
+    VtableImpl(VtableImplData<N>),
 
     /// Vtable automatically generated for an unboxed closure. The def
     /// ID is the ID of the closure expression. This is a `VtableImpl`
@@ -172,7 +172,7 @@ pub enum Vtable<N> {
 
     /// Successful resolution to an obligation provided by the caller
     /// for some type parameter.
-    VtableParam(VtableParam),
+    VtableParam(VtableParamData),
 
     /// Successful resolution for a builtin trait.
     VtableBuiltin,
@@ -191,7 +191,7 @@ pub enum Vtable<N> {
  * impl, and nested obligations are satisfied later.
  */
 #[deriving(Clone)]
-pub struct VtableImpl<N> {
+pub struct VtableImplData<N> {
     pub impl_def_id: ast::DefId,
     pub substs: subst::Substs,
     pub nested: subst::VecPerParamSpace<N>
@@ -203,7 +203,7 @@ pub struct VtableImpl<N> {
  * on an instance of `T`, the vtable would be of type `VtableParam`.
  */
 #[deriving(Clone)]
-pub struct VtableParam {
+pub struct VtableParamData {
     // In the above example, this would `Eq`
     pub bound: Rc<ty::TraitRef>,
 }
@@ -274,7 +274,7 @@ pub fn select_inherent_impl(infcx: &InferCtxt,
                             cause: ObligationCause,
                             impl_def_id: ast::DefId,
                             self_ty: ty::t)
-                            -> SelectionResult<VtableImpl<Obligation>>
+                            -> SelectionResult<VtableImplData<Obligation>>
 {
     /*!
      * Matches the self type of the inherent impl `impl_def_id`
@@ -398,21 +398,21 @@ impl<N> Vtable<N> {
     }
 }
 
-impl<N> VtableImpl<N> {
+impl<N> VtableImplData<N> {
     pub fn map_nested<M>(&self,
                          op: |&N| -> M)
-                         -> VtableImpl<M>
+                         -> VtableImplData<M>
     {
-        VtableImpl {
+        VtableImplData {
             impl_def_id: self.impl_def_id,
             substs: self.substs.clone(),
             nested: self.nested.map(op)
         }
     }
 
-    pub fn map_move_nested<M>(self, op: |N| -> M) -> VtableImpl<M> {
-        let VtableImpl { impl_def_id, substs, nested } = self;
-        VtableImpl {
+    pub fn map_move_nested<M>(self, op: |N| -> M) -> VtableImplData<M> {
+        let VtableImplData { impl_def_id, substs, nested } = self;
+        VtableImplData {
             impl_def_id: impl_def_id,
             substs: substs,
             nested: nested.map_move(op)
diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs
index 681e2650f39..e475dc6063d 100644
--- a/src/librustc/middle/traits/select.rs
+++ b/src/librustc/middle/traits/select.rs
@@ -18,6 +18,7 @@ use super::{SelectionError, Unimplemented, Overflow,
 use super::{Selection};
 use super::{SelectionResult};
 use super::{VtableBuiltin, VtableImpl, VtableParam, VtableUnboxedClosure};
+use super::{VtableImplData, VtableParamData};
 use super::{util};
 
 use middle::subst::{Subst, Substs, VecPerParamSpace};
@@ -82,7 +83,7 @@ enum MatchResult<T> {
 enum Candidate {
     MatchedBuiltinCandidate,
     AmbiguousBuiltinCandidate,
-    MatchedParamCandidate(VtableParam),
+    MatchedParamCandidate(VtableParamData),
     AmbiguousParamCandidate,
     Impl(ImplCandidate),
     MatchedUnboxedClosureCandidate(/* closure */ ast::DefId)
@@ -142,7 +143,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                                 impl_def_id: ast::DefId,
                                 obligation_cause: ObligationCause,
                                 obligation_self_ty: ty::t)
-                                -> SelectionResult<VtableImpl<Obligation>>
+                                -> SelectionResult<VtableImplData<Obligation>>
     {
         debug!("select_inherent_impl(impl_def_id={}, obligation_self_ty={})",
                impl_def_id.repr(self.tcx()),
@@ -597,8 +598,8 @@ v         */
 
     fn confirm_param_candidate(&self,
                                obligation: &Obligation,
-                               param: VtableParam)
-                               -> Result<VtableParam,SelectionError>
+                               param: VtableParamData)
+                               -> Result<VtableParamData,SelectionError>
     {
         debug!("confirm_param_candidate({},{})",
                obligation.repr(self.tcx()),
@@ -613,7 +614,7 @@ v         */
     fn confirm_impl_candidate(&self,
                               obligation: &Obligation,
                               impl_def_id: ast::DefId)
-                              -> Result<VtableImpl<Obligation>,SelectionError>
+                              -> Result<VtableImplData<Obligation>,SelectionError>
     {
         debug!("confirm_impl_candidate({},{})",
                obligation.repr(self.tcx()),
@@ -642,7 +643,7 @@ v         */
                                        obligation_cause: ObligationCause,
                                        obligation_self_ty: ty::t,
                                        obligation_recursion_depth: uint)
-                                       -> Result<VtableImpl<Obligation>,
+                                       -> Result<VtableImplData<Obligation>,
                                                  SelectionError>
     {
         let substs = match self.match_impl_self_types(impl_def_id,
@@ -663,7 +664,7 @@ v         */
                                   obligation_recursion_depth,
                                   impl_def_id,
                                   &substs);
-        let vtable_impl = VtableImpl { impl_def_id: impl_def_id,
+        let vtable_impl = VtableImplData { impl_def_id: impl_def_id,
                                        substs: substs,
                                        nested: impl_obligations };
 
diff --git a/src/librustc/middle/traits/util.rs b/src/librustc/middle/traits/util.rs
index 1eae4ac1932..c48b125ac35 100644
--- a/src/librustc/middle/traits/util.rs
+++ b/src/librustc/middle/traits/util.rs
@@ -19,7 +19,7 @@ use syntax::ast;
 use syntax::codemap::Span;
 use util::ppaux::Repr;
 
-use super::{Obligation, ObligationCause, VtableImpl, VtableParam};
+use super::{Obligation, ObligationCause, VtableImpl, VtableParam, VtableParamData, VtableImplData};
 
 ///////////////////////////////////////////////////////////////////////////
 // Supertrait iterator
@@ -137,13 +137,13 @@ pub fn fresh_substs_for_impl(infcx: &InferCtxt,
     infcx.fresh_substs_for_generics(span, &impl_generics)
 }
 
-impl<N> fmt::Show for VtableImpl<N> {
+impl<N> fmt::Show for VtableImplData<N> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "VtableImpl({})", self.impl_def_id)
     }
 }
 
-impl fmt::Show for VtableParam {
+impl fmt::Show for VtableParamData {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "VtableParam(...)")
     }
@@ -239,7 +239,7 @@ pub fn obligation_for_builtin_bound(
 pub fn search_trait_and_supertraits_from_bound(tcx: &ty::ctxt,
                                                caller_bound: Rc<ty::TraitRef>,
                                                test: |ast::DefId| -> bool)
-                                               -> Option<VtableParam>
+                                               -> Option<VtableParamData>
 {
     /*!
      * Starting from a caller obligation `caller_bound` (which has
@@ -252,7 +252,7 @@ pub fn search_trait_and_supertraits_from_bound(tcx: &ty::ctxt,
 
     for bound in transitive_bounds(tcx, &[caller_bound]) {
         if test(bound.def_id) {
-            let vtable_param = VtableParam { bound: bound };
+            let vtable_param = VtableParamData { bound: bound };
             return Some(vtable_param);
         }
     }
@@ -287,7 +287,7 @@ impl<N:Repr> Repr for super::Vtable<N> {
     }
 }
 
-impl<N:Repr> Repr for super::VtableImpl<N> {
+impl<N:Repr> Repr for super::VtableImplData<N> {
     fn repr(&self, tcx: &ty::ctxt) -> String {
         format!("VtableImpl(impl_def_id={}, substs={}, nested={})",
                 self.impl_def_id.repr(tcx),
@@ -296,7 +296,7 @@ impl<N:Repr> Repr for super::VtableImpl<N> {
     }
 }
 
-impl Repr for super::VtableParam {
+impl Repr for super::VtableParamData {
     fn repr(&self, tcx: &ty::ctxt) -> String {
         format!("VtableParam(bound={})",
                 self.bound.repr(tcx))
@@ -331,8 +331,8 @@ impl Repr for super::FulfillmentError {
 impl Repr for super::FulfillmentErrorCode {
     fn repr(&self, tcx: &ty::ctxt) -> String {
         match *self {
-            super::SelectionError(ref o) => o.repr(tcx),
-            super::Ambiguity => format!("Ambiguity")
+            super::CodeSelectionError(ref o) => o.repr(tcx),
+            super::CodeAmbiguity => format!("Ambiguity")
         }
     }
 }
@@ -340,8 +340,8 @@ impl Repr for super::FulfillmentErrorCode {
 impl fmt::Show for super::FulfillmentErrorCode {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
-            super::SelectionError(ref e) => write!(f, "{}", e),
-            super::Ambiguity => write!(f, "Ambiguity")
+            super::CodeSelectionError(ref e) => write!(f, "{}", e),
+            super::CodeAmbiguity => write!(f, "Ambiguity")
         }
     }
 }
diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs
index 51023d03c23..68d0bb2d8b4 100644
--- a/src/librustc/middle/trans/_match.rs
+++ b/src/librustc/middle/trans/_match.rs
@@ -1226,8 +1226,7 @@ pub fn trans_match<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 fn is_discr_reassigned(bcx: Block, discr: &ast::Expr, body: &ast::Expr) -> bool {
     match discr.node {
         ast::ExprPath(..) => match bcx.def(discr.id) {
-            def::DefArg(vid, _) | def::DefBinding(vid, _) |
-            def::DefLocal(vid, _) | def::DefUpvar(vid, _, _, _) => {
+            def::DefLocal(vid) | def::DefUpvar(vid, _, _) => {
                 let mut rc = ReassignmentChecker {
                     node: vid,
                     reassigned: false
@@ -1259,7 +1258,7 @@ impl euv::Delegate for ReassignmentChecker {
     fn mutate(&mut self, _: ast::NodeId, _: Span, cmt: mc::cmt, _: euv::MutateMode) {
         match cmt.cat {
             mc::cat_copied_upvar(mc::CopiedUpvar { upvar_id: vid, .. }) |
-            mc::cat_arg(vid) | mc::cat_local(vid) => self.reassigned = self.node == vid,
+            mc::cat_local(vid) => self.reassigned = self.node == vid,
             _ => {}
         }
     }
@@ -1391,13 +1390,6 @@ fn trans_match_inner<'blk, 'tcx>(scope_cx: Block<'blk, 'tcx>,
     return bcx;
 }
 
-enum IrrefutablePatternBindingMode {
-    // Stores the association between node ID and LLVM value in `lllocals`.
-    BindLocal,
-    // Stores the association between node ID and LLVM value in `llargs`.
-    BindArgument
-}
-
 pub fn store_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                local: &ast::Local)
                                -> Block<'blk, 'tcx> {
@@ -1419,7 +1411,7 @@ pub fn store_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         pat_bindings(&tcx.def_map, pat, |_, p_id, _, path1| {
             let scope = cleanup::var_scope(tcx, p_id);
             bcx = mk_binding_alloca(
-                bcx, p_id, &path1.node, BindLocal, scope, (),
+                bcx, p_id, &path1.node, scope, (),
                 |(), bcx, llval, ty| { zero_mem(bcx, llval, ty); bcx });
         });
         bcx
@@ -1441,7 +1433,7 @@ pub fn store_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 Some(ident) => {
                     let var_scope = cleanup::var_scope(tcx, local.id);
                     return mk_binding_alloca(
-                        bcx, pat.id, ident, BindLocal, var_scope, (),
+                        bcx, pat.id, ident, var_scope, (),
                         |(), bcx, v, _| expr::trans_into(bcx, &**init_expr,
                                                          expr::SaveIn(v)));
                 }
@@ -1459,7 +1451,7 @@ pub fn store_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                     add_comment(bcx, "creating zeroable ref llval");
                 }
                 let var_scope = cleanup::var_scope(tcx, local.id);
-                bind_irrefutable_pat(bcx, pat, init_datum.val, BindLocal, var_scope)
+                bind_irrefutable_pat(bcx, pat, init_datum.val, var_scope)
             }
         }
         None => {
@@ -1475,7 +1467,7 @@ pub fn store_arg<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                              -> Block<'blk, 'tcx> {
     /*!
      * Generates code for argument patterns like `fn foo(<pat>: T)`.
-     * Creates entries in the `llargs` map for each of the bindings
+     * Creates entries in the `lllocals` map for each of the bindings
      * in `pat`.
      *
      * # Arguments
@@ -1499,12 +1491,12 @@ pub fn store_arg<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                 // already put it in a temporary alloca and gave it up, unless
                 // we emit extra-debug-info, which requires local allocas :(.
                 let arg_val = arg.add_clean(bcx.fcx, arg_scope);
-                bcx.fcx.llargs.borrow_mut()
+                bcx.fcx.lllocals.borrow_mut()
                    .insert(pat.id, Datum::new(arg_val, arg_ty, Lvalue));
                 bcx
             } else {
                 mk_binding_alloca(
-                    bcx, pat.id, ident, BindArgument, arg_scope, arg,
+                    bcx, pat.id, ident, arg_scope, arg,
                     |arg, bcx, llval, _| arg.store_to(bcx, llval))
             }
         }
@@ -1514,8 +1506,7 @@ pub fn store_arg<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
             // pattern.
             let arg = unpack_datum!(
                 bcx, arg.to_lvalue_datum_in_scope(bcx, "__arg", arg_scope));
-            bind_irrefutable_pat(bcx, pat, arg.val,
-                                 BindArgument, arg_scope)
+            bind_irrefutable_pat(bcx, pat, arg.val, arg_scope)
         }
     }
 }
@@ -1541,13 +1532,12 @@ pub fn store_for_loop_binding<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     }
 
     // General path. Copy out the values that are used in the pattern.
-    bind_irrefutable_pat(bcx, pat, llvalue, BindLocal, body_scope)
+    bind_irrefutable_pat(bcx, pat, llvalue, body_scope)
 }
 
 fn mk_binding_alloca<'blk, 'tcx, A>(bcx: Block<'blk, 'tcx>,
                                     p_id: ast::NodeId,
                                     ident: &ast::Ident,
-                                    binding_mode: IrrefutablePatternBindingMode,
                                     cleanup_scope: cleanup::ScopeId,
                                     arg: A,
                                     populate: |A, Block<'blk, 'tcx>, ValueRef, ty::t|
@@ -1567,18 +1557,13 @@ fn mk_binding_alloca<'blk, 'tcx, A>(bcx: Block<'blk, 'tcx>,
     // Now that memory is initialized and has cleanup scheduled,
     // create the datum and insert into the local variable map.
     let datum = Datum::new(llval, var_ty, Lvalue);
-    let mut llmap = match binding_mode {
-        BindLocal => bcx.fcx.lllocals.borrow_mut(),
-        BindArgument => bcx.fcx.llargs.borrow_mut()
-    };
-    llmap.insert(p_id, datum);
+    bcx.fcx.lllocals.borrow_mut().insert(p_id, datum);
     bcx
 }
 
 fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                     pat: &ast::Pat,
                                     val: ValueRef,
-                                    binding_mode: IrrefutablePatternBindingMode,
                                     cleanup_scope: cleanup::ScopeId)
                                     -> Block<'blk, 'tcx> {
     /*!
@@ -1594,13 +1579,11 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
      * - bcx: starting basic block context
      * - pat: the irrefutable pattern being matched.
      * - val: the value being matched -- must be an lvalue (by ref, with cleanup)
-     * - binding_mode: is this for an argument or a local variable?
      */
 
-    debug!("bind_irrefutable_pat(bcx={}, pat={}, binding_mode={:?})",
+    debug!("bind_irrefutable_pat(bcx={}, pat={})",
            bcx.to_str(),
-           pat.repr(bcx.tcx()),
-           binding_mode);
+           pat.repr(bcx.tcx()));
 
     if bcx.sess().asm_comments() {
         add_comment(bcx, format!("bind_irrefutable_pat(pat={})",
@@ -1620,7 +1603,7 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 // binding will live and place it into the appropriate
                 // map.
                 bcx = mk_binding_alloca(
-                    bcx, pat.id, &path1.node, binding_mode, cleanup_scope, (),
+                    bcx, pat.id, &path1.node, cleanup_scope, (),
                     |(), bcx, llval, ty| {
                         match pat_binding_mode {
                             ast::BindByValue(_) => {
@@ -1641,8 +1624,7 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             }
 
             for inner_pat in inner.iter() {
-                bcx = bind_irrefutable_pat(bcx, &**inner_pat, val,
-                                           binding_mode, cleanup_scope);
+                bcx = bind_irrefutable_pat(bcx, &**inner_pat, val, cleanup_scope);
             }
         }
         ast::PatEnum(_, ref sub_pats) => {
@@ -1660,8 +1642,7 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                     for sub_pat in sub_pats.iter() {
                         for (i, &argval) in args.vals.iter().enumerate() {
                             bcx = bind_irrefutable_pat(bcx, &**sub_pat.get(i),
-                                                       argval, binding_mode,
-                                                       cleanup_scope);
+                                                       argval, cleanup_scope);
                         }
                     }
                 }
@@ -1678,8 +1659,7 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                 let fldptr = adt::trans_field_ptr(bcx, &*repr,
                                                                   val, 0, i);
                                 bcx = bind_irrefutable_pat(bcx, &**elem,
-                                                           fldptr, binding_mode,
-                                                           cleanup_scope);
+                                                           fldptr, cleanup_scope);
                             }
                         }
                     }
@@ -1698,8 +1678,7 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                     let ix = ty::field_idx_strict(tcx, f.ident.name, field_tys);
                     let fldptr = adt::trans_field_ptr(bcx, &*pat_repr, val,
                                                       discr, ix);
-                    bcx = bind_irrefutable_pat(bcx, &*f.pat, fldptr,
-                                               binding_mode, cleanup_scope);
+                    bcx = bind_irrefutable_pat(bcx, &*f.pat, fldptr, cleanup_scope);
                 }
             })
         }
@@ -1707,17 +1686,16 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             let repr = adt::represent_node(bcx, pat.id);
             for (i, elem) in elems.iter().enumerate() {
                 let fldptr = adt::trans_field_ptr(bcx, &*repr, val, 0, i);
-                bcx = bind_irrefutable_pat(bcx, &**elem, fldptr,
-                                           binding_mode, cleanup_scope);
+                bcx = bind_irrefutable_pat(bcx, &**elem, fldptr, cleanup_scope);
             }
         }
         ast::PatBox(ref inner) => {
             let llbox = Load(bcx, val);
-            bcx = bind_irrefutable_pat(bcx, &**inner, llbox, binding_mode, cleanup_scope);
+            bcx = bind_irrefutable_pat(bcx, &**inner, llbox, cleanup_scope);
         }
         ast::PatRegion(ref inner) => {
             let loaded_val = Load(bcx, val);
-            bcx = bind_irrefutable_pat(bcx, &**inner, loaded_val, binding_mode, cleanup_scope);
+            bcx = bind_irrefutable_pat(bcx, &**inner, loaded_val, cleanup_scope);
         }
         ast::PatVec(ref before, ref slice, ref after) => {
             let pat_ty = node_id_type(bcx, pat.id);
@@ -1737,7 +1715,7 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 .chain(after.iter())
                 .zip(extracted.vals.into_iter())
                 .fold(bcx, |bcx, (inner, elem)|
-                    bind_irrefutable_pat(bcx, &**inner, elem, binding_mode, cleanup_scope)
+                    bind_irrefutable_pat(bcx, &**inner, elem, cleanup_scope)
                 );
         }
         ast::PatMac(..) => {
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index a814c9d624c..72e0401e7ab 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -191,21 +191,13 @@ pub fn decl_fn(ccx: &CrateContext, name: &str, cc: llvm::CallConv,
     match ty::get(output).sty {
         // functions returning bottom may unwind, but can never return normally
         ty::ty_bot => {
-            unsafe {
-                llvm::LLVMAddFunctionAttribute(llfn,
-                                               llvm::FunctionIndex as c_uint,
-                                               llvm::NoReturnAttribute as uint64_t)
-            }
+            llvm::SetFunctionAttribute(llfn, llvm::NoReturnAttribute)
         }
         _ => {}
     }
 
     if ccx.tcx().sess.opts.cg.no_redzone {
-        unsafe {
-            llvm::LLVMAddFunctionAttribute(llfn,
-                                           llvm::FunctionIndex as c_uint,
-                                           llvm::NoRedZoneAttribute as uint64_t)
-        }
+        llvm::SetFunctionAttribute(llfn, llvm::NoRedZoneAttribute)
     }
 
     llvm::SetFunctionCallConv(llfn, cc);
@@ -1468,7 +1460,6 @@ pub fn new_fn_ctxt<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>,
           needs_ret_allocas: nested_returns,
           personality: Cell::new(None),
           caller_expects_out_pointer: uses_outptr,
-          llargs: RefCell::new(NodeMap::new()),
           lllocals: RefCell::new(NodeMap::new()),
           llupvars: RefCell::new(NodeMap::new()),
           id: id,
diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs
index c54a446c455..53c13f56284 100644
--- a/src/librustc/middle/trans/callee.rs
+++ b/src/librustc/middle/trans/callee.rs
@@ -196,9 +196,7 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
                 }
             }
             def::DefStatic(..) |
-            def::DefArg(..) |
             def::DefLocal(..) |
-            def::DefBinding(..) |
             def::DefUpvar(..) => {
                 datum_callee(bcx, ref_expr)
             }
@@ -860,10 +858,10 @@ pub enum CallArgs<'a> {
     // value.
     ArgVals(&'a [ValueRef]),
 
-    // For overloaded operators: `(lhs, Option(rhs, rhs_id))`. `lhs`
+    // For overloaded operators: `(lhs, Vec(rhs, rhs_id))`. `lhs`
     // is the left-hand-side and `rhs/rhs_id` is the datum/expr-id of
-    // the right-hand-side (if any).
-    ArgOverloadedOp(Datum<Expr>, Option<(Datum<Expr>, ast::NodeId)>),
+    // the right-hand-side arguments (if any).
+    ArgOverloadedOp(Datum<Expr>, Vec<(Datum<Expr>, ast::NodeId)>),
 
     // Supply value of arguments as a list of expressions that must be
     // translated, for overloaded call operators.
@@ -1047,17 +1045,13 @@ pub fn trans_args<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
                                 DontAutorefArg)
             }));
 
-            match rhs {
-                Some((rhs, rhs_id)) => {
-                    assert_eq!(arg_tys.len(), 2);
-
-                    llargs.push(unpack_result!(bcx, {
-                        trans_arg_datum(bcx, *arg_tys.get(1), rhs,
-                                        arg_cleanup_scope,
-                                        DoAutorefArg(rhs_id))
-                    }));
-                }
-                None => assert_eq!(arg_tys.len(), 1)
+            assert_eq!(arg_tys.len(), 1 + rhs.len());
+            for (rhs, rhs_id) in rhs.move_iter() {
+                llargs.push(unpack_result!(bcx, {
+                    trans_arg_datum(bcx, *arg_tys.get(1), rhs,
+                                    arg_cleanup_scope,
+                                    DoAutorefArg(rhs_id))
+                }));
             }
         }
         ArgVals(vs) => {
diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs
index 6ab344ff69e..fa8c6b8b448 100644
--- a/src/librustc/middle/trans/closure.rs
+++ b/src/librustc/middle/trans/closure.rs
@@ -14,7 +14,7 @@ use back::link::mangle_internal_name_by_path_and_seq;
 use driver::config::FullDebugInfo;
 use llvm::ValueRef;
 use middle::def;
-use middle::freevars;
+use middle::mem_categorization::Typer;
 use middle::trans::adt;
 use middle::trans::base::*;
 use middle::trans::build::*;
@@ -100,7 +100,7 @@ use syntax::ast_util;
 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 pub struct EnvValue {
-    action: freevars::CaptureMode,
+    action: ast::CaptureClause,
     datum: Datum<Lvalue>
 }
 
@@ -120,8 +120,8 @@ pub fn mk_closure_tys(tcx: &ty::ctxt,
     // converted to ptrs.
     let bound_tys = bound_values.iter().map(|bv| {
         match bv.action {
-            freevars::CaptureByValue => bv.datum.ty,
-            freevars::CaptureByRef => ty::mk_mut_ptr(tcx, bv.datum.ty)
+            ast::CaptureByValue => bv.datum.ty,
+            ast::CaptureByRef => ty::mk_mut_ptr(tcx, bv.datum.ty)
         }
     }).collect();
     let cdata_ty = ty::mk_tup(tcx, bound_tys);
@@ -208,10 +208,10 @@ pub fn store_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         let bound_data = GEPi(bcx, llbox, [0u, abi::box_field_body, i]);
 
         match bv.action {
-            freevars::CaptureByValue => {
+            ast::CaptureByValue => {
                 bcx = bv.datum.store_to(bcx, bound_data);
             }
-            freevars::CaptureByRef => {
+            ast::CaptureByRef => {
                 Store(bcx, bv.datum.to_llref(), bound_data);
             }
         }
@@ -223,8 +223,8 @@ pub fn store_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 // Given a context and a list of upvars, build a closure. This just
 // collects the upvars and packages them up for store_environment.
 fn build_closure<'blk, 'tcx>(bcx0: Block<'blk, 'tcx>,
-                             freevar_mode: freevars::CaptureMode,
-                             freevars: &Vec<freevars::freevar_entry>,
+                             freevar_mode: ast::CaptureClause,
+                             freevars: &Vec<ty::Freevar>,
                              store: ty::TraitStore)
                              -> ClosureResult<'blk, 'tcx> {
     let _icx = push_ctxt("closure::build_closure");
@@ -247,7 +247,7 @@ fn build_closure<'blk, 'tcx>(bcx0: Block<'blk, 'tcx>,
 // with the upvars and type descriptors.
 fn load_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                 cdata_ty: ty::t,
-                                freevars: &Vec<freevars::freevar_entry>,
+                                freevars: &Vec<ty::Freevar>,
                                 store: ty::TraitStore)
                                 -> Block<'blk, 'tcx> {
     let _icx = push_ctxt("closure::load_environment");
@@ -301,7 +301,7 @@ fn load_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 fn load_unboxed_closure_environment<'blk, 'tcx>(
                                     bcx: Block<'blk, 'tcx>,
                                     arg_scope_id: ScopeId,
-                                    freevars: &Vec<freevars::freevar_entry>,
+                                    freevars: &Vec<ty::Freevar>,
                                     closure_id: ast::DefId)
                                     -> Block<'blk, 'tcx> {
     let _icx = push_ctxt("closure::load_environment");
@@ -386,11 +386,9 @@ pub fn trans_expr_fn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     // set an inline hint for all closures
     set_inline_hint(llfn);
 
-    let freevar_mode = freevars::get_capture_mode(tcx, id);
-    let freevars: Vec<freevars::freevar_entry> =
-        freevars::with_freevars(tcx,
-                                id,
-                                |fv| fv.iter().map(|&fv| fv).collect());
+    let freevar_mode = tcx.capture_mode(id);
+    let freevars: Vec<ty::Freevar> =
+        ty::with_freevars(tcx, id, |fv| fv.iter().map(|&fv| fv).collect());
 
     let ClosureResult {
         llbox,
@@ -476,10 +474,8 @@ pub fn trans_unboxed_closure<'blk, 'tcx>(
                                         .clone();
     let function_type = ty::mk_closure(bcx.tcx(), function_type);
 
-    let freevars: Vec<freevars::freevar_entry> =
-        freevars::with_freevars(bcx.tcx(),
-                                id,
-                                |fv| fv.iter().map(|&fv| fv).collect());
+    let freevars: Vec<ty::Freevar> =
+        ty::with_freevars(bcx.tcx(), id, |fv| fv.iter().map(|&fv| fv).collect());
     let freevars_ptr = &freevars;
 
     trans_closure(bcx.ccx(),
diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs
index 60ae26439b4..a5a9d685176 100644
--- a/src/librustc/middle/trans/common.rs
+++ b/src/librustc/middle/trans/common.rs
@@ -17,7 +17,6 @@ use llvm;
 use llvm::{ValueRef, BasicBlockRef, BuilderRef, ContextRef};
 use llvm::{True, False, Bool};
 use middle::def;
-use middle::freevars;
 use middle::lang_items::LangItem;
 use middle::mem_categorization as mc;
 use middle::subst;
@@ -267,10 +266,7 @@ pub struct FunctionContext<'a, 'tcx: 'a> {
     // points to, but if this value is false, that slot will be a local alloca.
     pub caller_expects_out_pointer: bool,
 
-    // Maps arguments to allocas created for them in llallocas.
-    pub llargs: RefCell<NodeMap<LvalueDatum>>,
-
-    // Maps the def_ids for local variables to the allocas created for
+    // Maps the DefId's for local variables to the allocas created for
     // them in llallocas.
     pub lllocals: RefCell<NodeMap<LvalueDatum>>,
 
@@ -528,7 +524,7 @@ impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> {
     }
 
     fn capture_mode(&self, closure_expr_id: ast::NodeId)
-                    -> freevars::CaptureMode {
+                    -> ast::CaptureClause {
         self.tcx().capture_modes.borrow().get_copy(&closure_expr_id)
     }
 }
diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs
index 576031500b9..d39fe4a1e70 100644
--- a/src/librustc/middle/trans/consts.rs
+++ b/src/librustc/middle/trans/consts.rs
@@ -207,7 +207,7 @@ pub fn const_expr(cx: &CrateContext, e: &ast::Expr, is_local: bool) -> (ValueRef
         None => { }
         Some(adj) => {
             match adj {
-                ty::AutoAddEnv(ty::RegionTraitStore(ty::ReStatic, _)) => {
+                ty::AdjustAddEnv(ty::RegionTraitStore(ty::ReStatic, _)) => {
                     let def = ty::resolve_expr(cx.tcx(), e);
                     let wrapper = closure::get_wrapper_for_bare_fn(cx,
                                                                    ety_adjusted,
@@ -216,13 +216,13 @@ pub fn const_expr(cx: &CrateContext, e: &ast::Expr, is_local: bool) -> (ValueRef
                                                                    is_local);
                     llconst = C_struct(cx, [wrapper, C_null(Type::i8p(cx))], false)
                 }
-                ty::AutoAddEnv(store) => {
+                ty::AdjustAddEnv(store) => {
                     cx.sess()
                       .span_bug(e.span,
                                 format!("unexpected static function: {:?}",
                                         store).as_slice())
                 }
-                ty::AutoDerefRef(ref adj) => {
+                ty::AdjustDerefRef(ref adj) => {
                     let mut ty = ety;
                     // Save the last autoderef in case we can avoid it.
                     if adj.autoderefs > 0 {
diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs
index 62571ef9f9b..1980d67fc47 100644
--- a/src/librustc/middle/trans/debuginfo.rs
+++ b/src/librustc/middle/trans/debuginfo.rs
@@ -664,7 +664,7 @@ pub struct FunctionDebugContext {
 }
 
 enum FunctionDebugContextRepr {
-    FunctionDebugContext(Box<FunctionDebugContextData>),
+    DebugInfo(Box<FunctionDebugContextData>),
     DebugInfoDisabled,
     FunctionWithoutDebugInfo,
 }
@@ -675,7 +675,7 @@ impl FunctionDebugContext {
                    span: Span)
                    -> &'a FunctionDebugContextData {
         match self.repr {
-            FunctionDebugContext(box ref data) => data,
+            DebugInfo(box ref data) => data,
             DebugInfoDisabled => {
                 cx.sess().span_bug(span,
                                    FunctionDebugContext::debuginfo_disabled_message());
@@ -999,11 +999,11 @@ pub fn create_argument_metadata(bcx: Block, arg: &ast::Arg) {
     let scope_metadata = bcx.fcx.debug_context.get_ref(cx, arg.pat.span).fn_metadata;
 
     pat_util::pat_bindings(def_map, &*arg.pat, |_, node_id, span, path1| {
-        let llarg = match bcx.fcx.llargs.borrow().find_copy(&node_id) {
+        let llarg = match bcx.fcx.lllocals.borrow().find_copy(&node_id) {
             Some(v) => v,
             None => {
                 bcx.sess().span_bug(span,
-                    format!("no entry in llargs table for {:?}",
+                    format!("no entry in lllocals table for {:?}",
                             node_id).as_slice());
             }
         };
@@ -1044,7 +1044,7 @@ pub fn set_source_location(fcx: &FunctionContext,
             set_debug_location(fcx.ccx, UnknownLocation);
             return;
         }
-        FunctionDebugContext(box ref function_debug_context) => {
+        DebugInfo(box ref function_debug_context) => {
             let cx = fcx.ccx;
 
             debug!("set_source_location: {}", cx.sess().codemap().span_to_string(span));
@@ -1082,7 +1082,7 @@ pub fn clear_source_location(fcx: &FunctionContext) {
 /// first real statement/expression of the function is translated.
 pub fn start_emitting_source_locations(fcx: &FunctionContext) {
     match fcx.debug_context.repr {
-        FunctionDebugContext(box ref data) => {
+        DebugInfo(box ref data) => {
             data.source_locations_enabled.set(true)
         },
         _ => { /* safe to ignore */ }
@@ -1291,7 +1291,7 @@ pub fn create_function_debug_context(cx: &CrateContext,
                        fn_metadata,
                        &mut *fn_debug_context.scope_map.borrow_mut());
 
-    return FunctionDebugContext { repr: FunctionDebugContext(fn_debug_context) };
+    return FunctionDebugContext { repr: DebugInfo(fn_debug_context) };
 
     fn get_function_signature(cx: &CrateContext,
                               fn_ast_id: ast::NodeId,
@@ -3134,7 +3134,7 @@ fn DIB(cx: &CrateContext) -> DIBuilderRef {
 
 fn fn_should_be_ignored(fcx: &FunctionContext) -> bool {
     match fcx.debug_context.repr {
-        FunctionDebugContext(_) => false,
+        DebugInfo(_) => false,
         _ => true
     }
 }
@@ -3479,6 +3479,12 @@ fn populate_scope_map(cx: &CrateContext,
                 walk_expr(cx, &**rhs, scope_stack, scope_map);
             }
 
+            ast::ExprSlice(ref base, ref start, ref end, _) => {
+                walk_expr(cx, &**base, scope_stack, scope_map);
+                start.as_ref().map(|x| walk_expr(cx, &**x, scope_stack, scope_map));
+                end.as_ref().map(|x| walk_expr(cx, &**x, scope_stack, scope_map));
+            }
+
             ast::ExprVec(ref init_expressions) |
             ast::ExprTup(ref init_expressions) => {
                 for ie in init_expressions.iter() {
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index 77712570185..75c28477414 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -64,14 +64,13 @@ use middle::trans::inline;
 use middle::trans::tvec;
 use middle::trans::type_of;
 use middle::ty::{struct_fields, tup_fields};
-use middle::ty::{AutoDerefRef, AutoAddEnv, AutoUnsafe};
+use middle::ty::{AdjustDerefRef, AdjustAddEnv, AutoUnsafe};
 use middle::ty::{AutoPtr};
 use middle::ty;
 use middle::typeck;
 use middle::typeck::MethodCall;
 use util::common::indenter;
 use util::ppaux::Repr;
-use util::nodemap::NodeMap;
 use middle::trans::machine::{llsize_of, llsize_of_alloc};
 use middle::trans::type_::Type;
 
@@ -190,10 +189,10 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     debug!("unadjusted datum for expr {}: {}",
            expr.id, datum.to_string(bcx.ccx()));
     match adjustment {
-        AutoAddEnv(..) => {
+        AdjustAddEnv(..) => {
             datum = unpack_datum!(bcx, add_env(bcx, expr, datum));
         }
-        AutoDerefRef(ref adj) => {
+        AdjustDerefRef(ref adj) => {
             let (autoderefs, use_autoref) = match adj.autoref {
                 // Extracting a value from a box counts as a deref, but if we are
                 // just converting Box<[T, ..n]> to Box<[T]> we aren't really doing
@@ -590,6 +589,34 @@ fn trans_datum_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         ast::ExprIndex(ref base, ref idx) => {
             trans_index(bcx, expr, &**base, &**idx, MethodCall::expr(expr.id))
         }
+        ast::ExprSlice(ref base, ref start, ref end, _) => {
+            let _icx = push_ctxt("trans_slice");
+            let ccx = bcx.ccx();
+
+            let method_call = MethodCall::expr(expr.id);
+            let method_ty = ccx.tcx()
+                               .method_map
+                               .borrow()
+                               .find(&method_call)
+                               .map(|method| method.ty);
+            let base_datum = unpack_datum!(bcx, trans(bcx, &**base));
+
+            let mut args = vec![];
+            start.as_ref().map(|e| args.push((unpack_datum!(bcx, trans(bcx, &**e)), e.id)));
+            end.as_ref().map(|e| args.push((unpack_datum!(bcx, trans(bcx, &**e)), e.id)));
+
+            let result_ty = ty::ty_fn_ret(monomorphize_type(bcx, method_ty.unwrap()));
+            let scratch = rvalue_scratch_datum(bcx, result_ty, "trans_slice");
+
+            unpack_result!(bcx,
+                           trans_overloaded_op(bcx,
+                                               expr,
+                                               method_call,
+                                               base_datum,
+                                               args,
+                                               Some(SaveIn(scratch.val))));
+            DatumBlock::new(bcx, scratch.to_expr_datum())
+        }
         ast::ExprBox(_, ref contents) => {
             // Special case for `Box<T>` and `Gc<T>`
             let box_ty = expr_ty(bcx, expr);
@@ -725,7 +752,7 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                                    index_expr,
                                                    method_call,
                                                    base_datum,
-                                                   Some((ix_datum, idx.id)),
+                                                   vec![(ix_datum, idx.id)],
                                                    None));
             let ref_ty = ty::ty_fn_ret(monomorphize_type(bcx, method_ty));
             let elt_ty = match ty::deref(ref_ty, true) {
@@ -1044,20 +1071,20 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             let lhs = unpack_datum!(bcx, trans(bcx, &**lhs));
             let rhs_datum = unpack_datum!(bcx, trans(bcx, &**rhs));
             trans_overloaded_op(bcx, expr, MethodCall::expr(expr.id), lhs,
-                                Some((rhs_datum, rhs.id)), Some(dest)).bcx
+                                vec![(rhs_datum, rhs.id)], Some(dest)).bcx
         }
         ast::ExprUnary(_, ref subexpr) => {
             // if not overloaded, would be RvalueDatumExpr
             let arg = unpack_datum!(bcx, trans(bcx, &**subexpr));
             trans_overloaded_op(bcx, expr, MethodCall::expr(expr.id),
-                                arg, None, Some(dest)).bcx
+                                arg, Vec::new(), Some(dest)).bcx
         }
         ast::ExprIndex(ref base, ref idx) => {
             // if not overloaded, would be RvalueDatumExpr
             let base = unpack_datum!(bcx, trans(bcx, &**base));
             let idx_datum = unpack_datum!(bcx, trans(bcx, &**idx));
             trans_overloaded_op(bcx, expr, MethodCall::expr(expr.id), base,
-                                Some((idx_datum, idx.id)), Some(dest)).bcx
+                                vec![(idx_datum, idx.id)], Some(dest)).bcx
         }
         ast::ExprCast(ref val, _) => {
             // DPS output mode means this is a trait cast:
@@ -1176,8 +1203,8 @@ pub fn trans_local_var<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
     let _icx = push_ctxt("trans_local_var");
 
-    return match def {
-        def::DefUpvar(nid, _, _, _) => {
+    match def {
+        def::DefUpvar(nid, _, _) => {
             // Can't move upvars, so this is never a ZeroMemLastUse.
             let local_ty = node_id_type(bcx, nid);
             match bcx.fcx.llupvars.borrow().find(&nid) {
@@ -1189,34 +1216,24 @@ pub fn trans_local_var<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 }
             }
         }
-        def::DefArg(nid, _) => {
-            take_local(bcx, &*bcx.fcx.llargs.borrow(), nid)
-        }
-        def::DefLocal(nid, _) | def::DefBinding(nid, _) => {
-            take_local(bcx, &*bcx.fcx.lllocals.borrow(), nid)
+        def::DefLocal(nid) => {
+            let datum = match bcx.fcx.lllocals.borrow().find(&nid) {
+                Some(&v) => v,
+                None => {
+                    bcx.sess().bug(format!(
+                        "trans_local_var: no datum for local/arg {:?} found",
+                        nid).as_slice());
+                }
+            };
+            debug!("take_local(nid={:?}, v={}, ty={})",
+                   nid, bcx.val_to_string(datum.val), bcx.ty_to_string(datum.ty));
+            datum
         }
         _ => {
             bcx.sess().unimpl(format!(
                 "unsupported def type in trans_local_var: {:?}",
                 def).as_slice());
         }
-    };
-
-    fn take_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
-                              table: &NodeMap<Datum<Lvalue>>,
-                              nid: ast::NodeId)
-                              -> Datum<Lvalue> {
-        let datum = match table.find(&nid) {
-            Some(&v) => v,
-            None => {
-                bcx.sess().bug(format!(
-                    "trans_local_var: no datum for local/arg {:?} found",
-                    nid).as_slice());
-            }
-        };
-        debug!("take_local(nid={:?}, v={}, ty={})",
-               nid, bcx.val_to_string(datum.val), bcx.ty_to_string(datum.ty));
-        datum
     }
 }
 
@@ -1751,7 +1768,7 @@ fn trans_overloaded_op<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                    expr: &ast::Expr,
                                    method_call: MethodCall,
                                    lhs: Datum<Expr>,
-                                   rhs: Option<(Datum<Expr>, ast::NodeId)>,
+                                   rhs: Vec<(Datum<Expr>, ast::NodeId)>,
                                    dest: Option<Dest>)
                                    -> Result<'blk, 'tcx> {
     let method_ty = bcx.tcx().method_map.borrow().get(&method_call).ty;
@@ -2074,7 +2091,7 @@ fn deref_once<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             let scratch = rvalue_scratch_datum(bcx, ref_ty, "overloaded_deref");
 
             unpack_result!(bcx, trans_overloaded_op(bcx, expr, method_call,
-                                                    datum, None, Some(SaveIn(scratch.val))));
+                                                    datum, Vec::new(), Some(SaveIn(scratch.val))));
             scratch.to_expr_datum()
         }
         None => {
diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs
index f3049dcee50..9cff7261806 100644
--- a/src/librustc/middle/trans/foreign.rs
+++ b/src/librustc/middle/trans/foreign.rs
@@ -998,7 +998,7 @@ fn add_argument_attributes(tys: &ForeignTypes,
 
     match tys.fn_ty.ret_ty.attr {
         Some(attr) => unsafe {
-            llvm::LLVMAddFunctionAttribute(llfn, i as c_uint, attr as u64);
+            llvm::LLVMAddFunctionAttribute(llfn, i as c_uint, attr.bits() as u64);
         },
         None => {}
     }
@@ -1014,7 +1014,7 @@ fn add_argument_attributes(tys: &ForeignTypes,
 
         match arg_ty.attr {
             Some(attr) => unsafe {
-                llvm::LLVMAddFunctionAttribute(llfn, i as c_uint, attr as u64);
+                llvm::LLVMAddFunctionAttribute(llfn, i as c_uint, attr.bits() as u64);
             },
             None => ()
         }
diff --git a/src/librustc/middle/trans/intrinsic.rs b/src/librustc/middle/trans/intrinsic.rs
index 36184b2eed3..3b3d7d02a2c 100644
--- a/src/librustc/middle/trans/intrinsic.rs
+++ b/src/librustc/middle/trans/intrinsic.rs
@@ -11,7 +11,7 @@
 #![allow(non_uppercase_statics)]
 
 use llvm;
-use llvm::{SequentiallyConsistent, Acquire, Release, Xchg, ValueRef};
+use llvm::{SequentiallyConsistent, Acquire, Release, AtomicXchg, ValueRef};
 use middle::subst;
 use middle::subst::FnSpace;
 use middle::trans::base::*;
@@ -510,17 +510,17 @@ pub fn trans_intrinsic_call<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, node: ast::N
                 // These are all AtomicRMW ops
                 op => {
                     let atom_op = match op {
-                        "xchg"  => llvm::Xchg,
-                        "xadd"  => llvm::Add,
-                        "xsub"  => llvm::Sub,
-                        "and"   => llvm::And,
-                        "nand"  => llvm::Nand,
-                        "or"    => llvm::Or,
-                        "xor"   => llvm::Xor,
-                        "max"   => llvm::Max,
-                        "min"   => llvm::Min,
-                        "umax"  => llvm::UMax,
-                        "umin"  => llvm::UMin,
+                        "xchg"  => llvm::AtomicXchg,
+                        "xadd"  => llvm::AtomicAdd,
+                        "xsub"  => llvm::AtomicSub,
+                        "and"   => llvm::AtomicAnd,
+                        "nand"  => llvm::AtomicNand,
+                        "or"    => llvm::AtomicOr,
+                        "xor"   => llvm::AtomicXor,
+                        "max"   => llvm::AtomicMax,
+                        "min"   => llvm::AtomicMin,
+                        "umax"  => llvm::AtomicUMax,
+                        "umin"  => llvm::AtomicUMin,
                         _ => ccx.sess().fatal("unknown atomic operation")
                     };
 
diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs
index f1276387745..844ee0a60c6 100644
--- a/src/librustc/middle/trans/meth.rs
+++ b/src/librustc/middle/trans/meth.rs
@@ -131,7 +131,7 @@ pub fn trans_method_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             }
         }
 
-        typeck::MethodParam(typeck::MethodParam {
+        typeck::MethodTypeParam(typeck::MethodParam {
             trait_ref: ref trait_ref,
             method_num: method_num
         }) => {
@@ -147,7 +147,7 @@ pub fn trans_method_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                        method_num, origin)
         }
 
-        typeck::MethodObject(ref mt) => {
+        typeck::MethodTraitObject(ref mt) => {
             let self_expr = match self_expr {
                 Some(self_expr) => self_expr,
                 None => {
@@ -243,7 +243,7 @@ pub fn trans_static_method_callee(bcx: Block,
     // Now that we know which impl is being used, we can dispatch to
     // the actual function:
     match vtbl {
-        traits::VtableImpl(traits::VtableImpl {
+        traits::VtableImpl(traits::VtableImplData {
             impl_def_id: impl_did,
             substs: impl_substs,
             nested: _ }) =>
@@ -562,7 +562,7 @@ pub fn get_vtable(bcx: Block,
                                         trait_ref.clone());
         match vtable {
             traits::VtableImpl(
-                traits::VtableImpl {
+                traits::VtableImplData {
                     impl_def_id: id,
                     substs: substs,
                     nested: _ }) => {
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 897bc4517f4..33ade80afd3 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -17,8 +17,6 @@ use metadata::csearch;
 use middle::const_eval;
 use middle::def;
 use middle::dependency_format;
-use middle::freevars::CaptureModeMap;
-use middle::freevars;
 use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem};
 use middle::lang_items::{FnOnceTraitLangItem, OpaqueStructLangItem};
 use middle::lang_items::{TyDescStructLangItem, TyVisitorTraitLangItem};
@@ -279,8 +277,8 @@ pub enum Variance {
 
 #[deriving(Clone)]
 pub enum AutoAdjustment {
-    AutoAddEnv(ty::TraitStore),
-    AutoDerefRef(AutoDerefRef)
+    AdjustAddEnv(ty::TraitStore),
+    AdjustDerefRef(AutoDerefRef)
 }
 
 #[deriving(Clone, PartialEq)]
@@ -352,7 +350,7 @@ fn autoref_object_region(autoref: &AutoRef) -> (bool, bool, Option<Region>) {
 // returns the region of the borrowed reference.
 pub fn adjusted_object_region(adj: &AutoAdjustment) -> Option<Region> {
     match adj {
-        &AutoDerefRef(AutoDerefRef{autoref: Some(ref autoref), ..}) => {
+        &AdjustDerefRef(AutoDerefRef{autoref: Some(ref autoref), ..}) => {
             let (b, _, r) = autoref_object_region(autoref);
             if b {
                 r
@@ -367,7 +365,7 @@ pub fn adjusted_object_region(adj: &AutoAdjustment) -> Option<Region> {
 // Returns true if there is a trait cast at the bottom of the adjustment.
 pub fn adjust_is_object(adj: &AutoAdjustment) -> bool {
     match adj {
-        &AutoDerefRef(AutoDerefRef{autoref: Some(ref autoref), ..}) => {
+        &AdjustDerefRef(AutoDerefRef{autoref: Some(ref autoref), ..}) => {
             let (b, _, _) = autoref_object_region(autoref);
             b
         }
@@ -409,7 +407,7 @@ pub fn type_of_adjust(cx: &ctxt, adj: &AutoAdjustment) -> Option<t> {
     }
 
     match adj {
-        &AutoDerefRef(AutoDerefRef{autoref: Some(ref autoref), ..}) => {
+        &AdjustDerefRef(AutoDerefRef{autoref: Some(ref autoref), ..}) => {
             type_of_autoref(cx, autoref)
         }
         _ => None
@@ -480,7 +478,7 @@ pub struct ctxt<'tcx> {
 
     pub map: ast_map::Map<'tcx>,
     pub intrinsic_defs: RefCell<DefIdMap<t>>,
-    pub freevars: RefCell<freevars::freevar_map>,
+    pub freevars: RefCell<FreevarMap>,
     pub tcache: type_cache,
     pub rcache: creader_cache,
     pub short_names_cache: RefCell<HashMap<t, String>>,
@@ -1463,8 +1461,8 @@ pub fn mk_ctxt<'tcx>(s: Session,
                      dm: resolve::DefMap,
                      named_region_map: resolve_lifetime::NamedRegionMap,
                      map: ast_map::Map<'tcx>,
-                     freevars: freevars::freevar_map,
-                     capture_modes: freevars::CaptureModeMap,
+                     freevars: RefCell<FreevarMap>,
+                     capture_modes: RefCell<CaptureModeMap>,
                      region_maps: middle::region::RegionMaps,
                      lang_items: middle::lang_items::LanguageItems,
                      stability: stability::Index) -> ctxt<'tcx> {
@@ -1485,7 +1483,7 @@ pub fn mk_ctxt<'tcx>(s: Session,
         object_cast_map: RefCell::new(NodeMap::new()),
         map: map,
         intrinsic_defs: RefCell::new(DefIdMap::new()),
-        freevars: RefCell::new(freevars),
+        freevars: freevars,
         tcache: RefCell::new(DefIdMap::new()),
         rcache: RefCell::new(HashMap::new()),
         short_names_cache: RefCell::new(HashMap::new()),
@@ -1522,7 +1520,7 @@ pub fn mk_ctxt<'tcx>(s: Session,
         node_lint_levels: RefCell::new(HashMap::new()),
         transmute_restrictions: RefCell::new(Vec::new()),
         stability: RefCell::new(stability),
-        capture_modes: RefCell::new(capture_modes),
+        capture_modes: capture_modes,
         associated_types: RefCell::new(DefIdMap::new()),
         trait_associated_types: RefCell::new(DefIdMap::new()),
     }
@@ -3425,7 +3423,7 @@ pub fn adjust_ty(cx: &ctxt,
     return match adjustment {
         Some(adjustment) => {
             match *adjustment {
-                AutoAddEnv(store) => {
+                AdjustAddEnv(store) => {
                     match ty::get(unadjusted_ty).sty {
                         ty::ty_bare_fn(ref b) => {
                             let bounds = ty::ExistentialBounds {
@@ -3451,7 +3449,7 @@ pub fn adjust_ty(cx: &ctxt,
                     }
                 }
 
-                AutoDerefRef(ref adj) => {
+                AdjustDerefRef(ref adj) => {
                     let mut adjusted_ty = unadjusted_ty;
 
                     if !ty::type_is_error(adjusted_ty) {
@@ -3584,12 +3582,12 @@ pub fn method_call_type_param_defs<'tcx, T>(typer: &T,
                               .trait_did(typer.tcx());
             lookup_trait_def(typer.tcx(), def_id).generics.types.clone()
         }
-        typeck::MethodParam(typeck::MethodParam{
+        typeck::MethodTypeParam(typeck::MethodParam{
             trait_ref: ref trait_ref,
             method_num: n_mth,
             ..
         }) |
-        typeck::MethodObject(typeck::MethodObject{
+        typeck::MethodTraitObject(typeck::MethodObject{
                 trait_ref: ref trait_ref,
                 method_num: n_mth,
                 ..
@@ -3648,6 +3646,9 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
             // the index method invoked for `a[i]` always yields an `&T`
             ast::ExprIndex(..) => LvalueExpr,
 
+            // the slice method invoked for `a[..]` always yields an `&T`
+            ast::ExprSlice(..) => LvalueExpr,
+
             // `for` loops are statements
             ast::ExprForLoop(..) => RvalueStmtExpr,
 
@@ -3684,9 +3685,7 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
                 // DefArg's, particularly those of immediate type, ought to
                 // considered rvalues.
                 def::DefStatic(..) |
-                def::DefBinding(..) |
                 def::DefUpvar(..) |
-                def::DefArg(..) |
                 def::DefLocal(..) => LvalueExpr,
 
                 def => {
@@ -3702,7 +3701,8 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
         ast::ExprUnary(ast::UnDeref, _) |
         ast::ExprField(..) |
         ast::ExprTupField(..) |
-        ast::ExprIndex(..) => {
+        ast::ExprIndex(..) |
+        ast::ExprSlice(..) => {
             LvalueExpr
         }
 
@@ -4759,7 +4759,7 @@ pub fn unboxed_closure_upvars(tcx: &ctxt, closure_id: ast::DefId)
                               -> Vec<UnboxedClosureUpvar> {
     if closure_id.krate == ast::LOCAL_CRATE {
         match tcx.freevars.borrow().find(&closure_id.node) {
-            None => tcx.sess.bug("no freevars for unboxed closure?!"),
+            None => vec![],
             Some(ref freevars) => {
                 freevars.iter().map(|freevar| {
                     let freevar_def_id = freevar.def.def_id();
@@ -5617,7 +5617,7 @@ impl<'tcx> mc::Typer<'tcx> for ty::ctxt<'tcx> {
     }
 
     fn capture_mode(&self, closure_expr_id: ast::NodeId)
-                    -> freevars::CaptureMode {
+                    -> ast::CaptureClause {
         self.capture_modes.borrow().get_copy(&closure_expr_id)
     }
 
@@ -5688,3 +5688,24 @@ pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec<ty::Region>,
         }
     })
 }
+
+/// A free variable referred to in a function.
+#[deriving(Encodable, Decodable)]
+pub struct Freevar {
+    /// The variable being accessed free.
+    pub def: def::Def,
+
+    // First span where it is accessed (there can be multiple).
+    pub span: Span
+}
+
+pub type FreevarMap = NodeMap<Vec<Freevar>>;
+
+pub type CaptureModeMap = NodeMap<ast::CaptureClause>;
+
+pub fn with_freevars<T>(tcx: &ty::ctxt, fid: ast::NodeId, f: |&[Freevar]| -> T) -> T {
+    match tcx.freevars.borrow().find(&fid) {
+        None => f(&[]),
+        Some(d) => f(d.as_slice())
+    }
+}
diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs
index 3b08ccd5a7b..2e964c457bf 100644
--- a/src/librustc/middle/ty_fold.rs
+++ b/src/librustc/middle/ty_fold.rs
@@ -353,9 +353,9 @@ impl TypeFoldable for traits::Obligation {
     }
 }
 
-impl<N:TypeFoldable> TypeFoldable for traits::VtableImpl<N> {
-    fn fold_with<'tcx, F:TypeFolder<'tcx>>(&self, folder: &mut F) -> traits::VtableImpl<N> {
-        traits::VtableImpl {
+impl<N:TypeFoldable> TypeFoldable for traits::VtableImplData<N> {
+    fn fold_with<'tcx, F:TypeFolder<'tcx>>(&self, folder: &mut F) -> traits::VtableImplData<N> {
+        traits::VtableImplData {
             impl_def_id: self.impl_def_id,
             substs: self.substs.fold_with(folder),
             nested: self.nested.fold_with(folder),
@@ -374,9 +374,9 @@ impl<N:TypeFoldable> TypeFoldable for traits::Vtable<N> {
     }
 }
 
-impl TypeFoldable for traits::VtableParam {
-    fn fold_with<'tcx, F:TypeFolder<'tcx>>(&self, folder: &mut F) -> traits::VtableParam {
-        traits::VtableParam {
+impl TypeFoldable for traits::VtableParamData {
+    fn fold_with<'tcx, F:TypeFolder<'tcx>>(&self, folder: &mut F) -> traits::VtableParamData {
+        traits::VtableParamData {
             bound: self.bound.fold_with(folder),
         }
     }
diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs
index 8f60be8f7fb..2503fb2541b 100644
--- a/src/librustc/middle/typeck/astconv.rs
+++ b/src/librustc/middle/typeck/astconv.rs
@@ -585,32 +585,29 @@ pub fn trait_ref_for_unboxed_function<'tcx, AC: AstConv<'tcx>,
                                       RS:RegionScope>(
                                       this: &AC,
                                       rscope: &RS,
-                                      unboxed_function: &ast::UnboxedFnTy,
+                                      kind: ast::UnboxedClosureKind,
+                                      decl: &ast::FnDecl,
                                       self_ty: Option<ty::t>)
                                       -> ty::TraitRef {
-    let lang_item = match unboxed_function.kind {
+    let lang_item = match kind {
         ast::FnUnboxedClosureKind => FnTraitLangItem,
         ast::FnMutUnboxedClosureKind => FnMutTraitLangItem,
         ast::FnOnceUnboxedClosureKind => FnOnceTraitLangItem,
     };
     let trait_did = this.tcx().lang_items.require(lang_item).unwrap();
-    let input_types =
-        unboxed_function.decl
-                        .inputs
-                        .iter()
-                        .map(|input| {
+    let input_types = decl.inputs
+                          .iter()
+                          .map(|input| {
                             ast_ty_to_ty(this, rscope, &*input.ty)
-                        }).collect::<Vec<_>>();
+                          }).collect::<Vec<_>>();
     let input_tuple = if input_types.len() == 0 {
         ty::mk_nil()
     } else {
         ty::mk_tup(this.tcx(), input_types)
     };
-    let output_type = ast_ty_to_ty(this,
-                                   rscope,
-                                   &*unboxed_function.decl.output);
+    let output_type = ast_ty_to_ty(this, rscope, &*decl.output);
     let mut substs = Substs::new_type(vec!(input_tuple, output_type),
-                                             Vec::new());
+                                      Vec::new());
 
     match self_ty {
         Some(s) => substs.types.push(SelfSpace, s),
@@ -648,7 +645,8 @@ fn mk_pointer<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
                 substs
             } = trait_ref_for_unboxed_function(this,
                                                rscope,
-                                               &**unboxed_function,
+                                               unboxed_function.kind,
+                                               &*unboxed_function.decl,
                                                None);
             let r = ptr_ty.default_region();
             let tr = ty::mk_trait(this.tcx(),
@@ -1510,7 +1508,7 @@ fn compute_region_bound<'tcx, AC: AstConv<'tcx>, RS:RegionScope>(
 pub struct PartitionedBounds<'a> {
     pub builtin_bounds: ty::BuiltinBounds,
     pub trait_bounds: Vec<&'a ast::TraitRef>,
-    pub unboxed_fn_ty_bounds: Vec<&'a ast::UnboxedFnTy>,
+    pub unboxed_fn_ty_bounds: Vec<&'a ast::UnboxedFnBound>,
     pub region_bounds: Vec<&'a ast::Lifetime>,
 }
 
@@ -1574,7 +1572,7 @@ pub fn partition_bounds<'a>(tcx: &ty::ctxt,
                 region_bounds.push(l);
             }
             ast::UnboxedFnTyParamBound(ref unboxed_function) => {
-                unboxed_fn_ty_bounds.push(unboxed_function);
+                unboxed_fn_ty_bounds.push(&**unboxed_function);
             }
         }
     }
diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs
index 5d2ce7b080e..7d28a63d935 100644
--- a/src/librustc/middle/typeck/check/method.rs
+++ b/src/librustc/middle/typeck/check/method.rs
@@ -90,8 +90,8 @@ use middle::typeck::check::{FnCtxt, PreferMutLvalue, impl_self_ty};
 use middle::typeck::check;
 use middle::typeck::infer;
 use middle::typeck::MethodCallee;
-use middle::typeck::{MethodOrigin, MethodParam};
-use middle::typeck::{MethodStatic, MethodStaticUnboxedClosure, MethodObject};
+use middle::typeck::{MethodOrigin, MethodParam, MethodTypeParam};
+use middle::typeck::{MethodStatic, MethodStaticUnboxedClosure, MethodObject, MethodTraitObject};
 use middle::typeck::check::regionmanip::replace_late_bound_regions_in_fn_sig;
 use middle::typeck::TypeAndSubsts;
 use util::common::indenter;
@@ -636,7 +636,7 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> {
                     rcvr_match_condition: RcvrMatchesIfObject(did),
                     rcvr_substs: new_trait_ref.substs.clone(),
                     method_ty: Rc::new(m),
-                    origin: MethodObject(MethodObject {
+                    origin: MethodTraitObject(MethodObject {
                         trait_ref: new_trait_ref,
                         object_trait_id: did,
                         method_num: method_num,
@@ -702,7 +702,7 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> {
                     rcvr_match_condition: condition,
                     rcvr_substs: trait_ref.substs.clone(),
                     method_ty: m,
-                    origin: MethodParam(MethodParam {
+                    origin: MethodTypeParam(MethodParam {
                         trait_ref: trait_ref,
                         method_num: method_num,
                     })
@@ -874,7 +874,7 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> {
         }
 
         let (self_ty, auto_deref_ref) = self.consider_reborrow(self_ty, autoderefs);
-        let adjustment = Some((self.self_expr.unwrap().id, ty::AutoDerefRef(auto_deref_ref)));
+        let adjustment = Some((self.self_expr.unwrap().id, ty::AdjustDerefRef(auto_deref_ref)));
 
         match self.search_for_method(self_ty) {
             None => None,
@@ -1159,7 +1159,7 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> {
                             self.fcx.write_adjustment(
                                 self_expr_id,
                                 self.span,
-                                ty::AutoDerefRef(ty::AutoDerefRef {
+                                ty::AdjustDerefRef(ty::AutoDerefRef {
                                     autoderefs: autoderefs,
                                     autoref: Some(kind(region, *mutbl))
                                 }));
@@ -1245,7 +1245,7 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> {
                        candidate_a.repr(self.tcx()),
                        candidate_b.repr(self.tcx()));
                 match (&candidate_a.origin, &candidate_b.origin) {
-                    (&MethodParam(ref p1), &MethodParam(ref p2)) => {
+                    (&MethodTypeParam(ref p1), &MethodTypeParam(ref p2)) => {
                         let same_trait =
                             p1.trait_ref.def_id == p2.trait_ref.def_id;
                         let same_method =
@@ -1330,7 +1330,7 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> {
 
         let fn_sig = &bare_fn_ty.sig;
         let inputs = match candidate.origin {
-            MethodObject(..) => {
+            MethodTraitObject(..) => {
                 // For annoying reasons, we've already handled the
                 // substitution of self for object calls.
                 let args = fn_sig.inputs.slice_from(1).iter().map(|t| {
@@ -1403,11 +1403,11 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> {
 
         match candidate.origin {
             MethodStatic(..) |
-            MethodParam(..) |
+            MethodTypeParam(..) |
             MethodStaticUnboxedClosure(..) => {
                 return; // not a call to a trait instance
             }
-            MethodObject(..) => {}
+            MethodTraitObject(..) => {}
         }
 
         match candidate.method_ty.explicit_self {
@@ -1463,8 +1463,8 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> {
             MethodStaticUnboxedClosure(_) => bad = false,
             // FIXME: does this properly enforce this on everything now
             // that self has been merged in? -sully
-            MethodParam(MethodParam { trait_ref: ref trait_ref, .. }) |
-            MethodObject(MethodObject { trait_ref: ref trait_ref, .. }) => {
+            MethodTypeParam(MethodParam { trait_ref: ref trait_ref, .. }) |
+            MethodTraitObject(MethodObject { trait_ref: ref trait_ref, .. }) => {
                 bad = self.tcx().destructor_for_type.borrow()
                           .contains_key(&trait_ref.def_id);
             }
@@ -1612,10 +1612,10 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> {
             MethodStaticUnboxedClosure(did) => {
                 self.report_static_candidate(idx, did)
             }
-            MethodParam(ref mp) => {
+            MethodTypeParam(ref mp) => {
                 self.report_param_candidate(idx, mp.trait_ref.def_id)
             }
-            MethodObject(ref mo) => {
+            MethodTraitObject(ref mo) => {
                 self.report_trait_candidate(idx, mo.trait_ref.def_id)
             }
         }
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index c8728d375f6..a8b2e0bbff2 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -79,7 +79,6 @@ type parameter).
 
 use middle::const_eval;
 use middle::def;
-use middle::freevars;
 use middle::lang_items::IteratorItem;
 use middle::mem_categorization::McResult;
 use middle::mem_categorization;
@@ -110,7 +109,7 @@ use middle::typeck::rscope::RegionScope;
 use middle::typeck::{lookup_def_ccx};
 use middle::typeck::no_params;
 use middle::typeck::{require_same_types};
-use middle::typeck::{MethodCall, MethodMap, ObjectCastMap};
+use middle::typeck::{MethodCall, MethodCallee, MethodMap, ObjectCastMap};
 use middle::typeck::{TypeAndSubsts};
 use middle::typeck;
 use middle::lang_items::TypeIdLangItem;
@@ -124,7 +123,6 @@ use std::cell::{Cell, RefCell};
 use std::collections::HashMap;
 use std::mem::replace;
 use std::rc::Rc;
-use std::slice;
 use syntax::abi;
 use syntax::ast::{ProvidedMethod, RequiredMethod, TypeTraitItem};
 use syntax::ast;
@@ -318,7 +316,7 @@ impl<'a, 'tcx> mem_categorization::Typer<'tcx> for FnCtxt<'a, 'tcx> {
         self.ccx.tcx.upvar_borrow(upvar_id)
     }
     fn capture_mode(&self, closure_expr_id: ast::NodeId)
-                    -> freevars::CaptureMode {
+                    -> ast::CaptureClause {
         self.ccx.tcx.capture_mode(closure_expr_id)
     }
     fn unboxed_closures<'a>(&'a self)
@@ -1704,7 +1702,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.write_adjustment(
             node_id,
             span,
-            ty::AutoDerefRef(ty::AutoDerefRef {
+            ty::AdjustDerefRef(ty::AutoDerefRef {
                 autoderefs: derefs,
                 autoref: None })
         );
@@ -1730,8 +1728,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                        span: Span,
                                        adj: &ty::AutoAdjustment) {
         match *adj {
-            ty::AutoAddEnv(..) => { }
-            ty::AutoDerefRef(ref d_r) => {
+            ty::AdjustAddEnv(..) => { }
+            ty::AdjustDerefRef(ref d_r) => {
                 match d_r.autoref {
                     Some(ref a_r) => {
                         self.register_autoref_obligations(span, a_r);
@@ -2188,12 +2186,12 @@ pub fn autoderef<T>(fcx: &FnCtxt, sp: Span, base_ty: ty::t,
 }
 
 /// Attempts to resolve a call expression as an overloaded call.
-fn try_overloaded_call(fcx: &FnCtxt,
-                       call_expression: &ast::Expr,
-                       callee: &ast::Expr,
-                       callee_type: ty::t,
-                       args: &[P<ast::Expr>])
-                       -> bool {
+fn try_overloaded_call<'a>(fcx: &FnCtxt,
+                           call_expression: &ast::Expr,
+                           callee: &ast::Expr,
+                           callee_type: ty::t,
+                           args: &[&'a P<ast::Expr>])
+                           -> bool {
     // Bail out if the callee is a bare function or a closure. We check those
     // manually.
     match *structure_of(fcx, callee.span, callee_type) {
@@ -2276,18 +2274,125 @@ fn try_overloaded_deref(fcx: &FnCtxt,
         (method, _) => method
     };
 
+    make_return_type(fcx, method_call, method)
+}
+
+fn get_method_ty(method: &Option<MethodCallee>) -> ty::t {
+    match method {
+        &Some(ref method) => method.ty,
+        &None => ty::mk_err()
+    }
+}
+
+fn make_return_type(fcx: &FnCtxt,
+                    method_call: Option<MethodCall>,
+                    method: Option<MethodCallee>)
+                    -> Option<ty::mt> {
     match method {
         Some(method) => {
             let ref_ty = ty::ty_fn_ret(method.ty);
             match method_call {
                 Some(method_call) => {
-                    fcx.inh.method_map.borrow_mut().insert(method_call, method);
+                    fcx.inh.method_map.borrow_mut().insert(method_call,
+                                                           method);
                 }
                 None => {}
             }
             ty::deref(ref_ty, true)
         }
-        None => None
+        None => None,
+    }
+}
+
+fn try_overloaded_slice(fcx: &FnCtxt,
+                        method_call: Option<MethodCall>,
+                        expr: &ast::Expr,
+                        base_expr: &ast::Expr,
+                        base_ty: ty::t,
+                        start_expr: &Option<P<ast::Expr>>,
+                        end_expr: &Option<P<ast::Expr>>,
+                        mutbl: &ast::Mutability)
+                        -> Option<ty::mt> {
+    let method = if mutbl == &ast::MutMutable {
+        // Try `SliceMut` first, if preferred.
+        match fcx.tcx().lang_items.slice_mut_trait() {
+            Some(trait_did) => {
+                let method_name = match (start_expr, end_expr) {
+                    (&Some(_), &Some(_)) => "slice_mut_",
+                    (&Some(_), &None) => "slice_from_mut_",
+                    (&None, &Some(_)) => "slice_to_mut_",
+                    (&None, &None) => "as_mut_slice_",
+                };
+
+                method::lookup_in_trait(fcx,
+                                        expr.span,
+                                        Some(&*base_expr),
+                                        token::intern(method_name),
+                                        trait_did,
+                                        base_ty,
+                                        [],
+                                        DontAutoderefReceiver,
+                                        IgnoreStaticMethods)
+            }
+            _ => None,
+        }
+    } else {
+        // Otherwise, fall back to `Slice`.
+        // FIXME(#17293) this will not coerce base_expr, so we miss the Slice
+        // trait for `&mut [T]`.
+        match fcx.tcx().lang_items.slice_trait() {
+            Some(trait_did) => {
+                let method_name = match (start_expr, end_expr) {
+                    (&Some(_), &Some(_)) => "slice_",
+                    (&Some(_), &None) => "slice_from_",
+                    (&None, &Some(_)) => "slice_to_",
+                    (&None, &None) => "as_slice_",
+                };
+
+                method::lookup_in_trait(fcx,
+                                        expr.span,
+                                        Some(&*base_expr),
+                                        token::intern(method_name),
+                                        trait_did,
+                                        base_ty,
+                                        [],
+                                        DontAutoderefReceiver,
+                                        IgnoreStaticMethods)
+            }
+            _ => None,
+        }
+    };
+
+
+    // Regardless of whether the lookup succeeds, check the method arguments
+    // so that we have *some* type for each argument.
+    let method_type = get_method_ty(&method);
+
+    let mut args = vec![];
+    start_expr.as_ref().map(|x| args.push(x));
+    end_expr.as_ref().map(|x| args.push(x));
+
+    check_method_argument_types(fcx,
+                                expr.span,
+                                method_type,
+                                expr,
+                                args.as_slice(),
+                                DoDerefArgs,
+                                DontTupleArguments);
+
+    match method {
+        Some(method) => {
+            let result_ty = ty::ty_fn_ret(method.ty);
+            match method_call {
+                Some(method_call) => {
+                    fcx.inh.method_map.borrow_mut().insert(method_call,
+                                                           method);
+                }
+                None => {}
+            }
+            Some(ty::mt { ty: result_ty, mutbl: ast::MutImmutable })
+        }
+        None => None,
     }
 }
 
@@ -2333,32 +2438,16 @@ fn try_overloaded_index(fcx: &FnCtxt,
 
     // Regardless of whether the lookup succeeds, check the method arguments
     // so that we have *some* type for each argument.
-    let method_type = match method {
-        Some(ref method) => method.ty,
-        None => ty::mk_err()
-    };
+    let method_type = get_method_ty(&method);
     check_method_argument_types(fcx,
                                 expr.span,
                                 method_type,
                                 expr,
-                                slice::ref_slice(index_expr),
+                                &[index_expr],
                                 DoDerefArgs,
                                 DontTupleArguments);
 
-    match method {
-        Some(method) => {
-            let ref_ty = ty::ty_fn_ret(method.ty);
-            match method_call {
-                Some(method_call) => {
-                    fcx.inh.method_map.borrow_mut().insert(method_call,
-                                                           method);
-                }
-                None => {}
-            }
-            ty::deref(ref_ty, true)
-        }
-        None => None,
-    }
+    make_return_type(fcx, method_call, method)
 }
 
 /// Given the head of a `for` expression, looks up the `next` method in the
@@ -2442,14 +2531,14 @@ fn lookup_method_for_for_loop(fcx: &FnCtxt,
     }
 }
 
-fn check_method_argument_types(fcx: &FnCtxt,
-                               sp: Span,
-                               method_fn_ty: ty::t,
-                               callee_expr: &ast::Expr,
-                               args_no_rcvr: &[P<ast::Expr>],
-                               deref_args: DerefArgs,
-                               tuple_arguments: TupleArgumentsFlag)
-                               -> ty::t {
+fn check_method_argument_types<'a>(fcx: &FnCtxt,
+                                   sp: Span,
+                                   method_fn_ty: ty::t,
+                                   callee_expr: &ast::Expr,
+                                   args_no_rcvr: &[&'a P<ast::Expr>],
+                                   deref_args: DerefArgs,
+                                   tuple_arguments: TupleArgumentsFlag)
+                                   -> ty::t {
     if ty::type_is_error(method_fn_ty) {
        let err_inputs = err_args(args_no_rcvr.len());
         check_argument_types(fcx,
@@ -2483,14 +2572,14 @@ fn check_method_argument_types(fcx: &FnCtxt,
     }
 }
 
-fn check_argument_types(fcx: &FnCtxt,
-                        sp: Span,
-                        fn_inputs: &[ty::t],
-                        _callee_expr: &ast::Expr,
-                        args: &[P<ast::Expr>],
-                        deref_args: DerefArgs,
-                        variadic: bool,
-                        tuple_arguments: TupleArgumentsFlag) {
+fn check_argument_types<'a>(fcx: &FnCtxt,
+                            sp: Span,
+                            fn_inputs: &[ty::t],
+                            _callee_expr: &ast::Expr,
+                            args: &[&'a P<ast::Expr>],
+                            deref_args: DerefArgs,
+                            variadic: bool,
+                            tuple_arguments: TupleArgumentsFlag) {
     /*!
      *
      * Generic function that factors out common logic from
@@ -2627,7 +2716,7 @@ fn check_argument_types(fcx: &FnCtxt,
                     DontDerefArgs => {}
                 }
 
-                check_expr_coercable_to_type(fcx, &**arg, formal_ty);
+                check_expr_coercable_to_type(fcx, &***arg, formal_ty);
             }
         }
     }
@@ -2636,12 +2725,12 @@ fn check_argument_types(fcx: &FnCtxt,
     // arguments which we skipped above.
     if variadic {
         for arg in args.iter().skip(expected_arg_count) {
-            check_expr(fcx, &**arg);
+            check_expr(fcx, &***arg);
 
             // There are a few types which get autopromoted when passed via varargs
             // in C but we just error out instead and require explicit casts.
             let arg_ty = structurally_resolved_type(fcx, arg.span,
-                                                    fcx.expr_ty(&**arg));
+                                                    fcx.expr_ty(&***arg));
             match ty::get(arg_ty).sty {
                 ty::ty_float(ast::TyF32) => {
                     fcx.type_error_message(arg.span,
@@ -2877,10 +2966,10 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
            expr.repr(fcx.tcx()), expected.repr(fcx.tcx()));
 
     // A generic function for doing all of the checking for call expressions
-    fn check_call(fcx: &FnCtxt,
-                  call_expr: &ast::Expr,
-                  f: &ast::Expr,
-                  args: &[P<ast::Expr>]) {
+    fn check_call<'a>(fcx: &FnCtxt,
+                      call_expr: &ast::Expr,
+                      f: &ast::Expr,
+                      args: &[&'a P<ast::Expr>]) {
         // Store the type of `f` as the type of the callee
         let fn_ty = fcx.expr_ty(f);
 
@@ -2990,11 +3079,12 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
         };
 
         // Call the generic checker.
+        let args: Vec<_> = args.slice_from(1).iter().map(|x| x).collect();
         let ret_ty = check_method_argument_types(fcx,
                                                  method_name.span,
                                                  fn_ty,
                                                  expr,
-                                                 args.slice_from(1),
+                                                 args.as_slice(),
                                                  DontDerefArgs,
                                                  DontTupleArguments);
 
@@ -3085,12 +3175,8 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
             None => None
         };
         let args = match rhs {
-            Some(rhs) => slice::ref_slice(rhs),
-            None => {
-                // Work around the lack of coercion.
-                let empty: &[_] = &[];
-                empty
-            }
+            Some(rhs) => vec![rhs],
+            None => vec![]
         };
         match method {
             Some(method) => {
@@ -3102,7 +3188,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
                                             op_ex.span,
                                             method_ty,
                                             op_ex,
-                                            args,
+                                            args.as_slice(),
                                             DoDerefArgs,
                                             DontTupleArguments)
             }
@@ -3115,7 +3201,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
                                             op_ex.span,
                                             expected_ty,
                                             op_ex,
-                                            args,
+                                            args.as_slice(),
                                             DoDerefArgs,
                                             DontTupleArguments);
                 ty::mk_err()
@@ -4136,12 +4222,13 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
           check_expr(fcx, &**f);
           let f_ty = fcx.expr_ty(&**f);
 
+          let args: Vec<_> = args.iter().map(|x| x).collect();
           if !try_overloaded_call(fcx, expr, &**f, f_ty, args.as_slice()) {
               check_call(fcx, expr, &**f, args.as_slice());
               let (args_bot, args_err) = args.iter().fold((false, false),
                  |(rest_bot, rest_err), a| {
                      // is this not working?
-                     let a_ty = fcx.expr_ty(&**a);
+                     let a_ty = fcx.expr_ty(&***a);
                      (rest_bot || ty::type_is_bot(a_ty),
                       rest_err || ty::type_is_error(a_ty))});
               if ty::type_is_error(f_ty) || args_err {
@@ -4427,6 +4514,61 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
               }
           }
        }
+       ast::ExprSlice(ref base, ref start, ref end, ref mutbl) => {
+          check_expr_with_lvalue_pref(fcx, &**base, lvalue_pref);
+          let raw_base_t = fcx.expr_ty(&**base);
+
+          let mut some_err = false;
+          if ty::type_is_error(raw_base_t) || ty::type_is_bot(raw_base_t) {
+              fcx.write_ty(id, raw_base_t);
+              some_err = true;
+          }
+
+          {
+              let check_slice_idx = |e: &ast::Expr| {
+                  check_expr(fcx, e);
+                  let e_t = fcx.expr_ty(e);
+                  if ty::type_is_error(e_t) || ty::type_is_bot(e_t) {
+                    fcx.write_ty(id, e_t);
+                    some_err = true;
+                  }
+              };
+              start.as_ref().map(|e| check_slice_idx(&**e));
+              end.as_ref().map(|e| check_slice_idx(&**e));
+          }
+
+          if !some_err {
+              let base_t = structurally_resolved_type(fcx,
+                                                      expr.span,
+                                                      raw_base_t);
+              let method_call = MethodCall::expr(expr.id);
+              match try_overloaded_slice(fcx,
+                                         Some(method_call),
+                                         expr,
+                                         &**base,
+                                         base_t,
+                                         start,
+                                         end,
+                                         mutbl) {
+                  Some(mt) => fcx.write_ty(id, mt.ty),
+                  None => {
+                        fcx.type_error_message(expr.span,
+                           |actual| {
+                                format!("cannot take a {}slice of a value with type `{}`",
+                                        if mutbl == &ast::MutMutable {
+                                            "mutable "
+                                        } else {
+                                            ""
+                                        },
+                                        actual)
+                           },
+                           base_t,
+                           None);
+                        fcx.write_ty(id, ty::mk_err())
+                  }
+              }
+          }
+       }
     }
 
     debug!("type of expr({}) {} is...", expr.id,
@@ -5027,8 +5169,7 @@ pub fn polytype_for_def(fcx: &FnCtxt,
                         defn: def::Def)
                         -> Polytype {
     match defn {
-      def::DefArg(nid, _) | def::DefLocal(nid, _) |
-      def::DefBinding(nid, _) => {
+      def::DefLocal(nid) | def::DefUpvar(nid, _, _) => {
           let typ = fcx.local_ty(sp, nid);
           return no_params(typ);
       }
@@ -5037,9 +5178,6 @@ pub fn polytype_for_def(fcx: &FnCtxt,
       def::DefStruct(id) => {
         return ty::lookup_item_type(fcx.ccx.tcx, id);
       }
-      def::DefUpvar(_, inner, _, _) => {
-        return polytype_for_def(fcx, sp, *inner);
-      }
       def::DefTrait(_) |
       def::DefTy(..) |
       def::DefAssociatedTy(..) |
@@ -5183,10 +5321,8 @@ pub fn instantiate_path(fcx: &FnCtxt,
         // elsewhere. (I hope)
         def::DefMod(..) |
         def::DefForeignMod(..) |
-        def::DefArg(..) |
         def::DefLocal(..) |
         def::DefMethod(..) |
-        def::DefBinding(..) |
         def::DefUse(..) |
         def::DefRegion(..) |
         def::DefLabel(..) |
diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs
index a8f2a8f6f1d..d0791191c0f 100644
--- a/src/librustc/middle/typeck/check/regionck.rs
+++ b/src/librustc/middle/typeck/check/regionck.rs
@@ -119,8 +119,6 @@ and report an error, and it just seems like more mess in the end.)
 */
 
 use middle::def;
-use middle::def::{DefArg, DefBinding, DefLocal, DefUpvar};
-use middle::freevars;
 use middle::mem_categorization as mc;
 use middle::ty::{ReScope};
 use middle::ty;
@@ -243,14 +241,14 @@ fn region_of_def(fcx: &FnCtxt, def: def::Def) -> ty::Region {
 
     let tcx = fcx.tcx();
     match def {
-        DefLocal(node_id, _) | DefArg(node_id, _) |
-        DefBinding(node_id, _) => {
+        def::DefLocal(node_id) => {
             tcx.region_maps.var_region(node_id)
         }
-        DefUpvar(_, subdef, closure_id, body_id) => {
-            match ty::ty_closure_store(fcx.node_ty(closure_id)) {
-                ty::RegionTraitStore(..) => region_of_def(fcx, *subdef),
-                ty::UniqTraitStore => ReScope(body_id)
+        def::DefUpvar(node_id, _, body_id) => {
+            if body_id == ast::DUMMY_NODE_ID {
+                tcx.region_maps.var_region(node_id)
+            } else {
+                ReScope(body_id)
             }
         }
         _ => {
@@ -479,7 +477,7 @@ impl<'fcx, 'tcx> mc::Typer<'tcx> for Rcx<'fcx, 'tcx> {
     }
 
     fn capture_mode(&self, closure_expr_id: ast::NodeId)
-                    -> freevars::CaptureMode {
+                    -> ast::CaptureClause {
         self.tcx().capture_modes.borrow().get_copy(&closure_expr_id)
     }
 
@@ -592,7 +590,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
     for &adjustment in rcx.fcx.inh.adjustments.borrow().find(&expr.id).iter() {
         debug!("adjustment={:?}", adjustment);
         match *adjustment {
-            ty::AutoDerefRef(ty::AutoDerefRef {autoderefs, autoref: ref opt_autoref}) => {
+            ty::AdjustDerefRef(ty::AutoDerefRef {autoderefs, autoref: ref opt_autoref}) => {
                 let expr_ty = rcx.resolve_node_type(expr.id);
                 constrain_autoderefs(rcx, expr, autoderefs, expr_ty);
                 for autoref in opt_autoref.iter() {
@@ -852,7 +850,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
                                          ..}) => {
             // For closure, ensure that the variables outlive region
             // bound, since they are captured by reference.
-            freevars::with_freevars(tcx, expr.id, |freevars| {
+            ty::with_freevars(tcx, expr.id, |freevars| {
                 if freevars.is_empty() {
                     // No free variables means that the environment
                     // will be NULL at runtime and hence the closure
@@ -875,13 +873,13 @@ fn check_expr_fn_block(rcx: &mut Rcx,
                                          ..}) => {
             // For proc, ensure that the *types* of the variables
             // outlive region bound, since they are captured by value.
-            freevars::with_freevars(tcx, expr.id, |freevars| {
+            ty::with_freevars(tcx, expr.id, |freevars| {
                 ensure_free_variable_types_outlive_closure_bound(
                     rcx, bounds.region_bound, expr, freevars);
             });
         }
         ty::ty_unboxed_closure(_, region) => {
-            freevars::with_freevars(tcx, expr.id, |freevars| {
+            ty::with_freevars(tcx, expr.id, |freevars| {
                 // No free variables means that there is no environment and
                 // hence the closure has static lifetime. Otherwise, the
                 // closure must not outlive the variables it closes over
@@ -907,7 +905,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
                 store: ty::RegionTraitStore(..),
                 ..
             }) => {
-            freevars::with_freevars(tcx, expr.id, |freevars| {
+            ty::with_freevars(tcx, expr.id, |freevars| {
                 propagate_upupvar_borrow_kind(rcx, expr, freevars);
             })
         }
@@ -918,7 +916,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
         rcx: &mut Rcx,
         region_bound: ty::Region,
         expr: &ast::Expr,
-        freevars: &[freevars::freevar_entry])
+        freevars: &[ty::Freevar])
     {
         /*!
          * Make sure that the type of all free variables referenced
@@ -951,7 +949,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
         rcx: &mut Rcx,
         region_bound: ty::Region,
         expr: &ast::Expr,
-        freevars: &[freevars::freevar_entry])
+        freevars: &[ty::Freevar])
     {
         /*!
          * Make sure that all free variables referenced inside the
@@ -1001,7 +999,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
 
     fn propagate_upupvar_borrow_kind(rcx: &mut Rcx,
                                      expr: &ast::Expr,
-                                     freevars: &[freevars::freevar_entry]) {
+                                     freevars: &[ty::Freevar]) {
         let tcx = rcx.fcx.ccx.tcx;
         debug!("propagate_upupvar_borrow_kind({})", expr.repr(tcx));
         for freevar in freevars.iter() {
@@ -1031,7 +1029,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
             // determining the final borrow_kind) and propagate that as
             // a constraint on the outer closure.
             match freevar.def {
-                def::DefUpvar(var_id, _, outer_closure_id, _) => {
+                def::DefUpvar(var_id, outer_closure_id, _) => {
                     // thing being captured is itself an upvar:
                     let outer_upvar_id = ty::UpvarId {
                         var_id: var_id,
@@ -1475,7 +1473,6 @@ fn link_region(rcx: &Rcx,
             mc::cat_static_item |
             mc::cat_copied_upvar(..) |
             mc::cat_local(..) |
-            mc::cat_arg(..) |
             mc::cat_upvar(..) |
             mc::cat_rvalue(..) => {
                 // These are all "base cases" with independent lifetimes
@@ -1701,7 +1698,6 @@ fn adjust_upvar_borrow_kind_for_mut(rcx: &Rcx,
             mc::cat_rvalue(_) |
             mc::cat_copied_upvar(_) |
             mc::cat_local(_) |
-            mc::cat_arg(_) |
             mc::cat_upvar(..) => {
                 return;
             }
@@ -1753,7 +1749,6 @@ fn adjust_upvar_borrow_kind_for_unique(rcx: &Rcx, cmt: mc::cmt) {
             mc::cat_rvalue(_) |
             mc::cat_copied_upvar(_) |
             mc::cat_local(_) |
-            mc::cat_arg(_) |
             mc::cat_upvar(..) => {
                 return;
             }
diff --git a/src/librustc/middle/typeck/check/vtable2.rs b/src/librustc/middle/typeck/check/vtable2.rs
index f75d2622fdb..0022efd845e 100644
--- a/src/librustc/middle/typeck/check/vtable2.rs
+++ b/src/librustc/middle/typeck/check/vtable2.rs
@@ -13,7 +13,7 @@ use middle::traits;
 use middle::traits::{SelectionError, Overflow,
                      OutputTypeParameterMismatch, Unimplemented};
 use middle::traits::{Obligation, obligation_for_builtin_bound};
-use middle::traits::{FulfillmentError, Ambiguity};
+use middle::traits::{FulfillmentError, CodeSelectionError, CodeAmbiguity};
 use middle::traits::{ObligationCause};
 use middle::ty;
 use middle::typeck::check::{FnCtxt,
@@ -244,10 +244,10 @@ pub fn report_fulfillment_errors(fcx: &FnCtxt,
 pub fn report_fulfillment_error(fcx: &FnCtxt,
                                 error: &FulfillmentError) {
     match error.code {
-        SelectionError(ref e) => {
+        CodeSelectionError(ref e) => {
             report_selection_error(fcx, &error.obligation, e);
         }
-        Ambiguity => {
+        CodeAmbiguity => {
             maybe_report_ambiguity(fcx, &error.obligation);
         }
     }
diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs
index ffe019b314a..e2a04116f90 100644
--- a/src/librustc/middle/typeck/check/writeback.rs
+++ b/src/librustc/middle/typeck/check/writeback.rs
@@ -282,7 +282,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
             Some(adjustment) => {
                 let adj_object = ty::adjust_is_object(&adjustment);
                 let resolved_adjustment = match adjustment {
-                    ty::AutoAddEnv(store) => {
+                    ty::AdjustAddEnv(store) => {
                         // FIXME(eddyb) #2190 Allow only statically resolved
                         // bare functions to coerce to a closure to avoid
                         // constructing (slower) indirect call wrappers.
@@ -298,10 +298,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
                             }
                         }
 
-                        ty::AutoAddEnv(self.resolve(&store, reason))
+                        ty::AdjustAddEnv(self.resolve(&store, reason))
                     }
 
-                    ty::AutoDerefRef(adj) => {
+                    ty::AdjustDerefRef(adj) => {
                         for autoderef in range(0, adj.autoderefs) {
                             let method_call = MethodCall::autoderef(id, autoderef);
                             self.visit_method_map_entry(reason, method_call);
@@ -312,7 +312,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
                             self.visit_method_map_entry(reason, method_call);
                         }
 
-                        ty::AutoDerefRef(ty::AutoDerefRef {
+                        ty::AdjustDerefRef(ty::AutoDerefRef {
                             autoderefs: adj.autoderefs,
                             autoref: self.resolve(&adj.autoref, reason),
                         })
diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs
index b7aa7656ae9..40c52fd36b9 100644
--- a/src/librustc/middle/typeck/collect.rs
+++ b/src/librustc/middle/typeck/collect.rs
@@ -1427,7 +1427,8 @@ pub fn instantiate_unboxed_fn_ty<'tcx,AC>(this: &AC,
     let param_ty = param_ty.to_ty(this.tcx());
     Rc::new(astconv::trait_ref_for_unboxed_function(this,
                                                     &rscope,
-                                                    unboxed_function,
+                                                    unboxed_function.kind,
+                                                    &*unboxed_function.decl,
                                                     Some(param_ty)))
 }
 
@@ -2165,9 +2166,42 @@ fn conv_param_bounds<'tcx,AC>(this: &AC,
                                      region_bounds,
                                      unboxed_fn_ty_bounds } =
         astconv::partition_bounds(this.tcx(), span, all_bounds.as_slice());
-    let unboxed_fn_ty_bounds =
-        unboxed_fn_ty_bounds.into_iter()
-        .map(|b| instantiate_unboxed_fn_ty(this, b, param_ty));
+
+    let unboxed_fn_ty_bounds = unboxed_fn_ty_bounds.move_iter().map(|b| {
+        let trait_id = this.tcx().def_map.borrow().get(&b.ref_id).def_id();
+        let mut kind = None;
+        for &(lang_item, this_kind) in [
+            (this.tcx().lang_items.fn_trait(), ast::FnUnboxedClosureKind),
+            (this.tcx().lang_items.fn_mut_trait(),
+             ast::FnMutUnboxedClosureKind),
+            (this.tcx().lang_items.fn_once_trait(),
+             ast::FnOnceUnboxedClosureKind)
+        ].iter() {
+            if Some(trait_id) == lang_item {
+                kind = Some(this_kind);
+                break
+            }
+        }
+
+        let kind = match kind {
+            Some(kind) => kind,
+            None => {
+                this.tcx().sess.span_err(b.path.span,
+                                         "unboxed function trait must be one \
+                                          of `Fn`, `FnMut`, or `FnOnce`");
+                ast::FnMutUnboxedClosureKind
+            }
+        };
+
+        let rscope = ExplicitRscope;
+        let param_ty = param_ty.to_ty(this.tcx());
+        Rc::new(astconv::trait_ref_for_unboxed_function(this,
+                                                        &rscope,
+                                                        kind,
+                                                        &*b.decl,
+                                                        Some(param_ty)))
+    });
+
     let trait_bounds: Vec<Rc<ty::TraitRef>> =
         trait_bounds.into_iter()
         .map(|b| {
diff --git a/src/librustc/middle/typeck/infer/coercion.rs b/src/librustc/middle/typeck/infer/coercion.rs
index e0a35dc72a3..7f9f569c37e 100644
--- a/src/librustc/middle/typeck/infer/coercion.rs
+++ b/src/librustc/middle/typeck/infer/coercion.rs
@@ -65,7 +65,7 @@ we may want to adjust precisely when coercions occur.
 */
 
 use middle::subst;
-use middle::ty::{AutoPtr, AutoDerefRef, AutoUnsize, AutoUnsafe};
+use middle::ty::{AutoPtr, AutoDerefRef, AdjustDerefRef, AutoUnsize, AutoUnsafe};
 use middle::ty::{mt};
 use middle::ty;
 use middle::typeck::infer::{CoerceResult, resolve_type, Coercion};
@@ -270,7 +270,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                                      mt {ty: inner_ty, mutbl: mutbl_b});
         try!(sub.tys(a_borrowed, b));
 
-        Ok(Some(AutoDerefRef(AutoDerefRef {
+        Ok(Some(AdjustDerefRef(AutoDerefRef {
             autoderefs: 1,
             autoref: Some(AutoPtr(r_borrow, mutbl_b, None))
         })))
@@ -295,7 +295,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                 let unsized_ty = ty::mk_slice(self.get_ref().infcx.tcx, r_borrow,
                                               mt {ty: t_a, mutbl: mutbl_b});
                 try!(self.get_ref().infcx.try(|| sub.tys(unsized_ty, b)));
-                Ok(Some(AutoDerefRef(AutoDerefRef {
+                Ok(Some(AdjustDerefRef(AutoDerefRef {
                     autoderefs: 0,
                     autoref: Some(ty::AutoPtr(r_borrow,
                                               mutbl_b,
@@ -343,7 +343,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                             try!(self.get_ref().infcx.try(|| sub.tys(ty, b)));
                             debug!("Success, coerced with AutoDerefRef(1, \
                                     AutoPtr(AutoUnsize({:?})))", kind);
-                            Ok(Some(AutoDerefRef(AutoDerefRef {
+                            Ok(Some(AdjustDerefRef(AutoDerefRef {
                                 autoderefs: 1,
                                 autoref: Some(ty::AutoPtr(r_borrow, mt_b.mutbl,
                                                           Some(box AutoUnsize(kind))))
@@ -366,7 +366,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                             try!(self.get_ref().infcx.try(|| sub.tys(ty, b)));
                             debug!("Success, coerced with AutoDerefRef(1, \
                                     AutoPtr(AutoUnsize({:?})))", kind);
-                            Ok(Some(AutoDerefRef(AutoDerefRef {
+                            Ok(Some(AdjustDerefRef(AutoDerefRef {
                                 autoderefs: 1,
                                 autoref: Some(ty::AutoUnsafe(mt_b.mutbl,
                                                              Some(box AutoUnsize(kind))))
@@ -384,7 +384,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                             try!(self.get_ref().infcx.try(|| sub.tys(ty, b)));
                             debug!("Success, coerced with AutoDerefRef(1, \
                                     AutoUnsizeUniq({:?}))", kind);
-                            Ok(Some(AutoDerefRef(AutoDerefRef {
+                            Ok(Some(AdjustDerefRef(AutoDerefRef {
                                 autoderefs: 1,
                                 autoref: Some(ty::AutoUnsizeUniq(kind))
                             })))
@@ -537,7 +537,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
 
                     let tr = ty::mk_trait(tcx, def_id, substs.clone(), bounds);
                     try!(self.subtype(mk_ty(tr), b));
-                    Ok(Some(AutoDerefRef(AutoDerefRef {
+                    Ok(Some(AdjustDerefRef(AutoDerefRef {
                         autoderefs: 1,
                         autoref: Some(mk_adjust())
                     })))
@@ -593,7 +593,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                 _ => return self.subtype(a, b)
             };
 
-            let adj = ty::AutoAddEnv(fn_ty_b.store);
+            let adj = ty::AdjustAddEnv(fn_ty_b.store);
             let a_closure = ty::mk_closure(self.get_ref().infcx.tcx,
                                            ty::ClosureTy {
                                                 sig: fn_ty_a.sig.clone(),
@@ -630,7 +630,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         // Although references and unsafe ptrs have the same
         // representation, we still register an AutoDerefRef so that
         // regionck knows that the region for `a` must be valid here.
-        Ok(Some(AutoDerefRef(AutoDerefRef {
+        Ok(Some(AdjustDerefRef(AutoDerefRef {
             autoderefs: 1,
             autoref: Some(ty::AutoUnsafe(mutbl_b, None))
         })))
diff --git a/src/librustc/middle/typeck/infer/test.rs b/src/librustc/middle/typeck/infer/test.rs
index c0236cefca3..29cd2e77e8b 100644
--- a/src/librustc/middle/typeck/infer/test.rs
+++ b/src/librustc/middle/typeck/infer/test.rs
@@ -22,7 +22,6 @@ use driver::diagnostic;
 use driver::diagnostic::Emitter;
 use driver::driver;
 use driver::session;
-use middle::freevars;
 use middle::lang_items;
 use middle::region;
 use middle::resolve;
@@ -125,10 +124,8 @@ fn test_env(_test_name: &str,
 
     // run just enough stuff to build a tcx:
     let lang_items = lang_items::collect_language_items(krate, &sess);
-    let resolve::CrateMap { def_map: def_map, .. } =
+    let resolve::CrateMap { def_map, freevars, capture_mode_map, .. } =
         resolve::resolve_crate(&sess, &lang_items, krate);
-    let (freevars_map, captures_map) = freevars::annotate_freevars(&def_map,
-                                                                   krate);
     let named_region_map = resolve_lifetime::krate(&sess, krate);
     let region_map = region::resolve_crate(&sess, krate);
     let stability_index = stability::Index::build(krate);
@@ -138,8 +135,8 @@ fn test_env(_test_name: &str,
                           def_map,
                           named_region_map,
                           ast_map,
-                          freevars_map,
-                          captures_map,
+                          freevars,
+                          capture_mode_map,
                           region_map,
                           lang_items,
                           stability_index);
diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs
index 7a913699280..e93ad056051 100644
--- a/src/librustc/middle/typeck/mod.rs
+++ b/src/librustc/middle/typeck/mod.rs
@@ -102,10 +102,10 @@ pub enum MethodOrigin {
     MethodStaticUnboxedClosure(ast::DefId),
 
     // method invoked on a type parameter with a bounded trait
-    MethodParam(MethodParam),
+    MethodTypeParam(MethodParam),
 
     // method invoked on a trait instance
-    MethodObject(MethodObject),
+    MethodTraitObject(MethodObject),
 
 }
 
diff --git a/src/librustc/plugin/registry.rs b/src/librustc/plugin/registry.rs
index be31e81d29b..88e6f0ad186 100644
--- a/src/librustc/plugin/registry.rs
+++ b/src/librustc/plugin/registry.rs
@@ -13,7 +13,7 @@
 use lint::{LintPassObject, LintId, Lint};
 
 use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT};
-use syntax::ext::base::{IdentTT, LetSyntaxTT, ItemDecorator, ItemModifier};
+use syntax::ext::base::{IdentTT, LetSyntaxTT, Decorator, Modifier};
 use syntax::ext::base::{MacroExpanderFn};
 use syntax::codemap::Span;
 use syntax::parse::token;
@@ -61,8 +61,8 @@ impl Registry {
         self.syntax_exts.push((name, match extension {
             NormalTT(ext, _) => NormalTT(ext, Some(self.krate_span)),
             IdentTT(ext, _) => IdentTT(ext, Some(self.krate_span)),
-            ItemDecorator(ext) => ItemDecorator(ext),
-            ItemModifier(ext) => ItemModifier(ext),
+            Decorator(ext) => Decorator(ext),
+            Modifier(ext) => Modifier(ext),
             // there's probably a nicer way to signal this:
             LetSyntaxTT(_, _) => fail!("can't register a new LetSyntax!"),
         }));
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 2083aa52bec..5b83f024309 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -962,10 +962,10 @@ impl Repr for typeck::MethodOrigin {
             &typeck::MethodStaticUnboxedClosure(def_id) => {
                 format!("MethodStaticUnboxedClosure({})", def_id.repr(tcx))
             }
-            &typeck::MethodParam(ref p) => {
+            &typeck::MethodTypeParam(ref p) => {
                 p.repr(tcx)
             }
-            &typeck::MethodObject(ref p) => {
+            &typeck::MethodTraitObject(ref p) => {
                 p.repr(tcx)
             }
         }
diff --git a/src/librustc_back/svh.rs b/src/librustc_back/svh.rs
index 415141c0b94..f98a2dac084 100644
--- a/src/librustc_back/svh.rs
+++ b/src/librustc_back/svh.rs
@@ -245,6 +245,7 @@ mod svh_visitor {
         SawExprAssign,
         SawExprAssignOp(ast::BinOp),
         SawExprIndex,
+        SawExprSlice,
         SawExprPath,
         SawExprAddrOf(ast::Mutability),
         SawExprRet,
@@ -279,6 +280,7 @@ mod svh_visitor {
             ExprField(_, id, _)      => SawExprField(content(id.node)),
             ExprTupField(_, id, _)   => SawExprTupField(id.node),
             ExprIndex(..)            => SawExprIndex,
+            ExprSlice(..)            => SawExprSlice,
             ExprPath(..)             => SawExprPath,
             ExprAddrOf(m, _)         => SawExprAddrOf(m),
             ExprBreak(id)            => SawExprBreak(id.map(content)),
diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs
index 690b288043d..22e7ec6124f 100644
--- a/src/librustc_llvm/lib.rs
+++ b/src/librustc_llvm/lib.rs
@@ -91,34 +91,35 @@ pub enum DiagnosticSeverity {
     Note,
 }
 
-#[deriving(Clone)]
-pub enum Attribute {
-    ZExtAttribute = 1 << 0,
-    SExtAttribute = 1 << 1,
-    NoReturnAttribute = 1 << 2,
-    InRegAttribute = 1 << 3,
-    StructRetAttribute = 1 << 4,
-    NoUnwindAttribute = 1 << 5,
-    NoAliasAttribute = 1 << 6,
-    ByValAttribute = 1 << 7,
-    NestAttribute = 1 << 8,
-    ReadNoneAttribute = 1 << 9,
-    ReadOnlyAttribute = 1 << 10,
-    NoInlineAttribute = 1 << 11,
-    AlwaysInlineAttribute = 1 << 12,
-    OptimizeForSizeAttribute = 1 << 13,
-    StackProtectAttribute = 1 << 14,
-    StackProtectReqAttribute = 1 << 15,
-    AlignmentAttribute = 31 << 16,
-    NoCaptureAttribute = 1 << 21,
-    NoRedZoneAttribute = 1 << 22,
-    NoImplicitFloatAttribute = 1 << 23,
-    NakedAttribute = 1 << 24,
-    InlineHintAttribute = 1 << 25,
-    StackAttribute = 7 << 26,
-    ReturnsTwiceAttribute = 1 << 29,
-    UWTableAttribute = 1 << 30,
-    NonLazyBindAttribute = 1 << 31,
+bitflags! {
+    flags Attribute : u32 {
+        static ZExtAttribute = 1 << 0,
+        static SExtAttribute = 1 << 1,
+        static NoReturnAttribute = 1 << 2,
+        static InRegAttribute = 1 << 3,
+        static StructRetAttribute = 1 << 4,
+        static NoUnwindAttribute = 1 << 5,
+        static NoAliasAttribute = 1 << 6,
+        static ByValAttribute = 1 << 7,
+        static NestAttribute = 1 << 8,
+        static ReadNoneAttribute = 1 << 9,
+        static ReadOnlyAttribute = 1 << 10,
+        static NoInlineAttribute = 1 << 11,
+        static AlwaysInlineAttribute = 1 << 12,
+        static OptimizeForSizeAttribute = 1 << 13,
+        static StackProtectAttribute = 1 << 14,
+        static StackProtectReqAttribute = 1 << 15,
+        static AlignmentAttribute = 31 << 16,
+        static NoCaptureAttribute = 1 << 21,
+        static NoRedZoneAttribute = 1 << 22,
+        static NoImplicitFloatAttribute = 1 << 23,
+        static NakedAttribute = 1 << 24,
+        static InlineHintAttribute = 1 << 25,
+        static StackAttribute = 7 << 26,
+        static ReturnsTwiceAttribute = 1 << 29,
+        static UWTableAttribute = 1 << 30,
+        static NonLazyBindAttribute = 1 << 31,
+    }
 }
 
 #[repr(u64)]
@@ -160,13 +161,13 @@ trait AttrHelper {
 impl AttrHelper for Attribute {
     fn apply_llfn(&self, idx: c_uint, llfn: ValueRef) {
         unsafe {
-            LLVMAddFunctionAttribute(llfn, idx, *self as uint64_t);
+            LLVMAddFunctionAttribute(llfn, idx, self.bits() as uint64_t);
         }
     }
 
     fn apply_callsite(&self, idx: c_uint, callsite: ValueRef) {
         unsafe {
-            LLVMAddCallSiteAttribute(callsite, idx, *self as uint64_t);
+            LLVMAddCallSiteAttribute(callsite, idx, self.bits() as uint64_t);
         }
     }
 }
@@ -296,17 +297,17 @@ pub enum TypeKind {
 
 #[repr(C)]
 pub enum AtomicBinOp {
-    Xchg = 0,
-    Add  = 1,
-    Sub  = 2,
-    And  = 3,
-    Nand = 4,
-    Or   = 5,
-    Xor  = 6,
-    Max  = 7,
-    Min  = 8,
-    UMax = 9,
-    UMin = 10,
+    AtomicXchg = 0,
+    AtomicAdd  = 1,
+    AtomicSub  = 2,
+    AtomicAnd  = 3,
+    AtomicNand = 4,
+    AtomicOr   = 5,
+    AtomicXor  = 6,
+    AtomicMax  = 7,
+    AtomicMin  = 8,
+    AtomicUMax = 9,
+    AtomicUMin = 10,
 }
 
 #[repr(C)]
@@ -324,11 +325,11 @@ pub enum AtomicOrdering {
 // Consts for the LLVMCodeGenFileType type (in include/llvm/c/TargetMachine.h)
 #[repr(C)]
 pub enum FileType {
-    AssemblyFile = 0,
-    ObjectFile = 1
+    AssemblyFileType = 0,
+    ObjectFileType = 1
 }
 
-pub enum Metadata {
+pub enum MetadataType {
     MD_dbg = 0,
     MD_tbaa = 1,
     MD_prof = 2,
@@ -2009,7 +2010,7 @@ pub fn ConstFCmp(pred: RealPredicate, v1: ValueRef, v2: ValueRef) -> ValueRef {
 
 pub fn SetFunctionAttribute(fn_: ValueRef, attr: Attribute) {
     unsafe {
-        LLVMAddFunctionAttribute(fn_, FunctionIndex as c_uint, attr as uint64_t)
+        LLVMAddFunctionAttribute(fn_, FunctionIndex as c_uint, attr.bits() as uint64_t)
     }
 }
 
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 9e05382fa55..b4d44aab239 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -99,7 +99,7 @@ pub struct Crate {
     pub name: String,
     pub module: Option<Item>,
     pub externs: Vec<(ast::CrateNum, ExternalCrate)>,
-    pub primitives: Vec<Primitive>,
+    pub primitives: Vec<PrimitiveType>,
 }
 
 impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
@@ -147,7 +147,7 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
                     ModuleItem(ref mut m) => m,
                     _ => continue,
                 };
-                let prim = match Primitive::find(child.attrs.as_slice()) {
+                let prim = match PrimitiveType::find(child.attrs.as_slice()) {
                     Some(prim) => prim,
                     None => continue,
                 };
@@ -187,7 +187,7 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
 pub struct ExternalCrate {
     pub name: String,
     pub attrs: Vec<Attribute>,
-    pub primitives: Vec<Primitive>,
+    pub primitives: Vec<PrimitiveType>,
 }
 
 impl Clean<ExternalCrate> for cstore::crate_metadata {
@@ -202,7 +202,7 @@ impl Clean<ExternalCrate> for cstore::crate_metadata {
                     _ => return
                 };
                 let attrs = inline::load_attrs(cx, tcx, did);
-                Primitive::find(attrs.as_slice()).map(|prim| primitives.push(prim));
+                PrimitiveType::find(attrs.as_slice()).map(|prim| primitives.push(prim));
             })
         });
         ExternalCrate {
@@ -316,7 +316,7 @@ pub enum ItemEnum {
     /// `static`s from an extern block
     ForeignStaticItem(Static),
     MacroItem(Macro),
-    PrimitiveItem(Primitive),
+    PrimitiveItem(PrimitiveType),
     AssociatedTypeItem,
 }
 
@@ -901,7 +901,7 @@ impl Clean<RetStyle> for ast::RetStyle {
 
 #[deriving(Clone, Encodable, Decodable)]
 pub struct Trait {
-    pub items: Vec<TraitItem>,
+    pub items: Vec<TraitMethod>,
     pub generics: Generics,
     pub bounds: Vec<TyParamBound>,
 }
@@ -931,13 +931,13 @@ impl Clean<Type> for ast::TraitRef {
 }
 
 #[deriving(Clone, Encodable, Decodable)]
-pub enum TraitItem {
+pub enum TraitMethod {
     RequiredMethod(Item),
     ProvidedMethod(Item),
     TypeTraitItem(Item),
 }
 
-impl TraitItem {
+impl TraitMethod {
     pub fn is_req(&self) -> bool {
         match self {
             &RequiredMethod(..) => true,
@@ -959,8 +959,8 @@ impl TraitItem {
     }
 }
 
-impl Clean<TraitItem> for ast::TraitItem {
-    fn clean(&self, cx: &DocContext) -> TraitItem {
+impl Clean<TraitMethod> for ast::TraitItem {
+    fn clean(&self, cx: &DocContext) -> TraitMethod {
         match self {
             &ast::RequiredMethod(ref t) => RequiredMethod(t.clean(cx)),
             &ast::ProvidedMethod(ref t) => ProvidedMethod(t.clean(cx)),
@@ -970,13 +970,13 @@ impl Clean<TraitItem> for ast::TraitItem {
 }
 
 #[deriving(Clone, Encodable, Decodable)]
-pub enum ImplItem {
+pub enum ImplMethod {
     MethodImplItem(Item),
     TypeImplItem(Item),
 }
 
-impl Clean<ImplItem> for ast::ImplItem {
-    fn clean(&self, cx: &DocContext) -> ImplItem {
+impl Clean<ImplMethod> for ast::ImplItem {
+    fn clean(&self, cx: &DocContext) -> ImplMethod {
         match self {
             &ast::MethodImplItem(ref t) => MethodImplItem(t.clean(cx)),
             &ast::TypeImplItem(ref t) => TypeImplItem(t.clean(cx)),
@@ -1058,7 +1058,7 @@ pub enum Type {
     /// For references to self
     Self(ast::DefId),
     /// Primitives are just the fixed-size numeric types (plus int/uint/float), and char.
-    Primitive(Primitive),
+    Primitive(PrimitiveType),
     Closure(Box<ClosureDecl>),
     Proc(Box<ClosureDecl>),
     /// extern "ABI" fn
@@ -1080,7 +1080,7 @@ pub enum Type {
 }
 
 #[deriving(Clone, Encodable, Decodable, PartialEq, Eq, Hash)]
-pub enum Primitive {
+pub enum PrimitiveType {
     Int, I8, I16, I32, I64,
     Uint, U8, U16, U32, U64,
     F32, F64,
@@ -1104,8 +1104,8 @@ pub enum TypeKind {
     TypeTypedef,
 }
 
-impl Primitive {
-    fn from_str(s: &str) -> Option<Primitive> {
+impl PrimitiveType {
+    fn from_str(s: &str) -> Option<PrimitiveType> {
         match s.as_slice() {
             "int" => Some(Int),
             "i8" => Some(I8),
@@ -1129,7 +1129,7 @@ impl Primitive {
         }
     }
 
-    fn find(attrs: &[Attribute]) -> Option<Primitive> {
+    fn find(attrs: &[Attribute]) -> Option<PrimitiveType> {
         for attr in attrs.iter() {
             let list = match *attr {
                 List(ref k, ref l) if k.as_slice() == "doc" => l,
@@ -1141,7 +1141,7 @@ impl Primitive {
                         if k.as_slice() == "primitive" => v.as_slice(),
                     _ => continue,
                 };
-                match Primitive::from_str(value) {
+                match PrimitiveType::from_str(value) {
                     Some(p) => return Some(p),
                     None => {}
                 }
diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs
index 54e9c29e11d..b771473473c 100644
--- a/src/librustdoc/fold.rs
+++ b/src/librustdoc/fold.rs
@@ -40,8 +40,8 @@ pub trait DocFolder {
                 EnumItem(i)
             },
             TraitItem(mut i) => {
-                fn vtrm<T: DocFolder>(this: &mut T, trm: TraitItem)
-                        -> Option<TraitItem> {
+                fn vtrm<T: DocFolder>(this: &mut T, trm: TraitMethod)
+                        -> Option<TraitMethod> {
                     match trm {
                         RequiredMethod(it) => {
                             match this.fold_item(it) {
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index e526286ef46..c807c180e64 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -277,7 +277,7 @@ fn path(w: &mut fmt::Formatter, path: &clean::Path, print_all: bool,
 }
 
 fn primitive_link(f: &mut fmt::Formatter,
-                  prim: clean::Primitive,
+                  prim: clean::PrimitiveType,
                   name: &str) -> fmt::Result {
     let m = cache_key.get().unwrap();
     let mut needs_termination = false;
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 2107854c52b..cf625d4ddfc 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -177,7 +177,7 @@ pub struct Cache {
     pub extern_locations: HashMap<ast::CrateNum, ExternalLocation>,
 
     /// Cache of where documentation for primitives can be found.
-    pub primitive_locations: HashMap<clean::Primitive, ast::CrateNum>,
+    pub primitive_locations: HashMap<clean::PrimitiveType, ast::CrateNum>,
 
     /// Set of definitions which have been inlined from external crates.
     pub inlined: HashSet<ast::DefId>,
@@ -1637,7 +1637,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
                                   _ => false,
                               }
                           })
-                          .collect::<Vec<&clean::TraitItem>>();
+                          .collect::<Vec<&clean::TraitMethod>>();
     let provided = t.items.iter()
                           .filter(|m| {
                               match **m {
@@ -1645,7 +1645,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
                                   _ => false,
                               }
                           })
-                          .collect::<Vec<&clean::TraitItem>>();
+                          .collect::<Vec<&clean::TraitMethod>>();
 
     if t.items.len() == 0 {
         try!(write!(w, "{{ }}"));
@@ -1671,7 +1671,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
     // Trait documentation
     try!(document(w, it));
 
-    fn trait_item(w: &mut fmt::Formatter, m: &clean::TraitItem)
+    fn trait_item(w: &mut fmt::Formatter, m: &clean::TraitMethod)
                   -> fmt::Result {
         try!(write!(w, "<h3 id='{}.{}' class='method'>{}<code>",
                     shortty(m.item()),
@@ -2180,7 +2180,7 @@ fn item_macro(w: &mut fmt::Formatter, it: &clean::Item,
 
 fn item_primitive(w: &mut fmt::Formatter,
                   it: &clean::Item,
-                  _p: &clean::Primitive) -> fmt::Result {
+                  _p: &clean::PrimitiveType) -> fmt::Result {
     try!(document(w, it));
     render_methods(w, it)
 }
diff --git a/src/librustdoc/stability_summary.rs b/src/librustdoc/stability_summary.rs
index 02dc4e9bdb6..f7d43037723 100644
--- a/src/librustdoc/stability_summary.rs
+++ b/src/librustdoc/stability_summary.rs
@@ -21,7 +21,7 @@ use syntax::attr::{Deprecated, Experimental, Unstable, Stable, Frozen, Locked};
 use syntax::ast::Public;
 
 use clean::{Crate, Item, ModuleItem, Module, StructItem, Struct, EnumItem, Enum};
-use clean::{ImplItem, Impl, Trait, TraitItem, ProvidedMethod, RequiredMethod};
+use clean::{ImplItem, Impl, Trait, TraitItem, TraitMethod, ProvidedMethod, RequiredMethod};
 use clean::{TypeTraitItem, ViewItemItem, PrimitiveItem};
 
 #[deriving(Zero, Encodable, Decodable, PartialEq, Eq)]
@@ -128,7 +128,7 @@ fn summarize_item(item: &Item) -> (Counts, Option<ModuleSummary>) {
             items: ref trait_items,
             ..
         }) => {
-            fn extract_item<'a>(trait_item: &'a TraitItem) -> &'a Item {
+            fn extract_item<'a>(trait_item: &'a TraitMethod) -> &'a Item {
                 match *trait_item {
                     ProvidedMethod(ref item) |
                     RequiredMethod(ref item) |
diff --git a/src/librustrt/c_str.rs b/src/librustrt/c_str.rs
index 5e0004f2a2a..04a4e96ecc4 100644
--- a/src/librustrt/c_str.rs
+++ b/src/librustrt/c_str.rs
@@ -36,6 +36,12 @@ not tied to the lifetime of the original string/data buffer). If C strings are
 heavily used in applications, then caching may be advisable to prevent
 unnecessary amounts of allocations.
 
+Be carefull to remember that the memory is managed by C allocator API and not
+by Rust allocator API.
+That means that the CString pointers should be freed with C allocator API
+if you intend to do that on your own, as the behaviour if you free them with
+Rust's allocator API is not well defined
+
 An example of creating and using a C string would be:
 
 ```rust
@@ -91,8 +97,8 @@ pub struct CString {
 
 impl Clone for CString {
     /// Clone this CString into a new, uniquely owned CString. For safety
-    /// reasons, this is always a deep clone, rather than the usual shallow
-    /// clone.
+    /// reasons, this is always a deep clone with the memory allocated
+    /// with C's allocator API, rather than the usual shallow clone.
     fn clone(&self) -> CString {
         let len = self.len() + 1;
         let buf = unsafe { malloc_raw(len) } as *mut libc::c_char;
@@ -131,7 +137,9 @@ impl<S: hash::Writer> hash::Hash<S> for CString {
 }
 
 impl CString {
-    /// Create a C String from a pointer.
+    /// Create a C String from a pointer, with memory managed by C's allocator
+    /// API, so avoid calling it with a pointer to memory managed by Rust's
+    /// allocator API, as the behaviour would not be well defined.
     ///
     ///# Failure
     ///
@@ -265,7 +273,8 @@ impl CString {
     /// forgotten, meaning that the backing allocation of this
     /// `CString` is not automatically freed if it owns the
     /// allocation. In this case, a user of `.unwrap()` should ensure
-    /// the allocation is freed, to avoid leaking memory.
+    /// the allocation is freed, to avoid leaking memory. You should
+    /// use libc's memory allocator in this case.
     ///
     /// Prefer `.as_ptr()` when just retrieving a pointer to the
     /// string data, as that does not relinquish ownership.
diff --git a/src/librustrt/local_data.rs b/src/librustrt/local_data.rs
index c71f86bb063..ba5a4dc3f21 100644
--- a/src/librustrt/local_data.rs
+++ b/src/librustrt/local_data.rs
@@ -67,7 +67,7 @@ use task::{Task, LocalStorage};
 pub type Key<T> = &'static KeyValue<T>;
 
 #[allow(missing_doc)]
-pub enum KeyValue<T> { Key }
+pub enum KeyValue<T> { KeyValueKey }
 
 // The task-local-map stores all TLD information for the currently running
 // task. It is stored as an owned pointer into the runtime, and it's only
@@ -417,7 +417,7 @@ mod tests {
 
     #[test]
     fn test_tls_multitask() {
-        static my_key: Key<String> = &Key;
+        static my_key: Key<String> = &KeyValueKey;
         my_key.replace(Some("parent data".to_string()));
         task::spawn(proc() {
             // TLD shouldn't carry over.
@@ -435,7 +435,7 @@ mod tests {
 
     #[test]
     fn test_tls_overwrite() {
-        static my_key: Key<String> = &Key;
+        static my_key: Key<String> = &KeyValueKey;
         my_key.replace(Some("first data".to_string()));
         my_key.replace(Some("next data".to_string())); // Shouldn't leak.
         assert!(my_key.get().unwrap().as_slice() == "next data");
@@ -443,7 +443,7 @@ mod tests {
 
     #[test]
     fn test_tls_pop() {
-        static my_key: Key<String> = &Key;
+        static my_key: Key<String> = &KeyValueKey;
         my_key.replace(Some("weasel".to_string()));
         assert!(my_key.replace(None).unwrap() == "weasel".to_string());
         // Pop must remove the data from the map.
@@ -458,7 +458,7 @@ mod tests {
         // to get recorded as something within a rust stack segment. Then a
         // subsequent upcall (esp. for logging, think vsnprintf) would run on
         // a stack smaller than 1 MB.
-        static my_key: Key<String> = &Key;
+        static my_key: Key<String> = &KeyValueKey;
         task::spawn(proc() {
             my_key.replace(Some("hax".to_string()));
         });
@@ -466,9 +466,9 @@ mod tests {
 
     #[test]
     fn test_tls_multiple_types() {
-        static str_key: Key<String> = &Key;
-        static box_key: Key<Gc<()>> = &Key;
-        static int_key: Key<int> = &Key;
+        static str_key: Key<String> = &KeyValueKey;
+        static box_key: Key<Gc<()>> = &KeyValueKey;
+        static int_key: Key<int> = &KeyValueKey;
         task::spawn(proc() {
             str_key.replace(Some("string data".to_string()));
             box_key.replace(Some(box(GC) ()));
@@ -478,9 +478,9 @@ mod tests {
 
     #[test]
     fn test_tls_overwrite_multiple_types() {
-        static str_key: Key<String> = &Key;
-        static box_key: Key<Gc<()>> = &Key;
-        static int_key: Key<int> = &Key;
+        static str_key: Key<String> = &KeyValueKey;
+        static box_key: Key<Gc<()>> = &KeyValueKey;
+        static int_key: Key<int> = &KeyValueKey;
         task::spawn(proc() {
             str_key.replace(Some("string data".to_string()));
             str_key.replace(Some("string data 2".to_string()));
@@ -497,9 +497,9 @@ mod tests {
     #[test]
     #[should_fail]
     fn test_tls_cleanup_on_failure() {
-        static str_key: Key<String> = &Key;
-        static box_key: Key<Gc<()>> = &Key;
-        static int_key: Key<int> = &Key;
+        static str_key: Key<String> = &KeyValueKey;
+        static box_key: Key<Gc<()>> = &KeyValueKey;
+        static int_key: Key<int> = &KeyValueKey;
         str_key.replace(Some("parent data".to_string()));
         box_key.replace(Some(box(GC) ()));
         task::spawn(proc() {
@@ -524,7 +524,7 @@ mod tests {
                 self.tx.send(());
             }
         }
-        static key: Key<Dropper> = &Key;
+        static key: Key<Dropper> = &KeyValueKey;
         let _ = task::try(proc() {
             key.replace(Some(Dropper{ tx: tx }));
         });
@@ -535,14 +535,14 @@ mod tests {
 
     #[test]
     fn test_static_pointer() {
-        static key: Key<&'static int> = &Key;
+        static key: Key<&'static int> = &KeyValueKey;
         static VALUE: int = 0;
         key.replace(Some(&VALUE));
     }
 
     #[test]
     fn test_owned() {
-        static key: Key<Box<int>> = &Key;
+        static key: Key<Box<int>> = &KeyValueKey;
         key.replace(Some(box 1));
 
         {
@@ -559,11 +559,11 @@ mod tests {
 
     #[test]
     fn test_same_key_type() {
-        static key1: Key<int> = &Key;
-        static key2: Key<int> = &Key;
-        static key3: Key<int> = &Key;
-        static key4: Key<int> = &Key;
-        static key5: Key<int> = &Key;
+        static key1: Key<int> = &KeyValueKey;
+        static key2: Key<int> = &KeyValueKey;
+        static key3: Key<int> = &KeyValueKey;
+        static key4: Key<int> = &KeyValueKey;
+        static key5: Key<int> = &KeyValueKey;
         key1.replace(Some(1));
         key2.replace(Some(2));
         key3.replace(Some(3));
@@ -580,7 +580,7 @@ mod tests {
     #[test]
     #[should_fail]
     fn test_nested_get_set1() {
-        static key: Key<int> = &Key;
+        static key: Key<int> = &KeyValueKey;
         assert_eq!(key.replace(Some(4)), None);
 
         let _k = key.get();
@@ -602,7 +602,7 @@ mod tests {
 
     #[bench]
     fn bench_replace_none(b: &mut test::Bencher) {
-        static key: Key<uint> = &Key;
+        static key: Key<uint> = &KeyValueKey;
         let _clear = ClearKey(key);
         key.replace(None);
         b.iter(|| {
@@ -612,7 +612,7 @@ mod tests {
 
     #[bench]
     fn bench_replace_some(b: &mut test::Bencher) {
-        static key: Key<uint> = &Key;
+        static key: Key<uint> = &KeyValueKey;
         let _clear = ClearKey(key);
         key.replace(Some(1u));
         b.iter(|| {
@@ -622,7 +622,7 @@ mod tests {
 
     #[bench]
     fn bench_replace_none_some(b: &mut test::Bencher) {
-        static key: Key<uint> = &Key;
+        static key: Key<uint> = &KeyValueKey;
         let _clear = ClearKey(key);
         key.replace(Some(0u));
         b.iter(|| {
@@ -634,7 +634,7 @@ mod tests {
 
     #[bench]
     fn bench_100_keys_replace_last(b: &mut test::Bencher) {
-        static keys: [KeyValue<uint>, ..100] = [Key, ..100];
+        static keys: [KeyValue<uint>, ..100] = [KeyValueKey, ..100];
         let _clear = keys.iter().map(ClearKey).collect::<Vec<ClearKey<uint>>>();
         for (i, key) in keys.iter().enumerate() {
             key.replace(Some(i));
@@ -647,7 +647,7 @@ mod tests {
 
     #[bench]
     fn bench_1000_keys_replace_last(b: &mut test::Bencher) {
-        static keys: [KeyValue<uint>, ..1000] = [Key, ..1000];
+        static keys: [KeyValue<uint>, ..1000] = [KeyValueKey, ..1000];
         let _clear = keys.iter().map(ClearKey).collect::<Vec<ClearKey<uint>>>();
         for (i, key) in keys.iter().enumerate() {
             key.replace(Some(i));
@@ -661,7 +661,7 @@ mod tests {
 
     #[bench]
     fn bench_get(b: &mut test::Bencher) {
-        static key: Key<uint> = &Key;
+        static key: Key<uint> = &KeyValueKey;
         let _clear = ClearKey(key);
         key.replace(Some(42));
         b.iter(|| {
@@ -671,7 +671,7 @@ mod tests {
 
     #[bench]
     fn bench_100_keys_get_last(b: &mut test::Bencher) {
-        static keys: [KeyValue<uint>, ..100] = [Key, ..100];
+        static keys: [KeyValue<uint>, ..100] = [KeyValueKey, ..100];
         let _clear = keys.iter().map(ClearKey).collect::<Vec<ClearKey<uint>>>();
         for (i, key) in keys.iter().enumerate() {
             key.replace(Some(i));
@@ -684,7 +684,7 @@ mod tests {
 
     #[bench]
     fn bench_1000_keys_get_last(b: &mut test::Bencher) {
-        static keys: [KeyValue<uint>, ..1000] = [Key, ..1000];
+        static keys: [KeyValue<uint>, ..1000] = [KeyValueKey, ..1000];
         let _clear = keys.iter().map(ClearKey).collect::<Vec<ClearKey<uint>>>();
         for (i, key) in keys.iter().enumerate() {
             key.replace(Some(i));
diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs
index 833c5cd0f98..14274ef9f9b 100644
--- a/src/libserialize/json.rs
+++ b/src/libserialize/json.rs
@@ -28,7 +28,7 @@ Data types that can be encoded are JavaScript types (see the `Json` enum for mor
 * `Boolean`: equivalent to rust's `bool`
 * `Number`: equivalent to rust's `f64`
 * `String`: equivalent to rust's `String`
-* `Array`: equivalent to rust's `Vec<T>`, but also allowing objects of different types in the same
+* `List`: equivalent to rust's `Vec<T>`, but also allowing objects of different types in the same
 array
 * `Object`: equivalent to rust's `Treemap<String, json::Json>`
 * `Null`
@@ -201,7 +201,7 @@ use std::io::MemWriter;
 use std::mem::{swap, transmute};
 use std::num::{FPNaN, FPInfinite};
 use std::str::ScalarValue;
-use std::string::String;
+use std::string;
 use std::vec::Vec;
 
 use Encodable;
@@ -212,15 +212,15 @@ pub enum Json {
     I64(i64),
     U64(u64),
     F64(f64),
-    String(String),
+    String(string::String),
     Boolean(bool),
-    List(List),
-    Object(Object),
+    List(JsonList),
+    Object(JsonObject),
     Null,
 }
 
-pub type List = Vec<Json>;
-pub type Object = TreeMap<String, Json>;
+pub type JsonList = Vec<Json>;
+pub type JsonObject = TreeMap<string::String, Json>;
 
 /// The errors that can arise while parsing a JSON stream.
 #[deriving(Clone, PartialEq)]
@@ -257,10 +257,10 @@ pub type BuilderError = ParserError;
 #[deriving(Clone, PartialEq, Show)]
 pub enum DecoderError {
     ParseError(ParserError),
-    ExpectedError(String, String),
-    MissingFieldError(String),
-    UnknownVariantError(String),
-    ApplicationError(String)
+    ExpectedError(string::String, string::String),
+    MissingFieldError(string::String),
+    UnknownVariantError(string::String),
+    ApplicationError(string::String)
 }
 
 /// Returns a readable error string for a given error code.
@@ -298,9 +298,9 @@ pub fn decode<T: ::Decodable<Decoder, DecoderError>>(s: &str) -> DecodeResult<T>
 }
 
 /// Shortcut function to encode a `T` into a JSON `String`
-pub fn encode<'a, T: Encodable<Encoder<'a>, io::IoError>>(object: &T) -> String {
+pub fn encode<'a, T: Encodable<Encoder<'a>, io::IoError>>(object: &T) -> string::String {
     let buff = Encoder::buffer_encode(object);
-    String::from_utf8(buff).unwrap()
+    string::String::from_utf8(buff).unwrap()
 }
 
 impl fmt::Show for ErrorCode {
@@ -375,9 +375,9 @@ fn spaces(wr: &mut io::Writer, mut n: uint) -> Result<(), io::IoError> {
     }
 }
 
-fn fmt_number_or_null(v: f64) -> String {
+fn fmt_number_or_null(v: f64) -> string::String {
     match v.classify() {
-        FPNaN | FPInfinite => String::from_str("null"),
+        FPNaN | FPInfinite => string::String::from_str("null"),
         _ => f64::to_str_digits(v, 6u)
     }
 }
@@ -411,7 +411,7 @@ impl<'a> Encoder<'a> {
     ///
     /// Note: this function is deprecated. Consider using `json::encode` instead.
     #[deprecated = "Replaced by `json::encode`"]
-    pub fn str_encode<T: Encodable<Encoder<'a>, io::IoError>>(object: &T) -> String {
+    pub fn str_encode<T: Encodable<Encoder<'a>, io::IoError>>(object: &T) -> string::String {
         encode(object)
     }
 }
@@ -877,15 +877,15 @@ impl Json {
     }
 
     /// Encodes a json value into a string
-    pub fn to_pretty_str(&self) -> String {
+    pub fn to_pretty_str(&self) -> string::String {
         let mut s = MemWriter::new();
         self.to_pretty_writer(&mut s as &mut io::Writer).unwrap();
-        String::from_utf8(s.unwrap()).unwrap()
+        string::String::from_utf8(s.unwrap()).unwrap()
     }
 
      /// If the Json value is an Object, returns the value associated with the provided key.
     /// Otherwise, returns None.
-    pub fn find<'a>(&'a self, key: &String) -> Option<&'a Json>{
+    pub fn find<'a>(&'a self, key: &string::String) -> Option<&'a Json>{
         match self {
             &Object(ref map) => map.find(key),
             _ => None
@@ -895,7 +895,7 @@ impl Json {
     /// Attempts to get a nested Json Object for each key in `keys`.
     /// If any key is found not to exist, find_path will return None.
     /// Otherwise, it will return the Json value associated with the final key.
-    pub fn find_path<'a>(&'a self, keys: &[&String]) -> Option<&'a Json>{
+    pub fn find_path<'a>(&'a self, keys: &[&string::String]) -> Option<&'a Json>{
         let mut target = self;
         for key in keys.iter() {
             match target.find(*key) {
@@ -909,7 +909,7 @@ impl Json {
     /// If the Json value is an Object, performs a depth-first search until
     /// a value associated with the provided key is found. If no value is found
     /// or the Json value is not an Object, returns None.
-    pub fn search<'a>(&'a self, key: &String) -> Option<&'a Json> {
+    pub fn search<'a>(&'a self, key: &string::String) -> Option<&'a Json> {
         match self {
             &Object(ref map) => {
                 match map.find(key) {
@@ -937,7 +937,7 @@ impl Json {
 
     /// If the Json value is an Object, returns the associated TreeMap.
     /// Returns None otherwise.
-    pub fn as_object<'a>(&'a self) -> Option<&'a Object> {
+    pub fn as_object<'a>(&'a self) -> Option<&'a JsonObject> {
         match self {
             &Object(ref map) => Some(map),
             _ => None
@@ -951,7 +951,7 @@ impl Json {
 
     /// If the Json value is a List, returns the associated vector.
     /// Returns None otherwise.
-    pub fn as_list<'a>(&'a self) -> Option<&'a List> {
+    pub fn as_list<'a>(&'a self) -> Option<&'a JsonList> {
         match self {
             &List(ref list) => Some(&*list),
             _ => None
@@ -1075,7 +1075,7 @@ pub enum JsonEvent {
     I64Value(i64),
     U64Value(u64),
     F64Value(f64),
-    StringValue(String),
+    StringValue(string::String),
     NullValue,
     Error(ParserError),
 }
@@ -1083,7 +1083,7 @@ pub enum JsonEvent {
 #[deriving(PartialEq, Show)]
 enum ParserState {
     // Parse a value in a list, true means first element.
-    ParseList(bool),
+    ParseArray(bool),
     // Parse ',' or ']' after an element in a list.
     ParseListComma,
     // Parse a key:value in an object, true means first element.
@@ -1191,7 +1191,7 @@ impl Stack {
     }
 
     // Used by Parser to insert Key elements at the top of the stack.
-    fn push_key(&mut self, key: String) {
+    fn push_key(&mut self, key: string::String) {
         self.stack.push(InternalKey(self.str_buffer.len() as u16, key.len() as u16));
         for c in key.as_bytes().iter() {
             self.str_buffer.push(*c);
@@ -1502,9 +1502,9 @@ impl<T: Iterator<char>> Parser<T> {
         Ok(n)
     }
 
-    fn parse_str(&mut self) -> Result<String, ParserError> {
+    fn parse_str(&mut self) -> Result<string::String, ParserError> {
         let mut escape = false;
-        let mut res = String::new();
+        let mut res = string::String::new();
 
         loop {
             self.bump();
@@ -1574,7 +1574,7 @@ impl<T: Iterator<char>> Parser<T> {
             // The only paths where the loop can spin a new iteration
             // are in the cases ParseListComma and ParseObjectComma if ','
             // is parsed. In these cases the state is set to (respectively)
-            // ParseList(false) and ParseObject(false), which always return,
+            // ParseArray(false) and ParseObject(false), which always return,
             // so there is no risk of getting stuck in an infinite loop.
             // All other paths return before the end of the loop's iteration.
             self.parse_whitespace();
@@ -1583,7 +1583,7 @@ impl<T: Iterator<char>> Parser<T> {
                 ParseStart => {
                     return self.parse_start();
                 }
-                ParseList(first) => {
+                ParseArray(first) => {
                     return self.parse_list(first);
                 }
                 ParseListComma => {
@@ -1615,7 +1615,7 @@ impl<T: Iterator<char>> Parser<T> {
         let val = self.parse_value();
         self.state = match val {
             Error(_) => { ParseFinished }
-            ListStart => { ParseList(true) }
+            ListStart => { ParseArray(true) }
             ObjectStart => { ParseObject(true) }
             _ => { ParseBeforeFinish }
         };
@@ -1647,7 +1647,7 @@ impl<T: Iterator<char>> Parser<T> {
 
         self.state = match val {
             Error(_) => { ParseFinished }
-            ListStart => { ParseList(true) }
+            ListStart => { ParseArray(true) }
             ObjectStart => { ParseObject(true) }
             _ => { ParseListComma }
         };
@@ -1657,7 +1657,7 @@ impl<T: Iterator<char>> Parser<T> {
     fn parse_list_comma_or_end(&mut self) -> Option<JsonEvent> {
         if self.ch_is(',') {
             self.stack.bump_index();
-            self.state = ParseList(false);
+            self.state = ParseArray(false);
             self.bump();
             return None;
         } else if self.ch_is(']') {
@@ -1728,7 +1728,7 @@ impl<T: Iterator<char>> Parser<T> {
 
         self.state = match val {
             Error(_) => { ParseFinished }
-            ListStart => { ParseList(true) }
+            ListStart => { ParseArray(true) }
             ObjectStart => { ParseObject(true) }
             _ => { ParseObjectComma }
         };
@@ -1830,7 +1830,7 @@ impl<T: Iterator<char>> Builder<T> {
             Some(F64Value(n)) => { Ok(F64(n)) }
             Some(BooleanValue(b)) => { Ok(Boolean(b)) }
             Some(StringValue(ref mut s)) => {
-                let mut temp = String::new();
+                let mut temp = string::String::new();
                 swap(s, &mut temp);
                 Ok(String(temp))
             }
@@ -2034,7 +2034,7 @@ impl ::Decoder<DecoderError> for Decoder {
         Err(ExpectedError("single character string".to_string(), format!("{}", s)))
     }
 
-    fn read_str(&mut self) -> DecodeResult<String> {
+    fn read_str(&mut self) -> DecodeResult<string::String> {
         debug!("read_str");
         expect!(self.pop(), String)
     }
@@ -2284,7 +2284,7 @@ impl ToJson for bool {
     fn to_json(&self) -> Json { Boolean(*self) }
 }
 
-impl ToJson for String {
+impl ToJson for string::String {
     fn to_json(&self) -> Json { String((*self).clone()) }
 }
 
@@ -2328,7 +2328,7 @@ impl<A: ToJson> ToJson for Vec<A> {
     fn to_json(&self) -> Json { List(self.iter().map(|elt| elt.to_json()).collect()) }
 }
 
-impl<A: ToJson> ToJson for TreeMap<String, A> {
+impl<A: ToJson> ToJson for TreeMap<string::String, A> {
     fn to_json(&self) -> Json {
         let mut d = TreeMap::new();
         for (key, value) in self.iter() {
@@ -2338,7 +2338,7 @@ impl<A: ToJson> ToJson for TreeMap<String, A> {
     }
 }
 
-impl<A: ToJson> ToJson for HashMap<String, A> {
+impl<A: ToJson> ToJson for HashMap<string::String, A> {
     fn to_json(&self) -> Json {
         let mut d = TreeMap::new();
         for (key, value) in self.iter() {
@@ -2375,7 +2375,7 @@ mod tests {
     extern crate test;
     use self::test::Bencher;
     use {Encodable, Decodable};
-    use super::{Encoder, Decoder, Error, Boolean, I64, U64, F64, List, String, Null,
+    use super::{List, Encoder, Decoder, Error, Boolean, I64, U64, F64, String, Null,
                 PrettyEncoder, Object, Json, from_str, ParseError, ExpectedError,
                 MissingFieldError, UnknownVariantError, DecodeResult, DecoderError,
                 JsonEvent, Parser, StackElement,
@@ -2386,6 +2386,7 @@ mod tests {
                 TrailingCharacters, TrailingComma};
     use std::{i64, u64, f32, f64, io};
     use std::collections::TreeMap;
+    use std::string;
 
     #[deriving(Decodable, Eq, PartialEq, Show)]
     struct OptionData {
@@ -2417,14 +2418,14 @@ mod tests {
     #[deriving(PartialEq, Encodable, Decodable, Show)]
     enum Animal {
         Dog,
-        Frog(String, int)
+        Frog(string::String, int)
     }
 
     #[deriving(PartialEq, Encodable, Decodable, Show)]
     struct Inner {
         a: (),
         b: uint,
-        c: Vec<String>,
+        c: Vec<string::String>,
     }
 
     #[deriving(PartialEq, Encodable, Decodable, Show)]
@@ -2432,7 +2433,7 @@ mod tests {
         inner: Vec<Inner>,
     }
 
-    fn mk_object(items: &[(String, Json)]) -> Json {
+    fn mk_object(items: &[(string::String, Json)]) -> Json {
         let mut d = TreeMap::new();
 
         for item in items.iter() {
@@ -2610,7 +2611,7 @@ mod tests {
                    from_str(a.to_pretty_str().as_slice()).unwrap());
     }
 
-    fn with_str_writer(f: |&mut io::Writer|) -> String {
+    fn with_str_writer(f: |&mut io::Writer|) -> string::String {
         use std::io::MemWriter;
         use std::str;
 
@@ -2678,7 +2679,7 @@ mod tests {
 
     #[test]
     fn test_write_none() {
-        let value: Option<String> = None;
+        let value: Option<string::String> = None;
         let s = with_str_writer(|writer| {
             let mut encoder = Encoder::new(writer);
             value.encode(&mut encoder).unwrap();
@@ -2825,7 +2826,7 @@ mod tests {
                  ("\"\\uAB12\"", "\uAB12")];
 
         for &(i, o) in s.iter() {
-            let v: String = super::decode(i).unwrap();
+            let v: string::String = super::decode(i).unwrap();
             assert_eq!(v.as_slice(), o);
         }
     }
@@ -2959,10 +2960,10 @@ mod tests {
 
     #[test]
     fn test_decode_option() {
-        let value: Option<String> = super::decode("null").unwrap();
+        let value: Option<string::String> = super::decode("null").unwrap();
         assert_eq!(value, None);
 
-        let value: Option<String> = super::decode("\"jodhpurs\"").unwrap();
+        let value: Option<string::String> = super::decode("\"jodhpurs\"").unwrap();
         assert_eq!(value, Some("jodhpurs".to_string()));
     }
 
@@ -2980,7 +2981,7 @@ mod tests {
     fn test_decode_map() {
         let s = "{\"a\": \"Dog\", \"b\": {\"variant\":\"Frog\",\
                   \"fields\":[\"Henry\", 349]}}";
-        let mut map: TreeMap<String, Animal> = super::decode(s).unwrap();
+        let mut map: TreeMap<string::String, Animal> = super::decode(s).unwrap();
 
         assert_eq!(map.pop(&"a".to_string()), Some(Dog));
         assert_eq!(map.pop(&"b".to_string()), Some(Frog("Henry".to_string(), 349)));
@@ -2997,13 +2998,13 @@ mod tests {
     struct DecodeStruct {
         x: f64,
         y: bool,
-        z: String,
+        z: string::String,
         w: Vec<DecodeStruct>
     }
     #[deriving(Decodable)]
     enum DecodeEnum {
         A(f64),
-        B(String)
+        B(string::String)
     }
     fn check_err<T: Decodable<Decoder, DecoderError>>(to_parse: &'static str,
                                                       expected: DecoderError) {
@@ -3709,7 +3710,7 @@ mod tests {
         });
     }
 
-    fn big_json() -> String {
+    fn big_json() -> string::String {
         let mut src = "[\n".to_string();
         for _ in range(0i, 500) {
             src.push_str(r#"{ "a": true, "b": null, "c":3.1415, "d": "Hello world", "e": \
diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs
index e1f2f43673f..86c03708e40 100644
--- a/src/libstd/macros.rs
+++ b/src/libstd/macros.rs
@@ -304,10 +304,10 @@ macro_rules! println(
 #[macro_export]
 macro_rules! local_data_key(
     ($name:ident: $ty:ty) => (
-        static $name: ::std::local_data::Key<$ty> = &::std::local_data::Key;
+        static $name: ::std::local_data::Key<$ty> = &::std::local_data::KeyValueKey;
     );
     (pub $name:ident: $ty:ty) => (
-        pub static $name: ::std::local_data::Key<$ty> = &::std::local_data::Key;
+        pub static $name: ::std::local_data::Key<$ty> = &::std::local_data::KeyValueKey;
     );
 )
 
diff --git a/src/libstd/rt/backtrace.rs b/src/libstd/rt/backtrace.rs
index 5557ef9943b..f4887a143d1 100644
--- a/src/libstd/rt/backtrace.rs
+++ b/src/libstd/rt/backtrace.rs
@@ -831,9 +831,11 @@ mod imp {
     mod arch {
         use libc::{c_longlong, c_ulonglong};
         use libc::types::os::arch::extra::{WORD, DWORD, DWORDLONG};
+        use simd;
 
         #[repr(C)]
         pub struct CONTEXT {
+            _align_hack: [simd::u64x2, ..0], // FIXME align on 16-byte
             P1Home: DWORDLONG,
             P2Home: DWORDLONG,
             P3Home: DWORDLONG,
@@ -892,12 +894,14 @@ mod imp {
 
         #[repr(C)]
         pub struct M128A {
+            _align_hack: [simd::u64x2, ..0], // FIXME align on 16-byte
             Low:  c_ulonglong,
             High: c_longlong
         }
 
         #[repr(C)]
         pub struct FLOATING_SAVE_AREA {
+            _align_hack: [simd::u64x2, ..0], // FIXME align on 16-byte
             _Dummy: [u8, ..512] // FIXME: Fill this out
         }
 
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index eac158e664c..5c84745c20c 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -213,13 +213,20 @@ pub static DUMMY_NODE_ID: NodeId = -1;
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub enum TyParamBound {
     TraitTyParamBound(TraitRef),
-    UnboxedFnTyParamBound(UnboxedFnTy),
+    UnboxedFnTyParamBound(P<UnboxedFnBound>),
     RegionTyParamBound(Lifetime)
 }
 
 pub type TyParamBounds = OwnedSlice<TyParamBound>;
 
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
+pub struct UnboxedFnBound {
+    pub path: Path,
+    pub decl: P<FnDecl>,
+    pub ref_id: NodeId,
+}
+
+#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub struct TyParam {
     pub ident: Ident,
     pub id: NodeId,
@@ -531,6 +538,7 @@ pub enum Expr_ {
     ExprField(P<Expr>, SpannedIdent, Vec<P<Ty>>),
     ExprTupField(P<Expr>, Spanned<uint>, Vec<P<Ty>>),
     ExprIndex(P<Expr>, P<Expr>),
+    ExprSlice(P<Expr>, Option<P<Expr>>, Option<P<Expr>>, Mutability),
 
     /// Variable reference, possibly containing `::` and/or
     /// type parameters, e.g. foo::bar::<baz>
@@ -1363,7 +1371,7 @@ mod test {
                 inner: Span {
                     lo: BytePos(11),
                     hi: BytePos(19),
-                    expn_info: None,
+                    expn_id: NO_EXPANSION,
                 },
                 view_items: Vec::new(),
                 items: Vec::new(),
@@ -1373,7 +1381,7 @@ mod test {
             span: Span {
                 lo: BytePos(10),
                 hi: BytePos(20),
-                expn_info: None,
+                expn_id: NO_EXPANSION,
             },
             exported_macros: Vec::new(),
         };
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index 2f30108c27b..9072889463c 100644
--- a/src/libsyntax/codemap.rs
+++ b/src/libsyntax/codemap.rs
@@ -25,7 +25,6 @@ source code snippets, etc.
 
 use serialize::{Encodable, Decodable, Encoder, Decoder};
 use std::cell::RefCell;
-use std::gc::Gc;
 use std::rc::Rc;
 
 pub trait Pos {
@@ -93,10 +92,10 @@ pub struct Span {
     pub hi: BytePos,
     /// Information about where the macro came from, if this piece of
     /// code was created by a macro expansion.
-    pub expn_info: Option<Gc<ExpnInfo>>
+    pub expn_id: ExpnId
 }
 
-pub static DUMMY_SP: Span = Span { lo: BytePos(0), hi: BytePos(0), expn_info: None };
+pub static DUMMY_SP: Span = Span { lo: BytePos(0), hi: BytePos(0), expn_id: NO_EXPANSION };
 
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub struct Spanned<T> {
@@ -140,17 +139,19 @@ pub fn dummy_spanned<T>(t: T) -> Spanned<T> {
 
 /* assuming that we're not in macro expansion */
 pub fn mk_sp(lo: BytePos, hi: BytePos) -> Span {
-    Span {lo: lo, hi: hi, expn_info: None}
+    Span {lo: lo, hi: hi, expn_id: NO_EXPANSION}
 }
 
 /// Return the span itself if it doesn't come from a macro expansion,
 /// otherwise return the call site span up to the `enclosing_sp` by
 /// following the `expn_info` chain.
-pub fn original_sp(sp: Span, enclosing_sp: Span) -> Span {
-    match (sp.expn_info, enclosing_sp.expn_info) {
+pub fn original_sp(cm: &CodeMap, sp: Span, enclosing_sp: Span) -> Span {
+    let call_site1 = cm.with_expn_info(sp.expn_id, |ei| ei.map(|ei| ei.call_site));
+    let call_site2 = cm.with_expn_info(enclosing_sp.expn_id, |ei| ei.map(|ei| ei.call_site));
+    match (call_site1, call_site2) {
         (None, _) => sp,
-        (Some(expn1), Some(expn2)) if expn1.call_site == expn2.call_site => sp,
-        (Some(expn1), _) => original_sp(expn1.call_site, enclosing_sp),
+        (Some(call_site1), Some(call_site2)) if call_site1 == call_site2 => sp,
+        (Some(call_site1), _) => original_sp(cm, call_site1, enclosing_sp),
     }
 }
 
@@ -222,6 +223,11 @@ pub struct ExpnInfo {
     pub callee: NameAndSpan
 }
 
+#[deriving(PartialEq, Eq, Clone, Show, Hash)]
+pub struct ExpnId(u32);
+
+pub static NO_EXPANSION: ExpnId = ExpnId(-1);
+
 pub type FileName = String;
 
 pub struct FileLines {
@@ -299,13 +305,15 @@ impl FileMap {
 }
 
 pub struct CodeMap {
-    pub files: RefCell<Vec<Rc<FileMap>>>
+    pub files: RefCell<Vec<Rc<FileMap>>>,
+    expansions: RefCell<Vec<ExpnInfo>>
 }
 
 impl CodeMap {
     pub fn new() -> CodeMap {
         CodeMap {
             files: RefCell::new(Vec::new()),
+            expansions: RefCell::new(Vec::new()),
         }
     }
 
@@ -527,6 +535,19 @@ impl CodeMap {
             col: chpos - linechpos
         }
     }
+
+    pub fn record_expansion(&self, expn_info: ExpnInfo) -> ExpnId {
+        let mut expansions = self.expansions.borrow_mut();
+        expansions.push(expn_info);
+        ExpnId(expansions.len().to_u32().expect("too many ExpnInfo's!") - 1)
+    }
+
+    pub fn with_expn_info<T>(&self, id: ExpnId, f: |Option<&ExpnInfo>| -> T) -> T {
+        match id {
+            NO_EXPANSION => f(None),
+            ExpnId(i) => f(Some(&(*self.expansions.borrow())[i as uint]))
+        }
+    }
 }
 
 #[cfg(test)]
@@ -665,7 +686,7 @@ mod test {
     fn t7() {
         // Test span_to_lines for a span ending at the end of filemap
         let cm = init_code_map();
-        let span = Span {lo: BytePos(12), hi: BytePos(23), expn_info: None};
+        let span = Span {lo: BytePos(12), hi: BytePos(23), expn_id: NO_EXPANSION};
         let file_lines = cm.span_to_lines(span);
 
         assert_eq!(file_lines.file.name, "blork.rs".to_string());
@@ -677,7 +698,7 @@ mod test {
     fn t8() {
         // Test span_to_snippet for a span ending at the end of filemap
         let cm = init_code_map();
-        let span = Span {lo: BytePos(12), hi: BytePos(23), expn_info: None};
+        let span = Span {lo: BytePos(12), hi: BytePos(23), expn_id: NO_EXPANSION};
         let snippet = cm.span_to_snippet(span);
 
         assert_eq!(snippet, Some("second line".to_string()));
@@ -687,7 +708,7 @@ mod test {
     fn t9() {
         // Test span_to_str for a span ending at the end of filemap
         let cm = init_code_map();
-        let span = Span {lo: BytePos(12), hi: BytePos(23), expn_info: None};
+        let span = Span {lo: BytePos(12), hi: BytePos(23), expn_id: NO_EXPANSION};
         let sstr =  cm.span_to_string(span);
 
         assert_eq!(sstr, "blork.rs:2:1: 2:12".to_string());
diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs
index faa3946b74d..f33c768d647 100644
--- a/src/libsyntax/diagnostic.rs
+++ b/src/libsyntax/diagnostic.rs
@@ -389,7 +389,7 @@ fn emit(dst: &mut EmitterWriter, cm: &codemap::CodeMap, rsp: RenderSpan,
         // we want to tell compiletest/runtest to look at the last line of the
         // span (since `custom_highlight_lines` displays an arrow to the end of
         // the span)
-        let span_end = Span { lo: sp.hi, hi: sp.hi, expn_info: sp.expn_info};
+        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.as_slice(), lvl, msg, code));
         if rsp.is_full_span() {
@@ -523,24 +523,24 @@ fn print_macro_backtrace(w: &mut EmitterWriter,
                          cm: &codemap::CodeMap,
                          sp: Span)
                          -> io::IoResult<()> {
-    for ei in sp.expn_info.iter() {
-        let ss = ei.callee
-                   .span
-                   .as_ref()
-                   .map_or("".to_string(), |span| cm.span_to_string(*span));
-        let (pre, post) = match ei.callee.format {
-            codemap::MacroAttribute => ("#[", "]"),
-            codemap::MacroBang => ("", "!")
-        };
-        try!(print_diagnostic(w, ss.as_slice(), Note,
-                              format!("in expansion of {}{}{}", pre,
-                                      ei.callee.name,
-                                      post).as_slice(), None));
-        let ss = cm.span_to_string(ei.call_site);
-        try!(print_diagnostic(w, ss.as_slice(), Note, "expansion site", None));
-        try!(print_macro_backtrace(w, cm, ei.call_site));
-    }
-    Ok(())
+    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.as_slice(), Note,
+                                  format!("in expansion of {}{}{}", pre,
+                                          ei.callee.name,
+                                          post).as_slice(), None));
+            let ss = cm.span_to_string(ei.call_site);
+            try!(print_diagnostic(w, ss.as_slice(), 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))
 }
 
 pub fn expect<T>(diag: &SpanHandler, opt: Option<T>, msg: || -> String) -> T {
diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs
index 132b59c89b2..d3c39284f55 100644
--- a/src/libsyntax/diagnostics/plugin.rs
+++ b/src/libsyntax/diagnostics/plugin.rs
@@ -13,7 +13,7 @@ use std::collections::HashMap;
 use ast;
 use ast::{Ident, Name, TokenTree};
 use codemap::Span;
-use ext::base::{ExtCtxt, MacExpr, MacItem, MacResult};
+use ext::base::{ExtCtxt, MacExpr, MacResult, MacItems};
 use ext::build::AstBuilder;
 use parse::token;
 use ptr::P;
@@ -102,7 +102,7 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt,
     let sym = Ident::new(token::gensym((
         "__register_diagnostic_".to_string() + token::get_ident(*code).get()
     ).as_slice()));
-    MacItem::new(quote_item!(ecx, mod $sym {}).unwrap())
+    MacItems::new(vec![quote_item!(ecx, mod $sym {}).unwrap()].into_iter())
 }
 
 pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt,
@@ -133,7 +133,7 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt,
             (descriptions.len(), ecx.expr_vec(span, descriptions))
         })
     });
-    MacItem::new(quote_item!(ecx,
+    MacItems::new(vec![quote_item!(ecx,
         pub static $name: [(&'static str, &'static str), ..$count] = $expr;
-    ).unwrap())
+    ).unwrap()].into_iter())
 }
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 773daa4a4c5..b35a9456757 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -11,7 +11,7 @@
 use ast;
 use ast::Name;
 use codemap;
-use codemap::{CodeMap, Span, ExpnInfo};
+use codemap::{CodeMap, Span, ExpnId, ExpnInfo, NO_EXPANSION};
 use ext;
 use ext::expand;
 use parse;
@@ -24,7 +24,6 @@ use ext::mtwt;
 use fold::Folder;
 
 use std::collections::HashMap;
-use std::gc::{Gc, GC};
 use std::rc::Rc;
 
 // new-style macro! tt code:
@@ -203,25 +202,20 @@ impl MacResult for MacPat {
         Some(self.p)
     }
 }
-/// A convenience type for macros that return a single item.
-pub struct MacItem {
-    i: P<ast::Item>
+/// A type for macros that return multiple items.
+pub struct MacItems {
+    items: SmallVector<P<ast::Item>>
 }
-impl MacItem {
-    pub fn new(i: P<ast::Item>) -> Box<MacResult+'static> {
-        box MacItem { i: i } as Box<MacResult+'static>
+
+impl MacItems {
+    pub fn new<I: Iterator<P<ast::Item>>>(mut it: I) -> Box<MacResult+'static> {
+        box MacItems { items: it.collect() } as Box<MacResult+'static>
     }
 }
-impl MacResult for MacItem {
-    fn make_items(self: Box<MacItem>) -> Option<SmallVector<P<ast::Item>>> {
-        Some(SmallVector::one(self.i))
-    }
-    fn make_stmt(self: Box<MacItem>) -> Option<P<ast::Stmt>> {
-        Some(P(codemap::respan(
-            self.i.span,
-            ast::StmtDecl(
-                P(codemap::respan(self.i.span, ast::DeclItem(self.i))),
-                ast::DUMMY_NODE_ID))))
+
+impl MacResult for MacItems {
+    fn make_items(self: Box<MacItems>) -> Option<SmallVector<P<ast::Item>>> {
+        Some(self.items)
     }
 }
 
@@ -305,11 +299,11 @@ pub enum SyntaxExtension {
     /// based upon it.
     ///
     /// `#[deriving(...)]` is an `ItemDecorator`.
-    ItemDecorator(Box<ItemDecorator + 'static>),
+    Decorator(Box<ItemDecorator + 'static>),
 
     /// A syntax extension that is attached to an item and modifies it
     /// in-place.
-    ItemModifier(Box<ItemModifier + 'static>),
+    Modifier(Box<ItemModifier + 'static>),
 
     /// A normal, function-like syntax extension.
     ///
@@ -387,7 +381,7 @@ fn initial_syntax_expander_table() -> SyntaxEnv {
                             builtin_normal_expander(
                                     ext::log_syntax::expand_syntax_ext));
     syntax_expanders.insert(intern("deriving"),
-                            ItemDecorator(box ext::deriving::expand_meta_deriving));
+                            Decorator(box ext::deriving::expand_meta_deriving));
 
     // Quasi-quoting expanders
     syntax_expanders.insert(intern("quote_tokens"),
@@ -457,7 +451,7 @@ fn initial_syntax_expander_table() -> SyntaxEnv {
 pub struct ExtCtxt<'a> {
     pub parse_sess: &'a parse::ParseSess,
     pub cfg: ast::CrateConfig,
-    pub backtrace: Option<Gc<ExpnInfo>>,
+    pub backtrace: ExpnId,
     pub ecfg: expand::ExpansionConfig,
 
     pub mod_path: Vec<ast::Ident> ,
@@ -473,7 +467,7 @@ impl<'a> ExtCtxt<'a> {
         ExtCtxt {
             parse_sess: parse_sess,
             cfg: cfg,
-            backtrace: None,
+            backtrace: NO_EXPANSION,
             mod_path: Vec::new(),
             ecfg: ecfg,
             trace_mac: false,
@@ -501,13 +495,49 @@ impl<'a> ExtCtxt<'a> {
     pub fn parse_sess(&self) -> &'a parse::ParseSess { self.parse_sess }
     pub fn cfg(&self) -> ast::CrateConfig { self.cfg.clone() }
     pub fn call_site(&self) -> Span {
-        match self.backtrace {
+        self.codemap().with_expn_info(self.backtrace, |ei| match ei {
             Some(expn_info) => expn_info.call_site,
             None => self.bug("missing top span")
-        }
+        })
     }
     pub fn print_backtrace(&self) { }
-    pub fn backtrace(&self) -> Option<Gc<ExpnInfo>> { self.backtrace }
+    pub fn backtrace(&self) -> ExpnId { self.backtrace }
+    pub fn original_span(&self) -> Span {
+        let mut expn_id = self.backtrace;
+        let mut call_site = None;
+        loop {
+            match self.codemap().with_expn_info(expn_id, |ei| ei.map(|ei| ei.call_site)) {
+                None => break,
+                Some(cs) => {
+                    call_site = Some(cs);
+                    expn_id = cs.expn_id;
+                }
+            }
+        }
+        call_site.expect("missing expansion backtrace")
+    }
+    pub fn original_span_in_file(&self) -> Span {
+        let mut expn_id = self.backtrace;
+        let mut call_site = None;
+        loop {
+            let expn_info = self.codemap().with_expn_info(expn_id, |ei| {
+                ei.map(|ei| (ei.call_site, ei.callee.name.as_slice() == "include"))
+            });
+            match expn_info {
+                None => break,
+                Some((cs, is_include)) => {
+                    if is_include {
+                        // Don't recurse into file using "include!".
+                        break;
+                    }
+                    call_site = Some(cs);
+                    expn_id = cs.expn_id;
+                }
+            }
+        }
+        call_site.expect("missing expansion backtrace")
+    }
+
     pub fn mod_push(&mut self, i: ast::Ident) { self.mod_path.push(i); }
     pub fn mod_pop(&mut self) { self.mod_path.pop().unwrap(); }
     pub fn mod_path(&self) -> Vec<ast::Ident> {
@@ -516,22 +546,22 @@ impl<'a> ExtCtxt<'a> {
         v.extend(self.mod_path.iter().map(|a| *a));
         return v;
     }
-    pub fn bt_push(&mut self, ei: codemap::ExpnInfo) {
-        match ei {
-            ExpnInfo {call_site: cs, callee: ref callee} => {
-                self.backtrace =
-                    Some(box(GC) ExpnInfo {
-                        call_site: Span {lo: cs.lo, hi: cs.hi,
-                                         expn_info: self.backtrace.clone()},
-                        callee: (*callee).clone()
-                    });
-            }
-        }
+    pub fn bt_push(&mut self, ei: ExpnInfo) {
+        let mut call_site = ei.call_site;
+        call_site.expn_id = self.backtrace;
+        self.backtrace = self.codemap().record_expansion(ExpnInfo {
+            call_site: call_site,
+            callee: ei.callee
+        });
     }
     pub fn bt_pop(&mut self) {
         match self.backtrace {
-            Some(expn_info) => self.backtrace = expn_info.call_site.expn_info,
-            _ => self.bug("tried to pop without a push")
+            NO_EXPANSION => self.bug("tried to pop without a push"),
+            expn_id => {
+                self.backtrace = self.codemap().with_expn_info(expn_id, |expn_info| {
+                    expn_info.map_or(NO_EXPANSION, |ei| ei.call_site.expn_id)
+                });
+            }
         }
     }
     /// Emit `msg` attached to `sp`, and stop compilation immediately.
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 7b2613d4e8b..16ecd83180e 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -573,7 +573,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
         let field_span = Span {
             lo: sp.lo - Pos::from_uint(field_name.get().len()),
             hi: sp.hi,
-            expn_info: sp.expn_info,
+            expn_id: sp.expn_id,
         };
 
         let id = Spanned { node: ident, span: field_span };
@@ -583,7 +583,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
         let field_span = Span {
             lo: sp.lo - Pos::from_uint(idx.to_string().len()),
             hi: sp.hi,
-            expn_info: sp.expn_info,
+            expn_id: sp.expn_id,
         };
 
         let id = Spanned { node: idx, span: field_span };
diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs
index ff249495bd7..142adc9b721 100644
--- a/src/libsyntax/ext/deriving/generic/mod.rs
+++ b/src/libsyntax/ext/deriving/generic/mod.rs
@@ -181,7 +181,6 @@
 //! ~~~
 
 use std::cell::RefCell;
-use std::gc::GC;
 use std::vec;
 
 use abi::Abi;
@@ -1169,7 +1168,7 @@ impl<'a> TraitDef<'a> {
             None => cx.span_bug(self.span, "trait with empty path in generic `deriving`"),
             Some(name) => *name
         };
-        to_set.expn_info = Some(box(GC) codemap::ExpnInfo {
+        to_set.expn_id = cx.codemap().record_expansion(codemap::ExpnInfo {
             call_site: to_set,
             callee: codemap::NameAndSpan {
                 name: format!("deriving({})", trait_name),
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 4ff9912645a..e173b93e468 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -30,8 +30,6 @@ use util::small_vector::SmallVector;
 use visit;
 use visit::Visitor;
 
-use std::gc::Gc;
-
 enum Either<L,R> {
     Left(L),
     Right(R)
@@ -161,11 +159,11 @@ fn expand_mac_invoc<T>(mac: ast::Mac, span: codemap::Span,
                         // be the root of the call stack. That's the most
                         // relevant span and it's the actual invocation of
                         // the macro.
-                        let mac_span = original_span(fld.cx);
+                        let mac_span = fld.cx.original_span();
 
                         let opt_parsed = {
                             let expanded = expandfun.expand(fld.cx,
-                                                            mac_span.call_site,
+                                                            mac_span,
                                                             marked_before.as_slice());
                             parse_thunk(expanded)
                         };
@@ -254,7 +252,7 @@ pub fn expand_item(it: P<ast::Item>, fld: &mut MacroExpander)
 
         match fld.cx.syntax_env.find(&intern(mname.get())) {
             Some(rc) => match *rc {
-                ItemDecorator(ref dec) => {
+                Decorator(ref dec) => {
                     attr::mark_used(attr);
 
                     fld.cx.bt_push(ExpnInfo {
@@ -311,7 +309,7 @@ fn expand_item_modifiers(mut it: P<ast::Item>, fld: &mut MacroExpander)
     // partition the attributes into ItemModifiers and others
     let (modifiers, other_attrs) = it.attrs.partitioned(|attr| {
         match fld.cx.syntax_env.find(&intern(attr.name().get())) {
-            Some(rc) => match *rc { ItemModifier(_) => true, _ => false },
+            Some(rc) => match *rc { Modifier(_) => true, _ => false },
             _ => false
         }
     });
@@ -330,7 +328,7 @@ fn expand_item_modifiers(mut it: P<ast::Item>, fld: &mut MacroExpander)
 
         match fld.cx.syntax_env.find(&intern(mname.get())) {
             Some(rc) => match *rc {
-                ItemModifier(ref mac) => {
+                Modifier(ref mac) => {
                     attr::mark_used(attr);
                     fld.cx.bt_push(ExpnInfo {
                         call_site: attr.span,
@@ -759,9 +757,9 @@ fn expand_pat(p: P<ast::Pat>, fld: &mut MacroExpander) -> P<ast::Pat> {
 
                     let fm = fresh_mark();
                     let marked_before = mark_tts(tts.as_slice(), fm);
-                    let mac_span = original_span(fld.cx);
+                    let mac_span = fld.cx.original_span();
                     let expanded = match expander.expand(fld.cx,
-                                        mac_span.call_site,
+                                        mac_span,
                                         marked_before.as_slice()).make_pat() {
                         Some(e) => e,
                         None => {
@@ -969,7 +967,7 @@ fn new_span(cx: &ExtCtxt, sp: Span) -> Span {
     Span {
         lo: sp.lo,
         hi: sp.hi,
-        expn_info: cx.backtrace(),
+        expn_id: cx.backtrace(),
     }
 }
 
@@ -1083,21 +1081,6 @@ fn mark_method(expr: P<ast::Method>, m: Mrk) -> P<ast::Method> {
         .expect_one("marking an item didn't return exactly one method")
 }
 
-fn original_span(cx: &ExtCtxt) -> Gc<codemap::ExpnInfo> {
-    let mut relevant_info = cx.backtrace();
-    let mut einfo = relevant_info.unwrap();
-    loop {
-        match relevant_info {
-            None => { break }
-            Some(e) => {
-                einfo = e;
-                relevant_info = einfo.call_site.expn_info;
-            }
-        }
-    }
-    return einfo;
-}
-
 /// Check that there are no macro invocations left in the AST:
 pub fn check_for_macros(sess: &parse::ParseSess, krate: &ast::Crate) {
     visit::walk_crate(&mut MacroExterminator{sess:sess}, krate);
diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs
index 26586684309..b760c893a10 100644
--- a/src/libsyntax/ext/format.rs
+++ b/src/libsyntax/ext/format.rs
@@ -19,17 +19,18 @@ use parse::token;
 use ptr::P;
 
 use std::collections::HashMap;
+use std::string;
 
 #[deriving(PartialEq)]
 enum ArgumentType {
-    Known(String),
+    Known(string::String),
     Unsigned,
     String,
 }
 
 enum Position {
     Exact(uint),
-    Named(String),
+    Named(string::String),
 }
 
 struct Context<'a, 'b:'a> {
@@ -44,12 +45,12 @@ struct Context<'a, 'b:'a> {
     /// Note that we keep a side-array of the ordering of the named arguments
     /// found to be sure that we can translate them in the same order that they
     /// were declared in.
-    names: HashMap<String, P<ast::Expr>>,
-    name_types: HashMap<String, ArgumentType>,
-    name_ordering: Vec<String>,
+    names: HashMap<string::String, P<ast::Expr>>,
+    name_types: HashMap<string::String, ArgumentType>,
+    name_ordering: Vec<string::String>,
 
     /// The latest consecutive literal strings, or empty if there weren't any.
-    literal: String,
+    literal: string::String,
 
     /// Collection of the compiled `rt::Argument` structures
     pieces: Vec<P<ast::Expr>>,
@@ -58,7 +59,7 @@ struct Context<'a, 'b:'a> {
     /// Stays `true` if all formatting parameters are default (as in "{}{}").
     all_pieces_simple: bool,
 
-    name_positions: HashMap<String, uint>,
+    name_positions: HashMap<string::String, uint>,
     method_statics: Vec<P<ast::Item>>,
 
     /// Updated as arguments are consumed or methods are entered
@@ -81,10 +82,10 @@ pub enum Invocation {
 ///           named arguments))
 fn parse_args(ecx: &mut ExtCtxt, sp: Span, allow_method: bool,
               tts: &[ast::TokenTree])
-    -> (Invocation, Option<(P<ast::Expr>, Vec<P<ast::Expr>>, Vec<String>,
-                            HashMap<String, P<ast::Expr>>)>) {
+    -> (Invocation, Option<(P<ast::Expr>, Vec<P<ast::Expr>>, Vec<string::String>,
+                            HashMap<string::String, P<ast::Expr>>)>) {
     let mut args = Vec::new();
-    let mut names = HashMap::<String, P<ast::Expr>>::new();
+    let mut names = HashMap::<string::String, P<ast::Expr>>::new();
     let mut order = Vec::new();
 
     let mut p = ecx.new_parser_from_tts(tts);
@@ -167,7 +168,7 @@ impl<'a, 'b> Context<'a, 'b> {
     fn verify_piece(&mut self, p: &parse::Piece) {
         match *p {
             parse::String(..) => {}
-            parse::Argument(ref arg) => {
+            parse::NextArgument(ref arg) => {
                 // width/precision first, if they have implicit positional
                 // parameters it makes more sense to consume them first.
                 self.verify_count(arg.format.width);
@@ -222,7 +223,7 @@ impl<'a, 'b> Context<'a, 'b> {
         }
     }
 
-    fn describe_num_args(&self) -> String {
+    fn describe_num_args(&self) -> string::String {
         match self.args.len() {
             0 => "no arguments given".to_string(),
             1 => "there is 1 argument".to_string(),
@@ -391,7 +392,7 @@ impl<'a, 'b> Context<'a, 'b> {
                 self.literal.push_str(s);
                 None
             }
-            parse::Argument(ref arg) => {
+            parse::NextArgument(ref arg) => {
                 // Translate the position
                 let pos = match arg.position {
                     // These two have a direct mapping
@@ -747,8 +748,8 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
                                     invocation: Invocation,
                                     efmt: P<ast::Expr>,
                                     args: Vec<P<ast::Expr>>,
-                                    name_ordering: Vec<String>,
-                                    names: HashMap<String, P<ast::Expr>>)
+                                    name_ordering: Vec<string::String>,
+                                    names: HashMap<string::String, P<ast::Expr>>)
                                     -> P<ast::Expr> {
     let arg_types = Vec::from_fn(args.len(), |_| None);
     let mut cx = Context {
@@ -761,7 +762,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
         name_ordering: name_ordering,
         nest_level: 0,
         next_arg: 0,
-        literal: String::new(),
+        literal: string::String::new(),
         pieces: Vec::new(),
         str_pieces: Vec::new(),
         all_pieces_simple: true,
diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs
index 5cc0ec4a122..41967b0680c 100644
--- a/src/libsyntax/ext/source_util.rs
+++ b/src/libsyntax/ext/source_util.rs
@@ -11,7 +11,6 @@
 use ast;
 use codemap;
 use codemap::{Pos, Span};
-use codemap::{ExpnInfo, NameAndSpan};
 use ext::base::*;
 use ext::base;
 use ext::build::AstBuilder;
@@ -19,7 +18,6 @@ use parse;
 use parse::token;
 use print::pprust;
 
-use std::gc::Gc;
 use std::io::File;
 use std::rc::Rc;
 
@@ -32,10 +30,10 @@ pub fn expand_line(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                    -> Box<base::MacResult+'static> {
     base::check_zero_tts(cx, sp, tts, "line!");
 
-    let topmost = topmost_expn_info(cx.backtrace().unwrap());
-    let loc = cx.codemap().lookup_char_pos(topmost.call_site.lo);
+    let topmost = cx.original_span_in_file();
+    let loc = cx.codemap().lookup_char_pos(topmost.lo);
 
-    base::MacExpr::new(cx.expr_uint(topmost.call_site, loc.line))
+    base::MacExpr::new(cx.expr_uint(topmost, loc.line))
 }
 
 /* col!(): expands to the current column number */
@@ -43,9 +41,9 @@ pub fn expand_col(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                   -> Box<base::MacResult+'static> {
     base::check_zero_tts(cx, sp, tts, "col!");
 
-    let topmost = topmost_expn_info(cx.backtrace().unwrap());
-    let loc = cx.codemap().lookup_char_pos(topmost.call_site.lo);
-    base::MacExpr::new(cx.expr_uint(topmost.call_site, loc.col.to_uint()))
+    let topmost = cx.original_span_in_file();
+    let loc = cx.codemap().lookup_char_pos(topmost.lo);
+    base::MacExpr::new(cx.expr_uint(topmost, loc.col.to_uint()))
 }
 
 /// file!(): expands to the current filename */
@@ -55,10 +53,10 @@ pub fn expand_file(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                    -> Box<base::MacResult+'static> {
     base::check_zero_tts(cx, sp, tts, "file!");
 
-    let topmost = topmost_expn_info(cx.backtrace().unwrap());
-    let loc = cx.codemap().lookup_char_pos(topmost.call_site.lo);
+    let topmost = cx.original_span_in_file();
+    let loc = cx.codemap().lookup_char_pos(topmost.lo);
     let filename = token::intern_and_get_ident(loc.file.name.as_slice());
-    base::MacExpr::new(cx.expr_str(topmost.call_site, filename))
+    base::MacExpr::new(cx.expr_str(topmost, filename))
 }
 
 pub fn expand_stringify(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
@@ -162,32 +160,6 @@ pub fn expand_include_bin(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
     }
 }
 
-// recur along an ExpnInfo chain to find the original expression
-fn topmost_expn_info(expn_info: Gc<codemap::ExpnInfo>) -> Gc<codemap::ExpnInfo> {
-    match *expn_info {
-        ExpnInfo { call_site: ref call_site, .. } => {
-            match call_site.expn_info {
-                Some(next_expn_info) => {
-                    match *next_expn_info {
-                        ExpnInfo {
-                            callee: NameAndSpan { name: ref name, .. },
-                            ..
-                        } => {
-                            // Don't recurse into file using "include!"
-                            if "include" == name.as_slice() {
-                                expn_info
-                            } else {
-                                topmost_expn_info(next_expn_info)
-                            }
-                        }
-                    }
-                },
-                None => expn_info
-            }
-        }
-    }
-}
-
 // resolve a file-system path to an absolute file-system path (if it
 // isn't already)
 fn res_rel_file(cx: &mut ExtCtxt, sp: codemap::Span, arg: &Path) -> Path {
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 3beba5bcda4..7ebb11c148b 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -657,16 +657,26 @@ pub fn noop_fold_fn_decl<T: Folder>(decl: P<FnDecl>, fld: &mut T) -> P<FnDecl> {
     })
 }
 
-pub fn noop_fold_ty_param_bound<T: Folder>(tpb: TyParamBound, fld: &mut T)
-                                           -> TyParamBound {
+pub fn noop_fold_ty_param_bound<T>(tpb: TyParamBound, fld: &mut T)
+                                   -> TyParamBound
+                                   where T: Folder {
     match tpb {
         TraitTyParamBound(ty) => TraitTyParamBound(fld.fold_trait_ref(ty)),
         RegionTyParamBound(lifetime) => RegionTyParamBound(fld.fold_lifetime(lifetime)),
-        UnboxedFnTyParamBound(UnboxedFnTy {decl, kind}) => {
-            UnboxedFnTyParamBound(UnboxedFnTy {
-                decl: fld.fold_fn_decl(decl),
-                kind: kind,
-            })
+        UnboxedFnTyParamBound(bound) => {
+            match *bound {
+                UnboxedFnBound {
+                    ref path,
+                    ref decl,
+                    ref_id
+                } => {
+                    UnboxedFnTyParamBound(P(UnboxedFnBound {
+                        path: fld.fold_path(path.clone()),
+                        decl: fld.fold_fn_decl(decl.clone()),
+                        ref_id: fld.new_id(ref_id),
+                    }))
+                }
+            }
         }
     }
 }
@@ -1242,6 +1252,12 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span}: Expr, folder: &mut T) ->
             ExprIndex(el, er) => {
                 ExprIndex(folder.fold_expr(el), folder.fold_expr(er))
             }
+            ExprSlice(e, e1, e2, m) => {
+                ExprSlice(folder.fold_expr(e),
+                          e1.map(|x| folder.fold_expr(x)),
+                          e2.map(|x| folder.fold_expr(x)),
+                          m)
+            }
             ExprPath(pth) => ExprPath(folder.fold_path(pth)),
             ExprBreak(opt_ident) => ExprBreak(opt_ident.map(|x| folder.fold_ident(x))),
             ExprAgain(opt_ident) => ExprAgain(opt_ident.map(|x| folder.fold_ident(x))),
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 457d77efb70..153b3cc90d6 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -23,7 +23,7 @@
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/master/")]
 
-#![feature(macro_rules, globs, managed_boxes, default_type_params, phase)]
+#![feature(macro_rules, globs, default_type_params, phase)]
 #![feature(quote, struct_variant, unsafe_destructor, import_shadowing)]
 #![allow(deprecated)]
 
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index da43f08a4e5..68ddd17dd01 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -1406,7 +1406,7 @@ fn ident_continue(c: Option<char>) -> bool {
 mod test {
     use super::*;
 
-    use codemap::{BytePos, CodeMap, Span};
+    use codemap::{BytePos, CodeMap, Span, NO_EXPANSION};
     use diagnostic;
     use parse::token;
     use parse::token::{str_to_ident};
@@ -1436,7 +1436,7 @@ mod test {
         let tok1 = string_reader.next_token();
         let tok2 = TokenAndSpan{
             tok:token::IDENT(id, false),
-            sp:Span {lo:BytePos(21),hi:BytePos(23),expn_info: None}};
+            sp:Span {lo:BytePos(21),hi:BytePos(23),expn_id: NO_EXPANSION}};
         assert_eq!(tok1,tok2);
         assert_eq!(string_reader.next_token().tok, token::WS);
         // the 'main' id is already read:
@@ -1445,7 +1445,7 @@ mod test {
         let tok3 = string_reader.next_token();
         let tok4 = TokenAndSpan{
             tok:token::IDENT(str_to_ident("main"), false),
-            sp:Span {lo:BytePos(24),hi:BytePos(28),expn_info: None}};
+            sp:Span {lo:BytePos(24),hi:BytePos(28),expn_id: NO_EXPANSION}};
         assert_eq!(tok3,tok4);
         // the lparen is already read:
         assert_eq!(string_reader.last_pos.clone(), BytePos(29))
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index d73cb211694..66ecdbfca02 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -721,7 +721,7 @@ pub fn integer_lit(s: &str, sd: &SpanHandler, sp: Span) -> ast::Lit_ {
 mod test {
     use super::*;
     use serialize::json;
-    use codemap::{Span, BytePos, Spanned};
+    use codemap::{Span, BytePos, Spanned, NO_EXPANSION};
     use owned_slice::OwnedSlice;
     use ast;
     use abi;
@@ -736,7 +736,7 @@ mod test {
 
     // produce a codemap::span
     fn sp(a: u32, b: u32) -> Span {
-        Span{lo:BytePos(a),hi:BytePos(b),expn_info:None}
+        Span {lo: BytePos(a), hi: BytePos(b), expn_id: NO_EXPANSION}
     }
 
     #[test] fn path_exprs_1() {
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index ff4fd41fbd7..069d30cbd83 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -23,7 +23,7 @@ use ast::{DeclLocal, DefaultBlock, UnDeref, BiDiv, EMPTY_CTXT, EnumDef, Explicit
 use ast::{Expr, Expr_, ExprAddrOf, ExprMatch, ExprAgain};
 use ast::{ExprAssign, ExprAssignOp, ExprBinary, ExprBlock, ExprBox};
 use ast::{ExprBreak, ExprCall, ExprCast};
-use ast::{ExprField, ExprTupField, ExprFnBlock, ExprIf, ExprIndex};
+use ast::{ExprField, ExprTupField, ExprFnBlock, ExprIf, ExprIndex, ExprSlice};
 use ast::{ExprLit, ExprLoop, ExprMac};
 use ast::{ExprMethodCall, ExprParen, ExprPath, ExprProc};
 use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary, ExprUnboxedFn};
@@ -55,7 +55,8 @@ use ast::{TyTypeof, TyInfer, TypeMethod};
 use ast::{TyNil, TyParam, TyParamBound, TyParen, TyPath, TyPtr, TyQPath};
 use ast::{TyRptr, TyTup, TyU32, TyUnboxedFn, TyUniq, TyVec, UnUniq};
 use ast::{TypeImplItem, TypeTraitItem, Typedef, UnboxedClosureKind};
-use ast::{UnboxedFnTy, UnboxedFnTyParamBound, UnnamedField, UnsafeBlock};
+use ast::{UnboxedFnBound, UnboxedFnTy, UnboxedFnTyParamBound};
+use ast::{UnnamedField, UnsafeBlock};
 use ast::{UnsafeFn, ViewItem, ViewItem_, ViewItemExternCrate, ViewItemUse};
 use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
 use ast::{Visibility, WhereClause, WherePredicate};
@@ -1986,6 +1987,14 @@ impl<'a> Parser<'a> {
         ExprIndex(expr, idx)
     }
 
+    pub fn mk_slice(&mut self, expr: P<Expr>,
+                    start: Option<P<Expr>>,
+                    end: Option<P<Expr>>,
+                    mutbl: Mutability)
+                    -> ast::Expr_ {
+        ExprSlice(expr, start, end, mutbl)
+    }
+
     pub fn mk_field(&mut self, expr: P<Expr>, ident: ast::SpannedIdent,
                     tys: Vec<P<Ty>>) -> ast::Expr_ {
         ExprField(expr, ident, tys)
@@ -2400,13 +2409,87 @@ impl<'a> Parser<'a> {
               }
 
               // expr[...]
+              // Could be either an index expression or a slicing expression.
+              // Any slicing non-terminal can have a mutable version with `mut`
+              // after the opening square bracket.
               token::LBRACKET => {
                 self.bump();
-                let ix = self.parse_expr();
-                hi = self.span.hi;
-                self.commit_expr_expecting(&*ix, token::RBRACKET);
-                let index = self.mk_index(e, ix);
-                e = self.mk_expr(lo, hi, index)
+                let mutbl = if self.eat_keyword(keywords::Mut) {
+                    MutMutable
+                } else {
+                    MutImmutable
+                };
+                match self.token {
+                    // e[]
+                    token::RBRACKET => {
+                        self.bump();
+                        hi = self.span.hi;
+                        let slice = self.mk_slice(e, None, None, mutbl);
+                        e = self.mk_expr(lo, hi, slice)
+                    }
+                    // e[..e]
+                    token::DOTDOT => {
+                        self.bump();
+                        match self.token {
+                            // e[..]
+                            token::RBRACKET => {
+                                self.bump();
+                                hi = self.span.hi;
+                                let slice = self.mk_slice(e, None, None, mutbl);
+                                e = self.mk_expr(lo, hi, slice);
+
+                                self.span_err(e.span, "incorrect slicing expression: `[..]`");
+                                self.span_note(e.span,
+                                    "use `expr[]` to construct a slice of the whole of expr");
+                            }
+                            // e[..e]
+                            _ => {
+                                hi = self.span.hi;
+                                let e2 = self.parse_expr();
+                                self.commit_expr_expecting(&*e2, token::RBRACKET);
+                                let slice = self.mk_slice(e, None, Some(e2), mutbl);
+                                e = self.mk_expr(lo, hi, slice)
+                            }
+                        }
+                    }
+                    // e[e] | e[e..] | e[e..e]
+                    _ => {
+                        let ix = self.parse_expr();
+                        match self.token {
+                            // e[e..] | e[e..e]
+                            token::DOTDOT => {
+                                self.bump();
+                                let e2 = match self.token {
+                                    // e[e..]
+                                    token::RBRACKET => {
+                                        self.bump();
+                                        None
+                                    }
+                                    // e[e..e]
+                                    _ => {
+                                        let e2 = self.parse_expr();
+                                        self.commit_expr_expecting(&*e2, token::RBRACKET);
+                                        Some(e2)
+                                    }
+                                };
+                                hi = self.span.hi;
+                                let slice = self.mk_slice(e, Some(ix), e2, mutbl);
+                                e = self.mk_expr(lo, hi, slice)
+                            }
+                            // e[e]
+                            _ => {
+                                if mutbl == ast::MutMutable {
+                                    self.span_err(e.span,
+                                                  "`mut` keyword is invalid in index expressions");
+                                }
+                                hi = self.span.hi;
+                                self.commit_expr_expecting(&*ix, token::RBRACKET);
+                                let index = self.mk_index(e, ix);
+                                e = self.mk_expr(lo, hi, index)
+                            }
+                        }
+                    }
+                }
               }
 
               _ => return e
@@ -3153,7 +3236,8 @@ impl<'a> Parser<'a> {
             // These expressions are limited to literals (possibly
             // preceded by unary-minus) or identifiers.
             let val = self.parse_literal_maybe_minus();
-            if self.token == token::DOTDOT &&
+            // FIXME(#17295) remove the DOTDOT option.
+            if (self.token == token::DOTDOTDOT || self.token == token::DOTDOT) &&
                     self.look_ahead(1, |t| {
                         *t != token::COMMA && *t != token::RBRACKET
                     }) {
@@ -3198,12 +3282,16 @@ impl<'a> Parser<'a> {
                 }
             });
 
-            if self.look_ahead(1, |t| *t == token::DOTDOT) &&
+            // FIXME(#17295) remove the DOTDOT option.
+            if self.look_ahead(1, |t| *t == token::DOTDOTDOT || *t == token::DOTDOT) &&
                     self.look_ahead(2, |t| {
                         *t != token::COMMA && *t != token::RBRACKET
                     }) {
                 let start = self.parse_expr_res(RestrictionNoBarOp);
-                self.eat(&token::DOTDOT);
+                // FIXME(#17295) remove the DOTDOT option (self.eat(&token::DOTDOTDOT)).
+                if self.token == token::DOTDOTDOT || self.token == token::DOTDOT {
+                    self.bump();
+                }
                 let end = self.parse_expr_res(RestrictionNoBarOp);
                 pat = PatRange(start, end);
             } else if is_plain_ident(&self.token) && !can_be_enum_or_struct {
@@ -3590,7 +3678,7 @@ impl<'a> Parser<'a> {
                                     let span_with_semi = Span {
                                         lo: span.lo,
                                         hi: self.last_span.hi,
-                                        expn_info: span.expn_info,
+                                        expn_id: span.expn_id,
                                     };
                                     stmts.push(P(Spanned {
                                         node: StmtSemi(e, stmt_id),
@@ -3666,39 +3754,6 @@ impl<'a> Parser<'a> {
         })
     }
 
-    fn parse_unboxed_function_type(&mut self) -> UnboxedFnTy {
-        let (optional_unboxed_closure_kind, inputs) =
-            if self.eat(&token::OROR) {
-                (None, Vec::new())
-            } else {
-                self.expect_or();
-
-                let optional_unboxed_closure_kind =
-                    self.parse_optional_unboxed_closure_kind();
-
-                let inputs = self.parse_seq_to_before_or(&token::COMMA,
-                                                         |p| {
-                    p.parse_arg_general(false)
-                });
-                self.expect_or();
-                (optional_unboxed_closure_kind, inputs)
-            };
-
-        let (return_style, output) = self.parse_ret_ty();
-        UnboxedFnTy {
-            decl: P(FnDecl {
-                inputs: inputs,
-                output: output,
-                cf: return_style,
-                variadic: false,
-            }),
-            kind: match optional_unboxed_closure_kind {
-                Some(kind) => kind,
-                None => FnMutUnboxedClosureKind,
-            },
-        }
-    }
-
     // Parses a sequence of bounds if a `:` is found,
     // otherwise returns empty list.
     fn parse_colon_then_ty_param_bounds(&mut self)
@@ -3730,13 +3785,31 @@ impl<'a> Parser<'a> {
                     self.bump();
                 }
                 token::MOD_SEP | token::IDENT(..) => {
-                    let tref = self.parse_trait_ref();
-                    result.push(TraitTyParamBound(tref));
-                }
-                token::BINOP(token::OR) | token::OROR => {
-                    let unboxed_function_type =
-                        self.parse_unboxed_function_type();
-                    result.push(UnboxedFnTyParamBound(unboxed_function_type));
+                    let path =
+                        self.parse_path(LifetimeAndTypesWithoutColons).path;
+                    if self.token == token::LPAREN {
+                        self.bump();
+                        let inputs = self.parse_seq_to_end(
+                            &token::RPAREN,
+                            seq_sep_trailing_allowed(token::COMMA),
+                            |p| p.parse_arg_general(false));
+                        let (return_style, output) = self.parse_ret_ty();
+                        result.push(UnboxedFnTyParamBound(P(UnboxedFnBound {
+                            path: path,
+                            decl: P(FnDecl {
+                                inputs: inputs,
+                                output: output,
+                                cf: return_style,
+                                variadic: false,
+                            }),
+                            ref_id: ast::DUMMY_NODE_ID,
+                        })));
+                    } else {
+                        result.push(TraitTyParamBound(ast::TraitRef {
+                            path: path,
+                            ref_id: ast::DUMMY_NODE_ID,
+                        }))
+                    }
                 }
                 _ => break,
             }
@@ -4423,14 +4496,6 @@ impl<'a> Parser<'a> {
          Some(attrs))
     }
 
-    /// Parse a::B<String,int>
-    fn parse_trait_ref(&mut self) -> TraitRef {
-        ast::TraitRef {
-            path: self.parse_path(LifetimeAndTypesWithoutColons).path,
-            ref_id: ast::DUMMY_NODE_ID,
-        }
-    }
-
     /// Parse struct Foo { ... }
     fn parse_item_struct(&mut self, is_virtual: bool) -> ItemInfo {
         let class_name = self.parse_ident();
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 5a0aeece272..f71190da430 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -431,9 +431,11 @@ macro_rules! declare_special_idents_and_keywords {(
 // If the special idents get renumbered, remember to modify these two as appropriate
 pub static SELF_KEYWORD_NAME: Name = Name(SELF_KEYWORD_NAME_NUM);
 static STATIC_KEYWORD_NAME: Name = Name(STATIC_KEYWORD_NAME_NUM);
+static SUPER_KEYWORD_NAME: Name = Name(SUPER_KEYWORD_NAME_NUM);
 
 pub static SELF_KEYWORD_NAME_NUM: u32 = 1;
 static STATIC_KEYWORD_NAME_NUM: u32 = 2;
+static SUPER_KEYWORD_NAME_NUM: u32 = 3;
 
 // NB: leaving holes in the ident table is bad! a different ident will get
 // interned with the id from the hole, but it will be between the min and max
@@ -443,52 +445,53 @@ declare_special_idents_and_keywords! {
     pub mod special_idents {
         // These ones are statics
         (0,                          invalid,                "");
-        (super::SELF_KEYWORD_NAME_NUM,   self_,                  "self");
-        (super::STATIC_KEYWORD_NAME_NUM, statik,                 "static");
-        (3,                          static_lifetime,        "'static");
+        (super::SELF_KEYWORD_NAME_NUM,   self_,              "self");
+        (super::STATIC_KEYWORD_NAME_NUM, statik,             "static");
+        (super::SUPER_KEYWORD_NAME_NUM, super_,              "super");
+        (4,                          static_lifetime,        "'static");
 
         // for matcher NTs
-        (4,                          tt,                     "tt");
-        (5,                          matchers,               "matchers");
+        (5,                          tt,                     "tt");
+        (6,                          matchers,               "matchers");
 
         // outside of libsyntax
-        (6,                          clownshoe_abi,          "__rust_abi");
-        (7,                          opaque,                 "<opaque>");
-        (8,                          unnamed_field,          "<unnamed_field>");
-        (9,                          type_self,              "Self");
-        (10,                         prelude_import,         "prelude_import");
+        (7,                          clownshoe_abi,          "__rust_abi");
+        (8,                          opaque,                 "<opaque>");
+        (9,                          unnamed_field,          "<unnamed_field>");
+        (10,                         type_self,              "Self");
+        (11,                         prelude_import,         "prelude_import");
     }
 
     pub mod keywords {
         // These ones are variants of the Keyword enum
 
         'strict:
-        (11,                         As,         "as");
-        (12,                         Break,      "break");
-        (13,                         Crate,      "crate");
-        (14,                         Else,       "else");
-        (15,                         Enum,       "enum");
-        (16,                         Extern,     "extern");
-        (17,                         False,      "false");
-        (18,                         Fn,         "fn");
-        (19,                         For,        "for");
-        (20,                         If,         "if");
-        (21,                         Impl,       "impl");
-        (22,                         In,         "in");
-        (23,                         Let,        "let");
-        (24,                         Loop,       "loop");
-        (25,                         Match,      "match");
-        (26,                         Mod,        "mod");
-        (27,                         Mut,        "mut");
-        (28,                         Once,       "once");
-        (29,                         Pub,        "pub");
-        (30,                         Ref,        "ref");
-        (31,                         Return,     "return");
+        (12,                         As,         "as");
+        (13,                         Break,      "break");
+        (14,                         Crate,      "crate");
+        (15,                         Else,       "else");
+        (16,                         Enum,       "enum");
+        (17,                         Extern,     "extern");
+        (18,                         False,      "false");
+        (19,                         Fn,         "fn");
+        (20,                         For,        "for");
+        (21,                         If,         "if");
+        (22,                         Impl,       "impl");
+        (23,                         In,         "in");
+        (24,                         Let,        "let");
+        (25,                         Loop,       "loop");
+        (26,                         Match,      "match");
+        (27,                         Mod,        "mod");
+        (28,                         Mut,        "mut");
+        (29,                         Once,       "once");
+        (30,                         Pub,        "pub");
+        (31,                         Ref,        "ref");
+        (32,                         Return,     "return");
         // Static and Self are also special idents (prefill de-dupes)
-        (super::STATIC_KEYWORD_NAME_NUM, Static,     "static");
-        (super::SELF_KEYWORD_NAME_NUM,   Self,       "self");
-        (32,                         Struct,     "struct");
-        (33,                         Super,      "super");
+        (super::STATIC_KEYWORD_NAME_NUM, Static, "static");
+        (super::SELF_KEYWORD_NAME_NUM,   Self,   "self");
+        (33,                         Struct,     "struct");
+        (super::SUPER_KEYWORD_NAME_NUM, Super,   "super");
         (34,                         True,       "true");
         (35,                         Trait,      "trait");
         (36,                         Type,       "type");
@@ -713,6 +716,7 @@ pub fn is_any_keyword(tok: &Token) -> bool {
 
                n == SELF_KEYWORD_NAME
             || n == STATIC_KEYWORD_NAME
+            || n == SUPER_KEYWORD_NAME
             || STRICT_KEYWORD_START <= n
             && n <= RESERVED_KEYWORD_FINAL
         },
@@ -727,9 +731,18 @@ pub fn is_strict_keyword(tok: &Token) -> bool {
 
                n == SELF_KEYWORD_NAME
             || n == STATIC_KEYWORD_NAME
+            || n == SUPER_KEYWORD_NAME
             || STRICT_KEYWORD_START <= n
             && n <= STRICT_KEYWORD_FINAL
         },
+        token::IDENT(sid, true) => {
+            let n = sid.name;
+
+               n != SELF_KEYWORD_NAME
+            && n != SUPER_KEYWORD_NAME
+            && STRICT_KEYWORD_START <= n
+            && n <= STRICT_KEYWORD_FINAL
+        }
         _ => false,
     }
 }
diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs
index 70da4e11961..f1fdc71b9c6 100644
--- a/src/libsyntax/print/pp.rs
+++ b/src/libsyntax/print/pp.rs
@@ -60,7 +60,7 @@
 //! avoid combining it with other lines and making matters even worse.
 
 use std::io;
-use std::string::String;
+use std::string;
 
 #[deriving(Clone, PartialEq)]
 pub enum Breaks {
@@ -82,7 +82,7 @@ pub struct BeginToken {
 
 #[deriving(Clone)]
 pub enum Token {
-    String(String, int),
+    String(string::String, int),
     Break(BreakToken),
     Begin(BeginToken),
     End,
@@ -107,7 +107,7 @@ impl Token {
     }
 }
 
-pub fn tok_str(t: Token) -> String {
+pub fn tok_str(t: Token) -> string::String {
     match t {
         String(s, len) => return format!("STR({},{})", s, len),
         Break(_) => return "BREAK".to_string(),
@@ -122,12 +122,12 @@ pub fn buf_str(toks: Vec<Token>,
                left: uint,
                right: uint,
                lim: uint)
-               -> String {
+               -> string::String {
     let n = toks.len();
     assert_eq!(n, szs.len());
     let mut i = left;
     let mut l = lim;
-    let mut s = String::from_str("[");
+    let mut s = string::String::from_str("[");
     while i != right && l != 0u {
         l -= 1u;
         if i != left {
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 0ae5303641b..473179a037a 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1651,6 +1651,28 @@ impl<'a> State<'a> {
                 try!(self.print_expr(&**index));
                 try!(word(&mut self.s, "]"));
             }
+            ast::ExprSlice(ref e, ref start, ref end, ref mutbl) => {
+                try!(self.print_expr(&**e));
+                try!(word(&mut self.s, "["));
+                if mutbl == &ast::MutMutable {
+                    try!(word(&mut self.s, "mut"));
+                    if start.is_some() || end.is_some() {
+                        try!(space(&mut self.s));
+                    }
+                }
+                match start {
+                    &Some(ref e) => try!(self.print_expr(&**e)),
+                    _ => {}
+                }
+                if start.is_some() || end.is_some() {
+                    try!(word(&mut self.s, ".."));
+                }
+                match end {
+                    &Some(ref e) => try!(self.print_expr(&**e)),
+                    _ => {}
+                }
+                try!(word(&mut self.s, "]"));
+            }
             ast::ExprPath(ref path) => try!(self.print_path(path, true)),
             ast::ExprBreak(opt_ident) => {
                 try!(word(&mut self.s, "break"));
@@ -1944,7 +1966,7 @@ impl<'a> State<'a> {
             ast::PatRange(ref begin, ref end) => {
                 try!(self.print_expr(&**begin));
                 try!(space(&mut self.s));
-                try!(word(&mut self.s, ".."));
+                try!(word(&mut self.s, "..."));
                 try!(self.print_expr(&**end));
             }
             ast::PatVec(ref before, ref slice, ref after) => {
@@ -2190,16 +2212,13 @@ impl<'a> State<'a> {
                         self.print_lifetime(lt)
                     }
                     UnboxedFnTyParamBound(ref unboxed_function_type) => {
-                        self.print_ty_fn(None,
-                                         None,
-                                         ast::NormalFn,
-                                         ast::Many,
-                                         &*unboxed_function_type.decl,
-                                         None,
-                                         &OwnedSlice::empty(),
-                                         None,
-                                         None,
-                                         Some(unboxed_function_type.kind))
+                        try!(self.print_path(&unboxed_function_type.path,
+                                             false));
+                        try!(self.popen());
+                        try!(self.print_fn_args(&*unboxed_function_type.decl,
+                                                None));
+                        try!(self.pclose());
+                        self.print_fn_output(&*unboxed_function_type.decl)
                     }
                 })
             }
@@ -2430,6 +2449,23 @@ impl<'a> State<'a> {
         self.end()
     }
 
+    pub fn print_fn_output(&mut self, decl: &ast::FnDecl) -> IoResult<()> {
+        match decl.output.node {
+            ast::TyNil => Ok(()),
+            _ => {
+                try!(self.space_if_not_bol());
+                try!(self.ibox(indent_unit));
+                try!(self.word_space("->"));
+                if decl.cf == ast::NoReturn {
+                    try!(self.word_nbsp("!"));
+                } else {
+                    try!(self.print_type(&*decl.output));
+                }
+                self.end()
+            }
+        }
+    }
+
     pub fn print_ty_fn(&mut self,
                        opt_abi: Option<abi::Abi>,
                        opt_sigil: Option<char>,
@@ -2510,20 +2546,7 @@ impl<'a> State<'a> {
 
         try!(self.maybe_print_comment(decl.output.span.lo));
 
-        match decl.output.node {
-            ast::TyNil => {}
-            _ => {
-                try!(self.space_if_not_bol());
-                try!(self.ibox(indent_unit));
-                try!(self.word_space("->"));
-                if decl.cf == ast::NoReturn {
-                    try!(self.word_nbsp("!"));
-                } else {
-                    try!(self.print_type(&*decl.output));
-                }
-                try!(self.end());
-            }
-        }
+        try!(self.print_fn_output(decl));
 
         match generics {
             Some(generics) => try!(self.print_where_clause(generics)),
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index d425c60f4c9..32084856817 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -785,6 +785,11 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
             visitor.visit_expr(&**main_expression);
             visitor.visit_expr(&**index_expression)
         }
+        ExprSlice(ref main_expression, ref start, ref end, _) => {
+            visitor.visit_expr(&**main_expression);
+            walk_expr_opt(visitor, start);
+            walk_expr_opt(visitor, end)
+        }
         ExprPath(ref path) => {
             visitor.visit_path(path, expression.id)
         }
diff --git a/src/libterm/terminfo/parm.rs b/src/libterm/terminfo/parm.rs
index e6fc64cbd3b..93f773f430d 100644
--- a/src/libterm/terminfo/parm.rs
+++ b/src/libterm/terminfo/parm.rs
@@ -41,7 +41,7 @@ enum FormatState {
 #[allow(missing_doc)]
 #[deriving(Clone)]
 pub enum Param {
-    String(String),
+    Words(String),
     Number(int)
 }
 
@@ -140,8 +140,8 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
                     '{' => state = IntConstant(0),
                     'l' => if stack.len() > 0 {
                         match stack.pop().unwrap() {
-                            String(s) => stack.push(Number(s.len() as int)),
-                            _         => return Err("a non-str was used with %l".to_string())
+                            Words(s) => stack.push(Number(s.len() as int)),
+                            _        => return Err("a non-str was used with %l".to_string())
                         }
                     } else { return Err("stack is empty".to_string()) },
                     '+' => if stack.len() > 1 {
@@ -543,7 +543,7 @@ fn format(val: Param, op: FormatOp, flags: Flags) -> Result<Vec<u8> ,String> {
             }
             s
         }
-        String(s) => {
+        Words(s) => {
             match op {
                 FormatString => {
                     let mut s = Vec::from_slice(s.as_bytes());
@@ -575,7 +575,7 @@ fn format(val: Param, op: FormatOp, flags: Flags) -> Result<Vec<u8> ,String> {
 
 #[cfg(test)]
 mod test {
-    use super::{expand,String,Variables,Number};
+    use super::{expand,Words,Variables,Number};
     use std::result::Ok;
 
     #[test]
@@ -611,7 +611,7 @@ mod test {
             assert!(res.is_err(),
                     "Op {} succeeded incorrectly with 0 stack entries", *cap);
             let p = if *cap == "%s" || *cap == "%l" {
-                String("foo".to_string())
+                Words("foo".to_string())
             } else {
                 Number(97)
             };
@@ -689,12 +689,12 @@ mod test {
         let mut varstruct = Variables::new();
         let vars = &mut varstruct;
         assert_eq!(expand(b"%p1%s%p2%2s%p3%2s%p4%.2s",
-                          [String("foo".to_string()),
-                           String("foo".to_string()),
-                           String("f".to_string()),
-                           String("foo".to_string())], vars),
+                          [Words("foo".to_string()),
+                           Words("foo".to_string()),
+                           Words("f".to_string()),
+                           Words("foo".to_string())], vars),
                    Ok("foofoo ffo".bytes().collect()));
-        assert_eq!(expand(b"%p1%:-4.2s", [String("foo".to_string())], vars),
+        assert_eq!(expand(b"%p1%:-4.2s", [Words("foo".to_string())], vars),
                    Ok("fo  ".bytes().collect()));
 
         assert_eq!(expand(b"%p1%d%p1%.3d%p1%5d%p1%:+d", [Number(1)], vars),
diff --git a/src/test/auxiliary/issue_16723_multiple_items_syntax_ext.rs b/src/test/auxiliary/issue_16723_multiple_items_syntax_ext.rs
new file mode 100644
index 00000000000..269afea52c2
--- /dev/null
+++ b/src/test/auxiliary/issue_16723_multiple_items_syntax_ext.rs
@@ -0,0 +1,33 @@
+// 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.
+//
+// ignore-stage1
+#![feature(plugin_registrar, managed_boxes, quote)]
+#![crate_type = "dylib"]
+
+extern crate syntax;
+extern crate rustc;
+
+use syntax::ast;
+use syntax::codemap;
+use syntax::ext::base::{ExtCtxt, MacResult, MacItems};
+use rustc::plugin::Registry;
+
+#[plugin_registrar]
+pub fn plugin_registrar(reg: &mut Registry) {
+    reg.register_macro("multiple_items", expand)
+}
+
+fn expand(cx: &mut ExtCtxt, _: codemap::Span, _: &[ast::TokenTree]) -> Box<MacResult+'static> {
+    MacItems::new(vec![
+        quote_item!(cx, struct Struct1;).unwrap(),
+        quote_item!(cx, struct Struct2;).unwrap()
+    ].into_iter())
+}
diff --git a/src/test/auxiliary/macro_crate_test.rs b/src/test/auxiliary/macro_crate_test.rs
index dd1f9c3404f..befd33fca4e 100644
--- a/src/test/auxiliary/macro_crate_test.rs
+++ b/src/test/auxiliary/macro_crate_test.rs
@@ -35,7 +35,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
     reg.register_macro("identity", expand_identity);
     reg.register_syntax_extension(
         token::intern("into_foo"),
-        ItemModifier(box expand_into_foo));
+        Modifier(box expand_into_foo));
 }
 
 fn expand_make_a_1(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
diff --git a/src/test/auxiliary/xcrate_unit_struct.rs b/src/test/auxiliary/xcrate_unit_struct.rs
index 7619513a2a6..6487c704765 100644
--- a/src/test/auxiliary/xcrate_unit_struct.rs
+++ b/src/test/auxiliary/xcrate_unit_struct.rs
@@ -15,7 +15,7 @@
 pub struct Struct;
 
 pub enum Unit {
-    Unit,
+    UnitVariant,
     Argument(Struct)
 }
 
diff --git a/src/test/compile-fail/borrowck-closures-unique.rs b/src/test/compile-fail/borrowck-closures-unique.rs
index 80d942e58d1..61c77ce7bba 100644
--- a/src/test/compile-fail/borrowck-closures-unique.rs
+++ b/src/test/compile-fail/borrowck-closures-unique.rs
@@ -43,7 +43,7 @@ fn d(x: &mut int) {
 }
 
 fn e(x: &mut int) {
-    let c1: || = || x = fail!(); //~ ERROR closure cannot assign to immutable argument `x`
+    let c1: || = || x = fail!(); //~ ERROR closure cannot assign to immutable local variable
 }
 
 fn main() {
diff --git a/src/test/compile-fail/borrowck-unboxed-closures.rs b/src/test/compile-fail/borrowck-unboxed-closures.rs
index d822bb22e2a..5f9dd72f5bf 100644
--- a/src/test/compile-fail/borrowck-unboxed-closures.rs
+++ b/src/test/compile-fail/borrowck-unboxed-closures.rs
@@ -10,17 +10,17 @@
 
 #![feature(overloaded_calls)]
 
-fn a<F:|&: int, int| -> int>(mut f: F) {
+fn a<F:Fn(int, int) -> int>(mut f: F) {
     let g = &mut f;
     f(1, 2);    //~ ERROR cannot borrow `f` as immutable
     //~^ ERROR cannot borrow `f` as immutable
 }
 
-fn b<F:|&mut: int, int| -> int>(f: F) {
-    f(1, 2);    //~ ERROR cannot borrow immutable argument
+fn b<F:FnMut(int, int) -> int>(f: F) {
+    f(1, 2);    //~ ERROR cannot borrow immutable local variable
 }
 
-fn c<F:|: int, int| -> int>(f: F) {
+fn c<F:FnOnce(int, int) -> int>(f: F) {
     f(1, 2);
     f(1, 2);    //~ ERROR use of moved value
 }
diff --git a/src/test/compile-fail/enum-variant-type-2.rs b/src/test/compile-fail/enum-variant-type-2.rs
new file mode 100644
index 00000000000..bf80626793d
--- /dev/null
+++ b/src/test/compile-fail/enum-variant-type-2.rs
@@ -0,0 +1,19 @@
+// 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 enum variants are not actually types.
+
+enum Foo {
+    Bar
+}
+
+fn foo(x: Bar) {} //~ERROR found value name used as a type
+
+fn main() {}
diff --git a/src/test/compile-fail/enum-variant-type.rs b/src/test/compile-fail/enum-variant-type.rs
new file mode 100644
index 00000000000..93d44f96c8a
--- /dev/null
+++ b/src/test/compile-fail/enum-variant-type.rs
@@ -0,0 +1,23 @@
+// 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 enum variants are in the type namespace.
+
+enum Foo {
+    Foo //~ERROR duplicate definition of type or module `Foo`
+}
+
+enum Bar {
+    Baz
+}
+
+trait Baz {} //~ERROR duplicate definition of type or module `Baz`
+
+pub fn main() {}
diff --git a/src/test/compile-fail/issue-3008-1.rs b/src/test/compile-fail/issue-3008-1.rs
index 3613fb8ccbe..d2d7d800470 100644
--- a/src/test/compile-fail/issue-3008-1.rs
+++ b/src/test/compile-fail/issue-3008-1.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-enum foo { foo(bar) }
+enum foo { foo_(bar) }
 enum bar { bar_none, bar_some(bar) }
 //~^ ERROR illegal recursive enum type; wrap the inner value in a box to make it representable
 
diff --git a/src/test/compile-fail/issue-3008-2.rs b/src/test/compile-fail/issue-3008-2.rs
index db3124214bd..1e8f81a05e7 100644
--- a/src/test/compile-fail/issue-3008-2.rs
+++ b/src/test/compile-fail/issue-3008-2.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-enum foo { foo(bar) }
+enum foo { foo_(bar) }
 struct bar { x: bar }
 //~^ ERROR illegal recursive struct type; wrap the inner value in a box to make it representable
 //~^^ ERROR this type cannot be instantiated without an instance of itself
diff --git a/src/test/run-pass/issue-3186.rs b/src/test/compile-fail/keywords-followed-by-double-colon.rs
index 6b35cd7e0c9..f69b041597e 100644
--- a/src/test/run-pass/issue-3186.rs
+++ b/src/test/compile-fail/keywords-followed-by-double-colon.rs
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// 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.
 //
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-enum y { x }
+fn main() {
+    struct::foo();  //~ ERROR expected identifier
+    mut::baz(); //~ ERROR expected identifier
+}
 
-enum x {}
-
-pub fn main() {}
diff --git a/src/test/compile-fail/qquote-1.rs b/src/test/compile-fail/qquote-1.rs
index 365a2fbe287..06d473baea8 100644
--- a/src/test/compile-fail/qquote-1.rs
+++ b/src/test/compile-fail/qquote-1.rs
@@ -39,7 +39,7 @@ impl fake_ext_ctxt for fake_session {
         codemap::span {
             lo: codemap::BytePos(0),
             hi: codemap::BytePos(0),
-            expn_info: None
+            expn_id: NO_EXPANSION
         }
     }
     fn ident_of(st: &str) -> ast::ident {
diff --git a/src/test/compile-fail/qquote-2.rs b/src/test/compile-fail/qquote-2.rs
index f202f1bb73c..f63dd91eb2b 100644
--- a/src/test/compile-fail/qquote-2.rs
+++ b/src/test/compile-fail/qquote-2.rs
@@ -36,7 +36,7 @@ impl fake_ext_ctxt for fake_session {
         codemap::span {
             lo: codemap::BytePos(0),
             hi: codemap::BytePos(0),
-            expn_info: None
+            expn_id: codemap::NO_EXPANSION
         }
     }
     fn ident_of(st: &str) -> ast::ident {
diff --git a/src/test/compile-fail/recursion.rs b/src/test/compile-fail/recursion.rs
index 96676257184..c99ec5187b0 100644
--- a/src/test/compile-fail/recursion.rs
+++ b/src/test/compile-fail/recursion.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-enum Nil {Nil}
+enum Nil {NilValue}
 struct Cons<T> {head:int, tail:T}
 trait Dot {fn dot(&self, other:Self) -> int;}
 impl Dot for Nil {
@@ -29,6 +29,6 @@ fn test<T:Dot> (n:int, i:int, first:T, second:T) ->int {
   }
 }
 pub fn main() {
-  let n = test(1, 0, Nil, Nil);
+  let n = test(1, 0, NilValue, NilValue);
   println!("{}", n);
 }
diff --git a/src/test/compile-fail/slice-1.rs b/src/test/compile-fail/slice-1.rs
new file mode 100644
index 00000000000..d0339745c9e
--- /dev/null
+++ b/src/test/compile-fail/slice-1.rs
@@ -0,0 +1,19 @@
+// 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 slicing expr[..] is an error and gives a helpful error message.
+
+struct Foo;
+
+fn main() {
+    let x = Foo;
+    x[..]; //~ ERROR incorrect slicing expression: `[..]`
+    //~^ NOTE use `expr[]` to construct a slice of the whole of expr
+}
diff --git a/src/test/compile-fail/slice-2.rs b/src/test/compile-fail/slice-2.rs
new file mode 100644
index 00000000000..fbfc438321c
--- /dev/null
+++ b/src/test/compile-fail/slice-2.rs
@@ -0,0 +1,25 @@
+// 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 slicing syntax gives errors if we have not implemented the trait.
+
+struct Foo;
+
+fn main() {
+    let x = Foo;
+    x[]; //~ ERROR cannot take a slice of a value with type `Foo`
+    x[Foo..]; //~ ERROR cannot take a slice of a value with type `Foo`
+    x[..Foo]; //~ ERROR cannot take a slice of a value with type `Foo`
+    x[Foo..Foo]; //~ ERROR cannot take a slice of a value with type `Foo`
+    x[mut]; //~ ERROR cannot take a mutable slice of a value with type `Foo`
+    x[mut Foo..]; //~ ERROR cannot take a mutable slice of a value with type `Foo`
+    x[mut ..Foo]; //~ ERROR cannot take a mutable slice of a value with type `Foo`
+    x[mut Foo..Foo]; //~ ERROR cannot take a mutable slice of a value with type `Foo`
+}
diff --git a/src/test/compile-fail/slice-borrow.rs b/src/test/compile-fail/slice-borrow.rs
new file mode 100644
index 00000000000..3d12511134f
--- /dev/null
+++ b/src/test/compile-fail/slice-borrow.rs
@@ -0,0 +1,19 @@
+// 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 slicing expressions doesn't defeat the borrow checker.
+
+fn main() {
+    let y;
+    {
+        let x: &[int] = &[1, 2, 3, 4, 5]; //~ ERROR borrowed value does not live long enough
+        y = x[1..];
+    }
+}
diff --git a/src/test/compile-fail/slice-mut-2.rs b/src/test/compile-fail/slice-mut-2.rs
new file mode 100644
index 00000000000..1176b637cec
--- /dev/null
+++ b/src/test/compile-fail/slice-mut-2.rs
@@ -0,0 +1,17 @@
+// 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 mutability and slicing syntax.
+
+fn main() {
+    let x: &[int] = &[1, 2, 3, 4, 5];
+    // Can't mutably slice an immutable slice
+    let y = x[mut 2..4]; //~ ERROR cannot take a mutable slice of a value with type `&[int]`
+}
diff --git a/src/test/compile-fail/slice-mut.rs b/src/test/compile-fail/slice-mut.rs
new file mode 100644
index 00000000000..8cd7c4ed0bb
--- /dev/null
+++ b/src/test/compile-fail/slice-mut.rs
@@ -0,0 +1,22 @@
+// 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 mutability and slicing syntax.
+
+fn main() {
+    let x: &[int] = &[1, 2, 3, 4, 5];
+    // Immutable slices are not mutable.
+    let y: &mut[_] = x[2..4]; //~ ERROR cannot borrow immutable dereference of `&`-pointer as mutabl
+
+    let x: &mut [int] = &mut [1, 2, 3, 4, 5];
+    // Can't borrow mutably twice
+    let y = x[mut 1..2];
+    let y = x[mut 4..5]; //~ERROR cannot borrow
+}
diff --git a/src/test/compile-fail/unboxed-closure-sugar-nonexistent-trait.rs b/src/test/compile-fail/unboxed-closure-sugar-nonexistent-trait.rs
new file mode 100644
index 00000000000..f51160a1b23
--- /dev/null
+++ b/src/test/compile-fail/unboxed-closure-sugar-nonexistent-trait.rs
@@ -0,0 +1,18 @@
+// 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.
+
+fn f<F:Nonexist(int) -> int>(x: F) {} //~ ERROR unresolved trait
+
+type Typedef = int;
+
+fn g<F:Typedef(int) -> int>(x: F) {} //~ ERROR `Typedef` is not a trait
+
+fn main() {}
+
diff --git a/src/test/compile-fail/unboxed-closure-sugar-wrong-trait.rs b/src/test/compile-fail/unboxed-closure-sugar-wrong-trait.rs
new file mode 100644
index 00000000000..a751ae1c518
--- /dev/null
+++ b/src/test/compile-fail/unboxed-closure-sugar-wrong-trait.rs
@@ -0,0 +1,17 @@
+// 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.
+
+trait Trait {}
+
+fn f<F:Trait(int) -> int>(x: F) {}
+//~^ ERROR unboxed function trait must be one of `Fn`, `FnMut`, or `FnOnce`
+
+fn main() {}
+
diff --git a/src/test/compile-fail/unboxed-closures-wrong-trait.rs b/src/test/compile-fail/unboxed-closures-wrong-trait.rs
index 27f1da75c3a..97ad64a77ba 100644
--- a/src/test/compile-fail/unboxed-closures-wrong-trait.rs
+++ b/src/test/compile-fail/unboxed-closures-wrong-trait.rs
@@ -10,7 +10,7 @@
 
 #![feature(lang_items, overloaded_calls, unboxed_closures)]
 
-fn c<F:|: int, int| -> int>(f: F) -> int {
+fn c<F:FnOnce(int, int) -> int>(f: F) -> int {
     f(5, 6)
 }
 
diff --git a/src/test/pretty/tag-blank-lines.rs b/src/test/pretty/tag-blank-lines.rs
index 93373b0066d..29a3b965251 100644
--- a/src/test/pretty/tag-blank-lines.rs
+++ b/src/test/pretty/tag-blank-lines.rs
@@ -11,8 +11,8 @@
 // pp-exact
 
 enum foo {
-    foo, // a foo.
-    bar,
+    bar, // a bar.
+    baz,
 }
 
 fn main() { }
diff --git a/src/test/run-fail/issue-2444.rs b/src/test/run-fail/issue-2444.rs
index dbe2a9e9229..9a5a8e7c38f 100644
--- a/src/test/run-fail/issue-2444.rs
+++ b/src/test/run-fail/issue-2444.rs
@@ -12,7 +12,7 @@
 
 use std::sync::Arc;
 
-enum e<T> { e(Arc<T>) }
+enum e<T> { ee(Arc<T>) }
 
 fn foo() -> e<int> {fail!();}
 
diff --git a/src/test/run-pass-fulldeps/issue_16723_multiple_items_syntax_ext.rs b/src/test/run-pass-fulldeps/issue_16723_multiple_items_syntax_ext.rs
new file mode 100644
index 00000000000..c5cfabd74e1
--- /dev/null
+++ b/src/test/run-pass-fulldeps/issue_16723_multiple_items_syntax_ext.rs
@@ -0,0 +1,31 @@
+// 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.
+
+// ignore-stage1
+// ignore-android
+// aux-build:issue_16723_multiple_items_syntax_ext.rs
+#![feature(phase)]
+
+#[phase(plugin)] extern crate issue_16723_multiple_items_syntax_ext;
+
+multiple_items!()
+
+impl Struct1 {
+    fn foo() {}
+}
+impl Struct2 {
+    fn foo() {}
+}
+
+fn main() {
+    Struct1::foo();
+    Struct2::foo();
+    println!("hallo");
+}
diff --git a/src/test/run-pass-fulldeps/qquote.rs b/src/test/run-pass-fulldeps/qquote.rs
index a5cf8e46b7e..252d297d12d 100644
--- a/src/test/run-pass-fulldeps/qquote.rs
+++ b/src/test/run-pass-fulldeps/qquote.rs
@@ -41,7 +41,7 @@ impl fake_ext_ctxt for fake_session {
         codemap::span {
             lo: codemap::BytePos(0),
             hi: codemap::BytePos(0),
-            expn_info: None
+            expn_id: codemap::NO_EXPANSION
         }
     }
     fn ident_of(st: &str) -> ast::ident {
diff --git a/src/test/run-pass/borrowck-univariant-enum.rs b/src/test/run-pass/borrowck-univariant-enum.rs
index 0910f02dc29..8192566da19 100644
--- a/src/test/run-pass/borrowck-univariant-enum.rs
+++ b/src/test/run-pass/borrowck-univariant-enum.rs
@@ -13,7 +13,7 @@ use std::cell::Cell;
 use std::gc::GC;
 
 enum newtype {
-    newtype(int)
+    newvar(int)
 }
 
 pub fn main() {
@@ -22,9 +22,9 @@ pub fn main() {
     // specially.
 
     let x = box(GC) Cell::new(5);
-    let y = box(GC) Cell::new(newtype(3));
+    let y = box(GC) Cell::new(newvar(3));
     let z = match y.get() {
-      newtype(b) => {
+      newvar(b) => {
         x.set(x.get() + 1);
         x.get() * b
       }
diff --git a/src/test/run-pass/coerce-to-closure-and-proc.rs b/src/test/run-pass/coerce-to-closure-and-proc.rs
index 15870b627b2..44a3517cc75 100644
--- a/src/test/run-pass/coerce-to-closure-and-proc.rs
+++ b/src/test/run-pass/coerce-to-closure-and-proc.rs
@@ -17,7 +17,7 @@ struct Foo<T>(T);
 
 #[deriving(PartialEq, Show)]
 enum Bar<T> {
-    Bar(T)
+    Baz(T)
 }
 
 pub fn main() {
@@ -33,11 +33,11 @@ pub fn main() {
     let f: proc(int) -> Foo<int> = Foo;
     assert_eq!(f(5), Foo(5));
 
-    let f: |int| -> Bar<int> = Bar;
-    assert_eq!(f(5), Bar(5));
+    let f: |int| -> Bar<int> = Baz;
+    assert_eq!(f(5), Baz(5));
 
-    let f: proc(int) -> Bar<int> = Bar;
-    assert_eq!(f(5), Bar(5));
+    let f: proc(int) -> Bar<int> = Baz;
+    assert_eq!(f(5), Baz(5));
 
     let f: |int| -> Option<int> = Some;
     assert_eq!(f(5), Some(5));
diff --git a/src/test/run-pass/fn-trait-sugar.rs b/src/test/run-pass/fn-trait-sugar.rs
index ccb5634f7a2..b0947f46a86 100644
--- a/src/test/run-pass/fn-trait-sugar.rs
+++ b/src/test/run-pass/fn-trait-sugar.rs
@@ -21,7 +21,7 @@ impl FnMut<(int,),int> for S {
     }
 }
 
-fn call_it<F:|int|->int>(mut f: F, x: int) -> int {
+fn call_it<F:FnMut(int)->int>(mut f: F, x: int) -> int {
     f.call_mut((x,)) + 3
 }
 
diff --git a/src/test/run-pass/issue-2804.rs b/src/test/run-pass/issue-2804.rs
index d4b77ea4976..b160fa34c91 100644
--- a/src/test/run-pass/issue-2804.rs
+++ b/src/test/run-pass/issue-2804.rs
@@ -22,7 +22,7 @@ enum object {
     int_value(i64),
 }
 
-fn lookup(table: json::Object, key: String, default: String) -> String
+fn lookup(table: json::JsonObject, key: String, default: String) -> String
 {
     match table.find(&key.to_string()) {
         option::Some(&json::String(ref s)) => {
diff --git a/src/test/run-pass/issue-3874.rs b/src/test/run-pass/issue-3874.rs
index 40725311f31..75f6a2faa80 100644
--- a/src/test/run-pass/issue-3874.rs
+++ b/src/test/run-pass/issue-3874.rs
@@ -8,10 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-enum PureCounter { PureCounter(uint) }
+enum PureCounter { PureCounterVariant(uint) }
 
 fn each(thing: PureCounter, blk: |v: &uint|) {
-    let PureCounter(ref x) = thing;
+    let PureCounterVariant(ref x) = thing;
     blk(x);
 }
 
diff --git a/src/test/run-pass/match-arm-statics.rs b/src/test/run-pass/match-arm-statics.rs
index a8f6d9c3917..6eb0a4dad1b 100644
--- a/src/test/run-pass/match-arm-statics.rs
+++ b/src/test/run-pass/match-arm-statics.rs
@@ -88,10 +88,10 @@ fn issue_14576() {
 }
 
 fn issue_13731() {
-    enum A { A(()) }
-    static B: A = A(());
+    enum A { AA(()) }
+    static B: A = AA(());
 
-    match A(()) {
+    match AA(()) {
         B => ()
     }
 }
diff --git a/src/test/run-pass/match-range-static.rs b/src/test/run-pass/match-range-static.rs
index 039b3f9a26c..08875699245 100644
--- a/src/test/run-pass/match-range-static.rs
+++ b/src/test/run-pass/match-range-static.rs
@@ -13,7 +13,7 @@ static e: int = 42;
 
 pub fn main() {
     match 7 {
-        s..e => (),
+        s...e => (),
         _ => (),
     }
 }
diff --git a/src/test/compile-fail/sepcomp-lib-lto.rs b/src/test/run-pass/sepcomp-lib-lto.rs
index 59706e20bed..51fd83a54cc 100644
--- a/src/test/compile-fail/sepcomp-lib-lto.rs
+++ b/src/test/run-pass/sepcomp-lib-lto.rs
@@ -8,12 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// Make sure we give a sane error message when the user requests LTO with a
-// library built with -C codegen-units > 1.
+// Check that we can use `-Z lto` when linking against libraries that were
+// separately compiled.
 
 // aux-build:sepcomp_lib.rs
 // compile-flags: -Z lto
-// error-pattern:missing compressed bytecode
 // no-prefer-dynamic
 
 extern crate sepcomp_lib;
diff --git a/src/test/run-pass/slice-2.rs b/src/test/run-pass/slice-2.rs
new file mode 100644
index 00000000000..3c0933a055c
--- /dev/null
+++ b/src/test/run-pass/slice-2.rs
@@ -0,0 +1,69 @@
+// 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 slicing expressions on slices and Vecs.
+
+fn main() {
+    let x: &[int] = &[1, 2, 3, 4, 5];
+    let cmp: &[int] = &[1, 2, 3, 4, 5];
+    assert!(x[] == cmp)
+    let cmp: &[int] = &[3, 4, 5];
+    assert!(x[2..] == cmp)
+    let cmp: &[int] = &[1, 2, 3];
+    assert!(x[..3] == cmp)
+    let cmp: &[int] = &[2, 3, 4];
+    assert!(x[1..4] == cmp)
+
+    let x: Vec<int> = vec![1, 2, 3, 4, 5];
+    let cmp: &[int] = &[1, 2, 3, 4, 5];
+    assert!(x[] == cmp)
+    let cmp: &[int] = &[3, 4, 5];
+    assert!(x[2..] == cmp)
+    let cmp: &[int] = &[1, 2, 3];
+    assert!(x[..3] == cmp)
+    let cmp: &[int] = &[2, 3, 4];
+    assert!(x[1..4] == cmp)
+
+    let x: &mut [int] = &mut [1, 2, 3, 4, 5];
+    {
+        let cmp: &mut [int] = &mut [1, 2, 3, 4, 5];
+        assert!(x[mut] == cmp)
+    }
+    {
+        let cmp: &mut [int] = &mut [3, 4, 5];
+        assert!(x[mut 2..] == cmp)
+    }
+    {
+        let cmp: &mut [int] = &mut [1, 2, 3];
+        assert!(x[mut ..3] == cmp)
+    }
+    {
+        let cmp: &mut [int] = &mut [2, 3, 4];
+        assert!(x[mut 1..4] == cmp)
+    }
+
+    let mut x: Vec<int> = vec![1, 2, 3, 4, 5];
+    {
+        let cmp: &mut [int] = &mut [1, 2, 3, 4, 5];
+        assert!(x[mut] == cmp)
+    }
+    {
+        let cmp: &mut [int] = &mut [3, 4, 5];
+        assert!(x[mut 2..] == cmp)
+    }
+    {
+        let cmp: &mut [int] = &mut [1, 2, 3];
+        assert!(x[mut ..3] == cmp)
+    }
+    {
+        let cmp: &mut [int] = &mut [2, 3, 4];
+        assert!(x[mut 1..4] == cmp)
+    }
+}
diff --git a/src/test/run-pass/slice-fail-1.rs b/src/test/run-pass/slice-fail-1.rs
new file mode 100644
index 00000000000..f6972023a72
--- /dev/null
+++ b/src/test/run-pass/slice-fail-1.rs
@@ -0,0 +1,31 @@
+// 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 is a slicing expr[..] fails, the correct cleanups happen.
+
+use std::task;
+
+struct Foo;
+
+static mut DTOR_COUNT: int = 0;
+
+impl Drop for Foo {
+    fn drop(&mut self) { unsafe { DTOR_COUNT += 1; } }
+}
+
+fn foo() {
+    let x: &[_] = &[Foo, Foo];
+    x[3..4];
+}
+
+fn main() {
+    let _ = task::try(proc() foo());
+    unsafe { assert!(DTOR_COUNT == 2); }
+}
diff --git a/src/test/run-pass/slice-fail-2.rs b/src/test/run-pass/slice-fail-2.rs
new file mode 100644
index 00000000000..cbe65fcd83d
--- /dev/null
+++ b/src/test/run-pass/slice-fail-2.rs
@@ -0,0 +1,35 @@
+// 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 is a slicing expr[..] fails, the correct cleanups happen.
+
+use std::task;
+
+struct Foo;
+
+static mut DTOR_COUNT: int = 0;
+
+impl Drop for Foo {
+    fn drop(&mut self) { unsafe { DTOR_COUNT += 1; } }
+}
+
+fn bar() -> uint {
+    fail!();
+}
+
+fn foo() {
+    let x: &[_] = &[Foo, Foo];
+    x[3..bar()];
+}
+
+fn main() {
+    let _ = task::try(proc() foo());
+    unsafe { assert!(DTOR_COUNT == 2); }
+}
diff --git a/src/test/run-pass/slice.rs b/src/test/run-pass/slice.rs
new file mode 100644
index 00000000000..39feb075add
--- /dev/null
+++ b/src/test/run-pass/slice.rs
@@ -0,0 +1,70 @@
+// 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 slicing sugar.
+
+extern crate core;
+use core::ops::{Slice,SliceMut};
+
+static mut COUNT: uint = 0;
+
+struct Foo;
+
+impl Slice<Foo, Foo> for Foo {
+    fn as_slice_<'a>(&'a self) -> &'a Foo {
+        unsafe { COUNT += 1; }
+        self
+    }
+    fn slice_from_<'a>(&'a self, _from: &Foo) -> &'a Foo {
+        unsafe { COUNT += 1; }
+        self
+    }
+    fn slice_to_<'a>(&'a self, _to: &Foo) -> &'a Foo {
+        unsafe { COUNT += 1; }
+        self
+    }
+    fn slice_<'a>(&'a self, _from: &Foo, _to: &Foo) -> &'a Foo {
+        unsafe { COUNT += 1; }
+        self
+    }
+}
+
+impl SliceMut<Foo, Foo> for Foo {
+    fn as_mut_slice_<'a>(&'a mut self) -> &'a mut Foo {
+        unsafe { COUNT += 1; }
+        self
+    }
+    fn slice_from_mut_<'a>(&'a mut self, _from: &Foo) -> &'a mut Foo {
+        unsafe { COUNT += 1; }
+        self
+    }
+    fn slice_to_mut_<'a>(&'a mut self, _to: &Foo) -> &'a mut Foo {
+        unsafe { COUNT += 1; }
+        self
+    }
+    fn slice_mut_<'a>(&'a mut self, _from: &Foo, _to: &Foo) -> &'a mut Foo {
+        unsafe { COUNT += 1; }
+        self
+    }
+}
+fn main() {
+    let mut x = Foo;
+    x[];
+    x[Foo..];
+    x[..Foo];
+    x[Foo..Foo];
+    x[mut];
+    x[mut Foo..];
+    x[mut ..Foo];
+    x[mut Foo..Foo];
+    unsafe {
+        assert!(COUNT == 8);
+    }
+}
diff --git a/src/test/run-pass/tag-align-dyn-u64.rs b/src/test/run-pass/tag-align-dyn-u64.rs
index 0fc20ef66b3..d6a154edd78 100644
--- a/src/test/run-pass/tag-align-dyn-u64.rs
+++ b/src/test/run-pass/tag-align-dyn-u64.rs
@@ -14,7 +14,7 @@
 use std::mem;
 
 enum Tag<A> {
-    Tag(A)
+    Tag2(A)
 }
 
 struct Rec {
@@ -23,7 +23,7 @@ struct Rec {
 }
 
 fn mk_rec() -> Rec {
-    return Rec { c8:0u8, t:Tag(0u64) };
+    return Rec { c8:0u8, t:Tag2(0u64) };
 }
 
 fn is_8_byte_aligned(u: &Tag<u64>) -> bool {
diff --git a/src/test/run-pass/tag-align-shape.rs b/src/test/run-pass/tag-align-shape.rs
index e161f6887e1..e032a5e4156 100644
--- a/src/test/run-pass/tag-align-shape.rs
+++ b/src/test/run-pass/tag-align-shape.rs
@@ -11,7 +11,7 @@
 extern crate debug;
 
 enum a_tag {
-    a_tag(u64)
+    a_tag_var(u64)
 }
 
 struct t_rec {
@@ -20,8 +20,8 @@ struct t_rec {
 }
 
 pub fn main() {
-    let x = t_rec {c8: 22u8, t: a_tag(44u64)};
+    let x = t_rec {c8: 22u8, t: a_tag_var(44u64)};
     let y = format!("{:?}", x);
     println!("y = {}", y);
-    assert_eq!(y, "t_rec{c8: 22u8, t: a_tag(44u64)}".to_string());
+    assert_eq!(y, "t_rec{c8: 22u8, t: a_tag_var(44u64)}".to_string());
 }
diff --git a/src/test/run-pass/tag-align-u64.rs b/src/test/run-pass/tag-align-u64.rs
index 8942e0b6b5d..398a0939d97 100644
--- a/src/test/run-pass/tag-align-u64.rs
+++ b/src/test/run-pass/tag-align-u64.rs
@@ -14,7 +14,7 @@
 use std::mem;
 
 enum Tag {
-    Tag(u64)
+    TagInner(u64)
 }
 
 struct Rec {
@@ -23,7 +23,7 @@ struct Rec {
 }
 
 fn mk_rec() -> Rec {
-    return Rec { c8:0u8, t:Tag(0u64) };
+    return Rec { c8:0u8, t:TagInner(0u64) };
 }
 
 fn is_8_byte_aligned(u: &Tag) -> bool {
diff --git a/src/test/run-pass/unboxed-closures-all-traits.rs b/src/test/run-pass/unboxed-closures-all-traits.rs
index c362a83e60c..d9120495155 100644
--- a/src/test/run-pass/unboxed-closures-all-traits.rs
+++ b/src/test/run-pass/unboxed-closures-all-traits.rs
@@ -10,15 +10,15 @@
 
 #![feature(lang_items, overloaded_calls, unboxed_closures)]
 
-fn a<F:|&: int, int| -> int>(f: F) -> int {
+fn a<F:Fn(int, int) -> int>(f: F) -> int {
     f(1, 2)
 }
 
-fn b<F:|&mut: int, int| -> int>(mut f: F) -> int {
+fn b<F:FnMut(int, int) -> int>(mut f: F) -> int {
     f(3, 4)
 }
 
-fn c<F:|: int, int| -> int>(f: F) -> int {
+fn c<F:FnOnce(int, int) -> int>(f: F) -> int {
     f(5, 6)
 }
 
diff --git a/src/test/run-pass/unboxed-closures-drop.rs b/src/test/run-pass/unboxed-closures-drop.rs
index f20dddcae54..a455e4d2032 100644
--- a/src/test/run-pass/unboxed-closures-drop.rs
+++ b/src/test/run-pass/unboxed-closures-drop.rs
@@ -41,15 +41,15 @@ impl Drop for Droppable {
     }
 }
 
-fn a<F:|&: int, int| -> int>(f: F) -> int {
+fn a<F:Fn(int, int) -> int>(f: F) -> int {
     f(1, 2)
 }
 
-fn b<F:|&mut: int, int| -> int>(mut f: F) -> int {
+fn b<F:FnMut(int, int) -> int>(mut f: F) -> int {
     f(3, 4)
 }
 
-fn c<F:|: int, int| -> int>(f: F) -> int {
+fn c<F:FnOnce(int, int) -> int>(f: F) -> int {
     f(5, 6)
 }
 
diff --git a/src/test/run-pass/unboxed-closures-single-word-env.rs b/src/test/run-pass/unboxed-closures-single-word-env.rs
index 754b1f70644..aef6956118e 100644
--- a/src/test/run-pass/unboxed-closures-single-word-env.rs
+++ b/src/test/run-pass/unboxed-closures-single-word-env.rs
@@ -13,15 +13,15 @@
 
 #![feature(overloaded_calls, unboxed_closures)]
 
-fn a<F:|&: int, int| -> int>(f: F) -> int {
+fn a<F:Fn(int, int) -> int>(f: F) -> int {
     f(1, 2)
 }
 
-fn b<F:|&mut: int, int| -> int>(mut f: F) -> int {
+fn b<F:FnMut(int, int) -> int>(mut f: F) -> int {
     f(3, 4)
 }
 
-fn c<F:|: int, int| -> int>(f: F) -> int {
+fn c<F:FnOnce(int, int) -> int>(f: F) -> int {
     f(5, 6)
 }
 
diff --git a/src/test/run-pass/unboxed-closures-unique-type-id.rs b/src/test/run-pass/unboxed-closures-unique-type-id.rs
index 55d89d4e4f6..f35daa65a43 100644
--- a/src/test/run-pass/unboxed-closures-unique-type-id.rs
+++ b/src/test/run-pass/unboxed-closures-unique-type-id.rs
@@ -21,8 +21,7 @@
 
 use std::ptr;
 
-pub fn replace_map<'a, T, F>(src: &mut T, prod: F)
-where F: |: T| -> T {
+pub fn replace_map<'a, T, F>(src: &mut T, prod: F) where F: FnOnce(T) -> T {
     unsafe { *src = prod(ptr::read(src as *mut T as *const T)); }
 }
 
diff --git a/src/test/run-pass/where-clauses-unboxed-closures.rs b/src/test/run-pass/where-clauses-unboxed-closures.rs
index ae005b4ae53..808e937bc72 100644
--- a/src/test/run-pass/where-clauses-unboxed-closures.rs
+++ b/src/test/run-pass/where-clauses-unboxed-closures.rs
@@ -13,7 +13,7 @@
 struct Bencher;
 
 // ICE
-fn warm_up<'a, F>(f: F) where F: |&: &'a mut Bencher| {
+fn warm_up<'a, F>(f: F) where F: Fn(&'a mut Bencher) {
 }
 
 fn main() {
diff --git a/src/test/run-pass/xcrate-unit-struct.rs b/src/test/run-pass/xcrate-unit-struct.rs
index ae8d628289d..9ba4b707268 100644
--- a/src/test/run-pass/xcrate-unit-struct.rs
+++ b/src/test/run-pass/xcrate-unit-struct.rs
@@ -12,7 +12,7 @@
 extern crate xcrate_unit_struct;
 
 static s1: xcrate_unit_struct::Struct = xcrate_unit_struct::Struct;
-static s2: xcrate_unit_struct::Unit = xcrate_unit_struct::Unit;
+static s2: xcrate_unit_struct::Unit = xcrate_unit_struct::UnitVariant;
 static s3: xcrate_unit_struct::Unit =
                 xcrate_unit_struct::Argument(xcrate_unit_struct::Struct);
 static s4: xcrate_unit_struct::Unit = xcrate_unit_struct::Argument(s1);
@@ -22,7 +22,7 @@ fn f2(_: xcrate_unit_struct::Unit) {}
 
 pub fn main() {
     f1(xcrate_unit_struct::Struct);
-    f2(xcrate_unit_struct::Unit);
+    f2(xcrate_unit_struct::UnitVariant);
     f2(xcrate_unit_struct::Argument(xcrate_unit_struct::Struct));
 
     f1(s1);