summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS.txt74
-rw-r--r--RELEASES.txt8
-rw-r--r--doc/tutorial-rustpkg.md14
-rw-r--r--doc/tutorial-tasks.md2
-rw-r--r--doc/tutorial.md30
-rw-r--r--mk/docs.mk10
-rwxr-xr-xsrc/etc/combine-tests.py2
-rw-r--r--src/libextra/arc.rs4
-rw-r--r--src/libextra/c_vec.rs59
-rw-r--r--src/libextra/rl.rs52
-rw-r--r--src/libextra/test.rs28
-rw-r--r--src/libextra/workcache.rs12
-rw-r--r--src/librust/rust.rs19
-rw-r--r--src/librustc/driver/driver.rs162
-rw-r--r--src/librustc/front/assign_node_ids.rs17
-rw-r--r--src/librustc/front/config.rs136
-rw-r--r--src/librustc/front/std_inject.rs179
-rw-r--r--src/librustc/front/test.rs177
-rw-r--r--src/librustc/metadata/csearch.rs9
-rw-r--r--src/librustc/metadata/decoder.rs43
-rw-r--r--src/librustc/metadata/encoder.rs23
-rw-r--r--src/librustc/metadata/filesearch.rs2
-rw-r--r--src/librustc/metadata/tydecode.rs3
-rw-r--r--src/librustc/metadata/tyencode.rs2
-rw-r--r--src/librustc/middle/astencode.rs124
-rw-r--r--src/librustc/middle/borrowck/check_loans.rs4
-rw-r--r--src/librustc/middle/borrowck/gather_loans/gather_moves.rs14
-rw-r--r--src/librustc/middle/borrowck/gather_loans/lifetime.rs8
-rw-r--r--src/librustc/middle/borrowck/gather_loans/mod.rs12
-rw-r--r--src/librustc/middle/borrowck/gather_loans/restrictions.rs8
-rw-r--r--src/librustc/middle/borrowck/mod.rs23
-rw-r--r--src/librustc/middle/dataflow.rs79
-rw-r--r--src/librustc/middle/kind.rs21
-rw-r--r--src/librustc/middle/lint.rs24
-rw-r--r--src/librustc/middle/mem_categorization.rs6
-rw-r--r--src/librustc/middle/moves.rs196
-rw-r--r--src/librustc/middle/privacy.rs190
-rw-r--r--src/librustc/middle/resolve.rs30
-rw-r--r--src/librustc/middle/stack_check.rs3
-rw-r--r--src/librustc/middle/trans/_match.rs102
-rw-r--r--src/librustc/middle/trans/base.rs96
-rw-r--r--src/librustc/middle/trans/closure.rs40
-rw-r--r--src/librustc/middle/trans/common.rs141
-rw-r--r--src/librustc/middle/trans/context.rs4
-rw-r--r--src/librustc/middle/trans/debuginfo.rs330
-rw-r--r--src/librustc/middle/trans/glue.rs10
-rw-r--r--src/librustc/middle/ty.rs7
-rw-r--r--src/librustc/middle/typeck/astconv.rs5
-rw-r--r--src/librustc/middle/typeck/check/_match.rs4
-rw-r--r--src/librustc/middle/typeck/check/regionck.rs130
-rw-r--r--src/librustc/middle/typeck/check/vtable.rs22
-rw-r--r--src/librustc/middle/typeck/check/writeback.rs56
-rw-r--r--src/librustc/middle/typeck/mod.rs3
-rw-r--r--src/librustc/rustc.rs49
-rw-r--r--src/librustc/util/common.rs28
-rw-r--r--src/librustdoc/core.rs13
-rw-r--r--src/librustdoc/rustdoc.rs20
-rw-r--r--src/librusti/rusti.rs78
-rw-r--r--src/librusti/utils.rs8
-rw-r--r--src/librustpkg/rustpkg.rs28
-rw-r--r--src/librustpkg/tests.rs9
-rw-r--r--src/librustpkg/util.rs135
-rw-r--r--src/libstd/io.rs32
-rw-r--r--src/libstd/local_data.rs6
-rw-r--r--src/libstd/reflect.rs8
-rw-r--r--src/libstd/routine.rs (renamed from src/test/run-pass/fn-assign-managed-to-bare-2.rs)28
-rw-r--r--src/libstd/rt/crate_map.rs71
-rw-r--r--src/libstd/rt/io/mod.rs2
-rw-r--r--src/libstd/rt/logging.rs6
-rw-r--r--src/libstd/rt/mod.rs13
-rw-r--r--src/libstd/rt/uv/file.rs2
-rw-r--r--src/libstd/std.rs2
-rw-r--r--src/libstd/str.rs4
-rw-r--r--src/libstd/unstable/dynamic_lib.rs4
-rw-r--r--src/libstd/unstable/extfmt.rs22
-rw-r--r--src/libstd/unstable/finally.rs12
-rw-r--r--src/libstd/unstable/lang.rs5
-rw-r--r--src/libsyntax/ast_util.rs103
-rw-r--r--src/libsyntax/diagnostic.rs79
-rw-r--r--src/libsyntax/ext/base.rs239
-rw-r--r--src/libsyntax/ext/build.rs32
-rw-r--r--src/libsyntax/ext/expand.rs497
-rw-r--r--src/libsyntax/ext/fmt.rs2
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs141
-rw-r--r--src/libsyntax/fold.rs1455
-rw-r--r--src/libsyntax/parse/lexer.rs50
-rw-r--r--src/libsyntax/parse/mod.rs58
-rw-r--r--src/libsyntax/parse/obsolete.rs22
-rw-r--r--src/libsyntax/parse/parser.rs48
-rw-r--r--src/libsyntax/print/pprust.rs74
-rw-r--r--src/snapshots.txt8
-rw-r--r--src/test/auxiliary/cci_nested_lib.rs2
-rw-r--r--src/test/auxiliary/issue2378a.rs2
-rw-r--r--src/test/auxiliary/issue2378b.rs2
-rw-r--r--src/test/auxiliary/nested_item.rs2
-rw-r--r--src/test/auxiliary/packed.rs2
-rw-r--r--src/test/auxiliary/static_priv_by_default.rs57
-rw-r--r--src/test/auxiliary/trait_inheritance_overloading_xc.rs2
-rw-r--r--src/test/bench/task-perf-alloc-unwind.rs5
-rw-r--r--src/test/compile-fail/bad-char-literals.rs (renamed from src/test/run-pass/issue-4929.rs)7
-rw-r--r--src/test/compile-fail/bad-char-literals2.rs (renamed from src/test/run-fail/unwind-closure.rs)15
-rw-r--r--src/test/compile-fail/bad-char-literals3.rs (renamed from src/test/auxiliary/issue4516_ty_param_lib.rs)9
-rw-r--r--src/test/compile-fail/bad-char-literals4.rs (renamed from src/test/run-pass/fn-bare-coerce-to-shared.rs)12
-rw-r--r--src/test/compile-fail/borrowck-addr-of-upvar.rs27
-rw-r--r--src/test/compile-fail/borrowck-move-by-capture.rs4
-rw-r--r--src/test/compile-fail/closure-bounds-cant-promote-superkind-in-struct.rs4
-rw-r--r--src/test/compile-fail/dead-code-ret.rs5
-rw-r--r--src/test/compile-fail/do2.rs2
-rw-r--r--src/test/compile-fail/fn-variance-2.rs30
-rw-r--r--src/test/compile-fail/fn-variance-3.rs32
-rw-r--r--src/test/compile-fail/issue-1451.rs8
-rw-r--r--src/test/compile-fail/issue-1896-1.rs26
-rw-r--r--src/test/compile-fail/issue-2074.rs4
-rw-r--r--src/test/compile-fail/issue-897-2.rs4
-rw-r--r--src/test/compile-fail/issue-897.rs2
-rw-r--r--src/test/compile-fail/kindck-owned.rs28
-rw-r--r--src/test/compile-fail/lambda-mutate-nested.rs25
-rw-r--r--src/test/compile-fail/lambda-mutate.rs22
-rw-r--r--src/test/compile-fail/liveness-init-in-called-fn-expr.rs2
-rw-r--r--src/test/compile-fail/liveness-init-in-fn-expr.rs2
-rw-r--r--src/test/compile-fail/missing-derivable-attr.rs2
-rw-r--r--src/test/compile-fail/obsolete-syntax.rs6
-rw-r--r--src/test/compile-fail/priv-in-bad-locations.rs (renamed from src/test/run-pass/issue-5783.rs)23
-rw-r--r--src/test/compile-fail/regions-fn-subtyping.rs16
-rw-r--r--src/test/compile-fail/regions-fns.rs2
-rw-r--r--src/test/compile-fail/regions-infer-at-fn-not-param.rs4
-rw-r--r--src/test/compile-fail/regions-infer-contravariance-due-to-ret.rs2
-rw-r--r--src/test/compile-fail/regions-infer-covariance-due-to-arg.rs2
-rw-r--r--src/test/compile-fail/regions-infer-invariance-due-to-mutability-3.rs2
-rw-r--r--src/test/compile-fail/regions-infer-invariance-due-to-mutability-4.rs2
-rw-r--r--src/test/compile-fail/regions-infer-not-param.rs4
-rw-r--r--src/test/compile-fail/sendfn-is-not-a-lambda.rs18
-rw-r--r--src/test/compile-fail/static-priv-by-default.rs39
-rw-r--r--src/test/compile-fail/static-priv-by-default2.rs29
-rw-r--r--src/test/compile-fail/useless-priv2.rs5
-rw-r--r--src/test/compile-fail/xc-private-method.rs22
-rw-r--r--src/test/compile-fail/xc-private-method2.rs (renamed from src/test/run-fail/unwind-box-fn.rs)18
-rw-r--r--src/test/compile-fail/xcrate-private-by-default.rs57
-rw-r--r--src/test/debug-info/generic-trait-generic-static-default-method.rs2
-rw-r--r--src/test/debug-info/lexical-scope-in-managed-closure.rs77
-rw-r--r--src/test/debug-info/self-in-default-method.rs2
-rw-r--r--src/test/debug-info/self-in-generic-default-method.rs2
-rw-r--r--src/test/debug-info/trait-generic-static-default-method.rs2
-rw-r--r--src/test/debug-info/var-captured-in-managed-closure.rs56
-rw-r--r--src/test/pretty/block-arg-disambig.rs12
-rw-r--r--src/test/pretty/do1.rs2
-rw-r--r--src/test/pretty/empty-impl.pp4
-rw-r--r--src/test/pretty/empty-impl.rs4
-rw-r--r--src/test/pretty/fn-types.rs1
-rw-r--r--src/test/pretty/path-type-bounds.rs2
-rw-r--r--src/test/run-fail/unwind-lambda.rs2
-rw-r--r--src/test/run-pass/alignment-gep-tup-like-1.rs25
-rw-r--r--src/test/run-pass/alignment-gep-tup-like-2.rs25
-rw-r--r--src/test/run-pass/attr-no-drop-flag-size.rs2
-rw-r--r--src/test/run-pass/attr-start.rs2
-rw-r--r--src/test/run-pass/block-arg-call-as.rs6
-rw-r--r--src/test/run-pass/block-arg-used-as-lambda.rs24
-rw-r--r--src/test/run-pass/borrowck-macro-interaction-issue-6304.rs2
-rw-r--r--src/test/run-pass/borrowck-move-by-capture-ok.rs2
-rw-r--r--src/test/run-pass/borrowck-pat-enum.rs2
-rw-r--r--src/test/run-pass/borrowck-static-item-in-fn.rs2
-rw-r--r--src/test/run-pass/borrowck-unary-move-2.rs2
-rw-r--r--src/test/run-pass/borrowck-uniq-via-ref.rs2
-rw-r--r--src/test/run-pass/borrowck-wg-autoderef-and-autoborrowvec-combined-issue-6272.rs2
-rw-r--r--src/test/run-pass/bug-7183-generics.rs2
-rw-r--r--src/test/run-pass/builtin-superkinds-capabilities-transitive.rs2
-rw-r--r--src/test/run-pass/builtin-superkinds-capabilities.rs2
-rw-r--r--src/test/run-pass/builtin-superkinds-phantom-typaram.rs2
-rw-r--r--src/test/run-pass/builtin-superkinds-self-type.rs2
-rw-r--r--src/test/run-pass/builtin-superkinds-simple.rs2
-rw-r--r--src/test/run-pass/builtin-superkinds-typaram.rs2
-rw-r--r--src/test/run-pass/call-closure-from-overloaded-op.rs2
-rw-r--r--src/test/run-pass/cap-clause-move.rs10
-rw-r--r--src/test/run-pass/cast-mutable-trait.rs4
-rw-r--r--src/test/run-pass/close-over-big-then-small-data.rs25
-rw-r--r--src/test/run-pass/closure-bounds-can-capture-chan.rs2
-rw-r--r--src/test/run-pass/const-binops.rs2
-rw-r--r--src/test/run-pass/const-struct-offsets.rs2
-rw-r--r--src/test/run-pass/core-rt-smoke.rs4
-rw-r--r--src/test/run-pass/cycle-collection2.rs28
-rw-r--r--src/test/run-pass/cycle-collection4.rs20
-rw-r--r--src/test/run-pass/cycle-collection5.rs22
-rw-r--r--src/test/run-pass/default-method-parsing.rs2
-rw-r--r--src/test/run-pass/default-method-supertrait-vtable.rs4
-rw-r--r--src/test/run-pass/deriving-clone-generic-enum.rs2
-rw-r--r--src/test/run-pass/deriving-clone-generic-tuple-struct.rs2
-rw-r--r--src/test/run-pass/deriving-clone-struct.rs2
-rw-r--r--src/test/run-pass/deriving-cmp-shortcircuit.rs2
-rw-r--r--src/test/run-pass/deriving-self-lifetime.rs2
-rw-r--r--src/test/run-pass/deriving-to-str.rs2
-rw-r--r--src/test/run-pass/deriving-zero.rs2
-rw-r--r--src/test/run-pass/do-no-args.rs4
-rw-r--r--src/test/run-pass/do1.rs2
-rw-r--r--src/test/run-pass/do2.rs2
-rw-r--r--src/test/run-pass/do3.rs2
-rw-r--r--src/test/run-pass/enum-discr.rs2
-rw-r--r--src/test/run-pass/enum-vec-initializer.rs2
-rw-r--r--src/test/run-pass/expr-block-fn.rs2
-rw-r--r--src/test/run-pass/expr-block-generic-box1.rs2
-rw-r--r--src/test/run-pass/expr-block-generic-box2.rs2
-rw-r--r--src/test/run-pass/expr-block-generic-unique1.rs2
-rw-r--r--src/test/run-pass/expr-block-generic-unique2.rs2
-rw-r--r--src/test/run-pass/expr-block-generic.rs2
-rw-r--r--src/test/run-pass/expr-if-generic-box1.rs2
-rw-r--r--src/test/run-pass/expr-if-generic-box2.rs2
-rw-r--r--src/test/run-pass/expr-if-generic.rs2
-rw-r--r--src/test/run-pass/expr-match-generic-box1.rs2
-rw-r--r--src/test/run-pass/expr-match-generic-box2.rs2
-rw-r--r--src/test/run-pass/expr-match-generic-unique1.rs2
-rw-r--r--src/test/run-pass/expr-match-generic-unique2.rs2
-rw-r--r--src/test/run-pass/expr-match-generic.rs2
-rw-r--r--src/test/run-pass/expr-repeat-vstore.rs2
-rw-r--r--src/test/run-pass/extern-call-direct.rs2
-rw-r--r--src/test/run-pass/extern-compare-with-return-type.rs2
-rw-r--r--src/test/run-pass/extoption_env-not-defined.rs2
-rw-r--r--src/test/run-pass/filter-block-view-items.rs2
-rw-r--r--src/test/run-pass/fixed-point-bind-box.rs30
-rw-r--r--src/test/run-pass/fixed-point-bind-unique.rs30
-rw-r--r--src/test/run-pass/fn-assign-managed-to-bare-1.rs20
-rw-r--r--src/test/run-pass/fn-coerce-field.rs4
-rw-r--r--src/test/run-pass/fn-type-infer.rs2
-rw-r--r--src/test/run-pass/foreach-external-iterators-break.rs2
-rw-r--r--src/test/run-pass/foreach-external-iterators-hashmap-break-restart.rs4
-rw-r--r--src/test/run-pass/foreach-external-iterators-hashmap.rs4
-rw-r--r--src/test/run-pass/foreach-external-iterators-loop.rs2
-rw-r--r--src/test/run-pass/foreach-external-iterators-nested.rs2
-rw-r--r--src/test/run-pass/foreach-external-iterators.rs4
-rw-r--r--src/test/run-pass/fun-call-variants.rs2
-rw-r--r--src/test/run-pass/func-arg-incomplete-pattern.rs4
-rw-r--r--src/test/run-pass/func-arg-ref-pattern.rs2
-rw-r--r--src/test/run-pass/func-arg-wild-pattern.rs2
-rwxr-xr-xsrc/test/run-pass/generic-static-methods.rs2
-rw-r--r--src/test/run-pass/generic-tag-corruption.rs2
-rw-r--r--src/test/run-pass/hashmap-memory.rs2
-rw-r--r--src/test/run-pass/hygiene-dodging-1.rs2
-rw-r--r--src/test/run-pass/infer-with-expected.rs25
-rw-r--r--src/test/run-pass/issue-1516.rs2
-rw-r--r--src/test/run-pass/issue-2185.rs16
-rw-r--r--src/test/run-pass/issue-2611-3.rs2
-rw-r--r--src/test/run-pass/issue-2633.rs8
-rw-r--r--src/test/run-pass/issue-3052.rs2
-rw-r--r--src/test/run-pass/issue-3429.rs2
-rw-r--r--src/test/run-pass/issue-3979-generics.rs2
-rw-r--r--src/test/run-pass/issue-3979-xcrate.rs2
-rw-r--r--src/test/run-pass/issue-3979.rs2
-rw-r--r--src/test/run-pass/issue-3991.rs2
-rw-r--r--src/test/run-pass/issue-4333.rs2
-rw-r--r--src/test/run-pass/issue-4446.rs2
-rw-r--r--src/test/run-pass/issue-4735.rs2
-rw-r--r--src/test/run-pass/issue-5008-borrowed-traitobject-method-call.rs2
-rw-r--r--src/test/run-pass/issue-5060.rs2
-rw-r--r--src/test/run-pass/issue-5192.rs2
-rw-r--r--src/test/run-pass/issue-5239-2.rs2
-rw-r--r--src/test/run-pass/issue-5280.rs2
-rw-r--r--src/test/run-pass/issue-5315.rs2
-rw-r--r--src/test/run-pass/issue-5321-immediates-with-bare-self.rs2
-rw-r--r--src/test/run-pass/issue-5353.rs2
-rw-r--r--src/test/run-pass/issue-5517.rs2
-rw-r--r--src/test/run-pass/issue-5550.rs2
-rw-r--r--src/test/run-pass/issue-5572.rs2
-rw-r--r--src/test/run-pass/issue-5688.rs2
-rw-r--r--src/test/run-pass/issue-5708.rs2
-rw-r--r--src/test/run-pass/issue-5741.rs2
-rw-r--r--src/test/run-pass/issue-5917.rs2
-rw-r--r--src/test/run-pass/issue-6128.rs2
-rw-r--r--src/test/run-pass/issue-6130.rs2
-rw-r--r--src/test/run-pass/issue-6141-leaking-owned-fn.rs4
-rw-r--r--src/test/run-pass/issue-6153.rs2
-rw-r--r--src/test/run-pass/issue-6341.rs2
-rw-r--r--src/test/run-pass/issue-6344-let.rs2
-rw-r--r--src/test/run-pass/issue-6344-match.rs2
-rw-r--r--src/test/run-pass/issue-7012.rs2
-rw-r--r--src/test/run-pass/issue-7344.rs2
-rw-r--r--src/test/run-pass/issue-7519-match-unit-in-arg.rs2
-rw-r--r--src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs2
-rw-r--r--src/test/run-pass/issue-7712.rs2
-rw-r--r--src/test/run-pass/issue-8171-default-method-self-inherit-builtin-trait.rs2
-rw-r--r--src/test/run-pass/issue-8248.rs2
-rw-r--r--src/test/run-pass/issue-8249.rs2
-rw-r--r--src/test/run-pass/issue-8398.rs2
-rw-r--r--src/test/run-pass/issue-9047.rs2
-rw-r--r--src/test/run-pass/issue-9110.rs2
-rw-r--r--src/test/run-pass/issue4516_ty_param.rs25
-rw-r--r--src/test/run-pass/lambda-infer-unresolved.rs4
-rw-r--r--src/test/run-pass/lambda-no-leak.rs17
-rw-r--r--src/test/run-pass/last-use-in-cap-clause.rs4
-rw-r--r--src/test/run-pass/last-use-is-capture.rs2
-rw-r--r--src/test/run-pass/let-destruct-ref.rs2
-rw-r--r--src/test/run-pass/let-var-hygiene.rs2
-rw-r--r--src/test/run-pass/link-section.rs2
-rw-r--r--src/test/run-pass/lint-cstack.rs2
-rw-r--r--src/test/run-pass/lint-non-camel-case-types-non-uppercase-statics-unicode.rs2
-rw-r--r--src/test/run-pass/lint-non-uppercase-statics-lowercase-mut-statics.rs2
-rw-r--r--src/test/run-pass/macro-local-data-key.rs2
-rw-r--r--src/test/run-pass/match-drop-strs-issue-4541.rs2
-rw-r--r--src/test/run-pass/match-in-macro.rs2
-rw-r--r--src/test/run-pass/match-pipe-binding.rs2
-rw-r--r--src/test/run-pass/match-range-static.rs2
-rw-r--r--src/test/run-pass/match-vec-rvalue.rs2
-rw-r--r--src/test/run-pass/mid-path-type-params.rs2
-rw-r--r--src/test/run-pass/monomorphize-trait-in-fn-at.rs30
-rw-r--r--src/test/run-pass/move-nullary-fn.rs4
-rw-r--r--src/test/run-pass/move-out-of-field.rs2
-rw-r--r--src/test/run-pass/multibyte.rs2
-rw-r--r--src/test/run-pass/nested-enum-same-names.rs18
-rw-r--r--src/test/run-pass/nested-function-names-issue-8587.rs2
-rw-r--r--src/test/run-pass/newlambdas-ret-infer.rs2
-rw-r--r--src/test/run-pass/newlambdas-ret-infer2.rs2
-rw-r--r--src/test/run-pass/newlambdas.rs7
-rw-r--r--src/test/run-pass/newtype-struct-drop-run.rs2
-rw-r--r--src/test/run-pass/newtype-temporary.rs2
-rw-r--r--src/test/run-pass/objects-coerce-freeze-borrored.rs2
-rw-r--r--src/test/run-pass/objects-coerce-from-managed-to-borrowed.rs2
-rw-r--r--src/test/run-pass/owned-implies-static.rs2
-rw-r--r--src/test/run-pass/packed-struct-borrow-element.rs2
-rw-r--r--src/test/run-pass/packed-struct-generic-layout.rs2
-rw-r--r--src/test/run-pass/packed-struct-generic-size.rs2
-rw-r--r--src/test/run-pass/packed-struct-layout.rs2
-rw-r--r--src/test/run-pass/packed-struct-match.rs2
-rw-r--r--src/test/run-pass/packed-struct-size.rs2
-rw-r--r--src/test/run-pass/packed-struct-vec.rs2
-rw-r--r--src/test/run-pass/packed-tuple-struct-layout.rs2
-rw-r--r--src/test/run-pass/packed-tuple-struct-size.rs2
-rw-r--r--src/test/run-pass/propagate-expected-type-through-block.rs12
-rw-r--r--src/test/run-pass/pub-extern-privacy.rs2
-rw-r--r--src/test/run-pass/reflect-visit-data.rs4
-rw-r--r--src/test/run-pass/region-dependent-autofn.rs2
-rw-r--r--src/test/run-pass/region-dependent-autoslice.rs2
-rw-r--r--src/test/run-pass/regions-fn-subtyping.rs8
-rw-r--r--src/test/run-pass/rl-human-test.rs24
-rw-r--r--src/test/run-pass/rt-start-main-thread.rs6
-rw-r--r--src/test/run-pass/send_str_hashmap.rs2
-rw-r--r--src/test/run-pass/send_str_treemap.rs2
-rw-r--r--src/test/run-pass/simd-binop.rs2
-rw-r--r--src/test/run-pass/simd-type.rs2
-rw-r--r--src/test/run-pass/sized-borrowed-pointer.rs2
-rw-r--r--src/test/run-pass/sized-owned-pointer.rs2
-rw-r--r--src/test/run-pass/static-assert.rs2
-rw-r--r--src/test/run-pass/struct-update-moves-and-copies.rs2
-rw-r--r--src/test/run-pass/supertrait-default-generics.rs2
-rw-r--r--src/test/run-pass/syntax-extension-bytes.rs2
-rw-r--r--src/test/run-pass/tag-variant-disr-type-mismatch.rs2
-rw-r--r--src/test/run-pass/trait-bounds-basic.rs2
-rw-r--r--src/test/run-pass/trait-bounds-recursion.rs2
-rw-r--r--src/test/run-pass/trait-inheritance-overloading-simple.rs2
-rw-r--r--src/test/run-pass/trait-inheritance-overloading.rs2
-rw-r--r--src/test/run-pass/trait-inheritance-subst.rs2
-rw-r--r--src/test/run-pass/trait-inheritance-subst2.rs2
-rw-r--r--src/test/run-pass/trait-inheritance2.rs2
-rw-r--r--src/test/run-pass/trait-object-generics.rs2
-rw-r--r--src/test/run-pass/trait-with-bounds-default.rs2
-rw-r--r--src/test/run-pass/traits-default-method-mut.rs2
-rw-r--r--src/test/run-pass/transmute-non-immediate-to-immediate.rs2
-rw-r--r--src/test/run-pass/tuple-struct-constructor-pointer.rs2
-rw-r--r--src/test/run-pass/typeck-macro-interaction-issue-8852.rs4
-rw-r--r--src/test/run-pass/unfold-cross-crate.rs2
-rw-r--r--src/test/run-pass/unused-move-capture.rs2
357 files changed, 4130 insertions, 3642 deletions
diff --git a/AUTHORS.txt b/AUTHORS.txt
index e742886961f..5bd7c7a584f 100644
--- a/AUTHORS.txt
+++ b/AUTHORS.txt
@@ -1,23 +1,23 @@
-Initial author, project lead, target of blame:
-
-Graydon Hoare <graydon@mozilla.com>
-
-Other authors:
-
-
+Aaron Laursen <aaronlaursen@gmail.com>
+Aaron Todd <github@opprobrio.us>
 Adam Bozanich <adam.boz@gmail.com>
+Adrien Tétar <adri-from-59@hotmail.fr>
 Aleksander Balicki <balicki.aleksander@gmail.com>
 Alex Crichton <alex@alexcrichton.com>
 Alex Rønne Petersen <alex@lycus.org>
 Alexander Stavonin <a.stavonin@gmail.com>
 Alexei Sholik <alcosholik@gmail.com>
+Aljaž "g5pw" Srebrnič <a2piratesoft@gmail.com>
+Anders Kaseorg <andersk@mit.edu>
 Andreas Gal <gal@mozilla.com>
+Andreas Martens <andreasm@fastmail.fm>
 Andrew Dunham <andrew@du.nham.ca>
 Andrew Paseltiner <apaseltiner@gmail.com>
 Anthony Juckel <ajuckel@gmail.com>
 Arkaitz Jimenez <arkaitzj@gmail.com>
 Armin Ronacher <armin.ronacher@active-4.com>
 Ashok Gautham <ScriptDevil@gmail.com>
+Austin King <shout@ozten.com>
 Austin Seipp <mad.one@gmail.com>
 Aydin Kim <ladinjin@hanmail.net>
 auREAX <mark@xn--hwg34fba.ws>
@@ -33,7 +33,12 @@ Bilal Husain <bilal@bilalhusain.com>
 Bill Fallon <bill.fallon@robos.li>
 Bill Myers <bill_myers@outlook.com>
 Bill Wendling <wendling@apple.com>
+Birunthan Mohanathas <birunthan@mohanathas.com>
 Björn Steinbrink <bsteinbr@gmail.com>
+blake2-ppc <ulrik.sverdrup@gmail.com>
+Bouke van der Bijl <boukevanderbijl@gmail.com>
+Brandon Sanderson <singingboyo@hotmail.com>
+Brendan Cully <brendan@kublai.com>
 Brendan Eich <brendan@mozilla.org>
 Brendan Zabarauskas <bjzaba@yahoo.com.au>
 Brett Cannon <brett@python.org>
@@ -42,7 +47,9 @@ Brian J. Burg <burg@cs.washington.edu>
 Brian Leibig <brian.leibig@gmail.com>
 Bryan Dunsmore <dunsmoreb@gmail.com>
 Caitlin Potter <snowball@defpixel.com>
+Carlos <toqueteos@gmail.com>
 Chris Double <chris.double@double.co.nz>
+Chris Morgan <me@chrismorgan.info>
 Chris Peterson <cpeterson@mozilla.com>
 Chris Pressey <cpressey@gmail.com>
 Cody Schroeder <codys@cs.washington.edu>
@@ -52,39 +59,58 @@ Damien Grassart <damien@grassart.com>
 Damien Schoof <damien.schoof@gmail.com>
 Daniel Brooks <db48x@db48x.net>
 Daniel Farina <daniel@fdr.io>
+Dan Connolly <dckc@madmode.com>
 Dan Luu <danluu@gmail.com>
 Daniel Luz <dev@mernen.com>
 Daniel Micay <danielmicay@gmail.com>
 Daniel Patterson <dbp@riseup.net>
 Daniel Ralston <Wubbulous@gmail.com>
+Daniel Rosenwasser <DanielRosenwasser@gmail.com>
 Daniel Ursache Dogariu <contact@danniel.net>
+darkf <lw9k123@gmail.com>
 Dave Herman <dherman@mozilla.com>
+David Creswick <dcrewi@gyrae.net>
 David Forsythe <dforsythe@gmail.com>
+David Halperin <halperin.dr@gmail.com>
 David Klein <david.klein@baesystemsdetica.com>
+David Manescu <dman2626@uni.sydney.edu.au>
 David Rajchenbach-Teller <dteller@mozilla.com>
 Diggory Hardy <diggory.hardy@gmail.com>
 Dimitri Krassovski <labria@startika.com>
+Dmitry Ermolov <epdmitry@yandex.ru>
+Do Nhat Minh <mrordinaire@gmail.com>
 Donovan Preston <donovanpreston@gmail.com>
 Drew Willcoxon <adw@mozilla.com>
 Elliott Slaughter <elliottslaughter@gmail.com>
 Elly Fong-Jones <elly@leptoquark.net>
 Eric Holk <eric.holk@gmail.com>
 Eric Holmes <eric@ejholmes.net>
+Eric Martin <e.a.martin1337@gmail.com>
+Eric Reed <ecreed@cs.washington.edu>
 Erick Tryzelaar <erick.tryzelaar@gmail.com>
 Erik Rose <erik@mozilla.com>
+Etienne Millon <me@emillon.org>
 Evan McClanahan <evan@evanmcc.com>
 Fedor Indutny <fedor.indutny@gmail.com>
 Felix S. Klock II <pnkfelix@pnkfx.org>
+Flaper Fesp <flaper87@gmail.com>
+Flavio Percoco <flaper87@gmail.com>
+Florian Hahn <flo@fhahn.com>
+Florian Zeitz <florob@babelmonkeys.de>
 Francisco Souza <f@souza.cc>
 Franklin Chen <franklinchen@franklinchen.com>
 Gábor Horváth <xazax.hun@gmail.com>
 Gabriel <g2p.code@gmail.com>
 Gareth Daniel Smith <garethdanielsmith@gmail.com>
+Gary Linscott <glinscott@gmail.com>
+Georges Dubus <georges.dubus@gmail.com>
 gifnksm <makoto.nksm@gmail.com>
 Glenn Willen <gwillen@nerdnet.org>
 Gonçalo Cabrita <_@gmcabrita.com>
 Graham Fawcett <fawcett@uwindsor.ca>
 Grahame Bowland <grahame@angrygoats.net>
+Graydon Hoare <graydon@mozilla.com>
+Grigoriy <ohaistarlight@gmail.com>
 Haitao Li <lihaitao@gmail.com>
 hansjorg <hansjorg@gmail.com>
 Herman J. Radtke III <hermanradtke@gmail.com>
@@ -96,9 +122,11 @@ Ivano Coppola <rgbfirefox@gmail.com>
 Jack Moffitt <jack@metajack.im>
 Jacob Harris Cryer Kragh <jhckragh@gmail.com>
 Jacob Parker <j3parker@csclub.uwaterloo.ca>
+Jakub <jakub@jakub.cc>
 Jakub Wieczorek <jakubw@jakubw.net>
 James Miller <bladeon@gmail.com>
 James Tranovich <james@openhorizonlabs.com>
+Jan Kobler <eng1@koblersystems.de>
 Jason Orendorff <jorendorff@mozilla.com>
 Jed Davis <jld@panix.com>
 Jeff Balogh <jbalogh@mozilla.com>
@@ -113,35 +141,48 @@ Jesse Ruderman <jruderman@gmail.com>
 Jihyun Yu <jihyun@nclab.kaist.ac.kr>
 Jim Blandy <jimb@red-bean.com>
 Jimmy Lu <jimmy.lu.2011@gmail.com>
+Jimmy Zelinskie <jimmyzelinskie@gmail.com>
 J. J. Weber <jjweber@gmail.com>
+jmgrosen <jmgrosen@gmail.com>
 Joe Pletcher <joepletcher@gmail.com>
+John Barker <jebarker@gmail.com>
 John Clements <clements@racket-lang.org>
 Jon Morton <jonanin@gmail.com>
 Jonathan Sternberg <jonathansternberg@gmail.com>
+Jordi Boggiano <j.boggiano@seld.be>
 Josh Matthews <josh@joshmatthews.net>
 Joshua Clark <joshua.clark@txstate.edu>
 Joshua Wise <joshua@joshuawise.com>
 Junyoung Cho <june0.cho@samsung.com>
 Jyun-Yan You <jyyou@cs.nctu.edu.tw>
 Kang Seonghoon <kang.seonghoon@mearie.org>
+Keegan McAllister <kmcallister@mozilla.com>
 Kelly Wilson <wilsonk@cpsc.ucalgary.ca>
 Kevin Atkinson <kevina@cs.utah.edu>
 Kevin Ballard <kevin@sb.org>
 Kevin Cantu <me@kevincantu.org>
+Kevin Mehall <km@kevinmehall.net>
+Kevin Murphy <kemurphy.cmu@gmail.com>
 klutzy <klutzytheklutzy@gmail.com>
+korenchkin <korenchkin2@gmail.com>
 Kyeongwoon Lee <kyeongwoon.lee@samsung.com>
+Lars Bergstrom <lbergstrom@mozilla.com>
 Laurent Bonnans <bonnans.l@gmail.com>
 Lawrence Velázquez <larryv@alum.mit.edu>
 Leah Hanson <astrieanna@gmail.com>
 Lennart Kudling <github@kudling.de>
 Lindsey Kuper <lindsey@composition.al>
 Luca Bruno <lucab@debian.org>
+Luis de Bethencourt <luis@debethencourt.com>
 Luqman Aden <laden@csclub.uwaterloo.ca>
 Magnus Auvinen <magnus.auvinen@gmail.com>
 Mahmut Bulut <mahmutbulut0@gmail.com>
+maikklein <maikklein@googlemail.com>
+Makoto Nakashima <makoto.nksm+github@gmail.com>
 Margaret Meyerhofer <mmeyerho@andrew.cmu.edu>
 Marijn Haverbeke <marijnh@gmail.com>
 Mark Lacey <641@rudkx.com>
+Mark Sinclair <mark.edward.x@gmail.com>
 Mark Vian <mrv.caseus@gmail.com>
 Marti Raudsepp <marti@juffo.org>
 Martin DeMello <martindemello@gmail.com>
@@ -151,18 +192,27 @@ Matthew McPherrin <matthew@mcpherrin.ca>
 Matthew O'Connor <thegreendragon@gmail.com>
 Matthijs Hofstra <thiezz@gmail.com>
 Max Penet <max.penet@gmail.com>
+Maxim Kolganov <kolganov.mv@gmail.com>
+Micah Chalmer <micah@micahchalmer.net>
 Michael Arntzenius <daekharel@gmail.com>
 Michael Bebenita <mbebenita@mozilla.com>
 Michael Neumann <mneumann@ntecs.de>
 Michael Sullivan <sully@msully.net>
+Michael Woerister <michaelwoerister@gmail>
+Mihnea Dobrescu-Balaur <mihnea@linux.com>
 Mikko Perttunen <cyndis@kapsi.fi>
+Mukilan Thiagarajan <mukilanthiagarajan@gmail.com>
 Nick Desaulniers <ndesaulniers@mozilla.com>
 Niko Matsakis <niko@alum.mit.edu>
+novalis <novalis@novalis.org>
+Ogino Masanori <masanori.ogino@gmail.com>
 Olivier Saut <osaut@airpost.net>
 Or Brostovski <tohava@gmail.com>
 Orphée Lafond-Lummis <o@orftz.com>
+Palmer Cox <p@lmercox.com>
 Patrick Walton <pwalton@mozilla.com>
 Patrik Kårlin <patrik.karlin@gmail.com>
+Paul Collins <paul@ondioline.org>
 Paul Stansifer <paul.stansifer@gmail.com>
 Paul Woolcock <pwoolcoc+github@gmail.com>
 Pavel Panchekha <me@pavpanchekha.com>
@@ -177,6 +227,8 @@ Reuben Morais <reuben.morais@gmail.com>
 Rick Waldron <waldron.rick@gmail.com>
 Rob Arnold <robarnold@cs.cmu.edu>
 Rob Hoelz <rob@hoelz.ro>
+Robert Knight <robertknight@gmail.com>
+Robert Millar <robert.millar@cantab.net>
 Roland Tanglao <roland@rolandtanglao.com>
 Ron Dahlgren <ronald.dahlgren@gmail.com>
 Roy Frostig <rfrostig@mozilla.com>
@@ -184,18 +236,23 @@ Ryan Scheel <ryan.havvy@gmail.com>
 Samuel Chase <samebchase@gmail.com>
 Sander Mathijs van Veen <smvv@kompiler.org>
 Sangeun Kim <sammy.kim@samsung.com>
+Sankha Narayan Guria <sankha93@gmail.com>
 Saurabh Anand <saurabhanandiit@gmail.com>
+Scott Lawrence <bytbox@gmail.com>
 Sean Moon <ssamoon@ucla.edu>
 Sean Stangl <sstangl@mozilla.com>
 Sebastian N. Fernandez <cachobot@gmail.com>
+Sébastien Crozet <developer@crozet.re>
 Seth Pink <sethpink@gmail.com>
 Seo Sanghyeon <sanxiyn@gmail.com>
 sevrak <sevrak@rediffmail.com>
 SiegeLord <slabode@aim.com>
 Simon Barber-Dueck <sbarberdueck@gmail.com>
 Simon Sapin <simon@exyr.org>
+sp3d <sp3d@github>
 startling <tdixon51793@gmail.com>
 Stefan Plantikow <stefan.plantikow@googlemail.com>
+Stepan Koltsov <stepan.koltsov@gmail.com>
 Steve Klabnik <steve@steveklabnik.com>
 Steven De Coeyer <steven@banteng.be>
 Steven Fackler <sfackler@gmail.com>
@@ -205,6 +262,7 @@ Ted Horst <ted.horst@earthlink.net>
 Thad Guidry <thadguidry@gmail.com>
 Thomas Daede <daede003@umn.edu>
 Tim Chevalier <chevalier@alum.wellesley.edu>
+Tim Kuehn <tkuehn@cmu.edu>
 Tim Taubert <tim@timtaubert.de>
 Tom Lee <github@tomlee.co>
 Tommy M. McGuire <mcguire@crsr.net>
@@ -213,6 +271,7 @@ Tony Young <tony@rfw.name>
 Trinick <slicksilver555@mac.com>
 Tycho Sci <tychosci@gmail.com>
 Tyler Bindon <martica@martica.org>
+U-NOV2010\eugals
 Uwe Dauernheim <uwe@dauernheim.net>
 Vadim Chugunov <vadimcn@gmail.com>
 Viktor Dahl <pazaconyoman@gmail.com>
@@ -225,4 +284,5 @@ Young-il Choi <duddlf.choi@samsung.com>
 Youngmin Yoo <youngmin.yoo@samsung.com>
 Youngsoo Son <ysson83@gmail.com>
 Zack Corr <zack@z0w0.me>
+Zack Slayton <zack.slayton@gmail.com>
 zofrex <zofrex@gmail.com>
diff --git a/RELEASES.txt b/RELEASES.txt
index 63080fe6528..e4d7086658d 100644
--- a/RELEASES.txt
+++ b/RELEASES.txt
@@ -31,6 +31,7 @@ Version 0.8 (October 2013)
       * `ref` bindings in irrefutable patterns work correctly now.
       * `char` is now prevented from containing invalid code points.
       * Casting to `bool` is no longer allowed.
+      * `\0` is now accepted as an escape in chars and strings.
       * `yield` is a reserved keyword.
       * `typeof` is a reserved keyword.
       * Crates may be imported by URL with `extern mod foo = "url";`.
@@ -111,6 +112,9 @@ Version 0.8 (October 2013)
         the `MutableSet` and `MutableMap` traits. `Container::is_empty`,
         `Map::contains_key`, `MutableMap::insert`, and `MutableMap::remove` have
         default implementations.
+      * std: Various `from_str` functions were removed in favor of a generic
+        `from_str` which is available in the prelude.
+      * std: `util::unreachable` removed in favor of the `unreachable!` macro.
       * extra: `dlist`, the doubly-linked list was modernized.
       * extra: Added a `hex` module with `ToHex` and `FromHex` traits.
       * extra: Added `glob` module, replacing `std::os::glob`.
@@ -125,6 +129,9 @@ Version 0.8 (October 2013)
       * extra: `semver` updated to SemVer 2.0.0.
       * extra: `term` handles more terminals correctly.
       * extra: `dbg` module removed.
+      * extra: `par` module removed.
+      * extra: `future` was cleaned up, with some method renames.
+      * extra: Most free functions in `getopts` were converted to methods.
 
    * Other
       * rustc's debug info generation (`-Z debug-info`) is greatly improved.
@@ -205,6 +212,7 @@ Version 0.7 (July 2013)
       * std: Many old internal vector and string iterators,
         incl. `any`, `all`. removed.
       * std: The `finalize` method of `Drop` renamed to `drop`.
+      * std: The `drop` method now takes `&mut self` instead of `&self`.
       * std: The prelude no longer reexports any modules, only types and traits.
       * std: Prelude additions: `print`, `println`, `FromStr`, `ApproxEq`, `Equiv`,
         `Iterator`, `IteratorUtil`, many numeric traits, many tuple traits.
diff --git a/doc/tutorial-rustpkg.md b/doc/tutorial-rustpkg.md
index 43d83093eea..f1cf78fc630 100644
--- a/doc/tutorial-rustpkg.md
+++ b/doc/tutorial-rustpkg.md
@@ -7,7 +7,7 @@ package up your Rust code and share it with other people. This tutorial will
 get you started on all of the concepts and commands you need to give the gift
 of Rust code to someone else.
 
-## Installing External Packages
+# Installing External Packages
 
 First, let's try to use an external package somehow. I've made a sample package
 called `hello` to demonstrate how to do so.  Here's how `hello` is used:
@@ -68,7 +68,7 @@ Hello, world.
 
 Simple! That's all it takes.
 
-## Workspaces
+# Workspaces
 
 Before we can talk about how to make packages of your own, you have to
 understand the big concept with `rustpkg`: workspaces. A 'workspace' is simply
@@ -88,14 +88,14 @@ There are also default file names you'll want to follow as well:
 * `main.rs`: A file that's going to become an executable.
 * `lib.rs`: A file that's going to become a library.
 
-## Building your own Package
+# Building your own Package
 
 Now that you've got workspaces down, let's build your own copy of `hello`. Go
 to wherever you keep your personal projects, and let's make all of the
 directories we'll need. I'll refer to this personal project directory as
 `~/src` for the rest of this tutorial.
 
-### Creating our workspace
+## Creating our workspace
 
 ~~~ {.notrust}
 $ cd ~/src
@@ -150,7 +150,7 @@ pub fn world() {
 
 Put this into `src/hello/lib.rs`. Let's talk about each of these attributes:
 
-### Crate attributes for packages
+## Crate attributes for packages
 
 `license` is equally simple: the license we want this code to have. I chose MIT
 here, but you should pick whatever license makes the most sense for you.
@@ -158,7 +158,7 @@ here, but you should pick whatever license makes the most sense for you.
 `desc` is a description of the package and what it does. This should just be a
 sentence or two.
 
-### Building your package
+## Building your package
 
 Building your package is simple:
 
@@ -206,7 +206,7 @@ note: Installed package github.com/YOUR_USERNAME/hello-0.1 to /home/yourusername
 
 That's it!
 
-## More resources
+# More resources
 
 There's a lot more going on with `rustpkg`, this is just to get you started.
 Check out [the rustpkg manual](rustpkg.html) for the full details on how to
diff --git a/doc/tutorial-tasks.md b/doc/tutorial-tasks.md
index e1f70a19e52..3ab44cb5441 100644
--- a/doc/tutorial-tasks.md
+++ b/doc/tutorial-tasks.md
@@ -423,7 +423,7 @@ do_some_work();
 While it isn't possible for a task to recover from failure, tasks may notify
 each other of failure. The simplest way of handling task failure is with the
 `try` function, which is similar to `spawn`, but immediately blocks waiting
-for the child task to finish. `try` returns a value of type `Result<int,
+for the child task to finish. `try` returns a value of type `Result<T,
 ()>`. `Result` is an `enum` type with two variants: `Ok` and `Err`. In this
 case, because the type arguments to `Result` are `int` and `()`, callers can
 pattern-match on a result to check whether it's an `Ok` result with an `int`
diff --git a/doc/tutorial.md b/doc/tutorial.md
index dd552f45f4e..2f9a84d984f 100644
--- a/doc/tutorial.md
+++ b/doc/tutorial.md
@@ -1469,34 +1469,6 @@ cannot be stored in data structures or returned from
 functions. Despite these limitations, stack closures are used
 pervasively in Rust code.
 
-## Managed closures
-
-When you need to store a closure in a data structure, a stack closure
-will not do, since the compiler will refuse to let you store it. For
-this purpose, Rust provides a type of closure that has an arbitrary
-lifetime, written `@fn` (boxed closure, analogous to the `@` pointer
-type described earlier). This type of closure *is* first-class.
-
-A managed closure does not directly access its environment, but merely
-copies out the values that it closes over into a private data
-structure. This means that it can not assign to these variables, and
-cannot observe updates to them.
-
-This code creates a closure that adds a given string to its argument,
-returns it from a function, and then calls it:
-
-~~~~
-fn mk_appender(suffix: ~str) -> @fn(~str) -> ~str {
-    // The compiler knows that we intend this closure to be of type @fn
-    return |s| s + suffix;
-}
-
-fn main() {
-    let shout = mk_appender(~"!");
-    println(shout(~"hey ho, let's go"));
-}
-~~~~
-
 ## Owned closures
 
 Owned closures, written `~fn` in analogy to the `~` pointer type,
@@ -3023,7 +2995,7 @@ There is further documentation on the [wiki], however those tend to be even more
 [tasks]: tutorial-tasks.html
 [macros]: tutorial-macros.html
 [ffi]: tutorial-ffi.html
-[rustpkg]: rustpkg.html
+[rustpkg]: tutorial-rustpkg.html
 
 [wiki]: https://github.com/mozilla/rust/wiki/Docs
 
diff --git a/mk/docs.mk b/mk/docs.mk
index b89bf3483fc..e38590188b3 100644
--- a/mk/docs.mk
+++ b/mk/docs.mk
@@ -160,6 +160,16 @@ doc/tutorial-conditions.html: tutorial-conditions.md doc/version_info.html doc/r
            --include-before-body=doc/version_info.html \
            --output=$@
 
+DOCS += doc/tutorial-rustpkg.html
+doc/tutorial-rustpkg.html: tutorial-rustpkg.md doc/version_info.html doc/rust.css
+	@$(call E, pandoc: $@)
+	$(Q)$(CFG_NODE) $(S)doc/prep.js --highlight $< | \
+          $(CFG_PANDOC) --standalone --toc \
+           --section-divs --number-sections \
+           --from=markdown --to=html --css=rust.css \
+           --include-before-body=doc/version_info.html \
+           --output=$@
+
   ifeq ($(CFG_PDFLATEX),)
     $(info cfg: no pdflatex found, omitting doc/rust.pdf)
   else
diff --git a/src/etc/combine-tests.py b/src/etc/combine-tests.py
index 36031d31149..692aa6871e6 100755
--- a/src/etc/combine-tests.py
+++ b/src/etc/combine-tests.py
@@ -29,6 +29,8 @@ for t in os.listdir(run_pass):
         if not ("xfail-test" in s or
                 "xfail-fast" in s or
                 "xfail-win32" in s):
+            if not "pub fn main" in s and "fn main" in s:
+                print("Warning: no public entry point in " + t)
             stage2_tests.append(t)
         f.close()
 
diff --git a/src/libextra/arc.rs b/src/libextra/arc.rs
index ca8000c984d..28a067a782b 100644
--- a/src/libextra/arc.rs
+++ b/src/libextra/arc.rs
@@ -162,7 +162,7 @@ struct MutexArcInner<T> { priv lock: Mutex, priv failed: bool, priv data: T }
 
 /// An Arc with mutable data protected by a blocking mutex.
 #[no_freeze]
-struct MutexArc<T> { priv x: UnsafeArc<MutexArcInner<T>> }
+pub struct MutexArc<T> { priv x: UnsafeArc<MutexArcInner<T>> }
 
 
 impl<T:Send> Clone for MutexArc<T> {
@@ -343,7 +343,7 @@ struct RWArcInner<T> { priv lock: RWLock, priv failed: bool, priv data: T }
  * Unlike mutex_arcs, rw_arcs are safe, because they cannot be nested.
  */
 #[no_freeze]
-struct RWArc<T> {
+pub struct RWArc<T> {
     priv x: UnsafeArc<RWArcInner<T>>,
 }
 
diff --git a/src/libextra/c_vec.rs b/src/libextra/c_vec.rs
index 30bce3a8170..bd3ce20742e 100644
--- a/src/libextra/c_vec.rs
+++ b/src/libextra/c_vec.rs
@@ -36,37 +36,39 @@
  * still held if needed.
  */
 
-
-use std::option;
 use std::ptr;
+use std::routine::Runnable;
+use std::util;
 
 /**
  * The type representing a foreign chunk of memory
- *
  */
 pub struct CVec<T> {
     priv base: *mut T,
     priv len: uint,
-    priv rsrc: @DtorRes
+    priv rsrc: @DtorRes,
 }
 
 struct DtorRes {
-  dtor: Option<@fn()>,
+    dtor: Option<~Runnable>,
 }
 
 #[unsafe_destructor]
 impl Drop for DtorRes {
     fn drop(&mut self) {
-        match self.dtor {
-            option::None => (),
-            option::Some(f) => f()
+        let dtor = util::replace(&mut self.dtor, None);
+        match dtor {
+            None => (),
+            Some(f) => f.run()
         }
     }
 }
 
-fn DtorRes(dtor: Option<@fn()>) -> DtorRes {
-    DtorRes {
-        dtor: dtor
+impl DtorRes {
+    fn new(dtor: Option<~Runnable>) -> DtorRes {
+        DtorRes {
+            dtor: dtor,
+        }
     }
 }
 
@@ -83,10 +85,10 @@ fn DtorRes(dtor: Option<@fn()>) -> DtorRes {
  * * len - The number of elements in the buffer
  */
 pub unsafe fn CVec<T>(base: *mut T, len: uint) -> CVec<T> {
-    return CVec{
+    return CVec {
         base: base,
         len: len,
-        rsrc: @DtorRes(option::None)
+        rsrc: @DtorRes::new(None)
     };
 }
 
@@ -101,12 +103,12 @@ pub unsafe fn CVec<T>(base: *mut T, len: uint) -> CVec<T> {
  * * dtor - A function to run when the value is destructed, useful
  *          for freeing the buffer, etc.
  */
-pub unsafe fn c_vec_with_dtor<T>(base: *mut T, len: uint, dtor: @fn())
-  -> CVec<T> {
+pub unsafe fn c_vec_with_dtor<T>(base: *mut T, len: uint, dtor: ~Runnable)
+                                 -> CVec<T> {
     return CVec{
         base: base,
         len: len,
-        rsrc: @DtorRes(option::Some(dtor))
+        rsrc: @DtorRes::new(Some(dtor))
     };
 }
 
@@ -153,6 +155,20 @@ mod tests {
 
     use std::libc::*;
     use std::libc;
+    use std::routine::Runnable;
+
+    struct LibcFree {
+        mem: *c_void,
+    }
+
+    impl Runnable for LibcFree {
+        #[fixed_stack_segment]
+        fn run(~self) {
+            unsafe {
+                libc::free(self.mem)
+            }
+        }
+    }
 
     fn malloc(n: size_t) -> CVec<u8> {
         #[fixed_stack_segment];
@@ -163,12 +179,11 @@ mod tests {
 
             assert!(mem as int != 0);
 
-            return c_vec_with_dtor(mem as *mut u8, n as uint, || f(mem));
-        }
-
-        fn f(mem: *c_void) {
-            #[fixed_stack_segment]; #[inline(never)];
-            unsafe { libc::free(mem) }
+            return c_vec_with_dtor(mem as *mut u8,
+                                   n as uint,
+                                   ~LibcFree {
+                                    mem: mem,
+                                   } as ~Runnable);
         }
     }
 
diff --git a/src/libextra/rl.rs b/src/libextra/rl.rs
index 9476bcb8926..7662a159ba4 100644
--- a/src/libextra/rl.rs
+++ b/src/libextra/rl.rs
@@ -30,7 +30,7 @@ pub mod rustrt {
 
 macro_rules! locked {
     ($expr:expr) => {
-        unsafe {
+        {
             // FIXME #9105: can't use a static mutex in pure Rust yet.
             rustrt::rust_take_linenoise_lock();
             let x = $expr;
@@ -43,20 +43,27 @@ macro_rules! locked {
 /// Add a line to history
 pub fn add_history(line: &str) -> bool {
     do line.with_c_str |buf| {
-        (locked!(rustrt::linenoiseHistoryAdd(buf))) == 1 as c_int
+        unsafe {
+            (locked!(rustrt::linenoiseHistoryAdd(buf))) == 1 as c_int
+        }
     }
 }
 
 /// Set the maximum amount of lines stored
 pub fn set_history_max_len(len: int) -> bool {
-    (locked!(rustrt::linenoiseHistorySetMaxLen(len as c_int))) == 1 as c_int
+    unsafe {
+        (locked!(rustrt::linenoiseHistorySetMaxLen(len as c_int))) == 1
+            as c_int
+    }
 }
 
 /// Save line history to a file
 pub fn save_history(file: &str) -> bool {
     do file.with_c_str |buf| {
         // 0 on success, -1 on failure
-        (locked!(rustrt::linenoiseHistorySave(buf))) == 0 as c_int
+        unsafe {
+            (locked!(rustrt::linenoiseHistorySave(buf))) == 0 as c_int
+        }
     }
 }
 
@@ -64,14 +71,18 @@ pub fn save_history(file: &str) -> bool {
 pub fn load_history(file: &str) -> bool {
     do file.with_c_str |buf| {
         // 0 on success, -1 on failure
-        (locked!(rustrt::linenoiseHistoryLoad(buf))) == 0 as c_int
+        unsafe {
+            (locked!(rustrt::linenoiseHistoryLoad(buf))) == 0 as c_int
+        }
     }
 }
 
 /// Print out a prompt and then wait for input and return it
 pub fn read(prompt: &str) -> Option<~str> {
     do prompt.with_c_str |buf| {
-        let line = locked!(rustrt::linenoise(buf));
+        let line = unsafe {
+            locked!(rustrt::linenoise(buf))
+        };
 
         if line.is_null() { None }
         else {
@@ -88,9 +99,13 @@ pub fn read(prompt: &str) -> Option<~str> {
     }
 }
 
-pub type CompletionCb = @fn(~str, @fn(~str));
+/// The callback used to perform completions.
+pub trait CompletionCb {
+    /// Performs a completion.
+    fn complete(&self, line: ~str, suggestion: &fn(~str));
+}
 
-local_data_key!(complete_key: CompletionCb)
+local_data_key!(complete_key: @CompletionCb)
 
 /// Bind to the main completion callback in the current task.
 ///
@@ -98,25 +113,22 @@ local_data_key!(complete_key: CompletionCb)
 /// other than the closure that it receives as its second
 /// argument. Calling such a function will deadlock on the mutex used
 /// to ensure that the calls are thread-safe.
-pub fn complete(cb: CompletionCb) {
+pub unsafe fn complete(cb: @CompletionCb) {
     local_data::set(complete_key, cb);
 
-    extern fn callback(c_line: *c_char, completions: *()) {
+    extern fn callback(line: *c_char, completions: *()) {
         do local_data::get(complete_key) |opt_cb| {
             // only fetch completions if a completion handler has been
             // registered in the current task.
             match opt_cb {
-                None => {},
+                None => {}
                 Some(cb) => {
-                    let line = unsafe { str::raw::from_c_str(c_line) };
-                    do (*cb)(line) |suggestion| {
-                        do suggestion.with_c_str |buf| {
-                            // This isn't locked, because `callback` gets
-                            // called inside `rustrt::linenoise`, which
-                            // *is* already inside the mutex, so
-                            // re-locking would be a deadlock.
-                            unsafe {
-                                rustrt::linenoiseAddCompletion(completions, buf);
+                    unsafe {
+                        do cb.complete(str::raw::from_c_str(line))
+                                |suggestion| {
+                            do suggestion.with_c_str |buf| {
+                                rustrt::linenoiseAddCompletion(completions,
+                                                               buf);
                             }
                         }
                     }
diff --git a/src/libextra/test.rs b/src/libextra/test.rs
index cc80da1506a..4721a6b4122 100644
--- a/src/libextra/test.rs
+++ b/src/libextra/test.rs
@@ -30,7 +30,6 @@ use treemap::TreeMap;
 
 use std::clone::Clone;
 use std::comm::{stream, SharedChan, GenericPort, GenericChan};
-use std::libc;
 use std::io;
 use std::result;
 use std::task;
@@ -125,8 +124,9 @@ pub type MetricDiff = TreeMap<~str,MetricChange>;
 pub fn test_main(args: &[~str], tests: ~[TestDescAndFn]) {
     let opts =
         match parse_opts(args) {
-            Ok(o) => o,
-            Err(msg) => fail!(msg)
+            Some(Ok(o)) => o,
+            Some(Err(msg)) => fail!(msg),
+            None => return
         };
     if !run_tests_console(&opts, tests) { fail!("Some tests failed"); }
 }
@@ -189,7 +189,7 @@ fn optgroups() -> ~[getopts::groups::OptGroup] {
                      "A.B")]
 }
 
-fn usage(binary: &str, helpstr: &str) -> ! {
+fn usage(binary: &str, helpstr: &str) {
     #[fixed_stack_segment]; #[inline(never)];
 
     let message = fmt!("Usage: %s [OPTIONS] [FILTER]", binary);
@@ -217,20 +217,19 @@ Test Attributes:
                      tests. This may also be written as #[ignore(cfg(...))] to
                      ignore the test on certain configurations.");
     }
-    unsafe { libc::exit(0) }
 }
 
 // Parses command line arguments into test options
-pub fn parse_opts(args: &[~str]) -> OptRes {
+pub fn parse_opts(args: &[~str]) -> Option<OptRes> {
     let args_ = args.tail();
     let matches =
         match groups::getopts(args_, optgroups()) {
           Ok(m) => m,
-          Err(f) => return Err(f.to_err_msg())
+          Err(f) => return Some(Err(f.to_err_msg()))
         };
 
-    if matches.opt_present("h") { usage(args[0], "h"); }
-    if matches.opt_present("help") { usage(args[0], "help"); }
+    if matches.opt_present("h") { usage(args[0], "h"); return None; }
+    if matches.opt_present("help") { usage(args[0], "help"); return None; }
 
     let filter =
         if matches.free.len() > 0 {
@@ -272,7 +271,7 @@ pub fn parse_opts(args: &[~str]) -> OptRes {
         logfile: logfile
     };
 
-    Ok(test_opts)
+    Some(Ok(test_opts))
 }
 
 pub fn opt_shard(maybestr: Option<~str>) -> Option<(uint,uint)> {
@@ -807,11 +806,6 @@ pub fn filter_tests(
     }
 }
 
-struct TestFuture {
-    test: TestDesc,
-    wait: @fn() -> TestResult,
-}
-
 pub fn run_test(force_ignore: bool,
                 test: TestDescAndFn,
                 monitor_ch: SharedChan<MonitorMsg>) {
@@ -1233,7 +1227,7 @@ mod tests {
     fn first_free_arg_should_be_a_filter() {
         let args = ~[~"progname", ~"filter"];
         let opts = match parse_opts(args) {
-            Ok(o) => o,
+            Some(Ok(o)) => o,
             _ => fail!("Malformed arg in first_free_arg_should_be_a_filter")
         };
         assert!("filter" == opts.filter.clone().unwrap());
@@ -1243,7 +1237,7 @@ mod tests {
     fn parse_ignored_flag() {
         let args = ~[~"progname", ~"filter", ~"--ignored"];
         let opts = match parse_opts(args) {
-            Ok(o) => o,
+            Some(Ok(o)) => o,
             _ => fail!("Malformed arg in parse_ignored_flag")
         };
         assert!((opts.run_ignored));
diff --git a/src/libextra/workcache.rs b/src/libextra/workcache.rs
index 24ab8360e8f..e24fe3eb8c2 100644
--- a/src/libextra/workcache.rs
+++ b/src/libextra/workcache.rs
@@ -127,7 +127,7 @@ impl WorkMap {
     }
 }
 
-struct Database {
+pub struct Database {
     db_filename: Path,
     db_cache: TreeMap<~str, ~str>,
     db_dirty: bool
@@ -207,7 +207,7 @@ impl Drop for Database {
     }
 }
 
-struct Logger {
+pub struct Logger {
     // FIXME #4432: Fill in
     a: ()
 }
@@ -223,10 +223,10 @@ impl Logger {
     }
 }
 
-type FreshnessMap = TreeMap<~str,extern fn(&str,&str)->bool>;
+pub type FreshnessMap = TreeMap<~str,extern fn(&str,&str)->bool>;
 
 #[deriving(Clone)]
-struct Context {
+pub struct Context {
     db: RWArc<Database>,
     logger: RWArc<Logger>,
     cfg: Arc<json::Object>,
@@ -239,13 +239,13 @@ struct Context {
     freshness: Arc<FreshnessMap>
 }
 
-struct Prep<'self> {
+pub struct Prep<'self> {
     ctxt: &'self Context,
     fn_name: &'self str,
     declared_inputs: WorkMap,
 }
 
-struct Exec {
+pub struct Exec {
     discovered_inputs: WorkMap,
     discovered_outputs: WorkMap
 }
diff --git a/src/librust/rust.rs b/src/librust/rust.rs
index eb82cfcc0b2..6ebce51b29f 100644
--- a/src/librust/rust.rs
+++ b/src/librust/rust.rs
@@ -28,7 +28,6 @@ extern mod rustc;
 use std::io;
 use std::os;
 use std::run;
-use std::libc::exit;
 
 enum ValidUsage {
     Valid(int), Invalid
@@ -45,7 +44,7 @@ impl ValidUsage {
 
 enum Action {
     Call(extern "Rust" fn(args: &[~str]) -> ValidUsage),
-    CallMain(&'static str, extern "Rust" fn(&[~str])),
+    CallMain(&'static str, extern "Rust" fn(&[~str]) -> int),
 }
 
 enum UsageSource<'self> {
@@ -186,18 +185,17 @@ fn cmd_run(args: &[~str]) -> ValidUsage {
     }
 }
 
-fn invoke(prog: &str, args: &[~str], f: &fn(&[~str])) {
+fn invoke(prog: &str, args: &[~str], f: &fn(&[~str]) -> int) -> int {
     let mut osargs = ~[prog.to_owned()];
     osargs.push_all_move(args.to_owned());
-    f(osargs);
+    f(osargs)
 }
 
 fn do_command(command: &Command, args: &[~str]) -> ValidUsage {
     match command.action {
         Call(f) => f(args),
         CallMain(prog, f) => {
-            invoke(prog, args, f);
-            Valid(0)
+            Valid(invoke(prog, args, f))
         }
     }
 }
@@ -235,7 +233,7 @@ pub fn main() {
 
     if (os_args.len() > 1 && (os_args[1] == ~"-v" || os_args[1] == ~"--version")) {
         rustc::version(os_args[0]);
-        unsafe { exit(0); }
+        return;
     }
 
     let args = os_args.tail();
@@ -245,8 +243,11 @@ pub fn main() {
         for command in r.iter() {
             let result = do_command(command, args.tail());
             match result {
-                Valid(exit_code) => unsafe { exit(exit_code.to_i32()) },
-                _                => loop
+                Valid(exit_code) => {
+                    os::set_exit_status(exit_code);
+                    return;
+                }
+                _ => loop
             }
         }
     }
diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs
index bd0462119bd..5518dde0ee9 100644
--- a/src/librustc/driver/driver.rs
+++ b/src/librustc/driver/driver.rs
@@ -113,8 +113,8 @@ pub fn build_configuration(sess: Session) ->
 }
 
 // Convert strings provided as --cfg [cfgspec] into a crate_cfg
-fn parse_cfgspecs(cfgspecs: ~[~str],
-                  demitter: diagnostic::Emitter) -> ast::CrateConfig {
+fn parse_cfgspecs(cfgspecs: ~[~str], demitter: @diagnostic::Emitter)
+                  -> ast::CrateConfig {
     do cfgspecs.move_iter().map |s| {
         let sess = parse::new_parse_sess(Some(demitter));
         parse::parse_meta_from_source_str(@"cfgspec", s.to_managed(), ~[], sess)
@@ -197,6 +197,7 @@ pub fn phase_2_configure_and_expand(sess: Session,
 
 pub struct CrateAnalysis {
     exp_map2: middle::resolve::ExportMap2,
+    exported_items: @middle::privacy::ExportedItems,
     ty_cx: ty::ctxt,
     maps: astencode::Maps,
     reachable: @mut HashSet<ast::NodeId>
@@ -258,8 +259,9 @@ pub fn phase_3_run_analysis_passes(sess: Session,
          middle::check_const::check_crate(sess, crate, ast_map, def_map,
                                           method_map, ty_cx));
 
-    time(time_passes, ~"privacy checking", ||
-         middle::privacy::check_crate(ty_cx, &method_map, crate));
+    let exported_items =
+        time(time_passes, ~"privacy checking", ||
+             middle::privacy::check_crate(ty_cx, &method_map, &exp_map2, crate));
 
     time(time_passes, ~"effect checking", ||
          middle::effect::check_crate(ty_cx, method_map, crate));
@@ -301,6 +303,7 @@ pub fn phase_3_run_analysis_passes(sess: Session,
 
     CrateAnalysis {
         exp_map2: exp_map2,
+        exported_items: @exported_items,
         ty_cx: ty_cx,
         maps: astencode::Maps {
             root_map: root_map,
@@ -439,15 +442,70 @@ pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &input,
     phase_6_link_output(sess, &trans, outputs);
 }
 
-pub fn pretty_print_input(sess: Session, cfg: ast::CrateConfig, input: &input,
-                          ppm: PpMode) {
+struct IdentifiedAnnotation {
+    contents: (),
+}
 
-    fn ann_paren_for_expr(node: pprust::ann_node) {
+impl pprust::pp_ann for IdentifiedAnnotation {
+    fn pre(&self, node: pprust::ann_node) {
         match node {
-          pprust::node_expr(s, _) => pprust::popen(s),
-          _ => ()
+            pprust::node_expr(s, _) => pprust::popen(s),
+            _ => ()
+        }
+    }
+    fn post(&self, node: pprust::ann_node) {
+        match node {
+            pprust::node_item(s, item) => {
+                pp::space(s.s);
+                pprust::synth_comment(s, item.id.to_str());
+            }
+            pprust::node_block(s, ref blk) => {
+                pp::space(s.s);
+                pprust::synth_comment(s, ~"block " + blk.id.to_str());
+            }
+            pprust::node_expr(s, expr) => {
+                pp::space(s.s);
+                pprust::synth_comment(s, expr.id.to_str());
+                pprust::pclose(s);
+            }
+            pprust::node_pat(s, pat) => {
+                pp::space(s.s);
+                pprust::synth_comment(s, ~"pat " + pat.id.to_str());
+            }
         }
     }
+}
+
+struct TypedAnnotation {
+    analysis: CrateAnalysis,
+}
+
+impl pprust::pp_ann for TypedAnnotation {
+    fn pre(&self, node: pprust::ann_node) {
+        match node {
+            pprust::node_expr(s, _) => pprust::popen(s),
+            _ => ()
+        }
+    }
+    fn post(&self, node: pprust::ann_node) {
+        let tcx = self.analysis.ty_cx;
+        match node {
+            pprust::node_expr(s, expr) => {
+                pp::space(s.s);
+                pp::word(s.s, "as");
+                pp::space(s.s);
+                pp::word(s.s, ppaux::ty_to_str(tcx, ty::expr_ty(tcx, expr)));
+                pprust::pclose(s);
+            }
+            _ => ()
+        }
+    }
+}
+
+pub fn pretty_print_input(sess: Session,
+                          cfg: ast::CrateConfig,
+                          input: &input,
+                          ppm: PpMode) {
     fn ann_typed_post(tcx: ty::ctxt, node: pprust::ann_node) {
         match node {
           pprust::node_expr(s, expr) => {
@@ -460,28 +518,6 @@ pub fn pretty_print_input(sess: Session, cfg: ast::CrateConfig, input: &input,
           _ => ()
         }
     }
-    fn ann_identified_post(node: pprust::ann_node) {
-        match node {
-          pprust::node_item(s, item) => {
-            pp::space(s.s);
-            pprust::synth_comment(s, item.id.to_str());
-          }
-          pprust::node_block(s, ref blk) => {
-            pp::space(s.s);
-            pprust::synth_comment(
-                s, ~"block " + blk.id.to_str());
-          }
-          pprust::node_expr(s, expr) => {
-            pp::space(s.s);
-            pprust::synth_comment(s, expr.id.to_str());
-            pprust::pclose(s);
-          }
-          pprust::node_pat(s, pat) => {
-            pp::space(s.s);
-            pprust::synth_comment(s, ~"pat " + pat.id.to_str());
-          }
-        }
-    }
 
     let crate = phase_1_parse_input(sess, cfg.clone(), input);
 
@@ -494,28 +530,30 @@ pub fn pretty_print_input(sess: Session, cfg: ast::CrateConfig, input: &input,
 
     let annotation = match ppm {
         PpmIdentified | PpmExpandedIdentified => {
-            pprust::pp_ann {
-                pre: ann_paren_for_expr,
-                post: ann_identified_post
-            }
+            @IdentifiedAnnotation {
+                contents: (),
+            } as @pprust::pp_ann
         }
         PpmTyped => {
             let analysis = phase_3_run_analysis_passes(sess, crate);
-            pprust::pp_ann {
-                pre: ann_paren_for_expr,
-                post: |a| ann_typed_post(analysis.ty_cx, a)
-            }
+            @TypedAnnotation {
+                analysis: analysis
+            } as @pprust::pp_ann
         }
-        _ => pprust::no_ann()
+        _ => @pprust::no_ann::new() as @pprust::pp_ann,
     };
 
     let src = sess.codemap.get_filemap(source_name(input)).src;
     do io::with_str_reader(src) |rdr| {
-        pprust::print_crate(sess.codemap, token::get_ident_interner(),
-                            sess.span_diagnostic, crate,
+        pprust::print_crate(sess.codemap,
+                            token::get_ident_interner(),
+                            sess.span_diagnostic,
+                            crate,
                             source_name(input),
-                            rdr, io::stdout(),
-                            annotation, is_expanded);
+                            rdr,
+                            io::stdout(),
+                            annotation,
+                            is_expanded);
     }
 }
 
@@ -554,8 +592,8 @@ static architecture_abis : &'static [(&'static str, abi::Architecture)] = &'stat
     ("mips",   abi::Mips)];
 
 pub fn build_target_config(sopts: @session::options,
-                           demitter: diagnostic::Emitter)
-                        -> @session::config {
+                           demitter: @diagnostic::Emitter)
+                           -> @session::config {
     let os = match get_os(sopts.target_triple) {
       Some(os) => os,
       None => early_error(demitter, ~"unknown operating system")
@@ -603,8 +641,8 @@ pub fn host_triple() -> ~str {
 
 pub fn build_session_options(binary: @str,
                              matches: &getopts::Matches,
-                             demitter: diagnostic::Emitter)
-                          -> @session::options {
+                             demitter: @diagnostic::Emitter)
+                             -> @session::options {
     let crate_type = if matches.opt_present("lib") {
         session::lib_crate
     } else if matches.opt_present("bin") {
@@ -777,8 +815,8 @@ pub fn build_session_options(binary: @str,
     return sopts;
 }
 
-pub fn build_session(sopts: @session::options,
-                     demitter: diagnostic::Emitter) -> Session {
+pub fn build_session(sopts: @session::options, demitter: @diagnostic::Emitter)
+                     -> Session {
     let codemap = @codemap::CodeMap::new();
     let diagnostic_handler =
         diagnostic::mk_handler(Some(demitter));
@@ -789,9 +827,9 @@ pub fn build_session(sopts: @session::options,
 
 pub fn build_session_(sopts: @session::options,
                       cm: @codemap::CodeMap,
-                      demitter: diagnostic::Emitter,
+                      demitter: @diagnostic::Emitter,
                       span_diagnostic_handler: @mut diagnostic::span_handler)
-                   -> Session {
+                      -> Session {
     let target_cfg = build_target_config(sopts, demitter);
     let p_s = parse::new_parse_sess_special_handler(span_diagnostic_handler,
                                                     cm);
@@ -1000,8 +1038,8 @@ pub fn build_output_filenames(input: &input,
     }
 }
 
-pub fn early_error(emitter: diagnostic::Emitter, msg: ~str) -> ! {
-    emitter(None, msg, diagnostic::fatal);
+pub fn early_error(emitter: @diagnostic::Emitter, msg: ~str) -> ! {
+    emitter.emit(None, msg, diagnostic::fatal);
     fail!();
 }
 
@@ -1030,8 +1068,12 @@ mod test {
               Err(f) => fail!("test_switch_implies_cfg_test: %s", f.to_err_msg())
             };
         let sessopts = build_session_options(
-            @"rustc", matches, diagnostic::emit);
-        let sess = build_session(sessopts, diagnostic::emit);
+            @"rustc",
+            matches,
+            @diagnostic::DefaultEmitter as @diagnostic::Emitter);
+        let sess = build_session(sessopts,
+                                 @diagnostic::DefaultEmitter as
+                                    @diagnostic::Emitter);
         let cfg = build_configuration(sess);
         assert!((attr::contains_name(cfg, "test")));
     }
@@ -1048,8 +1090,12 @@ mod test {
               }
             };
         let sessopts = build_session_options(
-            @"rustc", matches, diagnostic::emit);
-        let sess = build_session(sessopts, diagnostic::emit);
+            @"rustc",
+            matches,
+            @diagnostic::DefaultEmitter as @diagnostic::Emitter);
+        let sess = build_session(sessopts,
+                                 @diagnostic::DefaultEmitter as
+                                    @diagnostic::Emitter);
         let cfg = build_configuration(sess);
         let mut test_items = cfg.iter().filter(|m| "test" == m.name());
         assert!(test_items.next().is_some());
diff --git a/src/librustc/front/assign_node_ids.rs b/src/librustc/front/assign_node_ids.rs
index 446db5c35e9..fc1b034de97 100644
--- a/src/librustc/front/assign_node_ids.rs
+++ b/src/librustc/front/assign_node_ids.rs
@@ -11,9 +11,22 @@
 use driver::session::Session;
 
 use syntax::ast;
-use syntax::ast_util;
+use syntax::fold::ast_fold;
+
+struct NodeIdAssigner {
+    sess: Session,
+}
+
+impl ast_fold for NodeIdAssigner {
+    fn new_id(&self, old_id: ast::NodeId) -> ast::NodeId {
+        assert_eq!(old_id, ast::DUMMY_NODE_ID);
+        self.sess.next_node_id()
+    }
+}
 
 pub fn assign_node_ids(sess: Session, crate: @ast::Crate) -> @ast::Crate {
-    let fold = ast_util::node_id_assigner(|| sess.next_node_id());
+    let fold = NodeIdAssigner {
+        sess: sess,
+    };
     @fold.fold_crate(crate)
 }
diff --git a/src/librustc/front/config.rs b/src/librustc/front/config.rs
index 2c0068729a7..efaebcca011 100644
--- a/src/librustc/front/config.rs
+++ b/src/librustc/front/config.rs
@@ -9,13 +9,11 @@
 // except according to those terms.
 
 
-use std::option;
+use syntax::fold::ast_fold;
 use syntax::{ast, fold, attr};
 
-type in_cfg_pred = @fn(attrs: &[ast::Attribute]) -> bool;
-
-struct Context {
-    in_cfg: in_cfg_pred
+struct Context<'self> {
+    in_cfg: &'self fn(attrs: &[ast::Attribute]) -> bool,
 }
 
 // Support conditional compilation by transforming the AST, stripping out
@@ -26,43 +24,55 @@ pub fn strip_unconfigured_items(crate: @ast::Crate) -> @ast::Crate {
     }
 }
 
-pub fn strip_items(crate: &ast::Crate, in_cfg: in_cfg_pred)
-    -> @ast::Crate {
-
-    let ctxt = @Context { in_cfg: in_cfg };
+impl<'self> fold::ast_fold for Context<'self> {
+    fn fold_mod(&self, module: &ast::_mod) -> ast::_mod {
+        fold_mod(self, module)
+    }
+    fn fold_block(&self, block: &ast::Block) -> ast::Block {
+        fold_block(self, block)
+    }
+    fn fold_foreign_mod(&self, foreign_module: &ast::foreign_mod)
+                        -> ast::foreign_mod {
+        fold_foreign_mod(self, foreign_module)
+    }
+    fn fold_item_underscore(&self, item: &ast::item_) -> ast::item_ {
+        fold_item_underscore(self, item)
+    }
+}
 
-    let precursor = @fold::AstFoldFns {
-          fold_mod: |a,b| fold_mod(ctxt, a, b),
-          fold_block: |a,b| fold_block(ctxt, a, b),
-          fold_foreign_mod: |a,b| fold_foreign_mod(ctxt, a, b),
-          fold_item_underscore: |a,b| fold_item_underscore(ctxt, a, b),
-          .. *fold::default_ast_fold()
+pub fn strip_items(crate: &ast::Crate,
+                   in_cfg: &fn(attrs: &[ast::Attribute]) -> bool)
+                   -> @ast::Crate {
+    let ctxt = Context {
+        in_cfg: in_cfg,
     };
-
-    let fold = fold::make_fold(precursor);
-    @fold.fold_crate(crate)
+    @ctxt.fold_crate(crate)
 }
 
-fn filter_item(cx: @Context, item: @ast::item) ->
-   Option<@ast::item> {
-    if item_in_cfg(cx, item) { option::Some(item) } else { option::None }
+fn filter_item(cx: &Context, item: @ast::item) -> Option<@ast::item> {
+    if item_in_cfg(cx, item) {
+        Some(item)
+    } else {
+        None
+    }
 }
 
-fn filter_view_item<'r>(cx: @Context, view_item: &'r ast::view_item)-> Option<&'r ast::view_item> {
+fn filter_view_item<'r>(cx: &Context, view_item: &'r ast::view_item)
+                        -> Option<&'r ast::view_item> {
     if view_item_in_cfg(cx, view_item) {
-        option::Some(view_item)
+        Some(view_item)
     } else {
-        option::None
+        None
     }
 }
 
-fn fold_mod(cx: @Context, m: &ast::_mod, fld: @fold::ast_fold) -> ast::_mod {
-    let filtered_items = do  m.items.iter().filter_map |a| {
-        filter_item(cx, *a).and_then(|x| fld.fold_item(x))
+fn fold_mod(cx: &Context, m: &ast::_mod) -> ast::_mod {
+    let filtered_items = do m.items.iter().filter_map |a| {
+        filter_item(cx, *a).and_then(|x| cx.fold_item(x))
     }.collect();
     let filtered_view_items = do m.view_items.iter().filter_map |a| {
         do filter_view_item(cx, a).map_move |x| {
-            fld.fold_view_item(x)
+            cx.fold_view_item(x)
         }
     }.collect();
     ast::_mod {
@@ -71,22 +81,23 @@ fn fold_mod(cx: @Context, m: &ast::_mod, fld: @fold::ast_fold) -> ast::_mod {
     }
 }
 
-fn filter_foreign_item(cx: @Context, item: @ast::foreign_item) ->
-   Option<@ast::foreign_item> {
+fn filter_foreign_item(cx: &Context, item: @ast::foreign_item)
+                       -> Option<@ast::foreign_item> {
     if foreign_item_in_cfg(cx, item) {
-        option::Some(item)
-    } else { option::None }
+        Some(item)
+    } else {
+        None
+    }
 }
 
-fn fold_foreign_mod(
-    cx: @Context,
-    nm: &ast::foreign_mod,
-    fld: @fold::ast_fold
-) -> ast::foreign_mod {
-    let filtered_items = nm.items.iter().filter_map(|a| filter_foreign_item(cx, *a)).collect();
+fn fold_foreign_mod(cx: &Context, nm: &ast::foreign_mod) -> ast::foreign_mod {
+    let filtered_items = nm.items
+                           .iter()
+                           .filter_map(|a| filter_foreign_item(cx, *a))
+                           .collect();
     let filtered_view_items = do nm.view_items.iter().filter_map |a| {
         do filter_view_item(cx, a).map_move |x| {
-            fld.fold_view_item(x)
+            cx.fold_view_item(x)
         }
     }.collect();
     ast::foreign_mod {
@@ -97,8 +108,7 @@ fn fold_foreign_mod(
     }
 }
 
-fn fold_item_underscore(cx: @Context, item: &ast::item_,
-                        fld: @fold::ast_fold) -> ast::item_ {
+fn fold_item_underscore(cx: &Context, item: &ast::item_) -> ast::item_ {
     let item = match *item {
         ast::item_impl(ref a, ref b, ref c, ref methods) => {
             let methods = methods.iter().filter(|m| method_in_cfg(cx, **m))
@@ -106,71 +116,70 @@ fn fold_item_underscore(cx: @Context, item: &ast::item_,
             ast::item_impl((*a).clone(), (*b).clone(), (*c).clone(), methods)
         }
         ast::item_trait(ref a, ref b, ref methods) => {
-            let methods = methods.iter().filter(|m| trait_method_in_cfg(cx, *m) )
-                .map(|x| (*x).clone()).collect();
+            let methods = methods.iter()
+                                 .filter(|m| trait_method_in_cfg(cx, *m) )
+                                 .map(|x| (*x).clone())
+                                 .collect();
             ast::item_trait((*a).clone(), (*b).clone(), methods)
         }
         ref item => (*item).clone(),
     };
 
-    fold::noop_fold_item_underscore(&item, fld)
+    fold::noop_fold_item_underscore(&item, cx)
 }
 
-fn filter_stmt(cx: @Context, stmt: @ast::Stmt) ->
-   Option<@ast::Stmt> {
+fn filter_stmt(cx: &Context, stmt: @ast::Stmt) -> Option<@ast::Stmt> {
     match stmt.node {
       ast::StmtDecl(decl, _) => {
         match decl.node {
           ast::DeclItem(item) => {
             if item_in_cfg(cx, item) {
-                option::Some(stmt)
-            } else { option::None }
+                Some(stmt)
+            } else {
+                None
+            }
           }
-          _ => option::Some(stmt)
+          _ => Some(stmt)
         }
       }
-      _ => option::Some(stmt)
+      _ => Some(stmt),
     }
 }
 
-fn fold_block(
-    cx: @Context,
-    b: &ast::Block,
-    fld: @fold::ast_fold
-) -> ast::Block {
+fn fold_block(cx: &Context, b: &ast::Block) -> ast::Block {
     let resulting_stmts = do b.stmts.iter().filter_map |a| {
-        filter_stmt(cx, *a).and_then(|stmt| fld.fold_stmt(stmt))
+        filter_stmt(cx, *a).and_then(|stmt| cx.fold_stmt(stmt))
     }.collect();
     let filtered_view_items = do b.view_items.iter().filter_map |a| {
-        filter_view_item(cx, a).map(|x| fld.fold_view_item(*x))
+        filter_view_item(cx, a).map(|x| cx.fold_view_item(*x))
     }.collect();
     ast::Block {
         view_items: filtered_view_items,
         stmts: resulting_stmts,
-        expr: b.expr.map(|x| fld.fold_expr(*x)),
+        expr: b.expr.map(|x| cx.fold_expr(*x)),
         id: b.id,
         rules: b.rules,
         span: b.span,
     }
 }
 
-fn item_in_cfg(cx: @Context, item: @ast::item) -> bool {
+fn item_in_cfg(cx: &Context, item: @ast::item) -> bool {
     return (cx.in_cfg)(item.attrs);
 }
 
-fn foreign_item_in_cfg(cx: @Context, item: @ast::foreign_item) -> bool {
+fn foreign_item_in_cfg(cx: &Context, item: @ast::foreign_item) -> bool {
     return (cx.in_cfg)(item.attrs);
 }
 
-fn view_item_in_cfg(cx: @Context, item: &ast::view_item) -> bool {
+fn view_item_in_cfg(cx: &Context, item: &ast::view_item) -> bool {
     return (cx.in_cfg)(item.attrs);
 }
 
-fn method_in_cfg(cx: @Context, meth: @ast::method) -> bool {
+fn method_in_cfg(cx: &Context, meth: @ast::method) -> bool {
     return (cx.in_cfg)(meth.attrs);
 }
 
-fn trait_method_in_cfg(cx: @Context, meth: &ast::trait_method) -> bool {
+fn trait_method_in_cfg(cx: &Context, meth: &ast::trait_method) -> bool {
     match *meth {
         ast::required(ref meth) => (cx.in_cfg)(meth.attrs),
         ast::provided(@ref meth) => (cx.in_cfg)(meth.attrs)
@@ -182,3 +191,4 @@ fn trait_method_in_cfg(cx: @Context, meth: &ast::trait_method) -> bool {
 fn in_cfg(cfg: &[@ast::MetaItem], attrs: &[ast::Attribute]) -> bool {
     attr::test_cfg(cfg, attrs.iter().map(|x| *x))
 }
+
diff --git a/src/librustc/front/std_inject.rs b/src/librustc/front/std_inject.rs
index 79e554090f3..ab407806bcc 100644
--- a/src/librustc/front/std_inject.rs
+++ b/src/librustc/front/std_inject.rs
@@ -16,6 +16,7 @@ use syntax::ast;
 use syntax::attr;
 use syntax::codemap::dummy_sp;
 use syntax::codemap;
+use syntax::fold::ast_fold;
 use syntax::fold;
 use syntax::opt_vec;
 
@@ -38,91 +39,103 @@ fn no_prelude(attrs: &[ast::Attribute]) -> bool {
     attr::contains_name(attrs, "no_implicit_prelude")
 }
 
-fn inject_libstd_ref(sess: Session, crate: &ast::Crate) -> @ast::Crate {
-    fn spanned<T>(x: T) -> codemap::Spanned<T> {
-        codemap::Spanned { node: x, span: dummy_sp() }
+fn spanned<T>(x: T) -> codemap::Spanned<T> {
+    codemap::Spanned {
+        node: x,
+        span: dummy_sp(),
     }
+}
 
-    let precursor = @fold::AstFoldFns {
-        fold_crate: |crate, fld| {
-            let n1 = ast::DUMMY_NODE_ID;
-            let vi1 = ast::view_item {
-                node: ast::view_item_extern_mod(
-                        sess.ident_of("std"), None, ~[], n1),
-                attrs: ~[
-                    attr::mk_attr(
-                        attr::mk_name_value_item_str(@"vers", STD_VERSION.to_managed()))
-                ],
-                vis: ast::private,
-                span: dummy_sp()
-            };
-
-            let vis = vec::append(~[vi1], crate.module.view_items);
-            let mut new_module = ast::_mod {
-                view_items: vis,
-                ..crate.module.clone()
-            };
-
-            if !no_prelude(crate.attrs) {
-                // only add `use std::prelude::*;` if there wasn't a
-                // `#[no_implicit_prelude];` at the crate level.
-                new_module = fld.fold_mod(&new_module);
-            }
-
-            // FIXME #2543: Bad copy.
-            ast::Crate {
-                module: new_module,
-                ..(*crate).clone()
-            }
-        },
-        fold_item: |item, fld| {
-            if !no_prelude(item.attrs) {
-                // only recur if there wasn't `#[no_implicit_prelude];`
-                // on this item, i.e. this means that the prelude is not
-                // implicitly imported though the whole subtree
-                fold::noop_fold_item(item, fld)
-            } else {
-                Some(item)
-            }
-        },
-        fold_mod: |module, fld| {
-            let n2 = ast::DUMMY_NODE_ID;
-
-            let prelude_path = ast::Path {
-                span: dummy_sp(),
-                global: false,
-                segments: ~[
-                    ast::PathSegment {
-                        identifier: sess.ident_of("std"),
-                        lifetime: None,
-                        types: opt_vec::Empty,
-                    },
-                    ast::PathSegment {
-                        identifier: sess.ident_of("prelude"),
-                        lifetime: None,
-                        types: opt_vec::Empty,
-                    },
-                ],
-            };
-
-            let vp = @spanned(ast::view_path_glob(prelude_path, n2));
-            let vi2 = ast::view_item { node: ast::view_item_use(~[vp]),
-                                        attrs: ~[],
-                                        vis: ast::private,
-                                        span: dummy_sp() };
-
-            let vis = vec::append(~[vi2], module.view_items);
-
-            // FIXME #2543: Bad copy.
-            let new_module = ast::_mod {
-                view_items: vis,
-                ..(*module).clone()
-            };
-            fold::noop_fold_mod(&new_module, fld)
-        },
-        ..*fold::default_ast_fold()
-    };
+struct StandardLibraryInjector {
+    sess: Session,
+}
 
-    let fold = fold::make_fold(precursor);
+impl fold::ast_fold for StandardLibraryInjector {
+    fn fold_crate(&self, crate: &ast::Crate) -> ast::Crate {
+        let version = STD_VERSION.to_managed();
+        let vi1 = ast::view_item {
+            node: ast::view_item_extern_mod(self.sess.ident_of("std"),
+                                            None,
+                                            ~[],
+                                            ast::DUMMY_NODE_ID),
+            attrs: ~[
+                attr::mk_attr(attr::mk_name_value_item_str(@"vers", version))
+            ],
+            vis: ast::private,
+            span: dummy_sp()
+        };
+
+        let vis = vec::append(~[vi1], crate.module.view_items);
+        let mut new_module = ast::_mod {
+            view_items: vis,
+            ..crate.module.clone()
+        };
+
+        if !no_prelude(crate.attrs) {
+            // only add `use std::prelude::*;` if there wasn't a
+            // `#[no_implicit_prelude];` at the crate level.
+            new_module = self.fold_mod(&new_module);
+        }
+
+        // FIXME #2543: Bad copy.
+        ast::Crate {
+            module: new_module,
+            ..(*crate).clone()
+        }
+    }
+
+    fn fold_item(&self, item: @ast::item) -> Option<@ast::item> {
+        if !no_prelude(item.attrs) {
+            // only recur if there wasn't `#[no_implicit_prelude];`
+            // on this item, i.e. this means that the prelude is not
+            // implicitly imported though the whole subtree
+            fold::noop_fold_item(item, self)
+        } else {
+            Some(item)
+        }
+    }
+
+    fn fold_mod(&self, module: &ast::_mod) -> ast::_mod {
+        let prelude_path = ast::Path {
+            span: dummy_sp(),
+            global: false,
+            segments: ~[
+                ast::PathSegment {
+                    identifier: self.sess.ident_of("std"),
+                    lifetime: None,
+                    types: opt_vec::Empty,
+                },
+                ast::PathSegment {
+                    identifier: self.sess.ident_of("prelude"),
+                    lifetime: None,
+                    types: opt_vec::Empty,
+                },
+            ],
+        };
+
+        let vp = @spanned(ast::view_path_glob(prelude_path,
+                                              ast::DUMMY_NODE_ID));
+        let vi2 = ast::view_item {
+            node: ast::view_item_use(~[vp]),
+            attrs: ~[],
+            vis: ast::private,
+            span: dummy_sp(),
+        };
+
+        let vis = vec::append(~[vi2], module.view_items);
+
+        // FIXME #2543: Bad copy.
+        let new_module = ast::_mod {
+            view_items: vis,
+            ..(*module).clone()
+        };
+        fold::noop_fold_mod(&new_module, self)
+    }
+}
+
+fn inject_libstd_ref(sess: Session, crate: &ast::Crate) -> @ast::Crate {
+    let fold = StandardLibraryInjector {
+        sess: sess,
+    };
     @fold.fold_crate(crate)
 }
diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs
index f0d7f6c892b..18998015e95 100644
--- a/src/librustc/front/test.rs
+++ b/src/librustc/front/test.rs
@@ -21,13 +21,12 @@ use syntax::attr;
 use syntax::codemap::{dummy_sp, Span, ExpnInfo, NameAndSpan};
 use syntax::codemap;
 use syntax::ext::base::ExtCtxt;
+use syntax::fold::ast_fold;
 use syntax::fold;
 use syntax::opt_vec;
 use syntax::print::pprust;
 use syntax::{ast, ast_util};
 
-type node_id_gen = @fn() -> ast::NodeId;
-
 struct Test {
     span: Span,
     path: ~[ast::Ident],
@@ -61,9 +60,89 @@ pub fn modify_for_testing(sess: session::Session,
     }
 }
 
-fn generate_test_harness(sess: session::Session,
-                         crate: @ast::Crate)
-                      -> @ast::Crate {
+struct TestHarnessGenerator {
+    cx: @mut TestCtxt,
+}
+
+impl fold::ast_fold for TestHarnessGenerator {
+    fn fold_crate(&self, c: &ast::Crate) -> ast::Crate {
+        let folded = fold::noop_fold_crate(c, self);
+
+        // Add a special __test module to the crate that will contain code
+        // generated for the test harness
+        ast::Crate {
+            module: add_test_module(self.cx, &folded.module),
+            .. folded
+        }
+    }
+
+    fn fold_item(&self, i: @ast::item) -> Option<@ast::item> {
+        self.cx.path.push(i.ident);
+        debug!("current path: %s",
+               ast_util::path_name_i(self.cx.path.clone()));
+
+        if is_test_fn(self.cx, i) || is_bench_fn(i) {
+            match i.node {
+                ast::item_fn(_, purity, _, _, _)
+                    if purity == ast::unsafe_fn => {
+                    let sess = self.cx.sess;
+                    sess.span_fatal(i.span,
+                                    "unsafe functions cannot be used for \
+                                     tests");
+                }
+                _ => {
+                    debug!("this is a test function");
+                    let test = Test {
+                        span: i.span,
+                        path: self.cx.path.clone(),
+                        bench: is_bench_fn(i),
+                        ignore: is_ignored(self.cx, i),
+                        should_fail: should_fail(i)
+                    };
+                    self.cx.testfns.push(test);
+                    // debug!("have %u test/bench functions",
+                    //        cx.testfns.len());
+                }
+            }
+        }
+
+        let res = fold::noop_fold_item(i, self);
+        self.cx.path.pop();
+        return res;
+    }
+
+    fn fold_mod(&self, m: &ast::_mod) -> ast::_mod {
+        // Remove any #[main] from the AST so it doesn't clash with
+        // the one we're going to add. Only if compiling an executable.
+
+        fn nomain(cx: @mut TestCtxt, item: @ast::item) -> @ast::item {
+            if !*cx.sess.building_library {
+                @ast::item {
+                    attrs: do item.attrs.iter().filter_map |attr| {
+                        if "main" != attr.name() {
+                            Some(*attr)
+                        } else {
+                            None
+                        }
+                    }.collect(),
+                    .. (*item).clone()
+                }
+            } else {
+                item
+            }
+        }
+
+        let mod_nomain = ast::_mod {
+            view_items: m.view_items.clone(),
+            items: m.items.iter().map(|i| nomain(self.cx, *i)).collect(),
+        };
+
+        fold::noop_fold_mod(&mod_nomain, self)
+    }
+}
+
+fn generate_test_harness(sess: session::Session, crate: @ast::Crate)
+                         -> @ast::Crate {
     let cx: @mut TestCtxt = @mut TestCtxt {
         sess: sess,
         crate: crate,
@@ -81,12 +160,9 @@ fn generate_test_harness(sess: session::Session,
         }
     });
 
-    let precursor = @fold::AstFoldFns {
-        fold_crate: |a,b| fold_crate(cx, a, b),
-        fold_item: |a,b| fold_item(cx, a, b),
-        fold_mod: |a,b| fold_mod(cx, a, b),.. *fold::default_ast_fold()};
-
-    let fold = fold::make_fold(precursor);
+    let fold = TestHarnessGenerator {
+        cx: cx
+    };
     let res = @fold.fold_crate(&*crate);
     ext_cx.bt_pop();
     return res;
@@ -101,85 +177,6 @@ fn strip_test_functions(crate: &ast::Crate) -> @ast::Crate {
     }
 }
 
-fn fold_mod(cx: @mut TestCtxt,
-            m: &ast::_mod,
-            fld: @fold::ast_fold)
-         -> ast::_mod {
-    // Remove any #[main] from the AST so it doesn't clash with
-    // the one we're going to add. Only if compiling an executable.
-
-    fn nomain(cx: @mut TestCtxt, item: @ast::item) -> @ast::item {
-        if !*cx.sess.building_library {
-            @ast::item {
-                attrs: do item.attrs.iter().filter_map |attr| {
-                    if "main" != attr.name() {
-                        Some(*attr)
-                    } else {
-                        None
-                    }
-                }.collect(),
-                .. (*item).clone()
-            }
-        } else {
-            item
-        }
-    }
-
-    let mod_nomain = ast::_mod {
-        view_items: m.view_items.clone(),
-        items: m.items.iter().map(|i| nomain(cx, *i)).collect(),
-    };
-
-    fold::noop_fold_mod(&mod_nomain, fld)
-}
-
-fn fold_crate(cx: @mut TestCtxt, c: &ast::Crate, fld: @fold::ast_fold)
-              -> ast::Crate {
-    let folded = fold::noop_fold_crate(c, fld);
-
-    // Add a special __test module to the crate that will contain code
-    // generated for the test harness
-    ast::Crate {
-        module: add_test_module(cx, &folded.module),
-        .. folded
-    }
-}
-
-
-fn fold_item(cx: @mut TestCtxt, i: @ast::item, fld: @fold::ast_fold)
-          -> Option<@ast::item> {
-    cx.path.push(i.ident);
-    debug!("current path: %s",
-           ast_util::path_name_i(cx.path.clone()));
-
-    if is_test_fn(cx, i) || is_bench_fn(i) {
-        match i.node {
-          ast::item_fn(_, purity, _, _, _) if purity == ast::unsafe_fn => {
-            let sess = cx.sess;
-            sess.span_fatal(
-                i.span,
-                "unsafe functions cannot be used for tests");
-          }
-          _ => {
-            debug!("this is a test function");
-            let test = Test {
-                span: i.span,
-                path: cx.path.clone(),
-                bench: is_bench_fn(i),
-                ignore: is_ignored(cx, i),
-                should_fail: should_fail(i)
-            };
-            cx.testfns.push(test);
-            // debug!("have %u test/bench functions", cx.testfns.len());
-          }
-        }
-    }
-
-    let res = fold::noop_fold_item(i, fld);
-    cx.path.pop();
-    return res;
-}
-
 fn is_test_fn(cx: @mut TestCtxt, i: @ast::item) -> bool {
     let has_test_attr = attr::contains_name(i.attrs, "test");
 
diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs
index bc7cba46c6b..841142ee62f 100644
--- a/src/librustc/metadata/csearch.rs
+++ b/src/librustc/metadata/csearch.rs
@@ -27,7 +27,8 @@ use syntax::diagnostic::expect;
 pub struct StaticMethodInfo {
     ident: ast::Ident,
     def_id: ast::DefId,
-    purity: ast::purity
+    purity: ast::purity,
+    vis: ast::visibility,
 }
 
 pub fn get_symbol(cstore: @mut cstore::CStore, def: ast::DefId) -> ~str {
@@ -52,7 +53,8 @@ pub fn each_lang_item(cstore: @mut cstore::CStore,
 /// Iterates over each child of the given item.
 pub fn each_child_of_item(cstore: @mut cstore::CStore,
                           def_id: ast::DefId,
-                          callback: &fn(decoder::DefLike, ast::Ident)) {
+                          callback: &fn(decoder::DefLike, ast::Ident,
+                                        ast::visibility)) {
     let crate_data = cstore::get_crate_data(cstore, def_id.crate);
     let get_crate_data: decoder::GetCrateDataCb = |cnum| {
         cstore::get_crate_data(cstore, cnum)
@@ -68,7 +70,8 @@ pub fn each_child_of_item(cstore: @mut cstore::CStore,
 pub fn each_top_level_item_of_crate(cstore: @mut cstore::CStore,
                                     cnum: ast::CrateNum,
                                     callback: &fn(decoder::DefLike,
-                                                  ast::Ident)) {
+                                                  ast::Ident,
+                                                  ast::visibility)) {
     let crate_data = cstore::get_crate_data(cstore, cnum);
     let get_crate_data: decoder::GetCrateDataCb = |cnum| {
         cstore::get_crate_data(cstore, cnum)
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index c94151095a4..fe7309d4467 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -96,7 +96,7 @@ fn find_item(item_id: int, items: ebml::Doc) -> ebml::Doc {
 
 // Looks up an item in the given metadata and returns an ebml doc pointing
 // to the item data.
-fn lookup_item(item_id: int, data: @~[u8]) -> ebml::Doc {
+pub fn lookup_item(item_id: int, data: @~[u8]) -> ebml::Doc {
     let items = reader::get_doc(reader::Doc(data), tag_items);
     find_item(item_id, items)
 }
@@ -291,7 +291,7 @@ fn enum_variant_ids(item: ebml::Doc, cdata: Cmd) -> ~[ast::DefId] {
     return ids;
 }
 
-fn item_path(item_doc: ebml::Doc) -> ast_map::path {
+pub fn item_path(item_doc: ebml::Doc) -> ast_map::path {
     let path_doc = reader::get_doc(item_doc, tag_path);
 
     let len_doc = reader::get_doc(path_doc, tag_path_len);
@@ -332,7 +332,7 @@ fn item_name(intr: @ident_interner, item: ebml::Doc) -> ast::Ident {
     }
 }
 
-fn item_to_def_like(item: ebml::Doc, did: ast::DefId, cnum: ast::CrateNum)
+pub fn item_to_def_like(item: ebml::Doc, did: ast::DefId, cnum: ast::CrateNum)
     -> DefLike {
     let fam = item_family(item);
     match fam {
@@ -491,7 +491,7 @@ pub enum DefLike {
     DlField
 }
 
-fn def_like_to_def(def_like: DefLike) -> ast::Def {
+pub fn def_like_to_def(def_like: DefLike) -> ast::Def {
     match def_like {
         DlDef(def) => return def,
         DlImpl(*) => fail!("found impl in def_like_to_def"),
@@ -544,7 +544,8 @@ impl<'self> EachItemContext<'self> {
     fn process_item_and_pop_name(&mut self,
                                  doc: ebml::Doc,
                                  def_id: ast::DefId,
-                                 old_len: uint)
+                                 old_len: uint,
+                                 vis: ast::visibility)
                                  -> bool {
         let def_like = item_to_def_like(doc, def_id, self.cdata.cnum);
         match def_like {
@@ -563,8 +564,6 @@ impl<'self> EachItemContext<'self> {
             }
         }
 
-        let vis = item_visibility(doc);
-
         let mut continue = (self.callback)(*self.path_builder, def_like, vis);
 
         let family = item_family(doc);
@@ -653,9 +652,12 @@ impl<'self> EachItemContext<'self> {
                         self.push_name(token::ident_to_str(&child_name));
 
                     // Process this item.
+
+                    let vis = item_visibility(child_item_doc);
                     continue = self.process_item_and_pop_name(child_item_doc,
                                                               child_def_id,
-                                                              old_len);
+                                                              old_len,
+                                                              vis);
                 }
             }
             continue
@@ -701,12 +703,13 @@ impl<'self> EachItemContext<'self> {
 
             // Get the item.
             match maybe_find_item(def_id.node, other_crates_items) {
-                None => {}
+                None => { self.pop_name(old_len); }
                 Some(reexported_item_doc) => {
                     continue = self.process_item_and_pop_name(
                         reexported_item_doc,
                         def_id,
-                        old_len);
+                        old_len,
+                        ast::public);
                 }
             }
 
@@ -721,7 +724,8 @@ fn each_child_of_item_or_crate(intr: @ident_interner,
                                cdata: Cmd,
                                item_doc: ebml::Doc,
                                get_crate_data: GetCrateDataCb,
-                               callback: &fn(DefLike, ast::Ident)) {
+                               callback: &fn(DefLike, ast::Ident,
+                                             ast::visibility)) {
     // Iterate over all children.
     let _ = do reader::tagged_docs(item_doc, tag_mod_child) |child_info_doc| {
         let child_def_id = reader::with_doc_data(child_info_doc,
@@ -746,7 +750,8 @@ fn each_child_of_item_or_crate(intr: @ident_interner,
                 let def_like = item_to_def_like(child_item_doc,
                                                 child_def_id,
                                                 cdata.cnum);
-                callback(def_like, child_name);
+                let visibility = item_visibility(child_item_doc);
+                callback(def_like, child_name, visibility);
 
             }
         }
@@ -788,7 +793,8 @@ fn each_child_of_item_or_crate(intr: @ident_interner,
                                                          impl_method_def_id,
                                                          cdata.cnum);
                                     callback(static_method_def_like,
-                                             static_method_name);
+                                             static_method_name,
+                                             item_visibility(impl_method_doc));
                                 }
                                 _ => {}
                             }
@@ -831,7 +837,8 @@ fn each_child_of_item_or_crate(intr: @ident_interner,
                 let def_like = item_to_def_like(child_item_doc,
                                                 child_def_id,
                                                 cdata.cnum);
-                callback(def_like, token::str_to_ident(name));
+                callback(def_like, token::str_to_ident(name),
+                         item_visibility(child_item_doc));
             }
         }
 
@@ -844,7 +851,7 @@ pub fn each_child_of_item(intr: @ident_interner,
                           cdata: Cmd,
                           id: ast::NodeId,
                           get_crate_data: GetCrateDataCb,
-                          callback: &fn(DefLike, ast::Ident)) {
+                          callback: &fn(DefLike, ast::Ident, ast::visibility)) {
     // Find the item.
     let root_doc = reader::Doc(cdata.data);
     let items = reader::get_doc(root_doc, tag_items);
@@ -864,7 +871,8 @@ pub fn each_child_of_item(intr: @ident_interner,
 pub fn each_top_level_item_of_crate(intr: @ident_interner,
                                     cdata: Cmd,
                                     get_crate_data: GetCrateDataCb,
-                                    callback: &fn(DefLike, ast::Ident)) {
+                                    callback: &fn(DefLike, ast::Ident,
+                                                  ast::visibility)) {
     let root_doc = reader::Doc(cdata.data);
     let misc_info_doc = reader::get_doc(root_doc, tag_misc_info);
     let crate_items_doc = reader::get_doc(misc_info_doc,
@@ -1161,7 +1169,8 @@ pub fn get_static_methods_if_impl(intr: @ident_interner,
                 static_impl_methods.push(StaticMethodInfo {
                     ident: item_name(intr, impl_method_doc),
                     def_id: item_def_id(impl_method_doc, cdata),
-                    purity: purity
+                    purity: purity,
+                    vis: item_visibility(impl_method_doc),
                 });
             }
             _ => {}
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index 9e65e4ec18a..de60927f2a2 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -16,9 +16,9 @@ use metadata::cstore;
 use metadata::decoder;
 use metadata::tyencode;
 use middle::ty::{node_id_to_type, lookup_item_type};
+use middle::astencode;
 use middle::ty;
 use middle::typeck;
-use middle::astencode;
 use middle;
 
 use std::hashmap::{HashMap, HashSet};
@@ -58,6 +58,7 @@ pub struct EncodeParams<'self> {
     diag: @mut span_handler,
     tcx: ty::ctxt,
     reexports2: middle::resolve::ExportMap2,
+    exported_items: @middle::privacy::ExportedItems,
     item_symbols: &'self HashMap<ast::NodeId, ~str>,
     discrim_symbols: &'self HashMap<ast::NodeId, @str>,
     non_inlineable_statics: &'self HashSet<ast::NodeId>,
@@ -88,6 +89,7 @@ pub struct EncodeContext<'self> {
     tcx: ty::ctxt,
     stats: @mut Stats,
     reexports2: middle::resolve::ExportMap2,
+    exported_items: @middle::privacy::ExportedItems,
     item_symbols: &'self HashMap<ast::NodeId, ~str>,
     discrim_symbols: &'self HashMap<ast::NodeId, @str>,
     non_inlineable_statics: &'self HashSet<ast::NodeId>,
@@ -881,7 +883,8 @@ fn encode_info_for_item(ecx: &EncodeContext,
                         ebml_w: &mut writer::Encoder,
                         item: @item,
                         index: @mut ~[entry<i64>],
-                        path: &[ast_map::path_elt]) {
+                        path: &[ast_map::path_elt],
+                        vis: ast::visibility) {
     let tcx = ecx.tcx;
 
     fn add_to_index_(item: @item, ebml_w: &writer::Encoder,
@@ -912,6 +915,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
         if !ecx.non_inlineable_statics.contains(&item.id) {
             (ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item(item));
         }
+        encode_visibility(ebml_w, vis);
         ebml_w.end_tag();
       }
       item_fn(_, purity, _, ref generics, _) => {
@@ -929,6 +933,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
         } else {
             encode_symbol(ecx, ebml_w, item.id);
         }
+        encode_visibility(ebml_w, vis);
         ebml_w.end_tag();
       }
       item_mod(ref m) => {
@@ -955,7 +960,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
             ebml_w.wr_str(def_to_str(local_def(foreign_item.id)));
             ebml_w.end_tag();
         }
-
+        encode_visibility(ebml_w, vis);
         ebml_w.end_tag();
       }
       item_ty(*) => {
@@ -967,6 +972,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
         encode_name(ecx, ebml_w, item.ident);
         encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
         encode_region_param(ecx, ebml_w, item);
+        encode_visibility(ebml_w, vis);
         ebml_w.end_tag();
       }
       item_enum(ref enum_definition, ref generics) => {
@@ -987,6 +993,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
         // Encode inherent implementations for this enumeration.
         encode_inherent_implementations(ecx, ebml_w, def_id);
 
+        encode_visibility(ebml_w, vis);
         ebml_w.end_tag();
 
         encode_enum_variant_info(ecx,
@@ -1018,6 +1025,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
         encode_attributes(ebml_w, item.attrs);
         encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
         encode_region_param(ecx, ebml_w, item);
+        encode_visibility(ebml_w, vis);
 
         /* Encode def_ids for each field and method
          for methods, write all the stuff get_trait_method
@@ -1264,7 +1272,12 @@ fn my_visit_item(i:@item, items: ast_map::map, ebml_w:&writer::Encoder,
             let mut ebml_w = ebml_w.clone();
             // See above
             let ecx : &EncodeContext = unsafe { cast::transmute(ecx_ptr) };
-            encode_info_for_item(ecx, &mut ebml_w, i, index, *pt);
+            let vis = if ecx.exported_items.contains(&i.id) {
+                ast::public
+            } else {
+                ast::inherited
+            };
+            encode_info_for_item(ecx, &mut ebml_w, i, index, *pt, vis);
         }
         _ => fail!("bad item")
     }
@@ -1727,6 +1740,7 @@ pub fn encode_metadata(parms: EncodeParams, crate: &Crate) -> ~[u8] {
         diag,
         tcx,
         reexports2,
+        exported_items,
         discrim_symbols,
         cstore,
         encode_inlined_item,
@@ -1742,6 +1756,7 @@ pub fn encode_metadata(parms: EncodeParams, crate: &Crate) -> ~[u8] {
         tcx: tcx,
         stats: stats,
         reexports2: reexports2,
+        exported_items: exported_items,
         item_symbols: item_symbols,
         discrim_symbols: discrim_symbols,
         non_inlineable_statics: non_inlineable_statics,
diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs
index 892217988c7..c719146c999 100644
--- a/src/librustc/metadata/filesearch.rs
+++ b/src/librustc/metadata/filesearch.rs
@@ -150,7 +150,7 @@ fn make_rustpkg_target_lib_path(dir: &Path,
     dir.push_rel(&Path(libdir()).push(target_triple.to_owned()))
 }
 
-fn get_or_default_sysroot() -> Path {
+pub fn get_or_default_sysroot() -> Path {
     match os::self_exe_path() {
       option::Some(ref p) => (*p).pop(),
       option::None => fail!("can't determine value for sysroot")
diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs
index 6e4b6180fd2..b94a43e07a1 100644
--- a/src/librustc/metadata/tydecode.rs
+++ b/src/librustc/metadata/tydecode.rs
@@ -95,8 +95,7 @@ pub fn parse_ident(st: &mut PState, last: char) -> ast::Ident {
     return parse_ident_(st, |a| is_last(last, a) );
 }
 
-fn parse_ident_(st: &mut PState, is_last: @fn(char) -> bool) ->
-   ast::Ident {
+fn parse_ident_(st: &mut PState, is_last: &fn(char) -> bool) -> ast::Ident {
     let rslt = scan(st, is_last, str::from_utf8);
     return st.tcx.sess.ident_of(rslt);
 }
diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs
index e81da60ed17..417a6dae7be 100644
--- a/src/librustc/metadata/tyencode.rs
+++ b/src/librustc/metadata/tyencode.rs
@@ -26,7 +26,7 @@ use syntax::print::pprust::*;
 pub struct ctxt {
     diag: @mut span_handler,
     // Def -> str Callback:
-    ds: @fn(DefId) -> ~str,
+    ds: extern "Rust" fn(DefId) -> ~str,
     // The type context.
     tcx: ty::ctxt,
     abbrevs: abbrev_ctxt
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index bcc333afeec..683fbba09cc 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -24,6 +24,7 @@ use middle;
 use util::ppaux::ty_to_str;
 
 use std::at_vec;
+use std::libc;
 use extra::ebml::reader;
 use extra::ebml;
 use extra::serialize;
@@ -287,26 +288,24 @@ fn encode_ast(ebml_w: &mut writer::Encoder, item: ast::inlined_item) {
     ebml_w.end_tag();
 }
 
-// Produces a simplified copy of the AST which does not include things
-// that we do not need to or do not want to export.  For example, we
-// do not include any nested items: if these nested items are to be
-// inlined, their AST will be exported separately (this only makes
-// sense because, in Rust, nested items are independent except for
-// their visibility).
-//
-// As it happens, trans relies on the fact that we do not export
-// nested items, as otherwise it would get confused when translating
-// inlined items.
-fn simplify_ast(ii: &ast::inlined_item) -> ast::inlined_item {
-    fn drop_nested_items(blk: &ast::Block, fld: @fold::ast_fold) -> ast::Block {
+struct NestedItemsDropper {
+    contents: (),
+}
+
+impl fold::ast_fold for NestedItemsDropper {
+    fn fold_block(&self, blk: &ast::Block) -> ast::Block {
         let stmts_sans_items = do blk.stmts.iter().filter_map |stmt| {
             match stmt.node {
-              ast::StmtExpr(_, _) | ast::StmtSemi(_, _) |
-              ast::StmtDecl(@codemap::Spanned { node: ast::DeclLocal(_), span: _}, _)
-                => Some(*stmt),
-              ast::StmtDecl(@codemap::Spanned { node: ast::DeclItem(_), span: _}, _)
-                => None,
-              ast::StmtMac(*) => fail!("unexpanded macro in astencode")
+                ast::StmtExpr(_, _) | ast::StmtSemi(_, _) |
+                ast::StmtDecl(@codemap::Spanned {
+                    node: ast::DeclLocal(_),
+                    span: _
+                }, _) => Some(*stmt),
+                ast::StmtDecl(@codemap::Spanned {
+                    node: ast::DeclItem(_),
+                    span: _
+                }, _) => None,
+                ast::StmtMac(*) => fail!("unexpanded macro in astencode")
             }
         }.collect();
         let blk_sans_items = ast::Block {
@@ -318,13 +317,24 @@ fn simplify_ast(ii: &ast::inlined_item) -> ast::inlined_item {
             rules: blk.rules,
             span: blk.span,
         };
-        fold::noop_fold_block(&blk_sans_items, fld)
+        fold::noop_fold_block(&blk_sans_items, self)
     }
+}
 
-    let fld = fold::make_fold(@fold::AstFoldFns {
-        fold_block: drop_nested_items,
-        .. *fold::default_ast_fold()
-    });
+// Produces a simplified copy of the AST which does not include things
+// that we do not need to or do not want to export.  For example, we
+// do not include any nested items: if these nested items are to be
+// inlined, their AST will be exported separately (this only makes
+// sense because, in Rust, nested items are independent except for
+// their visibility).
+//
+// As it happens, trans relies on the fact that we do not export
+// nested items, as otherwise it would get confused when translating
+// inlined items.
+fn simplify_ast(ii: &ast::inlined_item) -> ast::inlined_item {
+    let fld = NestedItemsDropper {
+        contents: (),
+    };
 
     match *ii {
         //hack: we're not dropping items
@@ -341,14 +351,24 @@ fn decode_ast(par_doc: ebml::Doc) -> ast::inlined_item {
     Decodable::decode(&mut d)
 }
 
+struct AstRenumberer {
+    xcx: @ExtendedDecodeContext,
+}
+
+impl fold::ast_fold for AstRenumberer {
+    fn new_id(&self, id: ast::NodeId) -> ast::NodeId {
+        self.xcx.tr_id(id)
+    }
+    fn new_span(&self, span: Span) -> Span {
+        self.xcx.tr_span(span)
+    }
+}
+
 fn renumber_ast(xcx: @ExtendedDecodeContext, ii: ast::inlined_item)
     -> ast::inlined_item {
-    let fld = fold::make_fold(@fold::AstFoldFns{
-        new_id: |a| xcx.tr_id(a),
-        new_span: |a| xcx.tr_span(a),
-        .. *fold::default_ast_fold()
-    });
-
+    let fld = AstRenumberer {
+        xcx: xcx,
+    };
     match ii {
         ast::ii_item(i) => ast::ii_item(fld.fold_item(i).unwrap()),
         ast::ii_method(d, is_provided, m) =>
@@ -830,6 +850,26 @@ impl write_tag_and_id for writer::Encoder {
     }
 }
 
+struct SideTableEncodingIdVisitor {
+    ecx_ptr: *libc::c_void,
+    new_ebml_w: writer::Encoder,
+    maps: Maps,
+}
+
+impl ast_util::IdVisitingOperation for SideTableEncodingIdVisitor {
+    fn visit_id(&self, id: ast::NodeId) {
+        // Note: this will cause a copy of ebml_w, which is bad as
+        // it is mutable. But I believe it's harmless since we generate
+        // balanced EBML.
+        let mut new_ebml_w = self.new_ebml_w.clone();
+        // See above
+        let ecx: &e::EncodeContext = unsafe {
+            cast::transmute(self.ecx_ptr)
+        };
+        encode_side_tables_for_id(ecx, self.maps, &mut new_ebml_w, id)
+    }
+}
+
 fn encode_side_tables_for_ii(ecx: &e::EncodeContext,
                              maps: Maps,
                              ebml_w: &mut writer::Encoder,
@@ -837,22 +877,16 @@ fn encode_side_tables_for_ii(ecx: &e::EncodeContext,
     ebml_w.start_tag(c::tag_table as uint);
     let new_ebml_w = (*ebml_w).clone();
 
-    // Because the ast visitor uses @fn, I can't pass in
-    // ecx directly, but /I/ know that it'll be fine since
-    // the lifetime is tied to the CrateContext that
-    // lives this entire section.
-    let ecx_ptr : *() = unsafe { cast::transmute(ecx) };
-    ast_util::visit_ids_for_inlined_item(
-        ii,
-        |id: ast::NodeId| {
-            // Note: this will cause a copy of ebml_w, which is bad as
-            // it is mutable. But I believe it's harmless since we generate
-            // balanced EBML.
-            let mut new_ebml_w = new_ebml_w.clone();
-            // See above
-            let ecx : &e::EncodeContext = unsafe { cast::transmute(ecx_ptr) };
-            encode_side_tables_for_id(ecx, maps, &mut new_ebml_w, id)
-        });
+    // Because the ast visitor uses @IdVisitingOperation, I can't pass in
+    // ecx directly, but /I/ know that it'll be fine since the lifetime is
+    // tied to the CrateContext that lives throughout this entire section.
+    ast_util::visit_ids_for_inlined_item(ii, @SideTableEncodingIdVisitor {
+        ecx_ptr: unsafe {
+            cast::transmute(ecx)
+        },
+        new_ebml_w: new_ebml_w,
+        maps: maps,
+    } as @ast_util::IdVisitingOperation);
     ebml_w.end_tag();
 }
 
diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs
index 9280bbf1817..e8e658abc37 100644
--- a/src/librustc/middle/borrowck/check_loans.rs
+++ b/src/librustc/middle/borrowck/check_loans.rs
@@ -33,7 +33,7 @@ use util::ppaux::Repr;
 
 #[deriving(Clone)]
 struct CheckLoanCtxt<'self> {
-    bccx: @BorrowckCtxt,
+    bccx: &'self BorrowckCtxt,
     dfcx_loans: &'self LoanDataFlow,
     move_data: @move_data::FlowedMoveData,
     all_loans: &'self [Loan],
@@ -60,7 +60,7 @@ impl<'self> Visitor<()> for CheckLoanCtxt<'self> {
     }
 }
 
-pub fn check_loans(bccx: @BorrowckCtxt,
+pub fn check_loans(bccx: &BorrowckCtxt,
                    dfcx_loans: &LoanDataFlow,
                    move_data: move_data::FlowedMoveData,
                    all_loans: &[Loan],
diff --git a/src/librustc/middle/borrowck/gather_loans/gather_moves.rs b/src/librustc/middle/borrowck/gather_loans/gather_moves.rs
index 4b12fa202d4..549a7fe195c 100644
--- a/src/librustc/middle/borrowck/gather_loans/gather_moves.rs
+++ b/src/librustc/middle/borrowck/gather_loans/gather_moves.rs
@@ -22,7 +22,7 @@ use syntax::ast_util;
 use syntax::codemap::Span;
 use util::ppaux::{UserString};
 
-pub fn gather_decl(bccx: @BorrowckCtxt,
+pub fn gather_decl(bccx: &BorrowckCtxt,
                    move_data: &mut MoveData,
                    decl_id: ast::NodeId,
                    _decl_span: Span,
@@ -31,7 +31,7 @@ pub fn gather_decl(bccx: @BorrowckCtxt,
     move_data.add_move(bccx.tcx, loan_path, decl_id, Declared);
 }
 
-pub fn gather_move_from_expr(bccx: @BorrowckCtxt,
+pub fn gather_move_from_expr(bccx: &BorrowckCtxt,
                              move_data: &mut MoveData,
                              move_expr: @ast::Expr,
                              cmt: mc::cmt) {
@@ -39,7 +39,7 @@ pub fn gather_move_from_expr(bccx: @BorrowckCtxt,
                                  MoveExpr(move_expr), cmt);
 }
 
-pub fn gather_move_from_pat(bccx: @BorrowckCtxt,
+pub fn gather_move_from_pat(bccx: &BorrowckCtxt,
                             move_data: &mut MoveData,
                             move_pat: @ast::Pat,
                             cmt: mc::cmt) {
@@ -47,7 +47,7 @@ pub fn gather_move_from_pat(bccx: @BorrowckCtxt,
                                  MovePat(move_pat), cmt);
 }
 
-fn gather_move_from_expr_or_pat(bccx: @BorrowckCtxt,
+fn gather_move_from_expr_or_pat(bccx: &BorrowckCtxt,
                                 move_data: &mut MoveData,
                                 move_id: ast::NodeId,
                                 move_kind: MoveKind,
@@ -66,7 +66,7 @@ fn gather_move_from_expr_or_pat(bccx: @BorrowckCtxt,
     }
 }
 
-pub fn gather_captures(bccx: @BorrowckCtxt,
+pub fn gather_captures(bccx: &BorrowckCtxt,
                        move_data: &mut MoveData,
                        closure_expr: @ast::Expr) {
     let captured_vars = bccx.capture_map.get(&closure_expr.id);
@@ -83,7 +83,7 @@ pub fn gather_captures(bccx: @BorrowckCtxt,
     }
 }
 
-pub fn gather_assignment(bccx: @BorrowckCtxt,
+pub fn gather_assignment(bccx: &BorrowckCtxt,
                          move_data: &mut MoveData,
                          assignment_id: ast::NodeId,
                          assignment_span: Span,
@@ -96,7 +96,7 @@ pub fn gather_assignment(bccx: @BorrowckCtxt,
                              assignee_id);
 }
 
-fn check_is_legal_to_move_from(bccx: @BorrowckCtxt,
+fn check_is_legal_to_move_from(bccx: &BorrowckCtxt,
                                cmt0: mc::cmt,
                                cmt: mc::cmt) -> bool {
     match cmt.cat {
diff --git a/src/librustc/middle/borrowck/gather_loans/lifetime.rs b/src/librustc/middle/borrowck/gather_loans/lifetime.rs
index 1b94ac06c8e..2d71eef4de9 100644
--- a/src/librustc/middle/borrowck/gather_loans/lifetime.rs
+++ b/src/librustc/middle/borrowck/gather_loans/lifetime.rs
@@ -20,7 +20,7 @@ use syntax::ast;
 use syntax::codemap::Span;
 use util::ppaux::{note_and_explain_region};
 
-pub fn guarantee_lifetime(bccx: @BorrowckCtxt,
+pub fn guarantee_lifetime(bccx: &BorrowckCtxt,
                           item_scope_id: ast::NodeId,
                           root_scope_id: ast::NodeId,
                           span: Span,
@@ -42,8 +42,8 @@ pub fn guarantee_lifetime(bccx: @BorrowckCtxt,
 ///////////////////////////////////////////////////////////////////////////
 // Private
 
-struct GuaranteeLifetimeContext {
-    bccx: @BorrowckCtxt,
+struct GuaranteeLifetimeContext<'self> {
+    bccx: &'self BorrowckCtxt,
 
     // the node id of the function body for the enclosing item
     item_scope_id: ast::NodeId,
@@ -58,7 +58,7 @@ struct GuaranteeLifetimeContext {
     cmt_original: mc::cmt
 }
 
-impl GuaranteeLifetimeContext {
+impl<'self> GuaranteeLifetimeContext<'self> {
     fn tcx(&self) -> ty::ctxt {
         self.bccx.tcx
     }
diff --git a/src/librustc/middle/borrowck/gather_loans/mod.rs b/src/librustc/middle/borrowck/gather_loans/mod.rs
index d754e0360fd..4c526341446 100644
--- a/src/librustc/middle/borrowck/gather_loans/mod.rs
+++ b/src/librustc/middle/borrowck/gather_loans/mod.rs
@@ -64,8 +64,8 @@ mod gather_moves;
 /// No good.  Instead what will happen is that `root_ub` will be set to the
 /// body of the while loop and we will refuse to root the pointer `&*x`
 /// because it would have to be rooted for a region greater than `root_ub`.
-struct GatherLoanCtxt {
-    bccx: @BorrowckCtxt,
+struct GatherLoanCtxt<'self> {
+    bccx: &'self BorrowckCtxt,
     id_range: id_range,
     move_data: @mut move_data::MoveData,
     all_loans: @mut ~[Loan],
@@ -73,7 +73,7 @@ struct GatherLoanCtxt {
     repeating_ids: ~[ast::NodeId]
 }
 
-impl visit::Visitor<()> for GatherLoanCtxt {
+impl<'self> visit::Visitor<()> for GatherLoanCtxt<'self> {
     fn visit_expr(&mut self, ex:@Expr, _:()) {
         gather_loans_in_expr(self, ex);
     }
@@ -100,7 +100,7 @@ impl visit::Visitor<()> for GatherLoanCtxt {
     fn visit_item(&mut self, _:@ast::item, _:()) { }
 }
 
-pub fn gather_loans(bccx: @BorrowckCtxt,
+pub fn gather_loans(bccx: &BorrowckCtxt,
                     decl: &ast::fn_decl,
                     body: &ast::Block)
                     -> (id_range, @mut ~[Loan], @mut move_data::MoveData) {
@@ -315,7 +315,7 @@ fn gather_loans_in_expr(this: &mut GatherLoanCtxt,
     }
 }
 
-impl GatherLoanCtxt {
+impl<'self> GatherLoanCtxt<'self> {
     pub fn tcx(&self) -> ty::ctxt { self.bccx.tcx }
 
     pub fn push_repeating_id(&mut self, id: ast::NodeId) {
@@ -532,7 +532,7 @@ impl GatherLoanCtxt {
             //    }
         // }
 
-        fn check_mutability(bccx: @BorrowckCtxt,
+        fn check_mutability(bccx: &BorrowckCtxt,
                             borrow_span: Span,
                             cmt: mc::cmt,
                             req_mutbl: LoanMutability) {
diff --git a/src/librustc/middle/borrowck/gather_loans/restrictions.rs b/src/librustc/middle/borrowck/gather_loans/restrictions.rs
index 16ee45b2c68..7dbcb90327f 100644
--- a/src/librustc/middle/borrowck/gather_loans/restrictions.rs
+++ b/src/librustc/middle/borrowck/gather_loans/restrictions.rs
@@ -23,7 +23,7 @@ pub enum RestrictionResult {
     SafeIf(@LoanPath, ~[Restriction])
 }
 
-pub fn compute_restrictions(bccx: @BorrowckCtxt,
+pub fn compute_restrictions(bccx: &BorrowckCtxt,
                             span: Span,
                             cmt: mc::cmt,
                             restr: RestrictionSet) -> RestrictionResult {
@@ -39,13 +39,13 @@ pub fn compute_restrictions(bccx: @BorrowckCtxt,
 ///////////////////////////////////////////////////////////////////////////
 // Private
 
-struct RestrictionsContext {
-    bccx: @BorrowckCtxt,
+struct RestrictionsContext<'self> {
+    bccx: &'self BorrowckCtxt,
     span: Span,
     cmt_original: mc::cmt
 }
 
-impl RestrictionsContext {
+impl<'self> RestrictionsContext<'self> {
     fn tcx(&self) -> ty::ctxt {
         self.bccx.tcx
     }
diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs
index cdae2f5e066..852f1a53303 100644
--- a/src/librustc/middle/borrowck/mod.rs
+++ b/src/librustc/middle/borrowck/mod.rs
@@ -61,12 +61,10 @@ impl Clone for LoanDataFlowOperator {
 
 pub type LoanDataFlow = DataFlowContext<LoanDataFlowOperator>;
 
-struct BorrowckVisitor;
-
-impl Visitor<@BorrowckCtxt> for BorrowckVisitor {
+impl Visitor<()> for BorrowckCtxt {
     fn visit_fn(&mut self, fk:&fn_kind, fd:&fn_decl,
-                b:&Block, s:Span, n:NodeId, e:@BorrowckCtxt) {
-        borrowck_fn(self, fk, fd, b, s, n, e);
+                b:&Block, s:Span, n:NodeId, _:()) {
+        borrowck_fn(self, fk, fd, b, s, n);
     }
 }
 
@@ -78,7 +76,7 @@ pub fn check_crate(
     capture_map: moves::CaptureMap,
     crate: &ast::Crate) -> (root_map, write_guard_map)
 {
-    let bccx = @BorrowckCtxt {
+    let mut bccx = BorrowckCtxt {
         tcx: tcx,
         method_map: method_map,
         moves_map: moves_map,
@@ -96,9 +94,9 @@ pub fn check_crate(
             guaranteed_paths: 0,
         }
     };
+    let bccx = &mut bccx;
 
-    let mut v = BorrowckVisitor;
-    visit::walk_crate(&mut v, crate, bccx);
+    visit::walk_crate(bccx, crate, ());
 
     if tcx.sess.borrowck_stats() {
         io::println("--- borrowck stats ---");
@@ -116,20 +114,19 @@ pub fn check_crate(
 
     return (bccx.root_map, bccx.write_guard_map);
 
-    fn make_stat(bccx: &BorrowckCtxt, stat: uint) -> ~str {
+    fn make_stat(bccx: &mut BorrowckCtxt, stat: uint) -> ~str {
         let stat_f = stat as float;
         let total = bccx.stats.guaranteed_paths as float;
         fmt!("%u (%.0f%%)", stat  , stat_f * 100f / total)
     }
 }
 
-fn borrowck_fn(v: &mut BorrowckVisitor,
+fn borrowck_fn(this: &mut BorrowckCtxt,
                fk: &visit::fn_kind,
                decl: &ast::fn_decl,
                body: &ast::Block,
                sp: Span,
-               id: ast::NodeId,
-               this: @BorrowckCtxt) {
+               id: ast::NodeId) {
     match fk {
         &visit::fk_anon(*) |
         &visit::fk_fn_block(*) => {
@@ -166,7 +163,7 @@ fn borrowck_fn(v: &mut BorrowckVisitor,
         }
     }
 
-    visit::walk_fn(v, fk, decl, body, sp, id, this);
+    visit::walk_fn(this, fk, decl, body, sp, id, ());
 }
 
 // ----------------------------------------------------------------------
diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs
index 992d4ea2119..1af39f02d82 100644
--- a/src/librustc/middle/dataflow.rs
+++ b/src/librustc/middle/dataflow.rs
@@ -87,6 +87,42 @@ struct LoopScope<'self> {
     break_bits: ~[uint]
 }
 
+impl<O:DataFlowOperator> pprust::pp_ann for DataFlowContext<O> {
+    fn pre(&self, node: pprust::ann_node) {
+        let (ps, id) = match node {
+            pprust::node_expr(ps, expr) => (ps, expr.id),
+            pprust::node_block(ps, blk) => (ps, blk.id),
+            pprust::node_item(ps, _) => (ps, 0),
+            pprust::node_pat(ps, pat) => (ps, pat.id)
+        };
+
+        if self.nodeid_to_bitset.contains_key(&id) {
+            let (start, end) = self.compute_id_range_frozen(id);
+            let on_entry = self.on_entry.slice(start, end);
+            let entry_str = bits_to_str(on_entry);
+
+            let gens = self.gens.slice(start, end);
+            let gens_str = if gens.iter().any(|&u| u != 0) {
+                fmt!(" gen: %s", bits_to_str(gens))
+            } else {
+                ~""
+            };
+
+            let kills = self.kills.slice(start, end);
+            let kills_str = if kills.iter().any(|&u| u != 0) {
+                fmt!(" kill: %s", bits_to_str(kills))
+            } else {
+                ~""
+            };
+
+            let comment_str = fmt!("id %d: %s%s%s",
+                                   id, entry_str, gens_str, kills_str);
+            pprust::synth_comment(ps, comment_str);
+            pp::space(ps.s);
+        }
+    }
+}
+
 impl<O:DataFlowOperator> DataFlowContext<O> {
     pub fn new(tcx: ty::ctxt,
                method_map: typeck::method_map,
@@ -319,46 +355,9 @@ impl<O:DataFlowOperator+Clone+'static> DataFlowContext<O> {
     }
 
     fn pretty_print_to(@self, wr: @io::Writer, blk: &ast::Block) {
-        let pre: @fn(pprust::ann_node) = |node| {
-            let (ps, id) = match node {
-                pprust::node_expr(ps, expr) => (ps, expr.id),
-                pprust::node_block(ps, blk) => (ps, blk.id),
-                pprust::node_item(ps, _) => (ps, 0),
-                pprust::node_pat(ps, pat) => (ps, pat.id)
-            };
-
-            if self.nodeid_to_bitset.contains_key(&id) {
-                let (start, end) = self.compute_id_range_frozen(id);
-                let on_entry = self.on_entry.slice(start, end);
-                let entry_str = bits_to_str(on_entry);
-
-                let gens = self.gens.slice(start, end);
-                let gens_str = if gens.iter().any(|&u| u != 0) {
-                    fmt!(" gen: %s", bits_to_str(gens))
-                } else {
-                    ~""
-                };
-
-                let kills = self.kills.slice(start, end);
-                let kills_str = if kills.iter().any(|&u| u != 0) {
-                    fmt!(" kill: %s", bits_to_str(kills))
-                } else {
-                    ~""
-                };
-
-                let comment_str = fmt!("id %d: %s%s%s",
-                                       id, entry_str, gens_str, kills_str);
-                pprust::synth_comment(ps, comment_str);
-                pp::space(ps.s);
-            }
-        };
-
-        let post: @fn(pprust::ann_node) = |_| {
-        };
-
-        let ps = pprust::rust_printer_annotated(
-            wr, self.tcx.sess.intr(),
-            pprust::pp_ann {pre:pre, post:post});
+        let ps = pprust::rust_printer_annotated(wr,
+                                                self.tcx.sess.intr(),
+                                                self as @pprust::pp_ann);
         pprust::cbox(ps, pprust::indent_unit);
         pprust::ibox(ps, 0u);
         pprust::print_block(ps, blk);
diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs
index 6ca8086efc2..1b3224a2217 100644
--- a/src/librustc/middle/kind.rs
+++ b/src/librustc/middle/kind.rs
@@ -218,14 +218,25 @@ fn with_appropriate_checker(cx: Context, id: NodeId,
 
     let fty = ty::node_id_to_type(cx.tcx, id);
     match ty::get(fty).sty {
-        ty::ty_closure(ty::ClosureTy {sigil: OwnedSigil, bounds: bounds, _}) => {
+        ty::ty_closure(ty::ClosureTy {
+            sigil: OwnedSigil,
+            bounds: bounds,
+            _
+        }) => {
             b(|cx, fv| check_for_uniq(cx, fv, bounds))
         }
-        ty::ty_closure(ty::ClosureTy {sigil: ManagedSigil, bounds: bounds, _}) => {
-            b(|cx, fv| check_for_box(cx, fv, bounds))
+        ty::ty_closure(ty::ClosureTy {
+            sigil: ManagedSigil,
+            _
+        }) => {
+            // can't happen
         }
-        ty::ty_closure(ty::ClosureTy {sigil: BorrowedSigil, bounds: bounds,
-                                      region: region, _}) => {
+        ty::ty_closure(ty::ClosureTy {
+            sigil: BorrowedSigil,
+            bounds: bounds,
+            region: region,
+            _
+        }) => {
             b(|cx, fv| check_for_block(cx, fv, bounds, region))
         }
         ty::ty_bare_fn(_) => {
diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs
index da181ff2eb6..331bd25e359 100644
--- a/src/librustc/middle/lint.rs
+++ b/src/librustc/middle/lint.rs
@@ -375,8 +375,6 @@ enum AnyVisitor {
     NewVisitor(@mut visit::Visitor<()>),
 }
 
-type VCObj = @mut Visitor<@mut Context>;
-
 struct Context {
     // All known lint modes (string versions)
     dict: @LintDict,
@@ -1228,17 +1226,27 @@ fn lint_unused_mut() -> @mut OuterLint {
     @mut UnusedMutLintVisitor{ stopping_on_items: false } as @mut OuterLint
 }
 
-fn lint_session(cx: @mut Context) -> @mut visit::Visitor<()> {
-    ast_util::id_visitor(|id| {
-        match cx.tcx.sess.lints.pop(&id) {
-            None => {},
+struct LintReportingIdVisitor {
+    cx: @mut Context,
+}
+
+impl ast_util::IdVisitingOperation for LintReportingIdVisitor {
+    fn visit_id(&self, id: ast::NodeId) {
+        match self.cx.tcx.sess.lints.pop(&id) {
+            None => {}
             Some(l) => {
                 for (lint, span, msg) in l.move_iter() {
-                    cx.span_lint(lint, span, msg)
+                    self.cx.span_lint(lint, span, msg)
                 }
             }
         }
-    }, false)
+    }
+}
+
+fn lint_session(cx: @mut Context) -> @mut visit::Visitor<()> {
+    ast_util::id_visitor(@LintReportingIdVisitor {
+        cx: cx,
+    } as @ast_util::IdVisitingOperation, false)
 }
 
 struct UnnecessaryAllocationLintVisitor { stopping_on_items: bool }
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 0e3c10ef214..9cc95b873d2 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -187,8 +187,7 @@ pub fn opt_deref_kind(t: ty::t) -> Option<deref_kind> {
             Some(deref_ptr(gc_ptr(m)))
         }
 
-        ty::ty_estr(ty::vstore_box) |
-        ty::ty_closure(ty::ClosureTy {sigil: ast::ManagedSigil, _}) => {
+        ty::ty_estr(ty::vstore_box) => {
             Some(deref_ptr(gc_ptr(ast::MutImmutable)))
         }
 
@@ -515,7 +514,8 @@ impl mem_categorization_ctxt {
                           (ast::BorrowedSigil, ast::Once) => true,
                           // Heap closures always capture by copy/move, and can
                           // move out iff they are once.
-                          (ast::OwnedSigil, _) | (ast::ManagedSigil, _) => false,
+                          (ast::OwnedSigil, _) |
+                          (ast::ManagedSigil, _) => false,
 
                       };
                       if var_is_refd {
diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs
index a9527831d3a..b7bdb9a1e5d 100644
--- a/src/librustc/middle/moves.rs
+++ b/src/librustc/middle/moves.rs
@@ -191,18 +191,16 @@ enum UseMode {
     Read         // Read no matter what the type.
 }
 
-struct ComputeModesVisitor;
-
-impl visit::Visitor<VisitContext> for ComputeModesVisitor {
+impl visit::Visitor<()> for VisitContext {
     fn visit_fn(&mut self, fk:&visit::fn_kind, fd:&fn_decl,
-                b:&Block, s:Span, n:NodeId, e:VisitContext) {
-        compute_modes_for_fn(*self, fk, fd, b, s, n, e);
+                b:&Block, s:Span, n:NodeId, _:()) {
+        compute_modes_for_fn(self, fk, fd, b, s, n);
     }
-    fn visit_expr(&mut self, ex:@Expr, e:VisitContext) {
-        compute_modes_for_expr(*self, ex, e);
+    fn visit_expr(&mut self, ex:@Expr, _:()) {
+        compute_modes_for_expr(self, ex);
     }
-    fn visit_local(&mut self, l:@Local, e:VisitContext) {
-        compute_modes_for_local(*self, l, e);
+    fn visit_local(&mut self, l:@Local, _:()) {
+        compute_modes_for_local(self, l);
     }
 }
 
@@ -210,8 +208,7 @@ pub fn compute_moves(tcx: ty::ctxt,
                      method_map: method_map,
                      crate: &Crate) -> MoveMaps
 {
-    let mut visitor = ComputeModesVisitor;
-    let visit_cx = VisitContext {
+    let mut visit_cx = VisitContext {
         tcx: tcx,
         method_map: method_map,
         move_maps: MoveMaps {
@@ -220,7 +217,8 @@ pub fn compute_moves(tcx: ty::ctxt,
             moved_variables_set: @mut HashSet::new()
         }
     };
-    visit::walk_crate(&mut visitor, crate, visit_cx);
+    let visit_cx = &mut visit_cx;
+    visit::walk_crate(visit_cx, crate, ());
     return visit_cx.move_maps;
 }
 
@@ -238,44 +236,40 @@ pub fn moved_variable_node_id_from_def(def: Def) -> Option<NodeId> {
 ///////////////////////////////////////////////////////////////////////////
 // Expressions
 
-fn compute_modes_for_local<'a>(v: ComputeModesVisitor,
-                               local: @Local,
-                               cx: VisitContext) {
+fn compute_modes_for_local<'a>(cx: &mut VisitContext,
+                               local: @Local) {
     cx.use_pat(local.pat);
     for &init in local.init.iter() {
-        cx.use_expr(init, Read, v);
+        cx.use_expr(init, Read);
     }
 }
 
-fn compute_modes_for_fn(v: ComputeModesVisitor,
+fn compute_modes_for_fn(cx: &mut VisitContext,
                         fk: &visit::fn_kind,
                         decl: &fn_decl,
                         body: &Block,
                         span: Span,
-                        id: NodeId,
-                        cx: VisitContext) {
-    let mut v = v;
+                        id: NodeId) {
     for a in decl.inputs.iter() {
         cx.use_pat(a.pat);
     }
-    visit::walk_fn(&mut v, fk, decl, body, span, id, cx);
+    visit::walk_fn(cx, fk, decl, body, span, id, ());
 }
 
-fn compute_modes_for_expr(v: ComputeModesVisitor,
-                          expr: @Expr,
-                          cx: VisitContext)
+fn compute_modes_for_expr(cx: &mut VisitContext,
+                          expr: @Expr)
 {
-    cx.consume_expr(expr, v);
+    cx.consume_expr(expr);
 }
 
 impl VisitContext {
-    pub fn consume_exprs(&self, exprs: &[@Expr], visitor: ComputeModesVisitor) {
+    pub fn consume_exprs(&mut self, exprs: &[@Expr]) {
         for expr in exprs.iter() {
-            self.consume_expr(*expr, visitor);
+            self.consume_expr(*expr);
         }
     }
 
-    pub fn consume_expr(&self, expr: @Expr, visitor: ComputeModesVisitor) {
+    pub fn consume_expr(&mut self, expr: @Expr) {
         /*!
          * Indicates that the value of `expr` will be consumed,
          * meaning either copied or moved depending on its type.
@@ -287,13 +281,13 @@ impl VisitContext {
         let expr_ty = ty::expr_ty_adjusted(self.tcx, expr);
         if ty::type_moves_by_default(self.tcx, expr_ty) {
             self.move_maps.moves_map.insert(expr.id);
-            self.use_expr(expr, Move, visitor);
+            self.use_expr(expr, Move);
         } else {
-            self.use_expr(expr, Read, visitor);
+            self.use_expr(expr, Read);
         };
     }
 
-    pub fn consume_block(&self, blk: &Block, visitor: ComputeModesVisitor) {
+    pub fn consume_block(&mut self, blk: &Block) {
         /*!
          * Indicates that the value of `blk` will be consumed,
          * meaning either copied or moved depending on its type.
@@ -302,19 +296,17 @@ impl VisitContext {
         debug!("consume_block(blk.id=%?)", blk.id);
 
         for stmt in blk.stmts.iter() {
-            let mut v = visitor;
-            v.visit_stmt(*stmt, *self);
+            self.visit_stmt(*stmt, ());
         }
 
         for tail_expr in blk.expr.iter() {
-            self.consume_expr(*tail_expr, visitor);
+            self.consume_expr(*tail_expr);
         }
     }
 
-    pub fn use_expr(&self,
+    pub fn use_expr(&mut self,
                     expr: @Expr,
-                    expr_mode: UseMode,
-                    visitor: ComputeModesVisitor) {
+                    expr_mode: UseMode) {
         /*!
          * Indicates that `expr` is used with a given mode.  This will
          * in turn trigger calls to the subcomponents of `expr`.
@@ -351,25 +343,23 @@ impl VisitContext {
             }
 
             ExprUnary(_, UnDeref, base) => {       // *base
-                if !self.use_overloaded_operator(
-                    expr, base, [], visitor)
+                if !self.use_overloaded_operator(expr, base, [])
                 {
                     // Moving out of *base moves out of base.
-                    self.use_expr(base, comp_mode, visitor);
+                    self.use_expr(base, comp_mode);
                 }
             }
 
             ExprField(base, _, _) => {        // base.f
                 // Moving out of base.f moves out of base.
-                self.use_expr(base, comp_mode, visitor);
+                self.use_expr(base, comp_mode);
             }
 
             ExprIndex(_, lhs, rhs) => {          // lhs[rhs]
-                if !self.use_overloaded_operator(
-                    expr, lhs, [rhs], visitor)
+                if !self.use_overloaded_operator(expr, lhs, [rhs])
                 {
-                    self.use_expr(lhs, comp_mode, visitor);
-                    self.consume_expr(rhs, visitor);
+                    self.use_expr(lhs, comp_mode);
+                    self.consume_expr(rhs);
                 }
             }
 
@@ -394,20 +384,20 @@ impl VisitContext {
                 if mode == Move {
                     self.move_maps.moves_map.insert(callee.id);
                 }
-                self.use_expr(callee, mode, visitor);
-                self.use_fn_args(callee.id, *args, visitor);
+                self.use_expr(callee, mode);
+                self.use_fn_args(callee.id, *args);
             }
 
             ExprMethodCall(callee_id, rcvr, _, _, ref args, _) => { // callee.m(args)
                 // Implicit self is equivalent to & mode, but every
                 // other kind should be + mode.
-                self.use_receiver(rcvr, visitor);
-                self.use_fn_args(callee_id, *args, visitor);
+                self.use_receiver(rcvr);
+                self.use_fn_args(callee_id, *args);
             }
 
             ExprStruct(_, ref fields, opt_with) => {
                 for field in fields.iter() {
-                    self.consume_expr(field.expr, visitor);
+                    self.consume_expr(field.expr);
                 }
 
                 for with_expr in opt_with.iter() {
@@ -449,22 +439,22 @@ impl VisitContext {
                                                          which defines the `Drop` trait",
                                                         with_ty.user_string(self.tcx)));
                         }
-                        self.consume_expr(*with_expr, visitor);
+                        self.consume_expr(*with_expr);
                     } else {
-                        self.use_expr(*with_expr, Read, visitor);
+                        self.use_expr(*with_expr, Read);
                     }
                 }
             }
 
             ExprTup(ref exprs) => {
-                self.consume_exprs(*exprs, visitor);
+                self.consume_exprs(*exprs);
             }
 
             ExprIf(cond_expr, ref then_blk, opt_else_expr) => {
-                self.consume_expr(cond_expr, visitor);
-                self.consume_block(then_blk, visitor);
+                self.consume_expr(cond_expr);
+                self.consume_block(then_blk);
                 for else_expr in opt_else_expr.iter() {
-                    self.consume_expr(*else_expr, visitor);
+                    self.consume_expr(*else_expr);
                 }
             }
 
@@ -472,27 +462,27 @@ impl VisitContext {
                 // We must do this first so that `arms_have_by_move_bindings`
                 // below knows which bindings are moves.
                 for arm in arms.iter() {
-                    self.consume_arm(arm, visitor);
+                    self.consume_arm(arm);
                 }
 
                 // The discriminant may, in fact, be partially moved
                 // if there are by-move bindings, but borrowck deals
                 // with that itself.
-                self.use_expr(discr, Read, visitor);
+                self.use_expr(discr, Read);
             }
 
             ExprParen(base) => {
                 // Note: base is not considered a *component* here, so
                 // use `expr_mode` not `comp_mode`.
-                self.use_expr(base, expr_mode, visitor);
+                self.use_expr(base, expr_mode);
             }
 
             ExprVec(ref exprs, _) => {
-                self.consume_exprs(*exprs, visitor);
+                self.consume_exprs(*exprs);
             }
 
             ExprAddrOf(_, base) => {   // &base
-                self.use_expr(base, Read, visitor);
+                self.use_expr(base, Read);
             }
 
             ExprLogLevel |
@@ -502,70 +492,67 @@ impl VisitContext {
             ExprLit(*) => {}
 
             ExprLoop(ref blk, _) => {
-                self.consume_block(blk, visitor);
+                self.consume_block(blk);
             }
 
             ExprWhile(cond_expr, ref blk) => {
-                self.consume_expr(cond_expr, visitor);
-                self.consume_block(blk, visitor);
+                self.consume_expr(cond_expr);
+                self.consume_block(blk);
             }
 
             ExprForLoop(*) => fail!("non-desugared expr_for_loop"),
 
             ExprUnary(_, _, lhs) => {
-                if !self.use_overloaded_operator(
-                    expr, lhs, [], visitor)
+                if !self.use_overloaded_operator(expr, lhs, [])
                 {
-                    self.consume_expr(lhs, visitor);
+                    self.consume_expr(lhs);
                 }
             }
 
             ExprBinary(_, _, lhs, rhs) => {
-                if !self.use_overloaded_operator(
-                    expr, lhs, [rhs], visitor)
+                if !self.use_overloaded_operator(expr, lhs, [rhs])
                 {
-                    self.consume_expr(lhs, visitor);
-                    self.consume_expr(rhs, visitor);
+                    self.consume_expr(lhs);
+                    self.consume_expr(rhs);
                 }
             }
 
             ExprBlock(ref blk) => {
-                self.consume_block(blk, visitor);
+                self.consume_block(blk);
             }
 
             ExprRet(ref opt_expr) => {
                 for expr in opt_expr.iter() {
-                    self.consume_expr(*expr, visitor);
+                    self.consume_expr(*expr);
                 }
             }
 
             ExprAssign(lhs, rhs) => {
-                self.use_expr(lhs, Read, visitor);
-                self.consume_expr(rhs, visitor);
+                self.use_expr(lhs, Read);
+                self.consume_expr(rhs);
             }
 
             ExprCast(base, _) => {
-                self.consume_expr(base, visitor);
+                self.consume_expr(base);
             }
 
             ExprAssignOp(_, _, lhs, rhs) => {
                 // FIXME(#4712) --- Overloaded operators?
                 //
-                // if !self.use_overloaded_operator(
-                //     expr, DoDerefArgs, lhs, [rhs], visitor)
+                // if !self.use_overloaded_operator(expr, DoDerefArgs, lhs, [rhs])
                 // {
-                self.consume_expr(lhs, visitor);
-                self.consume_expr(rhs, visitor);
+                self.consume_expr(lhs);
+                self.consume_expr(rhs);
                 // }
             }
 
             ExprRepeat(base, count, _) => {
-                self.consume_expr(base, visitor);
-                self.consume_expr(count, visitor);
+                self.consume_expr(base);
+                self.consume_expr(count);
             }
 
             ExprDoBody(base) => {
-                self.use_expr(base, comp_mode, visitor);
+                self.use_expr(base, comp_mode);
             }
 
             ExprFnBlock(ref decl, ref body) => {
@@ -574,11 +561,11 @@ impl VisitContext {
                 }
                 let cap_vars = self.compute_captures(expr.id);
                 self.move_maps.capture_map.insert(expr.id, cap_vars);
-                self.consume_block(body, visitor);
+                self.consume_block(body);
             }
 
             ExprVstore(base, _) => {
-                self.use_expr(base, comp_mode, visitor);
+                self.use_expr(base, comp_mode);
             }
 
             ExprMac(*) => {
@@ -589,40 +576,39 @@ impl VisitContext {
         }
     }
 
-    pub fn use_overloaded_operator(&self,
+    pub fn use_overloaded_operator(&mut self,
                                    expr: &Expr,
                                    receiver_expr: @Expr,
-                                   arg_exprs: &[@Expr],
-                                   visitor: ComputeModesVisitor)
+                                   arg_exprs: &[@Expr])
                                    -> bool {
         if !self.method_map.contains_key(&expr.id) {
             return false;
         }
 
-        self.use_receiver(receiver_expr, visitor);
+        self.use_receiver(receiver_expr);
 
         // for overloaded operatrs, we are always passing in a
         // borrowed pointer, so it's always read mode:
         for arg_expr in arg_exprs.iter() {
-            self.use_expr(*arg_expr, Read, visitor);
+            self.use_expr(*arg_expr, Read);
         }
 
         return true;
     }
 
-    pub fn consume_arm(&self, arm: &Arm, visitor: ComputeModesVisitor) {
+    pub fn consume_arm(&mut self, arm: &Arm) {
         for pat in arm.pats.iter() {
             self.use_pat(*pat);
         }
 
         for guard in arm.guard.iter() {
-            self.consume_expr(*guard, visitor);
+            self.consume_expr(*guard);
         }
 
-        self.consume_block(&arm.body, visitor);
+        self.consume_block(&arm.body);
     }
 
-    pub fn use_pat(&self, pat: @Pat) {
+    pub fn use_pat(&mut self, pat: @Pat) {
         /*!
          *
          * Decides whether each binding in a pattern moves the value
@@ -651,28 +637,26 @@ impl VisitContext {
         }
     }
 
-    pub fn use_receiver(&self,
-                        receiver_expr: @Expr,
-                        visitor: ComputeModesVisitor) {
-        self.use_fn_arg(receiver_expr, visitor);
+    pub fn use_receiver(&mut self,
+                        receiver_expr: @Expr) {
+        self.use_fn_arg(receiver_expr);
     }
 
-    pub fn use_fn_args(&self,
+    pub fn use_fn_args(&mut self,
                        _: NodeId,
-                       arg_exprs: &[@Expr],
-                       visitor: ComputeModesVisitor) {
+                       arg_exprs: &[@Expr]) {
         //! Uses the argument expressions.
         for arg_expr in arg_exprs.iter() {
-            self.use_fn_arg(*arg_expr, visitor);
+            self.use_fn_arg(*arg_expr);
         }
     }
 
-    pub fn use_fn_arg(&self, arg_expr: @Expr, visitor: ComputeModesVisitor) {
+    pub fn use_fn_arg(&mut self, arg_expr: @Expr) {
         //! Uses the argument.
-        self.consume_expr(arg_expr, visitor)
+        self.consume_expr(arg_expr)
     }
 
-    pub fn arms_have_by_move_bindings(&self,
+    pub fn arms_have_by_move_bindings(&mut self,
                                       moves_map: MovesMap,
                                       arms: &[Arm])
                                       -> Option<@Pat> {
@@ -693,7 +677,7 @@ impl VisitContext {
         ret
     }
 
-    pub fn compute_captures(&self, fn_expr_id: NodeId) -> @[CaptureVar] {
+    pub fn compute_captures(&mut self, fn_expr_id: NodeId) -> @[CaptureVar] {
         debug!("compute_capture_vars(fn_expr_id=%?)", fn_expr_id);
         let _indenter = indenter();
 
diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs
index 51fe2acc72a..3c60bd67362 100644
--- a/src/librustc/middle/privacy.rs
+++ b/src/librustc/middle/privacy.rs
@@ -9,9 +9,13 @@
 // except according to those terms.
 
 //! A pass that checks to make sure private fields and methods aren't used
-//! outside their scopes.
+//! outside their scopes. This pass will also generate a set of exported items
+//! which are available for use externally when compiled as a library.
+
+use std::hashmap::HashSet;
 
 use metadata::csearch;
+use middle::resolve::ExportMap2;
 use middle::ty::{ty_struct, ty_enum};
 use middle::ty;
 use middle::typeck::{method_map, method_origin, method_param};
@@ -37,9 +41,23 @@ use syntax::visit;
 use syntax::visit::Visitor;
 use syntax::ast::{_mod,Expr,item,Block,Pat};
 
+// This set is a set of all item nodes which can be used by external crates if
+// we're building a library. The necessary qualifications for this are that all
+// items leading down to the current item (excluding an `impl`) must be `pub`.
+pub type ExportedItems = HashSet<NodeId>;
+
+type Context<'self> = (&'self method_map, &'self ExportMap2);
+
 struct PrivacyVisitor {
     tcx: ty::ctxt,
     privileged_items: @mut ~[NodeId],
+
+    // A set of all items which are re-exported to be used across crates
+    exported_items: ExportedItems,
+
+    // A flag as to whether the current path is public all the way down to the
+    // current point or not
+    path_all_public: bool,
 }
 
 impl PrivacyVisitor {
@@ -265,15 +283,20 @@ impl PrivacyVisitor {
                                                      .last()
                                                      .identifier)));
                     }
-                } else if csearch::get_item_visibility(self.tcx.sess.cstore,
-                                                       def_id) != public {
-                    self.tcx.sess.span_err(span,
-                                      fmt!("function `%s` is private",
-                                           token::ident_to_str(
-                                                &path.segments
-                                                     .last()
-                                                     .identifier)));
+                //} else if csearch::get_item_visibility(self.tcx.sess.cstore,
+                //                                       def_id) != public {
+                //    self.tcx.sess.span_err(span,
+                //                      fmt!("function `%s` is private",
+                //                           token::ident_to_str(
+                //                                &path.segments
+                //                                     .last()
+                //                                     .identifier)));
                 }
+                // If this is a function from a non-local crate, then the
+                // privacy check is enforced during resolve. All public items
+                // will be tagged as such in the crate metadata and then usage
+                // of the private items will be blocked during resolve. Hence,
+                // if this isn't from the local crate, nothing to check.
             }
             _ => {}
         }
@@ -341,31 +364,78 @@ impl PrivacyVisitor {
     }
 }
 
-impl<'self> Visitor<&'self method_map> for PrivacyVisitor {
+impl<'self> Visitor<Context<'self>> for PrivacyVisitor {
 
-    fn visit_mod<'mm>(&mut self, the_module:&_mod, _:Span, _:NodeId,
-                      method_map:&'mm method_map) {
+    fn visit_mod(&mut self, the_module:&_mod, _:Span, _:NodeId,
+                 cx: Context<'self>) {
 
             let n_added = self.add_privileged_items(the_module.items);
 
-            visit::walk_mod(self, the_module, method_map);
+            visit::walk_mod(self, the_module, cx);
 
             do n_added.times {
                 ignore(self.privileged_items.pop());
             }
     }
 
-    fn visit_item<'mm>(&mut self, item:@item, method_map:&'mm method_map) {
+    fn visit_item(&mut self, item:@item, cx: Context<'self>) {
+
+        // Do not check privacy inside items with the resolve_unexported
+        // attribute. This is used for the test runner.
+        if attr::contains_name(item.attrs, "!resolve_unexported") {
+            return;
+        }
+
+        // Disallow unnecessary visibility qualifiers
+        check_sane_privacy(self.tcx, item);
 
-            // Do not check privacy inside items with the resolve_unexported
-            // attribute. This is used for the test runner.
-            if !attr::contains_name(item.attrs, "!resolve_unexported") {
-                check_sane_privacy(self.tcx, item);
-                visit::walk_item(self, item, method_map);
+        // Keep track of whether this item is available for export or not.
+        let orig_all_pub = self.path_all_public;
+        match item.node {
+            // impls/extern blocks do not break the "public chain" because they
+            // cannot have visibility qualifiers on them anyway
+            ast::item_impl(*) | ast::item_foreign_mod(*) => {}
+
+            // Private by default, hence we only retain the "public chain" if
+            // `pub` is explicitly listed.
+            _ => {
+                self.path_all_public = orig_all_pub && item.vis == ast::public;
+            }
+        }
+        debug2!("public path at {}: {}", item.id, self.path_all_public);
+
+        if self.path_all_public {
+            debug2!("all the way public {}", item.id);
+            self.exported_items.insert(item.id);
+
+            // All re-exported items in a module which is public should also be
+            // public (in terms of how they should get encoded)
+            match item.node {
+                ast::item_mod(*) => {
+                    let (_, exp_map2) = cx;
+                    match exp_map2.find(&item.id) {
+                        Some(exports) => {
+                            for export in exports.iter() {
+                                if export.reexport && is_local(export.def_id) {
+                                    debug2!("found reexported {:?}", export);
+                                    let id = export.def_id.node;
+                                    self.exported_items.insert(id);
+                                }
+                            }
+                        }
+                        None => {}
+                    }
+                }
+                _ => {}
             }
+        }
+
+        visit::walk_item(self, item, cx);
+
+        self.path_all_public = orig_all_pub;
     }
 
-    fn visit_block<'mm>(&mut self, block:&Block, method_map:&'mm method_map) {
+    fn visit_block(&mut self, block:&Block, cx: Context<'self>) {
 
             // Gather up all the privileged items.
             let mut n_added = 0;
@@ -383,7 +453,7 @@ impl<'self> Visitor<&'self method_map> for PrivacyVisitor {
                 }
             }
 
-            visit::walk_block(self, block, method_map);
+            visit::walk_block(self, block, cx);
 
             do n_added.times {
                 ignore(self.privileged_items.pop());
@@ -391,8 +461,8 @@ impl<'self> Visitor<&'self method_map> for PrivacyVisitor {
 
     }
 
-    fn visit_expr<'mm>(&mut self, expr:@Expr, method_map:&'mm method_map) {
-
+    fn visit_expr(&mut self, expr:@Expr, cx: Context<'self>) {
+        let (method_map, _) = cx;
             match expr.node {
                 ExprField(base, ident, _) => {
                     // Method calls are now a special syntactic form,
@@ -499,11 +569,11 @@ impl<'self> Visitor<&'self method_map> for PrivacyVisitor {
                 _ => {}
             }
 
-            visit::walk_expr(self, expr, method_map);
+            visit::walk_expr(self, expr, cx);
 
     }
 
-    fn visit_pat<'mm>(&mut self, pattern:@Pat, method_map:&'mm method_map) {
+    fn visit_pat(&mut self, pattern:@Pat, cx: Context<'self>) {
 
             match pattern.node {
                 PatStruct(_, ref fields, _) => {
@@ -550,20 +620,24 @@ impl<'self> Visitor<&'self method_map> for PrivacyVisitor {
                 _ => {}
             }
 
-            visit::walk_pat(self, pattern, method_map);
+            visit::walk_pat(self, pattern, cx);
     }
 }
 
-pub fn check_crate<'mm>(tcx: ty::ctxt,
-                        method_map: &'mm method_map,
-                        crate: &ast::Crate) {
+pub fn check_crate(tcx: ty::ctxt,
+                   method_map: &method_map,
+                   exp_map2: &ExportMap2,
+                   crate: &ast::Crate) -> ExportedItems {
     let privileged_items = @mut ~[];
 
     let mut visitor = PrivacyVisitor {
         tcx: tcx,
         privileged_items: privileged_items,
+        exported_items: HashSet::new(),
+        path_all_public: true, // start out as public
     };
-    visit::walk_crate(&mut visitor, crate, method_map);
+    visit::walk_crate(&mut visitor, crate, (method_map, exp_map2));
+    return visitor.exported_items;
 }
 
 /// Validates all of the visibility qualifers placed on the item given. This
@@ -571,17 +645,45 @@ pub fn check_crate<'mm>(tcx: ty::ctxt,
 /// anything. In theory these qualifiers wouldn't parse, but that may happen
 /// later on down the road...
 fn check_sane_privacy(tcx: ty::ctxt, item: @ast::item) {
+    let check_inherited = |sp: Span, vis: ast::visibility, note: &str| {
+        if vis != ast::inherited {
+            tcx.sess.span_err(sp, "unnecessary visibility qualifier");
+            if note.len() > 0 {
+                tcx.sess.span_note(sp, note);
+            }
+        }
+    };
+    let check_not_priv = |sp: Span, vis: ast::visibility, note: &str| {
+        if vis == ast::private {
+            tcx.sess.span_err(sp, "unnecessary `priv` qualifier");
+            if note.len() > 0 {
+                tcx.sess.span_note(sp, note);
+            }
+        }
+    };
     match item.node {
         // implementations of traits don't need visibility qualifiers because
         // that's controlled by having the trait in scope.
         ast::item_impl(_, Some(*), _, ref methods) => {
+            check_inherited(item.span, item.vis,
+                            "visibility qualifiers have no effect on trait impls");
             for m in methods.iter() {
-                match m.vis {
-                    ast::private | ast::public => {
-                        tcx.sess.span_err(m.span, "unnecessary visibility")
-                    }
-                    ast::inherited => {}
-                }
+                check_inherited(m.span, m.vis, "");
+            }
+        }
+
+        ast::item_impl(_, _, _, ref methods) => {
+            check_inherited(item.span, item.vis,
+                            "place qualifiers on individual methods instead");
+            for i in methods.iter() {
+                check_not_priv(i.span, i.vis, "functions are private by default");
+            }
+        }
+        ast::item_foreign_mod(ref fm) => {
+            check_inherited(item.span, item.vis,
+                            "place qualifiers on individual functions instead");
+            for i in fm.items.iter() {
+                check_not_priv(i.span, i.vis, "functions are private by default");
             }
         }
 
@@ -624,22 +726,18 @@ fn check_sane_privacy(tcx: ty::ctxt, item: @ast::item) {
             for m in methods.iter() {
                 match *m {
                     ast::provided(ref m) => {
-                        match m.vis {
-                            ast::private | ast::public => {
-                                tcx.sess.span_err(m.span, "unnecessary \
-                                                           visibility");
-                            }
-                            ast::inherited => {}
-                        }
+                        check_inherited(m.span, m.vis,
+                                        "unnecessary visibility");
                     }
-                    // this is warned about in the parser
                     ast::required(*) => {}
                 }
             }
         }
 
-        ast::item_impl(*) | ast::item_static(*) | ast::item_foreign_mod(*) |
+        ast::item_static(*) |
         ast::item_fn(*) | ast::item_mod(*) | ast::item_ty(*) |
-        ast::item_mac(*) => {}
+        ast::item_mac(*) => {
+            check_not_priv(item.span, item.vis, "items are private by default");
+        }
     }
 }
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 3a9ef3cf06f..320baf33181 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -1661,6 +1661,9 @@ impl Resolver {
                            ident: Ident,
                            new_parent: ReducedGraphParent) {
         let privacy = visibility_to_privacy(visibility);
+        debug!("(building reduced graph for \
+                external crate) building external def, priv %?",
+               privacy);
         match def {
           DefMod(def_id) | DefForeignMod(def_id) | DefStruct(def_id) |
           DefTy(def_id) => {
@@ -1788,7 +1791,8 @@ impl Resolver {
     fn build_reduced_graph_for_external_crate_def(@mut self,
                                                   root: @mut Module,
                                                   def_like: DefLike,
-                                                  ident: Ident) {
+                                                  ident: Ident,
+                                                  visibility: visibility) {
         match def_like {
             DlDef(def) => {
                 // Add the new child item, if necessary.
@@ -1798,11 +1802,12 @@ impl Resolver {
                         // eagerly.
                         do csearch::each_child_of_item(self.session.cstore,
                                                        def_id)
-                                |def_like, child_ident| {
+                                |def_like, child_ident, vis| {
                             self.build_reduced_graph_for_external_crate_def(
                                 root,
                                 def_like,
-                                child_ident)
+                                child_ident,
+                                vis)
                         }
                     }
                     _ => {
@@ -1813,7 +1818,7 @@ impl Resolver {
                                            dummy_sp());
 
                         self.handle_external_def(def,
-                                                 public,
+                                                 visibility,
                                                  child_name_bindings,
                                                  self.session.str_of(ident),
                                                  ident,
@@ -1897,10 +1902,11 @@ impl Resolver {
                                     let def = DefFn(
                                         static_method_info.def_id,
                                         static_method_info.purity);
+
+                                    let p = visibility_to_privacy(
+                                        static_method_info.vis);
                                     method_name_bindings.define_value(
-                                        Public,
-                                        def,
-                                        dummy_sp());
+                                        p, def, dummy_sp());
                                 }
                             }
 
@@ -1931,12 +1937,13 @@ impl Resolver {
         };
 
         do csearch::each_child_of_item(self.session.cstore, def_id)
-                |def_like, child_ident| {
+                |def_like, child_ident, visibility| {
             debug!("(populating external module) ... found ident: %s",
                    token::ident_to_str(&child_ident));
             self.build_reduced_graph_for_external_crate_def(module,
                                                             def_like,
-                                                            child_ident)
+                                                            child_ident,
+                                                            visibility)
         }
         module.populated = true
     }
@@ -1956,10 +1963,11 @@ impl Resolver {
                                                   root: @mut Module) {
         do csearch::each_top_level_item_of_crate(self.session.cstore,
                                                  root.def_id.unwrap().crate)
-                |def_like, ident| {
+                |def_like, ident, visibility| {
             self.build_reduced_graph_for_external_crate_def(root,
                                                             def_like,
-                                                            ident)
+                                                            ident,
+                                                            visibility)
         }
     }
 
diff --git a/src/librustc/middle/stack_check.rs b/src/librustc/middle/stack_check.rs
index 7ab6cfcdf7b..5388e64348c 100644
--- a/src/librustc/middle/stack_check.rs
+++ b/src/librustc/middle/stack_check.rs
@@ -116,8 +116,7 @@ fn stack_check_fn<'a>(v: StackCheckVisitor,
         visit::fk_anon(*) | visit::fk_fn_block => {
             match ty::get(ty::node_id_to_type(in_cx.tcx, id)).sty {
                 ty::ty_bare_fn(*) |
-                ty::ty_closure(ty::ClosureTy {sigil: ast::OwnedSigil, _}) |
-                ty::ty_closure(ty::ClosureTy {sigil: ast::ManagedSigil, _}) => {
+                ty::ty_closure(ty::ClosureTy {sigil: ast::OwnedSigil, _}) => {
                     false
                 }
                 _ => {
diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs
index c9a113aeb96..0de01bced1f 100644
--- a/src/librustc/middle/trans/_match.rs
+++ b/src/librustc/middle/trans/_match.rs
@@ -533,7 +533,7 @@ fn enter_default<'r>(bcx: @mut Block,
                      m: &[Match<'r>],
                      col: uint,
                      val: ValueRef,
-                     chk: Option<mk_fail>)
+                     chk: FailureHandler)
                       -> ~[Match<'r>] {
     debug!("enter_default(bcx=%s, m=%s, col=%u, val=%s)",
            bcx.to_str(),
@@ -567,7 +567,7 @@ fn enter_default<'r>(bcx: @mut Block,
     // we don't need any default cases. If the check *isn't* nonexhaustive
     // (because chk is Some), then we need the defaults anyways.
     let is_exhaustive = match matches.last_opt() {
-        Some(m) if m.data.arm.guard.is_some() && chk.is_none() => true,
+        Some(m) if m.data.arm.guard.is_some() && chk.is_infallible() => true,
         _ => false
     };
 
@@ -1185,7 +1185,62 @@ fn any_tuple_struct_pat(bcx: @mut Block, m: &[Match], col: uint) -> bool {
     }
 }
 
-type mk_fail = @fn() -> BasicBlockRef;
+trait CustomFailureHandler {
+    fn handle_fail(&self) -> BasicBlockRef;
+}
+
+struct DynamicFailureHandler {
+    bcx: @mut Block,
+    sp: Span,
+    msg: @str,
+    finished: @mut Option<BasicBlockRef>,
+}
+
+impl CustomFailureHandler for DynamicFailureHandler {
+    fn handle_fail(&self) -> BasicBlockRef {
+        match *self.finished {
+            Some(bb) => return bb,
+            _ => (),
+        }
+
+        let fail_cx = sub_block(self.bcx, "case_fallthrough");
+        controlflow::trans_fail(fail_cx, Some(self.sp), self.msg);
+        *self.finished = Some(fail_cx.llbb);
+        fail_cx.llbb
+    }
+}
+
+/// What to do when the pattern match fails.
+enum FailureHandler {
+    Infallible,
+    JumpToBasicBlock(BasicBlockRef),
+    CustomFailureHandlerClass(@CustomFailureHandler),
+}
+
+impl FailureHandler {
+    fn is_infallible(&self) -> bool {
+        match *self {
+            Infallible => true,
+            _ => false,
+        }
+    }
+
+    fn is_fallible(&self) -> bool {
+        !self.is_infallible()
+    }
+
+    fn handle_fail(&self) -> BasicBlockRef {
+        match *self {
+            Infallible => {
+                fail!("attempted to fail in infallible failure handler!")
+            }
+            JumpToBasicBlock(basic_block) => basic_block,
+            CustomFailureHandlerClass(custom_failure_handler) => {
+                custom_failure_handler.handle_fail()
+            }
+        }
+    }
+}
 
 fn pick_col(m: &[Match]) -> uint {
     fn score(p: &ast::Pat) -> uint {
@@ -1347,7 +1402,7 @@ fn compile_guard(bcx: @mut Block,
                      data: &ArmData,
                      m: &[Match],
                      vals: &[ValueRef],
-                     chk: Option<mk_fail>)
+                     chk: FailureHandler)
                   -> @mut Block {
     debug!("compile_guard(bcx=%s, guard_expr=%s, m=%s, vals=%s)",
            bcx.to_str(),
@@ -1400,9 +1455,9 @@ fn compile_guard(bcx: @mut Block,
 }
 
 fn compile_submatch(bcx: @mut Block,
-                        m: &[Match],
-                        vals: &[ValueRef],
-                        chk: Option<mk_fail>) {
+                    m: &[Match],
+                    vals: &[ValueRef],
+                    chk: FailureHandler) {
     debug!("compile_submatch(bcx=%s, m=%s, vals=%s)",
            bcx.to_str(),
            m.repr(bcx.tcx()),
@@ -1412,11 +1467,11 @@ fn compile_submatch(bcx: @mut Block,
     /*
       For an empty match, a fall-through case must exist
      */
-    assert!((m.len() > 0u || chk.is_some()));
+    assert!((m.len() > 0u || chk.is_fallible()));
     let _icx = push_ctxt("match::compile_submatch");
     let mut bcx = bcx;
     if m.len() == 0u {
-        Br(bcx, chk.unwrap()());
+        Br(bcx, chk.handle_fail());
         return;
     }
     if m[0].pats.len() == 0u {
@@ -1454,7 +1509,7 @@ fn compile_submatch(bcx: @mut Block,
 fn compile_submatch_continue(mut bcx: @mut Block,
                              m: &[Match],
                              vals: &[ValueRef],
-                             chk: Option<mk_fail>,
+                             chk: FailureHandler,
                              col: uint,
                              val: ValueRef) {
     let tcx = bcx.tcx();
@@ -1617,7 +1672,7 @@ fn compile_submatch_continue(mut bcx: @mut Block,
     };
 
     let defaults = enter_default(else_cx, dm, m, col, val, chk);
-    let exhaustive = chk.is_none() && defaults.len() == 0u;
+    let exhaustive = chk.is_infallible() && defaults.len() == 0u;
     let len = opts.len();
 
     // Compile subtrees for each option
@@ -1721,7 +1776,7 @@ fn compile_submatch_continue(mut bcx: @mut Block,
 
                   // If none of these subcases match, move on to the
                   // next condition.
-                  branch_chk = Some::<mk_fail>(|| bcx.llbb);
+                  branch_chk = JumpToBasicBlock(bcx.llbb);
                   CondBr(after_cx, matches, opt_cx.llbb, bcx.llbb);
               }
               _ => ()
@@ -1860,11 +1915,15 @@ fn trans_match_inner(scope_cx: @mut Block,
         if ty::type_is_empty(tcx, t) {
             // Special case for empty types
             let fail_cx = @mut None;
-            let f: mk_fail = || mk_fail(scope_cx, discr_expr.span,
-                            @"scrutinizing value that can't exist", fail_cx);
-            Some(f)
+            let fail_handler = @DynamicFailureHandler {
+                bcx: scope_cx,
+                sp: discr_expr.span,
+                msg: @"scrutinizing value that can't exist",
+                finished: fail_cx,
+            } as @CustomFailureHandler;
+            CustomFailureHandlerClass(fail_handler)
         } else {
-            None
+            Infallible
         }
     };
     let lldiscr = discr_datum.to_zeroable_ref_llval(bcx);
@@ -1892,15 +1951,6 @@ fn trans_match_inner(scope_cx: @mut Block,
 
     bcx = controlflow::join_blocks(scope_cx, arm_cxs);
     return bcx;
-
-    fn mk_fail(bcx: @mut Block, sp: Span, msg: @str,
-               finished: @mut Option<BasicBlockRef>) -> BasicBlockRef {
-        match *finished { Some(bb) => return bb, _ => () }
-        let fail_cx = sub_block(bcx, "case_fallthrough");
-        controlflow::trans_fail(fail_cx, Some(sp), msg);
-        *finished = Some(fail_cx.llbb);
-        return fail_cx.llbb;
-    }
 }
 
 enum IrrefutablePatternBindingMode {
@@ -1913,7 +1963,7 @@ enum IrrefutablePatternBindingMode {
 pub fn store_local(bcx: @mut Block,
                    pat: @ast::Pat,
                    opt_init_expr: Option<@ast::Expr>)
-                               -> @mut Block {
+                   -> @mut Block {
     /*!
      * Generates code for a local variable declaration like
      * `let <pat>;` or `let <pat> = <opt_init_expr>`.
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index f7fcd8f908d..36904a1ba9b 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -1320,7 +1320,7 @@ pub fn trans_block_cleanups_(bcx: @mut Block,
                 // Some types don't need to be cleaned up during
                 // landing pads because they can be freed en mass later
                 if cleanup_type == normal_exit_and_unwind || !is_lpad {
-                    bcx = cfn(bcx);
+                    bcx = cfn.clean(bcx);
                 }
             }
         }
@@ -2321,6 +2321,23 @@ pub fn trans_mod(ccx: @mut CrateContext, m: &ast::_mod) {
     }
 }
 
+fn finish_register_fn(ccx: @mut CrateContext, sp: Span, sym: ~str, node_id: ast::NodeId,
+                      llfn: ValueRef) {
+    ccx.item_symbols.insert(node_id, sym);
+
+    if !*ccx.sess.building_library {
+        lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage);
+    }
+
+    // FIXME #4404 android JNI hacks
+    let is_entry = is_entry_fn(&ccx.sess, node_id) && (!*ccx.sess.building_library ||
+                      (*ccx.sess.building_library &&
+                       ccx.sess.targ_cfg.os == session::OsAndroid));
+    if is_entry {
+        create_entry_wrapper(ccx, sp, llfn);
+    }
+}
+
 pub fn register_fn(ccx: @mut CrateContext,
                    sp: Span,
                    sym: ~str,
@@ -2336,15 +2353,7 @@ pub fn register_fn(ccx: @mut CrateContext,
     };
 
     let llfn = decl_rust_fn(ccx, f.sig.inputs, f.sig.output, sym);
-    ccx.item_symbols.insert(node_id, sym);
-
-    // FIXME #4404 android JNI hacks
-    let is_entry = is_entry_fn(&ccx.sess, node_id) && (!*ccx.sess.building_library ||
-                      (*ccx.sess.building_library &&
-                       ccx.sess.targ_cfg.os == session::OsAndroid));
-    if is_entry {
-        create_entry_wrapper(ccx, sp, llfn);
-    }
+    finish_register_fn(ccx, sp, sym, node_id, llfn);
     llfn
 }
 
@@ -2361,15 +2370,7 @@ pub fn register_fn_llvmty(ccx: @mut CrateContext,
            ast_map::path_to_str(item_path(ccx, &node_id), token::get_ident_interner()));
 
     let llfn = decl_fn(ccx.llmod, sym, cc, fn_ty);
-    ccx.item_symbols.insert(node_id, sym);
-
-    // FIXME #4404 android JNI hacks
-    let is_entry = is_entry_fn(&ccx.sess, node_id) && (!*ccx.sess.building_library ||
-                      (*ccx.sess.building_library &&
-                       ccx.sess.targ_cfg.os == session::OsAndroid));
-    if is_entry {
-        create_entry_wrapper(ccx, sp, llfn);
-    }
+    finish_register_fn(ccx, sp, sym, node_id, llfn);
     llfn
 }
 
@@ -2416,11 +2417,6 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext,
         unsafe {
             llvm::LLVMPositionBuilderAtEnd(bld, llbb);
 
-            let crate_map = ccx.crate_map;
-            let opaque_crate_map = do "crate_map".with_c_str |buf| {
-                llvm::LLVMBuildPointerCast(bld, crate_map, Type::i8p().to_ref(), buf)
-            };
-
             let (start_fn, args) = if use_start_lang_item {
                 let start_def_id = match ccx.tcx.lang_items.require(StartFnLangItem) {
                     Ok(id) => id,
@@ -2443,8 +2439,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext,
                         C_null(Type::opaque_box(ccx).ptr_to()),
                         opaque_rust_main,
                         llvm::LLVMGetParam(llfn, 0),
-                        llvm::LLVMGetParam(llfn, 1),
-                        opaque_crate_map
+                        llvm::LLVMGetParam(llfn, 1)
                      ]
                 };
                 (start_fn, args)
@@ -2453,8 +2448,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext,
                 let args = ~[
                     C_null(Type::opaque_box(ccx).ptr_to()),
                     llvm::LLVMGetParam(llfn, 0 as c_uint),
-                    llvm::LLVMGetParam(llfn, 1 as c_uint),
-                    opaque_crate_map
+                    llvm::LLVMGetParam(llfn, 1 as c_uint)
                 ];
 
                 (rust_main, args)
@@ -2635,13 +2629,16 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::NodeId) -> ValueRef {
                         }
                         ast::foreign_item_static(*) => {
                             let ident = foreign::link_name(ccx, ni);
-                            let g = do ident.with_c_str |buf| {
-                                unsafe {
+                            unsafe {
+                                let g = do ident.with_c_str |buf| {
                                     let ty = type_of(ccx, ty);
                                     llvm::LLVMAddGlobal(ccx.llmod, ty.to_ref(), buf)
+                                };
+                                if attr::contains_name(ni.attrs, "weak_linkage") {
+                                    lib::llvm::SetLinkage(g, lib::llvm::ExternalWeakLinkage);
                                 }
-                            };
-                            g
+                                g
+                            }
                         }
                     }
                 }
@@ -2953,13 +2950,20 @@ pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta,
     };
     let sym_name = ~"_rust_crate_map_" + mapname;
     let arrtype = Type::array(&int_type, n_subcrates as u64);
-    let maptype = Type::struct_([Type::i32(), Type::i8p(), int_type, arrtype], false);
+    let maptype = Type::struct_([Type::i32(), int_type, arrtype], false);
     let map = do sym_name.with_c_str |buf| {
         unsafe {
             llvm::LLVMAddGlobal(llmod, maptype.to_ref(), buf)
         }
     };
-    lib::llvm::SetLinkage(map, lib::llvm::ExternalLinkage);
+    // On windows we'd like to export the toplevel cratemap
+    // such that we can find it from libstd.
+    if targ_cfg.os == session::OsWin32 && "toplevel" == mapname {
+        lib::llvm::SetLinkage(map, lib::llvm::DLLExportLinkage);
+    } else {
+        lib::llvm::SetLinkage(map, lib::llvm::ExternalLinkage);
+    }
+
     return map;
 }
 
@@ -2987,8 +2991,6 @@ pub fn fill_crate_map(ccx: @mut CrateContext, map: ValueRef) {
         let mod_map = create_module_map(ccx);
         llvm::LLVMSetInitializer(map, C_struct(
             [C_i32(1),
-             // FIXME #8431 This used to be the annihilate function, now it's nothing
-             C_null(Type::i8p()),
              p2i(ccx, mod_map),
              C_array(ccx.int_type, subcrates)]));
     }
@@ -3005,6 +3007,7 @@ pub fn crate_ctxt_to_encode_parms<'r>(cx: &'r CrateContext, ie: encoder::encode_
             diag: diag,
             tcx: cx.tcx,
             reexports2: cx.exp_map2,
+            exported_items: cx.exported_items,
             item_symbols: item_symbols,
             discrim_symbols: discrim_symbols,
             non_inlineable_statics: &cx.non_inlineable_statics,
@@ -3098,6 +3101,7 @@ pub fn trans_crate(sess: session::Session,
                                      llmod_id,
                                      analysis.ty_cx,
                                      analysis.exp_map2,
+                                     analysis.exported_items,
                                      analysis.maps,
                                      symbol_hasher,
                                      link_meta,
@@ -3114,6 +3118,26 @@ pub fn trans_crate(sess: session::Session,
 
     decl_gc_metadata(ccx, llmod_id);
     fill_crate_map(ccx, ccx.crate_map);
+
+    // NOTE win32: wart with exporting crate_map symbol
+    // We set the crate map (_rust_crate_map_toplevel) to use dll_export
+    // linkage but that ends up causing the linker to look for a
+    // __rust_crate_map_toplevel symbol (extra underscore) which it will
+    // subsequently fail to find. So to mitigate that we just introduce
+    // an alias from the symbol it expects to the one that actually exists.
+    if ccx.sess.targ_cfg.os == session::OsWin32 &&
+       !*ccx.sess.building_library {
+
+        let maptype = val_ty(ccx.crate_map).to_ref();
+
+        do "__rust_crate_map_toplevel".with_c_str |buf| {
+            unsafe {
+                llvm::LLVMAddAlias(ccx.llmod, maptype,
+                                   ccx.crate_map, buf);
+            }
+        }
+    }
+
     glue::emit_tydescs(ccx);
     write_abi_version(ccx);
     if ccx.sess.opts.debuginfo {
diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs
index 605032dc20c..b5b181e22a6 100644
--- a/src/librustc/middle/trans/closure.rs
+++ b/src/librustc/middle/trans/closure.rs
@@ -172,7 +172,7 @@ pub fn allocate_cbox(bcx: @mut Block, sigil: ast::Sigil, cdata_ty: ty::t)
     // Allocate and initialize the box:
     match sigil {
         ast::ManagedSigil => {
-            malloc_raw(bcx, cdata_ty, heap_managed)
+            tcx.sess.bug("trying to trans allocation of @fn")
         }
         ast::OwnedSigil => {
             malloc_raw(bcx, cdata_ty, heap_for_unique_closure(bcx, cdata_ty))
@@ -197,7 +197,8 @@ pub struct ClosureResult {
 // Otherwise, it is stack allocated and copies pointers to the upvars.
 pub fn store_environment(bcx: @mut Block,
                          bound_values: ~[EnvValue],
-                         sigil: ast::Sigil) -> ClosureResult {
+                         sigil: ast::Sigil)
+                         -> ClosureResult {
     let _icx = push_ctxt("closure::store_environment");
     let ccx = bcx.ccx();
     let tcx = ccx.tcx;
@@ -444,27 +445,6 @@ pub fn make_closure_glue(
     }
 }
 
-pub fn make_opaque_cbox_take_glue(
-    bcx: @mut Block,
-    sigil: ast::Sigil,
-    cboxptr: ValueRef)     // ptr to ptr to the opaque closure
-    -> @mut Block {
-    // Easy cases:
-    let _icx = push_ctxt("closure::make_opaque_cbox_take_glue");
-    match sigil {
-        ast::BorrowedSigil => {
-            return bcx;
-        }
-        ast::ManagedSigil => {
-            glue::incr_refcnt_of_boxed(bcx, Load(bcx, cboxptr));
-            return bcx;
-        }
-        ast::OwnedSigil => {
-            fail!("unique closures are not copyable")
-        }
-    }
-}
-
 pub fn make_opaque_cbox_drop_glue(
     bcx: @mut Block,
     sigil: ast::Sigil,
@@ -474,9 +454,7 @@ pub fn make_opaque_cbox_drop_glue(
     match sigil {
         ast::BorrowedSigil => bcx,
         ast::ManagedSigil => {
-            glue::decr_refcnt_maybe_free(
-                bcx, Load(bcx, cboxptr), Some(cboxptr),
-                ty::mk_opaque_closure_ptr(bcx.tcx(), sigil))
+            bcx.tcx().sess.bug("trying to trans drop glue of @fn")
         }
         ast::OwnedSigil => {
             glue::free_ty(
@@ -516,12 +494,8 @@ pub fn make_opaque_cbox_free_glue(
                                     abi::tydesc_field_drop_glue, None);
 
         // Free the ty descr (if necc) and the box itself
-        match sigil {
-            ast::ManagedSigil => glue::trans_free(bcx, cbox),
-            ast::OwnedSigil => glue::trans_exchange_free(bcx, cbox),
-            ast::BorrowedSigil => {
-                bcx.sess().bug("impossible")
-            }
-        }
+        glue::trans_exchange_free(bcx, cbox);
+
+        bcx
     }
 }
diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs
index b659a93f5f0..377144b38e7 100644
--- a/src/librustc/middle/trans/common.rs
+++ b/src/librustc/middle/trans/common.rs
@@ -294,9 +294,85 @@ pub enum cleantype {
     normal_exit_and_unwind
 }
 
+// Cleanup functions
+
+/// A cleanup function: a built-in destructor.
+pub trait CleanupFunction {
+    fn clean(&self, block: @mut Block) -> @mut Block;
+}
+
+/// A cleanup function that calls the "drop glue" (destructor function) on
+/// a typed value.
+pub struct TypeDroppingCleanupFunction {
+    val: ValueRef,
+    t: ty::t,
+}
+
+impl CleanupFunction for TypeDroppingCleanupFunction {
+    fn clean(&self, block: @mut Block) -> @mut Block {
+        glue::drop_ty(block, self.val, self.t)
+    }
+}
+
+/// A cleanup function that calls the "drop glue" (destructor function) on
+/// an immediate typed value.
+pub struct ImmediateTypeDroppingCleanupFunction {
+    val: ValueRef,
+    t: ty::t,
+}
+
+impl CleanupFunction for ImmediateTypeDroppingCleanupFunction {
+    fn clean(&self, block: @mut Block) -> @mut Block {
+        glue::drop_ty_immediate(block, self.val, self.t)
+    }
+}
+
+/// A cleanup function that releases a write guard, returning a value to
+/// mutable status.
+pub struct WriteGuardReleasingCleanupFunction {
+    root_key: root_map_key,
+    frozen_val_ref: ValueRef,
+    bits_val_ref: ValueRef,
+    filename_val: ValueRef,
+    line_val: ValueRef,
+}
+
+impl CleanupFunction for WriteGuardReleasingCleanupFunction {
+    fn clean(&self, bcx: @mut Block) -> @mut Block {
+        write_guard::return_to_mut(bcx,
+                                   self.root_key,
+                                   self.frozen_val_ref,
+                                   self.bits_val_ref,
+                                   self.filename_val,
+                                   self.line_val)
+    }
+}
+
+/// A cleanup function that frees some memory in the garbage-collected heap.
+pub struct GCHeapFreeingCleanupFunction {
+    ptr: ValueRef,
+}
+
+impl CleanupFunction for GCHeapFreeingCleanupFunction {
+    fn clean(&self, bcx: @mut Block) -> @mut Block {
+        glue::trans_free(bcx, self.ptr)
+    }
+}
+
+/// A cleanup function that frees some memory in the exchange heap.
+pub struct ExchangeHeapFreeingCleanupFunction {
+    ptr: ValueRef,
+}
+
+impl CleanupFunction for ExchangeHeapFreeingCleanupFunction {
+    fn clean(&self, bcx: @mut Block) -> @mut Block {
+        glue::trans_exchange_free(bcx, self.ptr)
+    }
+}
+
 pub enum cleanup {
-    clean(@fn(@mut Block) -> @mut Block, cleantype),
-    clean_temp(ValueRef, @fn(@mut Block) -> @mut Block, cleantype),
+    clean(@CleanupFunction, cleantype),
+    clean_temp(ValueRef, @CleanupFunction, cleantype),
 }
 
 // Can't use deriving(Clone) because of the managed closure.
@@ -337,13 +413,19 @@ pub fn cleanup_type(cx: ty::ctxt, ty: ty::t) -> cleantype {
 }
 
 pub fn add_clean(bcx: @mut Block, val: ValueRef, t: ty::t) {
-    if !ty::type_needs_drop(bcx.tcx(), t) { return; }
+    if !ty::type_needs_drop(bcx.tcx(), t) {
+        return
+    }
 
     debug!("add_clean(%s, %s, %s)", bcx.to_str(), bcx.val_to_str(val), t.repr(bcx.tcx()));
 
     let cleanup_type = cleanup_type(bcx.tcx(), t);
     do in_scope_cx(bcx, None) |scope_info| {
-        scope_info.cleanups.push(clean(|a| glue::drop_ty(a, val, t), cleanup_type));
+        scope_info.cleanups.push(clean(@TypeDroppingCleanupFunction {
+            val: val,
+            t: t,
+        } as @CleanupFunction,
+        cleanup_type));
         grow_scope_clean(scope_info);
     }
 }
@@ -355,9 +437,12 @@ pub fn add_clean_temp_immediate(cx: @mut Block, val: ValueRef, ty: ty::t) {
            ty.repr(cx.tcx()));
     let cleanup_type = cleanup_type(cx.tcx(), ty);
     do in_scope_cx(cx, None) |scope_info| {
-        scope_info.cleanups.push(
-            clean_temp(val, |a| glue::drop_ty_immediate(a, val, ty),
-                       cleanup_type));
+        scope_info.cleanups.push(clean_temp(val,
+            @ImmediateTypeDroppingCleanupFunction {
+                val: val,
+                t: ty,
+            } as @CleanupFunction,
+            cleanup_type));
         grow_scope_clean(scope_info);
     }
 }
@@ -381,7 +466,12 @@ pub fn add_clean_temp_mem_in_scope_(bcx: @mut Block, scope_id: Option<ast::NodeI
            t.repr(bcx.tcx()));
     let cleanup_type = cleanup_type(bcx.tcx(), t);
     do in_scope_cx(bcx, scope_id) |scope_info| {
-        scope_info.cleanups.push(clean_temp(val, |a| glue::drop_ty(a, val, t), cleanup_type));
+        scope_info.cleanups.push(clean_temp(val,
+            @TypeDroppingCleanupFunction {
+                val: val,
+                t: t,
+            } as @CleanupFunction,
+            cleanup_type));
         grow_scope_clean(scope_info);
     }
 }
@@ -405,29 +495,36 @@ pub fn add_clean_return_to_mut(bcx: @mut Block,
            bcx.val_to_str(frozen_val_ref),
            bcx.val_to_str(bits_val_ref));
     do in_scope_cx(bcx, Some(scope_id)) |scope_info| {
-        scope_info.cleanups.push(
-            clean_temp(
+        scope_info.cleanups.push(clean_temp(
                 frozen_val_ref,
-                |bcx| write_guard::return_to_mut(bcx, root_key, frozen_val_ref, bits_val_ref,
-                                                 filename_val, line_val),
+                @WriteGuardReleasingCleanupFunction {
+                    root_key: root_key,
+                    frozen_val_ref: frozen_val_ref,
+                    bits_val_ref: bits_val_ref,
+                    filename_val: filename_val,
+                    line_val: line_val,
+                } as @CleanupFunction,
                 normal_exit_only));
         grow_scope_clean(scope_info);
     }
 }
 pub fn add_clean_free(cx: @mut Block, ptr: ValueRef, heap: heap) {
     let free_fn = match heap {
-      heap_managed | heap_managed_unique => {
-        let f: @fn(@mut Block) -> @mut Block = |a| glue::trans_free(a, ptr);
-        f
-      }
-      heap_exchange | heap_exchange_closure => {
-        let f: @fn(@mut Block) -> @mut Block = |a| glue::trans_exchange_free(a, ptr);
-        f
-      }
+        heap_managed | heap_managed_unique => {
+            @GCHeapFreeingCleanupFunction {
+                ptr: ptr,
+            } as @CleanupFunction
+        }
+        heap_exchange | heap_exchange_closure => {
+            @ExchangeHeapFreeingCleanupFunction {
+                ptr: ptr,
+            } as @CleanupFunction
+        }
     };
     do in_scope_cx(cx, None) |scope_info| {
-        scope_info.cleanups.push(clean_temp(ptr, free_fn,
-                                      normal_exit_and_unwind));
+        scope_info.cleanups.push(clean_temp(ptr,
+                                            free_fn,
+                                            normal_exit_and_unwind));
         grow_scope_clean(scope_info);
     }
 }
diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs
index e342bcaf4fa..134db45be43 100644
--- a/src/librustc/middle/trans/context.rs
+++ b/src/librustc/middle/trans/context.rs
@@ -16,6 +16,7 @@ use lib::llvm::{llvm, TargetData, TypeNames};
 use lib::llvm::mk_target_data;
 use metadata::common::LinkMeta;
 use middle::astencode;
+use middle::privacy;
 use middle::resolve;
 use middle::trans::adt;
 use middle::trans::base;
@@ -49,6 +50,7 @@ pub struct CrateContext {
      intrinsics: HashMap<&'static str, ValueRef>,
      item_vals: HashMap<ast::NodeId, ValueRef>,
      exp_map2: resolve::ExportMap2,
+     exported_items: @privacy::ExportedItems,
      reachable: @mut HashSet<ast::NodeId>,
      item_symbols: HashMap<ast::NodeId, ~str>,
      link_meta: LinkMeta,
@@ -127,6 +129,7 @@ impl CrateContext {
                name: &str,
                tcx: ty::ctxt,
                emap2: resolve::ExportMap2,
+               exported_items: @privacy::ExportedItems,
                maps: astencode::Maps,
                symbol_hasher: hash::State,
                link_meta: LinkMeta,
@@ -187,6 +190,7 @@ impl CrateContext {
                   intrinsics: intrinsics,
                   item_vals: HashMap::new(),
                   exp_map2: emap2,
+                  exported_items: exported_items,
                   reachable: reachable,
                   item_symbols: HashMap::new(),
                   link_meta: link_meta,
diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs
index 272ce49a377..91f6169b419 100644
--- a/src/librustc/middle/trans/debuginfo.rs
+++ b/src/librustc/middle/trans/debuginfo.rs
@@ -1086,6 +1086,36 @@ fn pointer_type_metadata(cx: &mut CrateContext,
     return ptr_metadata;
 }
 
+trait MemberDescriptionFactory {
+    fn create_member_descriptions(&self, cx: &mut CrateContext)
+                                  -> ~[MemberDescription];
+}
+
+struct StructMemberDescriptionFactory {
+    fields: ~[ty::field],
+    span: Span,
+}
+
+impl MemberDescriptionFactory for StructMemberDescriptionFactory {
+    fn create_member_descriptions(&self, cx: &mut CrateContext)
+                                  -> ~[MemberDescription] {
+        do self.fields.map |field| {
+            let name = if field.ident.name == special_idents::unnamed_field.name {
+                @""
+            } else {
+                token::ident_to_str(&field.ident)
+            };
+
+            MemberDescription {
+                name: name,
+                llvm_type: type_of::type_of(cx, field.mt.ty),
+                type_metadata: type_metadata(cx, field.mt.ty, self.span),
+                offset: ComputedMemberOffset,
+            }
+        }
+    }
+}
+
 fn prepare_struct_metadata(cx: &mut CrateContext,
                            struct_type: ty::t,
                            def_id: ast::DefId,
@@ -1114,22 +1144,10 @@ fn prepare_struct_metadata(cx: &mut CrateContext,
         metadata_stub: struct_metadata_stub,
         llvm_type: struct_llvm_type,
         file_metadata: file_metadata,
-        member_description_factory: |cx| {
-            do fields.map |field| {
-                let name = if field.ident.name == special_idents::unnamed_field.name {
-                    @""
-                } else {
-                    token::ident_to_str(&field.ident)
-                };
-
-                MemberDescription {
-                    name: name,
-                    llvm_type: type_of::type_of(cx, field.mt.ty),
-                    type_metadata: type_metadata(cx, field.mt.ty, span),
-                    offset: ComputedMemberOffset,
-                }
-            }
-        }
+        member_description_factory: @StructMemberDescriptionFactory {
+            fields: fields,
+            span: span,
+        } as @MemberDescriptionFactory,
     }
 }
 
@@ -1139,7 +1157,7 @@ enum RecursiveTypeDescription {
         metadata_stub: DICompositeType,
         llvm_type: Type,
         file_metadata: DIFile,
-        member_description_factory: @fn(cx: &mut CrateContext) -> ~[MemberDescription],
+        member_description_factory: @MemberDescriptionFactory,
     },
     FinalMetadata(DICompositeType)
 }
@@ -1167,7 +1185,8 @@ impl RecursiveTypeDescription {
                 debug_context(cx).created_types.insert(cache_id, metadata_stub);
 
                 // ... then create the member descriptions ...
-                let member_descriptions = member_description_factory(cx);
+                let member_descriptions = member_description_factory.
+                    create_member_descriptions(cx);
 
                 // ... and attach them to the stub to complete it.
                 set_members_of_composite_type(cx,
@@ -1182,6 +1201,25 @@ impl RecursiveTypeDescription {
     }
 }
 
+struct TupleMemberDescriptionFactory {
+    component_types: ~[ty::t],
+    span: Span,
+}
+
+impl MemberDescriptionFactory for TupleMemberDescriptionFactory {
+    fn create_member_descriptions(&self, cx: &mut CrateContext)
+                                  -> ~[MemberDescription] {
+        do self.component_types.map |&component_type| {
+            MemberDescription {
+                name: @"",
+                llvm_type: type_of::type_of(cx, component_type),
+                type_metadata: type_metadata(cx, component_type, self.span),
+                offset: ComputedMemberOffset,
+            }
+        }
+    }
+}
+
 fn prepare_tuple_metadata(cx: &mut CrateContext,
                           tuple_type: ty::t,
                           component_types: &[ty::t],
@@ -1192,8 +1230,6 @@ fn prepare_tuple_metadata(cx: &mut CrateContext,
 
     let loc = span_start(cx, span);
     let file_metadata = file_metadata(cx, loc.file.name);
-    // Needs to be copied for closure below :(
-    let component_types = component_types.to_owned();
 
     UnfinishedMetadata {
         cache_id: cache_id_for_type(tuple_type),
@@ -1205,17 +1241,147 @@ fn prepare_tuple_metadata(cx: &mut CrateContext,
                                           span),
         llvm_type: tuple_llvm_type,
         file_metadata: file_metadata,
-        member_description_factory: |cx| {
-            do component_types.map |&component_type| {
+        member_description_factory: @TupleMemberDescriptionFactory {
+            component_types: component_types.to_owned(),
+            span: span,
+        } as @MemberDescriptionFactory
+    }
+}
+
+struct GeneralMemberDescriptionFactory {
+    type_rep: @adt::Repr,
+    variants: @~[@ty::VariantInfo],
+    discriminant_type_metadata: ValueRef,
+    containing_scope: DIScope,
+    file_metadata: DIFile,
+    span: Span,
+}
+
+impl MemberDescriptionFactory for GeneralMemberDescriptionFactory {
+    fn create_member_descriptions(&self, cx: &mut CrateContext)
+                                  -> ~[MemberDescription] {
+        // Capture type_rep, so we don't have to copy the struct_defs array
+        let struct_defs = match *self.type_rep {
+            adt::General(ref struct_defs) => struct_defs,
+            _ => cx.sess.bug("unreachable")
+        };
+
+        do struct_defs
+            .iter()
+            .enumerate()
+            .map |(i, struct_def)| {
+                let (variant_type_metadata, variant_llvm_type, member_desc_factory) =
+                    describe_variant(cx,
+                                     struct_def,
+                                     self.variants[i],
+                                     Some(self.discriminant_type_metadata),
+                                     self.containing_scope,
+                                     self.file_metadata,
+                                     self.span);
+
+                let member_descriptions =
+                    member_desc_factory.create_member_descriptions(cx);
+
+                set_members_of_composite_type(cx,
+                                              variant_type_metadata,
+                                              variant_llvm_type,
+                                              member_descriptions,
+                                              self.file_metadata,
+                                              codemap::dummy_sp());
                 MemberDescription {
                     name: @"",
-                    llvm_type: type_of::type_of(cx, component_type),
-                    type_metadata: type_metadata(cx, component_type, span),
-                    offset: ComputedMemberOffset,
+                    llvm_type: variant_llvm_type,
+                    type_metadata: variant_type_metadata,
+                    offset: FixedMemberOffset { bytes: 0 },
                 }
+        }.collect()
+    }
+}
+
+struct EnumVariantMemberDescriptionFactory {
+    args: ~[(@str, ty::t)],
+    discriminant_type_metadata: Option<DIType>,
+    span: Span,
+}
+
+impl MemberDescriptionFactory for EnumVariantMemberDescriptionFactory {
+    fn create_member_descriptions(&self, cx: &mut CrateContext)
+                                  -> ~[MemberDescription] {
+        do self.args.iter().enumerate().map |(i, &(name, ty))| {
+            MemberDescription {
+                name: name,
+                llvm_type: type_of::type_of(cx, ty),
+                type_metadata: match self.discriminant_type_metadata {
+                    Some(metadata) if i == 0 => metadata,
+                    _ => type_metadata(cx, ty, self.span)
+                },
+                offset: ComputedMemberOffset,
+            }
+        }.collect()
+    }
+}
+
+fn describe_variant(cx: &mut CrateContext,
+                    struct_def: &adt::Struct,
+                    variant_info: &ty::VariantInfo,
+                    discriminant_type_metadata: Option<DIType>,
+                    containing_scope: DIScope,
+                    file_metadata: DIFile,
+                    span: Span)
+                 -> (DICompositeType, Type, @MemberDescriptionFactory) {
+    let variant_name = token::ident_to_str(&variant_info.name);
+    let variant_llvm_type = Type::struct_(struct_def.fields.map(|&t| type_of::type_of(cx, t)),
+                                          struct_def.packed);
+    // Could some consistency checks here: size, align, field count, discr type
+
+    // Find the source code location of the variant's definition
+    let variant_definition_span = if variant_info.id.crate == ast::LOCAL_CRATE {
+        match cx.tcx.items.find(&variant_info.id.node) {
+            Some(&ast_map::node_variant(ref variant, _, _)) => variant.span,
+            ref node => {
+                cx.sess.span_warn(span,
+                    fmt!("debuginfo::enum_metadata()::adt_struct_metadata() - Unexpected node \
+                          type: %?. This is a bug.", node));
+                codemap::dummy_sp()
             }
         }
+    } else {
+        // For definitions from other crates we have no location information available.
+        codemap::dummy_sp()
+    };
+
+    let metadata_stub = create_struct_stub(cx,
+                                           variant_llvm_type,
+                                           variant_name,
+                                           containing_scope,
+                                           file_metadata,
+                                           variant_definition_span);
+
+    // Get the argument names from the enum variant info
+    let mut arg_names = match variant_info.arg_names {
+        Some(ref names) => do names.map |ident| { token::ident_to_str(ident) },
+        None => do variant_info.args.map |_| { @"" }
+    };
+
+    // If this is not a univariant enum, there is also the (unnamed) discriminant field
+    if discriminant_type_metadata.is_some() {
+        arg_names.insert(0, @"");
     }
+
+    // Build an array of (field name, field type) pairs to be captured in the factory closure.
+    let args: ~[(@str, ty::t)] = arg_names.iter()
+        .zip(struct_def.fields.iter())
+        .map(|(&s, &t)| (s, t))
+        .collect();
+
+    let member_description_factory =
+        @EnumVariantMemberDescriptionFactory {
+            args: args,
+            discriminant_type_metadata: discriminant_type_metadata,
+            span: span,
+        } as @MemberDescriptionFactory;
+
+    (metadata_stub, variant_llvm_type, member_description_factory)
 }
 
 fn prepare_enum_metadata(cx: &mut CrateContext,
@@ -1336,42 +1502,14 @@ fn prepare_enum_metadata(cx: &mut CrateContext,
                 metadata_stub: enum_metadata,
                 llvm_type: enum_llvm_type,
                 file_metadata: file_metadata,
-                member_description_factory: |cx| {
-                    // Capture type_rep, so we don't have to copy the struct_defs array
-                    let struct_defs = match *type_rep {
-                        adt::General(ref struct_defs) => struct_defs,
-                        _ => cx.sess.bug("unreachable")
-                    };
-
-                    do struct_defs
-                        .iter()
-                        .enumerate()
-                        .map |(i, struct_def)| {
-                            let (variant_type_metadata, variant_llvm_type, member_desc_factory) =
-                                describe_variant(cx,
-                                                 struct_def,
-                                                 variants[i],
-                                                 Some(discriminant_type_metadata),
-                                                 containing_scope,
-                                                 file_metadata,
-                                                 span);
-
-                            let member_descriptions = member_desc_factory(cx);
-
-                            set_members_of_composite_type(cx,
-                                                          variant_type_metadata,
-                                                          variant_llvm_type,
-                                                          member_descriptions,
-                                                          file_metadata,
-                                                          codemap::dummy_sp());
-                            MemberDescription {
-                                name: @"",
-                                llvm_type: variant_llvm_type,
-                                type_metadata: variant_type_metadata,
-                                offset: FixedMemberOffset { bytes: 0 },
-                            }
-                    }.collect()
-                }
+                member_description_factory: @GeneralMemberDescriptionFactory {
+                    type_rep: type_rep,
+                    variants: variants,
+                    discriminant_type_metadata: discriminant_type_metadata,
+                    containing_scope: containing_scope,
+                    file_metadata: file_metadata,
+                    span: span,
+                } as @MemberDescriptionFactory,
             }
         }
         adt::NullablePointer { nonnull: ref struct_def, nndiscr, _ } => {
@@ -1393,76 +1531,6 @@ fn prepare_enum_metadata(cx: &mut CrateContext,
             }
         }
     };
-
-    fn describe_variant(cx: &mut CrateContext,
-                        struct_def: &adt::Struct,
-                        variant_info: &ty::VariantInfo,
-                        discriminant_type_metadata: Option<DIType>,
-                        containing_scope: DIScope,
-                        file_metadata: DIFile,
-                        span: Span)
-                     -> (DICompositeType, Type, @fn(&mut CrateContext) -> ~[MemberDescription]) {
-        let variant_name = token::ident_to_str(&variant_info.name);
-        let variant_llvm_type = Type::struct_(struct_def.fields.map(|&t| type_of::type_of(cx, t)),
-                                              struct_def.packed);
-        // Could some consistency checks here: size, align, field count, discr type
-
-        // Find the source code location of the variant's definition
-        let variant_definition_span = if variant_info.id.crate == ast::LOCAL_CRATE {
-            match cx.tcx.items.find(&variant_info.id.node) {
-                Some(&ast_map::node_variant(ref variant, _, _)) => variant.span,
-                ref node => {
-                    cx.sess.span_warn(span,
-                        fmt!("debuginfo::enum_metadata()::adt_struct_metadata() - Unexpected node \
-                              type: %?. This is a bug.", node));
-                    codemap::dummy_sp()
-                }
-            }
-        } else {
-            // For definitions from other crates we have no location information available.
-            codemap::dummy_sp()
-        };
-
-        let metadata_stub = create_struct_stub(cx,
-                                               variant_llvm_type,
-                                               variant_name,
-                                               containing_scope,
-                                               file_metadata,
-                                               variant_definition_span);
-
-        // Get the argument names from the enum variant info
-        let mut arg_names = match variant_info.arg_names {
-            Some(ref names) => do names.map |ident| { token::ident_to_str(ident) },
-            None => do variant_info.args.map |_| { @"" }
-        };
-
-        // If this is not a univariant enum, there is also the (unnamed) discriminant field
-        if discriminant_type_metadata.is_some() {
-            arg_names.insert(0, @"");
-        }
-
-        // Build an array of (field name, field type) pairs to be captured in the factory closure.
-        let args: ~[(@str, ty::t)] = arg_names.iter()
-            .zip(struct_def.fields.iter())
-            .map(|(&s, &t)| (s, t))
-            .collect();
-
-        let member_description_factory: @fn(cx: &mut CrateContext) -> ~[MemberDescription] = |cx| {
-            do args.iter().enumerate().map |(i, &(name, ty))| {
-                MemberDescription {
-                    name: name,
-                    llvm_type: type_of::type_of(cx, ty),
-                    type_metadata: match discriminant_type_metadata {
-                        Some(metadata) if i == 0 => metadata,
-                        _ => type_metadata(cx, ty, span)
-                    },
-                    offset: ComputedMemberOffset,
-                }
-            }.collect()
-        };
-
-        (metadata_stub, variant_llvm_type, member_description_factory)
-    }
 }
 
 enum MemberOffset {
diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs
index 1958d3c9adb..a760801d73a 100644
--- a/src/librustc/middle/trans/glue.rs
+++ b/src/librustc/middle/trans/glue.rs
@@ -581,11 +581,7 @@ pub fn make_take_glue(bcx: @mut Block, v: ValueRef, t: ty::t) -> @mut Block {
       | ty::ty_estr(ty::vstore_slice(_)) => {
         bcx
       }
-      ty::ty_closure(ty::ClosureTy { sigil: ast::BorrowedSigil, _ }) |
-      ty::ty_closure(ty::ClosureTy { sigil: ast::ManagedSigil, _ }) => {
-        closure::make_closure_glue(bcx, v, t, take_ty)
-      }
-      ty::ty_closure(ty::ClosureTy { sigil: ast::OwnedSigil, _ }) => bcx,
+      ty::ty_closure(_) => bcx,
       ty::ty_trait(_, _, ty::BoxTraitStore, _, _) => {
         let llbox = Load(bcx, GEPi(bcx, v, [0u, abi::trt_field_box]));
         incr_refcnt_of_boxed(bcx, llbox);
@@ -606,9 +602,7 @@ pub fn make_take_glue(bcx: @mut Block, v: ValueRef, t: ty::t) -> @mut Block {
                                 None);
           bcx
       }
-      ty::ty_opaque_closure_ptr(ck) => {
-        closure::make_opaque_cbox_take_glue(bcx, ck, v)
-      }
+      ty::ty_opaque_closure_ptr(_) => bcx,
       ty::ty_struct(did, _) => {
         let tcx = bcx.tcx();
         let bcx = iter_structural_ty(bcx, v, t, take_ty);
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 9abee133290..bcf4de08073 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -2308,12 +2308,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
             ast::Many => TC_NONE
         };
         // Prevent noncopyable types captured in the environment from being copied.
-        let ct = if cty.sigil == ast::ManagedSigil {
-            TC_NONE
-        } else {
-            TC_NONCOPY_TRAIT
-        };
-        st + rt + ot + ct
+        st + rt + ot + TC_NONCOPY_TRAIT
     }
 
     fn trait_contents(store: TraitStore, mutbl: ast::Mutability,
diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs
index 36405136e63..024010e40df 100644
--- a/src/librustc/middle/typeck/astconv.rs
+++ b/src/librustc/middle/typeck/astconv.rs
@@ -400,6 +400,11 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope + Clone + 'static>(
                                             bf.abis, &bf.lifetimes, &bf.decl))
       }
       ast::ty_closure(ref f) => {
+        if f.sigil == ast::ManagedSigil {
+            tcx.sess.span_err(ast_ty.span,
+                              "managed closures are not supported");
+        }
+
           let bounds = conv_builtin_bounds(this.tcx(), &f.bounds, match f.sigil {
               // Use corresponding trait store to figure out default bounds
               // if none were specified.
diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs
index 061921e60e1..606b0255cd7 100644
--- a/src/librustc/middle/typeck/check/_match.rs
+++ b/src/librustc/middle/typeck/check/_match.rs
@@ -37,12 +37,12 @@ pub fn check_match(fcx: @mut FnCtxt,
     // Typecheck the patterns first, so that we get types for all the
     // bindings.
     for arm in arms.iter() {
-        let pcx = pat_ctxt {
+        let mut pcx = pat_ctxt {
             fcx: fcx,
             map: pat_id_map(tcx.def_map, arm.pats[0]),
         };
 
-        for p in arm.pats.iter() { check_pat(&pcx, *p, discrim_ty);}
+        for p in arm.pats.iter() { check_pat(&mut pcx, *p, discrim_ty);}
     }
 
     // The result of the match is the common supertype of all the
diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs
index 29f087094fb..78c20b54845 100644
--- a/src/librustc/middle/typeck/check/regionck.rs
+++ b/src/librustc/middle/typeck/check/regionck.rs
@@ -122,12 +122,13 @@ impl Rcx {
     }
 
     /// Try to resolve the type for the given node.
-    pub fn resolve_node_type(@mut self, id: ast::NodeId) -> ty::t {
-        self.resolve_type(self.fcx.node_ty(id))
+    pub fn resolve_node_type(&mut self, id: ast::NodeId) -> ty::t {
+        let t = self.fcx.node_ty(id);
+        self.resolve_type(t)
     }
 
     /// Try to resolve the type for the given node.
-    pub fn resolve_expr_type_adjusted(@mut self, expr: @ast::Expr) -> ty::t {
+    pub fn resolve_expr_type_adjusted(&mut self, expr: @ast::Expr) -> ty::t {
         let ty_unadjusted = self.resolve_node_type(expr.id);
         if ty::type_is_error(ty_unadjusted) || ty::type_is_bot(ty_unadjusted) {
             ty_unadjusted
@@ -141,30 +142,28 @@ impl Rcx {
 }
 
 pub fn regionck_expr(fcx: @mut FnCtxt, e: @ast::Expr) {
-    let rcx = @mut Rcx { fcx: fcx, errors_reported: 0,
+    let mut rcx = Rcx { fcx: fcx, errors_reported: 0,
                          repeating_scope: e.id };
+    let rcx = &mut rcx;
     if fcx.err_count_since_creation() == 0 {
         // regionck assumes typeck succeeded
-        let mut v = regionck_visitor();
-        v.visit_expr(e, rcx);
+        rcx.visit_expr(e, ());
     }
     fcx.infcx().resolve_regions();
 }
 
 pub fn regionck_fn(fcx: @mut FnCtxt, blk: &ast::Block) {
-    let rcx = @mut Rcx { fcx: fcx, errors_reported: 0,
+    let mut rcx = Rcx { fcx: fcx, errors_reported: 0,
                          repeating_scope: blk.id };
+    let rcx = &mut rcx;
     if fcx.err_count_since_creation() == 0 {
         // regionck assumes typeck succeeded
-        let mut v = regionck_visitor();
-        v.visit_block(blk, rcx);
+        rcx.visit_block(blk, ());
     }
     fcx.infcx().resolve_regions();
 }
 
-struct RegionckVisitor;
-
-impl Visitor<@mut Rcx> for RegionckVisitor {
+impl Visitor<()> for Rcx {
     // (*) FIXME(#3238) should use visit_pat, not visit_arm/visit_local,
     // However, right now we run into an issue whereby some free
     // regions are not properly related if they appear within the
@@ -173,48 +172,44 @@ impl Visitor<@mut Rcx> for RegionckVisitor {
     // hierarchy, and in particular the relationships between free
     // regions, until regionck, as described in #3238.
 
-    fn visit_item(&mut self, i:@ast::item, e:@mut Rcx) { visit_item(self, i, e); }
+    fn visit_item(&mut self, i:@ast::item, _:()) { visit_item(self, i); }
 
-    fn visit_expr(&mut self, ex:@ast::Expr, e:@mut Rcx) { visit_expr(self, ex, e); }
+    fn visit_expr(&mut self, ex:@ast::Expr, _:()) { visit_expr(self, ex); }
 
         //visit_pat: visit_pat, // (*) see above
 
-    fn visit_arm(&mut self, a:&ast::Arm, e:@mut Rcx) { visit_arm(self, a, e); }
-
-    fn visit_local(&mut self, l:@ast::Local, e:@mut Rcx) { visit_local(self, l, e); }
+    fn visit_arm(&mut self, a:&ast::Arm, _:()) { visit_arm(self, a); }
 
-    fn visit_block(&mut self, b:&ast::Block, e:@mut Rcx) { visit_block(self, b, e); }
-}
+    fn visit_local(&mut self, l:@ast::Local, _:()) { visit_local(self, l); }
 
-fn regionck_visitor() -> RegionckVisitor {
-    RegionckVisitor
+    fn visit_block(&mut self, b:&ast::Block, _:()) { visit_block(self, b); }
 }
 
-fn visit_item(_v: &mut RegionckVisitor, _item: @ast::item, _rcx: @mut Rcx) {
+fn visit_item(_rcx: &mut Rcx, _item: @ast::item) {
     // Ignore items
 }
 
-fn visit_block(v: &mut RegionckVisitor, b: &ast::Block, rcx: @mut Rcx) {
+fn visit_block(rcx: &mut Rcx, b: &ast::Block) {
     rcx.fcx.tcx().region_maps.record_cleanup_scope(b.id);
-    visit::walk_block(v, b, rcx);
+    visit::walk_block(rcx, b, ());
 }
 
-fn visit_arm(v: &mut RegionckVisitor, arm: &ast::Arm, rcx: @mut Rcx) {
+fn visit_arm(rcx: &mut Rcx, arm: &ast::Arm) {
     // see above
     for &p in arm.pats.iter() {
         constrain_bindings_in_pat(p, rcx);
     }
 
-    visit::walk_arm(v, arm, rcx);
+    visit::walk_arm(rcx, arm, ());
 }
 
-fn visit_local(v: &mut RegionckVisitor, l: @ast::Local, rcx: @mut Rcx) {
+fn visit_local(rcx: &mut Rcx, l: @ast::Local) {
     // see above
     constrain_bindings_in_pat(l.pat, rcx);
-    visit::walk_local(v, l, rcx);
+    visit::walk_local(rcx, l, ());
 }
 
-fn constrain_bindings_in_pat(pat: @ast::Pat, rcx: @mut Rcx) {
+fn constrain_bindings_in_pat(pat: @ast::Pat, rcx: &mut Rcx) {
     let tcx = rcx.fcx.tcx();
     debug!("regionck::visit_pat(pat=%s)", pat.repr(tcx));
     do pat_util::pat_bindings(tcx.def_map, pat) |_, id, span, _| {
@@ -248,7 +243,7 @@ fn constrain_bindings_in_pat(pat: @ast::Pat, rcx: @mut Rcx) {
     }
 }
 
-fn visit_expr(v: &mut RegionckVisitor, expr: @ast::Expr, rcx: @mut Rcx) {
+fn visit_expr(rcx: &mut Rcx, expr: @ast::Expr) {
     debug!("regionck::visit_expr(e=%s, repeating_scope=%?)",
            expr.repr(rcx.fcx.tcx()), rcx.repeating_scope);
 
@@ -336,13 +331,13 @@ fn visit_expr(v: &mut RegionckVisitor, expr: @ast::Expr, rcx: @mut Rcx) {
             constrain_callee(rcx, callee.id, expr, callee);
             constrain_call(rcx, callee.id, expr, None, *args, false);
 
-            visit::walk_expr(v, expr, rcx);
+            visit::walk_expr(rcx, expr, ());
         }
 
         ast::ExprMethodCall(callee_id, arg0, _, _, ref args, _) => {
             constrain_call(rcx, callee_id, expr, Some(arg0), *args, false);
 
-            visit::walk_expr(v,expr, rcx);
+            visit::walk_expr(rcx, expr, ());
         }
 
         ast::ExprIndex(callee_id, lhs, rhs) |
@@ -354,14 +349,14 @@ fn visit_expr(v: &mut RegionckVisitor, expr: @ast::Expr, rcx: @mut Rcx) {
             // should be converted to an adjustment!
             constrain_call(rcx, callee_id, expr, Some(lhs), [rhs], true);
 
-            visit::walk_expr(v, expr, rcx);
+            visit::walk_expr(rcx, expr, ());
         }
 
         ast::ExprUnary(callee_id, _, lhs) if has_method_map => {
             // As above.
             constrain_call(rcx, callee_id, expr, Some(lhs), [], true);
 
-            visit::walk_expr(v, expr, rcx);
+            visit::walk_expr(rcx, expr, ());
         }
 
         ast::ExprUnary(_, ast::UnDeref, base) => {
@@ -369,7 +364,7 @@ fn visit_expr(v: &mut RegionckVisitor, expr: @ast::Expr, rcx: @mut Rcx) {
             let base_ty = rcx.resolve_node_type(base.id);
             constrain_derefs(rcx, expr, 1, base_ty);
 
-            visit::walk_expr(v, expr, rcx);
+            visit::walk_expr(rcx, expr, ());
         }
 
         ast::ExprIndex(_, vec_expr, _) => {
@@ -377,7 +372,7 @@ fn visit_expr(v: &mut RegionckVisitor, expr: @ast::Expr, rcx: @mut Rcx) {
             let vec_type = rcx.resolve_expr_type_adjusted(vec_expr);
             constrain_index(rcx, expr, vec_type);
 
-            visit::walk_expr(v, expr, rcx);
+            visit::walk_expr(rcx, expr, ());
         }
 
         ast::ExprCast(source, _) => {
@@ -407,7 +402,7 @@ fn visit_expr(v: &mut RegionckVisitor, expr: @ast::Expr, rcx: @mut Rcx) {
                 _ => ()
             }
 
-            visit::walk_expr(v, expr, rcx);
+            visit::walk_expr(rcx, expr, ());
         }
 
         ast::ExprAddrOf(_, base) => {
@@ -423,44 +418,43 @@ fn visit_expr(v: &mut RegionckVisitor, expr: @ast::Expr, rcx: @mut Rcx) {
             let ty0 = rcx.resolve_node_type(expr.id);
             constrain_regions_in_type(rcx, ty::re_scope(expr.id),
                                       infer::AddrOf(expr.span), ty0);
-            visit::walk_expr(v, expr, rcx);
+            visit::walk_expr(rcx, expr, ());
         }
 
         ast::ExprMatch(discr, ref arms) => {
             guarantor::for_match(rcx, discr, *arms);
 
-            visit::walk_expr(v, expr, rcx);
+            visit::walk_expr(rcx, expr, ());
         }
 
         ast::ExprFnBlock(*) => {
-            check_expr_fn_block(rcx, expr, v);
+            check_expr_fn_block(rcx, expr);
         }
 
         ast::ExprLoop(ref body, _) => {
             let repeating_scope = rcx.set_repeating_scope(body.id);
-            visit::walk_expr(v, expr, rcx);
+            visit::walk_expr(rcx, expr, ());
             rcx.set_repeating_scope(repeating_scope);
         }
 
         ast::ExprWhile(cond, ref body) => {
             let repeating_scope = rcx.set_repeating_scope(cond.id);
-            v.visit_expr(cond, rcx);
+            rcx.visit_expr(cond, ());
 
             rcx.set_repeating_scope(body.id);
-            v.visit_block(body, rcx);
+            rcx.visit_block(body, ());
 
             rcx.set_repeating_scope(repeating_scope);
         }
 
         _ => {
-            visit::walk_expr(v, expr, rcx);
+            visit::walk_expr(rcx, expr, ());
         }
     }
 }
 
-fn check_expr_fn_block(rcx: @mut Rcx,
-                       expr: @ast::Expr,
-                       v: &mut RegionckVisitor) {
+fn check_expr_fn_block(rcx: &mut Rcx,
+                       expr: @ast::Expr) {
     let tcx = rcx.fcx.tcx();
     match expr.node {
         ast::ExprFnBlock(_, ref body) => {
@@ -489,7 +483,7 @@ fn check_expr_fn_block(rcx: @mut Rcx,
             }
 
             let repeating_scope = rcx.set_repeating_scope(body.id);
-            visit::walk_expr(v, expr, rcx);
+            visit::walk_expr(rcx, expr, ());
             rcx.set_repeating_scope(repeating_scope);
         }
 
@@ -501,7 +495,7 @@ fn check_expr_fn_block(rcx: @mut Rcx,
     }
 }
 
-fn constrain_callee(rcx: @mut Rcx,
+fn constrain_callee(rcx: &mut Rcx,
                     callee_id: ast::NodeId,
                     call_expr: @ast::Expr,
                     callee_expr: @ast::Expr)
@@ -526,7 +520,7 @@ fn constrain_callee(rcx: @mut Rcx,
     }
 }
 
-fn constrain_call(rcx: @mut Rcx,
+fn constrain_call(rcx: &mut Rcx,
                   // might be expr_call, expr_method_call, or an overloaded
                   // operator
                   callee_id: ast::NodeId,
@@ -589,7 +583,7 @@ fn constrain_call(rcx: @mut Rcx,
         fn_sig.output);
 }
 
-fn constrain_derefs(rcx: @mut Rcx,
+fn constrain_derefs(rcx: &mut Rcx,
                     deref_expr: @ast::Expr,
                     derefs: uint,
                     mut derefd_ty: ty::t)
@@ -625,7 +619,7 @@ fn constrain_derefs(rcx: @mut Rcx,
     }
 }
 
-pub fn mk_subregion_due_to_derefence(rcx: @mut Rcx,
+pub fn mk_subregion_due_to_derefence(rcx: &mut Rcx,
                                      deref_span: Span,
                                      minimum_lifetime: ty::Region,
                                      maximum_lifetime: ty::Region) {
@@ -634,7 +628,7 @@ pub fn mk_subregion_due_to_derefence(rcx: @mut Rcx,
 }
 
 
-fn constrain_index(rcx: @mut Rcx,
+fn constrain_index(rcx: &mut Rcx,
                    index_expr: @ast::Expr,
                    indexed_ty: ty::t)
 {
@@ -659,7 +653,7 @@ fn constrain_index(rcx: @mut Rcx,
     }
 }
 
-fn constrain_free_variables(rcx: @mut Rcx,
+fn constrain_free_variables(rcx: &mut Rcx,
                             region: ty::Region,
                             expr: @ast::Expr) {
     /*!
@@ -681,7 +675,7 @@ fn constrain_free_variables(rcx: @mut Rcx,
 }
 
 fn constrain_regions_in_type_of_node(
-    rcx: @mut Rcx,
+    rcx: &mut Rcx,
     id: ast::NodeId,
     minimum_lifetime: ty::Region,
     origin: infer::SubregionOrigin) -> bool
@@ -706,7 +700,7 @@ fn constrain_regions_in_type_of_node(
 }
 
 fn constrain_regions_in_type(
-    rcx: @mut Rcx,
+    rcx: &mut Rcx,
     minimum_lifetime: ty::Region,
     origin: infer::SubregionOrigin,
     ty: ty::t) -> bool
@@ -812,7 +806,7 @@ pub mod guarantor {
     use syntax::codemap::Span;
     use util::ppaux::{ty_to_str};
 
-    pub fn for_addr_of(rcx: @mut Rcx, expr: @ast::Expr, base: @ast::Expr) {
+    pub fn for_addr_of(rcx: &mut Rcx, expr: @ast::Expr, base: @ast::Expr) {
         /*!
          * Computes the guarantor for an expression `&base` and then
          * ensures that the lifetime of the resulting pointer is linked
@@ -825,7 +819,7 @@ pub mod guarantor {
         link(rcx, expr.span, expr.id, guarantor);
     }
 
-    pub fn for_match(rcx: @mut Rcx, discr: @ast::Expr, arms: &[ast::Arm]) {
+    pub fn for_match(rcx: &mut Rcx, discr: @ast::Expr, arms: &[ast::Arm]) {
         /*!
          * Computes the guarantors for any ref bindings in a match and
          * then ensures that the lifetime of the resulting pointer is
@@ -842,7 +836,7 @@ pub mod guarantor {
         }
     }
 
-    pub fn for_autoref(rcx: @mut Rcx,
+    pub fn for_autoref(rcx: &mut Rcx,
                        expr: @ast::Expr,
                        autoderefs: uint,
                        autoref: &ty::AutoRef) {
@@ -882,7 +876,7 @@ pub mod guarantor {
         }
 
         fn maybe_make_subregion(
-            rcx: @mut Rcx,
+            rcx: &mut Rcx,
             expr: @ast::Expr,
             sub_region: ty::Region,
             sup_region: Option<ty::Region>)
@@ -894,7 +888,7 @@ pub mod guarantor {
         }
     }
 
-    pub fn for_by_ref(rcx: @mut Rcx,
+    pub fn for_by_ref(rcx: &mut Rcx,
                       expr: @ast::Expr,
                       callee_scope: ast::NodeId) {
         /*!
@@ -917,7 +911,7 @@ pub mod guarantor {
     }
 
     fn link(
-        rcx: @mut Rcx,
+        rcx: &mut Rcx,
         span: Span,
         id: ast::NodeId,
         guarantor: Option<ty::Region>) {
@@ -974,7 +968,7 @@ pub mod guarantor {
         ty: ty::t
     }
 
-    fn guarantor(rcx: @mut Rcx, expr: @ast::Expr) -> Option<ty::Region> {
+    fn guarantor(rcx: &mut Rcx, expr: @ast::Expr) -> Option<ty::Region> {
         /*!
          *
          * Computes the guarantor of `expr`, or None if `expr` is
@@ -1045,7 +1039,7 @@ pub mod guarantor {
         }
     }
 
-    fn categorize(rcx: @mut Rcx, expr: @ast::Expr) -> ExprCategorization {
+    fn categorize(rcx: &mut Rcx, expr: @ast::Expr) -> ExprCategorization {
         debug!("categorize()");
 
         let mut expr_ct = categorize_unadjusted(rcx, expr);
@@ -1096,7 +1090,7 @@ pub mod guarantor {
         return expr_ct.cat;
     }
 
-    fn categorize_unadjusted(rcx: @mut Rcx,
+    fn categorize_unadjusted(rcx: &mut Rcx,
                              expr: @ast::Expr)
                           -> ExprCategorizationType {
         debug!("categorize_unadjusted()");
@@ -1120,7 +1114,7 @@ pub mod guarantor {
     }
 
     fn apply_autoderefs(
-        rcx: @mut Rcx,
+        rcx: &mut Rcx,
         expr: @ast::Expr,
         autoderefs: uint,
         ct: ExprCategorizationType)
@@ -1198,7 +1192,7 @@ pub mod guarantor {
     }
 
     fn link_ref_bindings_in_pat(
-        rcx: @mut Rcx,
+        rcx: &mut Rcx,
         pat: @ast::Pat,
         guarantor: Option<ty::Region>) {
         /*!
@@ -1271,7 +1265,7 @@ pub mod guarantor {
         }
     }
 
-    fn link_ref_bindings_in_pats(rcx: @mut Rcx,
+    fn link_ref_bindings_in_pats(rcx: &mut Rcx,
                                  pats: &~[@ast::Pat],
                                  guarantor: Option<ty::Region>) {
         for pat in pats.iter() {
diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs
index b96f85b676b..0e153635720 100644
--- a/src/librustc/middle/typeck/check/vtable.rs
+++ b/src/librustc/middle/typeck/check/vtable.rs
@@ -720,11 +720,11 @@ pub fn early_resolve_expr(ex: @ast::Expr,
     }
 }
 
-fn resolve_expr(v: &mut VtableResolveVisitor,
-                ex: @ast::Expr,
-                fcx: @mut FnCtxt) {
+fn resolve_expr(fcx: @mut FnCtxt,
+                ex: @ast::Expr) {
+    let mut fcx = fcx;
     early_resolve_expr(ex, fcx, false);
-    visit::walk_expr(v, ex, fcx);
+    visit::walk_expr(&mut fcx, ex, ());
 }
 
 pub fn resolve_impl(ccx: @mut CrateCtxt, impl_item: @ast::item) {
@@ -771,13 +771,11 @@ pub fn resolve_impl(ccx: @mut CrateCtxt, impl_item: @ast::item) {
     }
 }
 
-struct VtableResolveVisitor;
-
-impl visit::Visitor<@mut FnCtxt> for VtableResolveVisitor {
-    fn visit_expr(&mut self, ex:@ast::Expr, e:@mut FnCtxt) {
-        resolve_expr(self, ex, e);
+impl visit::Visitor<()> for @mut FnCtxt {
+    fn visit_expr(&mut self, ex:@ast::Expr, _:()) {
+        resolve_expr(*self, ex);
     }
-    fn visit_item(&mut self, _:@ast::item, _:@mut FnCtxt) {
+    fn visit_item(&mut self, _:@ast::item, _:()) {
         // no-op
     }
 }
@@ -785,6 +783,6 @@ impl visit::Visitor<@mut FnCtxt> for VtableResolveVisitor {
 // Detect points where a trait-bounded type parameter is
 // instantiated, resolve the impls for the parameters.
 pub fn resolve_in_block(fcx: @mut FnCtxt, bl: &ast::Block) {
-    let mut visitor = VtableResolveVisitor;
-    visit::walk_block(&mut visitor, bl, fcx);
+    let mut fcx = fcx;
+    visit::walk_block(&mut fcx, bl, ());
 }
diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs
index 2f11d9ff2eb..5e9ca576a56 100644
--- a/src/librustc/middle/typeck/check/writeback.rs
+++ b/src/librustc/middle/typeck/check/writeback.rs
@@ -114,7 +114,7 @@ fn resolve_vtable_map_entry(fcx: @mut FnCtxt, sp: Span, id: ast::NodeId) {
     }
 }
 
-fn resolve_type_vars_for_node(wbcx: @mut WbCtxt, sp: Span, id: ast::NodeId)
+fn resolve_type_vars_for_node(wbcx: &mut WbCtxt, sp: Span, id: ast::NodeId)
                            -> Option<ty::t> {
     let fcx = wbcx.fcx;
     let tcx = fcx.ccx.tcx;
@@ -196,7 +196,7 @@ fn resolve_type_vars_for_node(wbcx: @mut WbCtxt, sp: Span, id: ast::NodeId)
     }
 }
 
-fn maybe_resolve_type_vars_for_node(wbcx: @mut WbCtxt,
+fn maybe_resolve_type_vars_for_node(wbcx: &mut WbCtxt,
                                     sp: Span,
                                     id: ast::NodeId)
                                  -> Option<ty::t> {
@@ -215,15 +215,13 @@ struct WbCtxt {
     success: bool,
 }
 
-struct WbVisitor;
-
-fn visit_stmt(s: @ast::Stmt, (wbcx, v): (@mut WbCtxt, &mut WbVisitor)) {
+fn visit_stmt(s: @ast::Stmt, wbcx: &mut WbCtxt) {
     if !wbcx.success { return; }
     resolve_type_vars_for_node(wbcx, s.span, ty::stmt_node_id(s));
-    visit::walk_stmt(v, s, wbcx);
+    visit::walk_stmt(wbcx, s, ());
 }
 
-fn visit_expr(e: @ast::Expr, (wbcx, v): (@mut WbCtxt, &mut WbVisitor)) {
+fn visit_expr(e: @ast::Expr, wbcx: &mut WbCtxt) {
     if !wbcx.success {
         return;
     }
@@ -268,19 +266,19 @@ fn visit_expr(e: @ast::Expr, (wbcx, v): (@mut WbCtxt, &mut WbVisitor)) {
         _ => ()
     }
 
-    visit::walk_expr(v, e, wbcx);
+    visit::walk_expr(wbcx, e, ());
 }
 
-fn visit_block(b: &ast::Block, (wbcx, v): (@mut WbCtxt, &mut WbVisitor)) {
+fn visit_block(b: &ast::Block, wbcx: &mut WbCtxt) {
     if !wbcx.success {
         return;
     }
 
     resolve_type_vars_for_node(wbcx, b.span, b.id);
-    visit::walk_block(v, b, wbcx);
+    visit::walk_block(wbcx, b, ());
 }
 
-fn visit_pat(p: @ast::Pat, (wbcx, v): (@mut WbCtxt, &mut WbVisitor)) {
+fn visit_pat(p: @ast::Pat, wbcx: &mut WbCtxt) {
     if !wbcx.success {
         return;
     }
@@ -291,10 +289,10 @@ fn visit_pat(p: @ast::Pat, (wbcx, v): (@mut WbCtxt, &mut WbVisitor)) {
            wbcx.fcx.infcx().ty_to_str(
                ty::node_id_to_type(wbcx.fcx.ccx.tcx,
                                    p.id)));
-    visit::walk_pat(v, p, wbcx);
+    visit::walk_pat(wbcx, p, ());
 }
 
-fn visit_local(l: @ast::Local, (wbcx, v): (@mut WbCtxt, &mut WbVisitor)) {
+fn visit_local(l: @ast::Local, wbcx: &mut WbCtxt) {
     if !wbcx.success { return; }
     let var_ty = wbcx.fcx.local_ty(l.span, l.id);
     match resolve_type(wbcx.fcx.infcx(), var_ty, resolve_all | force_all) {
@@ -314,25 +312,25 @@ fn visit_local(l: @ast::Local, (wbcx, v): (@mut WbCtxt, &mut WbVisitor)) {
             wbcx.success = false;
         }
     }
-    visit::walk_local(v, l, wbcx);
+    visit::walk_local(wbcx, l, ());
 }
-fn visit_item(_item: @ast::item, (_wbcx, _v): (@mut WbCtxt, &mut WbVisitor)) {
+fn visit_item(_item: @ast::item, _wbcx: &mut WbCtxt) {
     // Ignore items
 }
 
-impl Visitor<@mut WbCtxt> for WbVisitor {
-    fn visit_item(&mut self, i:@ast::item, e:@mut WbCtxt) { visit_item(i, (e, self)); }
-    fn visit_stmt(&mut self, s:@ast::Stmt, e:@mut WbCtxt) { visit_stmt(s, (e, self)); }
-    fn visit_expr(&mut self, ex:@ast::Expr, e:@mut WbCtxt) { visit_expr(ex, (e, self)); }
-    fn visit_block(&mut self, b:&ast::Block, e:@mut WbCtxt) { visit_block(b, (e, self)); }
-    fn visit_pat(&mut self, p:@ast::Pat, e:@mut WbCtxt) { visit_pat(p, (e, self)); }
-    fn visit_local(&mut self, l:@ast::Local, e:@mut WbCtxt) { visit_local(l, (e, self)); }
+impl Visitor<()> for WbCtxt {
+    fn visit_item(&mut self, i:@ast::item, _:()) { visit_item(i, self); }
+    fn visit_stmt(&mut self, s:@ast::Stmt, _:()) { visit_stmt(s, self); }
+    fn visit_expr(&mut self, ex:@ast::Expr, _:()) { visit_expr(ex, self); }
+    fn visit_block(&mut self, b:&ast::Block, _:()) { visit_block(b, self); }
+    fn visit_pat(&mut self, p:@ast::Pat, _:()) { visit_pat(p, self); }
+    fn visit_local(&mut self, l:@ast::Local, _:()) { visit_local(l, self); }
 }
 
 pub fn resolve_type_vars_in_expr(fcx: @mut FnCtxt, e: @ast::Expr) -> bool {
-    let wbcx = @mut WbCtxt { fcx: fcx, success: true };
-    let mut visit = WbVisitor;
-    visit.visit_expr(e, wbcx);
+    let mut wbcx = WbCtxt { fcx: fcx, success: true };
+    let wbcx = &mut wbcx;
+    wbcx.visit_expr(e, ());
     return wbcx.success;
 }
 
@@ -340,16 +338,16 @@ pub fn resolve_type_vars_in_fn(fcx: @mut FnCtxt,
                                decl: &ast::fn_decl,
                                blk: &ast::Block,
                                self_info: Option<SelfInfo>) -> bool {
-    let wbcx = @mut WbCtxt { fcx: fcx, success: true };
-    let mut visit = WbVisitor;
-    visit.visit_block(blk, wbcx);
+    let mut wbcx = WbCtxt { fcx: fcx, success: true };
+    let wbcx = &mut wbcx;
+    wbcx.visit_block(blk, ());
     for self_info in self_info.iter() {
         resolve_type_vars_for_node(wbcx,
                                    self_info.span,
                                    self_info.self_id);
     }
     for arg in decl.inputs.iter() {
-        visit.visit_pat(arg.pat, wbcx);
+        wbcx.visit_pat(arg.pat, ());
         // Privacy needs the type for the whole pattern, not just each binding
         if !pat_util::pat_is_binding(fcx.tcx().def_map, arg.pat) {
             resolve_type_vars_for_node(wbcx, arg.pat.span, arg.pat.id);
diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs
index 8d7dbdf263e..45a65f954a3 100644
--- a/src/librustc/middle/typeck/mod.rs
+++ b/src/librustc/middle/typeck/mod.rs
@@ -402,8 +402,7 @@ fn check_start_fn_ty(ccx: &CrateCtxt,
                     bound_lifetime_names: opt_vec::Empty,
                     inputs: ~[
                         ty::mk_int(),
-                        ty::mk_imm_ptr(tcx, ty::mk_imm_ptr(tcx, ty::mk_u8())),
-                        ty::mk_imm_ptr(tcx, ty::mk_u8())
+                        ty::mk_imm_ptr(tcx, ty::mk_imm_ptr(tcx, ty::mk_u8()))
                     ],
                     output: ty::mk_int()
                 }
diff --git a/src/librustc/rustc.rs b/src/librustc/rustc.rs
index a90ab11535e..7599de1a9a3 100644
--- a/src/librustc/rustc.rs
+++ b/src/librustc/rustc.rs
@@ -33,6 +33,7 @@ use driver::driver::{compile_input};
 use driver::session;
 use middle::lint;
 
+use std::comm;
 use std::io;
 use std::num;
 use std::os;
@@ -43,6 +44,7 @@ use std::vec;
 use extra::getopts::groups;
 use extra::getopts;
 use syntax::codemap;
+use syntax::diagnostic::Emitter;
 use syntax::diagnostic;
 
 pub mod middle {
@@ -191,7 +193,7 @@ pub fn describe_debug_flags() {
     }
 }
 
-pub fn run_compiler(args: &[~str], demitter: diagnostic::Emitter) {
+pub fn run_compiler(args: &[~str], demitter: @diagnostic::Emitter) {
     // Don't display log spew by default. Can override with RUST_LOG.
     ::std::logging::console_off();
 
@@ -291,6 +293,23 @@ pub enum monitor_msg {
     done,
 }
 
+struct RustcEmitter {
+    ch_capture: comm::SharedChan<monitor_msg>
+}
+
+impl diagnostic::Emitter for RustcEmitter {
+    fn emit(&self,
+            cmsp: Option<(@codemap::CodeMap, codemap::Span)>,
+            msg: &str,
+            lvl: diagnostic::level) {
+        if lvl == diagnostic::fatal {
+            self.ch_capture.send(fatal)
+        }
+
+        diagnostic::DefaultEmitter.emit(cmsp, msg, lvl)
+    }
+}
+
 /*
 This is a sanity check that any failure of the compiler is performed
 through the diagnostic module and reported properly - we shouldn't be calling
@@ -303,7 +322,7 @@ diagnostic emitter which records when we hit a fatal error. If the task
 fails without recording a fatal error then we've encountered a compiler
 bug and need to present an error.
 */
-pub fn monitor(f: ~fn(diagnostic::Emitter)) {
+pub fn monitor(f: ~fn(@diagnostic::Emitter)) {
     use std::comm::*;
 
     // XXX: This is a hack for newsched since it doesn't support split stacks.
@@ -324,18 +343,11 @@ pub fn monitor(f: ~fn(diagnostic::Emitter)) {
 
     match do task_builder.try {
         let ch = ch_capture.clone();
-        let ch_capture = ch.clone();
         // The 'diagnostics emitter'. Every error, warning, etc. should
         // go through this function.
-        let demitter: @fn(Option<(@codemap::CodeMap, codemap::Span)>,
-                          &str,
-                          diagnostic::level) =
-                          |cmsp, msg, lvl| {
-            if lvl == diagnostic::fatal {
-                ch_capture.send(fatal);
-            }
-            diagnostic::emit(cmsp, msg, lvl);
-        };
+        let demitter = @RustcEmitter {
+            ch_capture: ch.clone(),
+        } as @diagnostic::Emitter;
 
         struct finally {
             ch: SharedChan<monitor_msg>,
@@ -357,7 +369,7 @@ pub fn monitor(f: ~fn(diagnostic::Emitter)) {
         result::Err(_) => {
             // Task failed without emitting a fatal diagnostic
             if p.recv() == done {
-                diagnostic::emit(
+                diagnostic::DefaultEmitter.emit(
                     None,
                     diagnostic::ice_msg("unexpected failure"),
                     diagnostic::error);
@@ -370,7 +382,9 @@ pub fn monitor(f: ~fn(diagnostic::Emitter)) {
                      to github.com/mozilla/rust/issues"
                 ];
                 for note in xs.iter() {
-                    diagnostic::emit(None, *note, diagnostic::note)
+                    diagnostic::DefaultEmitter.emit(None,
+                                                    *note,
+                                                    diagnostic::note)
                 }
             }
             // Fail so the process returns a failure code
@@ -380,13 +394,14 @@ pub fn monitor(f: ~fn(diagnostic::Emitter)) {
 }
 
 pub fn main() {
-    let args = os::args();
-    main_args(args);
+    std::os::set_exit_status(main_args(std::os::args()));
 }
 
-pub fn main_args(args: &[~str]) {
+pub fn main_args(args: &[~str]) -> int {
     let owned_args = args.to_owned();
     do monitor |demitter| {
         run_compiler(owned_args, demitter);
     }
+
+    return 0;
 }
diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs
index 46620319a82..8337354724a 100644
--- a/src/librustc/util/common.rs
+++ b/src/librustc/util/common.rs
@@ -60,12 +60,12 @@ pub fn field_exprs(fields: ~[ast::Field]) -> ~[@ast::Expr] {
     fields.map(|f| f.expr)
 }
 
-struct LoopQueryVisitor {
-    p: @fn(&ast::Expr_) -> bool
+struct LoopQueryVisitor<'self> {
+    p: &'self fn(&ast::Expr_) -> bool
 }
 
-impl Visitor<@mut bool> for LoopQueryVisitor {
-    fn visit_expr(&mut self, e:@ast::Expr, flag:@mut bool) {
+impl<'self> Visitor<@mut bool> for LoopQueryVisitor<'self> {
+    fn visit_expr(&mut self, e: @ast::Expr, flag: @mut bool) {
         *flag |= (self.p)(&e.node);
         match e.node {
           // Skip inner loops, since a break in the inner loop isn't a
@@ -78,19 +78,21 @@ impl Visitor<@mut bool> for LoopQueryVisitor {
 
 // Takes a predicate p, returns true iff p is true for any subexpressions
 // of b -- skipping any inner loops (loop, while, loop_body)
-pub fn loop_query(b: &ast::Block, p: @fn(&ast::Expr_) -> bool) -> bool {
+pub fn loop_query(b: &ast::Block, p: &fn(&ast::Expr_) -> bool) -> bool {
     let rs = @mut false;
-    let mut v = LoopQueryVisitor { p: p };
+    let mut v = LoopQueryVisitor {
+        p: p,
+    };
     visit::walk_block(&mut v, b, rs);
     return *rs;
 }
 
-struct BlockQueryVisitor {
-    p: @fn(@ast::Expr) -> bool
+struct BlockQueryVisitor<'self> {
+    p: &'self fn(@ast::Expr) -> bool
 }
 
-impl Visitor<@mut bool> for BlockQueryVisitor {
-    fn visit_expr(&mut self, e:@ast::Expr, flag:@mut bool) {
+impl<'self> Visitor<@mut bool> for BlockQueryVisitor<'self> {
+    fn visit_expr(&mut self, e: @ast::Expr, flag: @mut bool) {
         *flag |= (self.p)(e);
         visit::walk_expr(self, e, flag)
     }
@@ -98,9 +100,11 @@ impl Visitor<@mut bool> for BlockQueryVisitor {
 
 // Takes a predicate p, returns true iff p is true for any subexpressions
 // of b -- skipping any inner loops (loop, while, loop_body)
-pub fn block_query(b: &ast::Block, p: @fn(@ast::Expr) -> bool) -> bool {
+pub fn block_query(b: &ast::Block, p: &fn(@ast::Expr) -> bool) -> bool {
     let rs = @mut false;
-    let mut v = BlockQueryVisitor { p: p };
+    let mut v = BlockQueryVisitor {
+        p: p,
+    };
     visit::walk_block(&mut v, b, rs);
     return *rs;
 }
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 9fb5e8c04c1..8a7bb1f9346 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -11,9 +11,10 @@
 use rustc;
 use rustc::{driver, middle};
 
-use syntax;
-use syntax::parse;
 use syntax::ast;
+use syntax::diagnostic;
+use syntax::parse;
+use syntax;
 
 use std::os;
 use std::local_data;
@@ -48,9 +49,11 @@ fn get_ast_and_resolve(cpath: &Path, libs: ~[Path]) -> DocContext {
     let span_diagnostic_handler =
         syntax::diagnostic::mk_span_handler(diagnostic_handler, parsesess.cm);
 
-    let sess = driver::driver::build_session_(sessopts, parsesess.cm,
-                                                  syntax::diagnostic::emit,
-                                                  span_diagnostic_handler);
+    let sess = driver::driver::build_session_(sessopts,
+                                              parsesess.cm,
+                                              @diagnostic::DefaultEmitter as
+                                                @diagnostic::Emitter,
+                                              span_diagnostic_handler);
 
     let mut cfg = build_configuration(sess);
     cfg.push(@dummy_spanned(ast::MetaWord(@"stage2")));
diff --git a/src/librustdoc/rustdoc.rs b/src/librustdoc/rustdoc.rs
index bc7e6c8926d..c3d8cdf028e 100644
--- a/src/librustdoc/rustdoc.rs
+++ b/src/librustdoc/rustdoc.rs
@@ -52,7 +52,7 @@ enum OutputFormat {
 }
 
 pub fn main() {
-    main_args(std::os::args());
+    std::os::set_exit_status(main_args(std::os::args()));
 }
 
 pub fn opts() -> ~[groups::OptGroup] {
@@ -76,14 +76,14 @@ pub fn usage(argv0: &str) {
                                   argv0), opts()));
 }
 
-pub fn main_args(args: &[~str]) {
+pub fn main_args(args: &[~str]) -> int {
     //use extra::getopts::groups::*;
 
     let matches = groups::getopts(args.tail(), opts()).unwrap();
 
     if matches.opt_present("h") || matches.opt_present("help") {
         usage(args[0]);
-        return;
+        return 0;
     }
 
     let (format, cratefile) = match matches.free.clone() {
@@ -92,17 +92,17 @@ pub fn main_args(args: &[~str]) {
         [s, _] => {
             println!("Unknown output format: `{}`", s);
             usage(args[0]);
-            exit(1);
+            return 1;
         }
         [_, .._] => {
             println!("Expected exactly one crate to process");
             usage(args[0]);
-            exit(1);
+            return 1;
         }
         _ => {
             println!("Expected an output format and then one crate");
             usage(args[0]);
-            exit(1);
+            return 1;
         }
     };
 
@@ -179,6 +179,8 @@ pub fn main_args(args: &[~str]) {
     }
     let ended = time::precise_time_ns();
     info2!("Took {:.03f}s", (ended as f64 - started as f64) / 1000000000f64);
+
+    return 0;
 }
 
 fn jsonify(crate: clean::Crate, res: ~[plugins::PluginJson], dst: Path) {
@@ -208,9 +210,3 @@ fn jsonify(crate: clean::Crate, res: ~[plugins::PluginJson], dst: Path) {
     let output = extra::json::Object(json).to_str();
     file.write(output.as_bytes());
 }
-
-fn exit(status: int) -> ! {
-    #[fixed_stack_segment]; #[inline(never)];
-    use std::libc;
-    unsafe { libc::exit(status as libc::c_int) }
-}
diff --git a/src/librusti/rusti.rs b/src/librusti/rusti.rs
index 368596b3f44..eb94a112dd1 100644
--- a/src/librusti/rusti.rs
+++ b/src/librusti/rusti.rs
@@ -72,12 +72,14 @@ extern mod syntax;
 
 use std::{libc, io, os, task};
 use std::cell::Cell;
+use extra::rl::CompletionCb;
 use extra::rl;
 
 use rustc::driver::{driver, session};
 use rustc::back::link::jit;
-use syntax::{ast, diagnostic};
+use syntax::{ast, codemap, diagnostic};
 use syntax::ast_util::*;
+use syntax::diagnostic::Emitter;
 use syntax::parse::token;
 use syntax::print::pprust;
 
@@ -107,6 +109,28 @@ enum CmdAction {
     action_run_line(~str),
 }
 
+struct EncodableWarningEmitter;
+
+impl diagnostic::Emitter for EncodableWarningEmitter {
+    fn emit(&self,
+            cm: Option<(@codemap::CodeMap, codemap::Span)>,
+            msg: &str,
+            lvl: diagnostic::level) {
+        diagnostic::DefaultEmitter.emit(cm, msg, lvl);
+        if msg.contains("failed to find an implementation of trait") &&
+           msg.contains("extra::serialize::Encodable") {
+            diagnostic::DefaultEmitter.emit(cm,
+                                            "Currrently rusti serializes \
+                                             bound locals between different \
+                                             lines of input. This means that \
+                                             all values of local variables \
+                                             need to be encodable, and this \
+                                             type isn't encodable",
+                                            diagnostic::note);
+        }
+    }
+}
+
 /// Run an input string in a Repl, returning the new Repl.
 fn run(mut program: ~Program, binary: ~str, lib_search_paths: ~[~str],
        input: ~str) -> (~Program, Option<~jit::Engine>)
@@ -124,18 +148,9 @@ fn run(mut program: ~Program, binary: ~str, lib_search_paths: ~[~str],
     // extra helpful information if the error crops up. Otherwise people are
     // bound to be very confused when they find out code is running that they
     // never typed in...
-    let sess = driver::build_session(options, |cm, msg, lvl| {
-        diagnostic::emit(cm, msg, lvl);
-        if msg.contains("failed to find an implementation of trait") &&
-           msg.contains("extra::serialize::Encodable") {
-            diagnostic::emit(cm,
-                             "Currrently rusti serializes bound locals between \
-                              different lines of input. This means that all \
-                              values of local variables need to be encodable, \
-                              and this type isn't encodable",
-                             diagnostic::note);
-        }
-    });
+    let sess = driver::build_session(options,
+                                     @EncodableWarningEmitter as
+                                        @diagnostic::Emitter);
     let intr = token::get_ident_interner();
 
     //
@@ -243,7 +258,9 @@ fn run(mut program: ~Program, binary: ~str, lib_search_paths: ~[~str],
     let input = driver::str_input(code.to_managed());
     let cfg = driver::build_configuration(sess);
     let outputs = driver::build_output_filenames(&input, &None, &None, [], sess);
-    let sess = driver::build_session(options, diagnostic::emit);
+    let sess = driver::build_session(options,
+                                     @diagnostic::DefaultEmitter as
+                                        @diagnostic::Emitter);
 
     let crate = driver::phase_1_parse_input(sess, cfg.clone(), &input);
     let expanded_crate = driver::phase_2_configure_and_expand(sess, cfg, crate);
@@ -305,7 +322,9 @@ fn compile_crate(src_filename: ~str, binary: ~str) -> Option<bool> {
             .. (*session::basic_options()).clone()
         };
         let input = driver::file_input(src_path.clone());
-        let sess = driver::build_session(options, diagnostic::emit);
+        let sess = driver::build_session(options,
+                                         @diagnostic::DefaultEmitter as
+                                            @diagnostic::Emitter);
         *sess.building_library = true;
         let cfg = driver::build_configuration(sess);
         let outputs = driver::build_output_filenames(
@@ -498,11 +517,23 @@ pub fn run_line(repl: &mut Repl, input: @io::Reader, out: @io::Writer, line: ~st
 }
 
 pub fn main() {
-    let args = os::args();
-    main_args(args);
+    os::set_exit_status(main_args(os::args()));
+}
+
+struct Completer;
+
+impl CompletionCb for Completer {
+    fn complete(&self, line: ~str, suggest: &fn(~str)) {
+        if line.starts_with(":") {
+            suggest(~":clear");
+            suggest(~":exit");
+            suggest(~":help");
+            suggest(~":load");
+        }
+    }
 }
 
-pub fn main_args(args: &[~str]) {
+pub fn main_args(args: &[~str]) -> int {
     #[fixed_stack_segment]; #[inline(never)];
 
     let input = io::stdin();
@@ -525,13 +556,8 @@ pub fn main_args(args: &[~str]) {
         println("unstable. If you encounter problems, please use the");
         println("compiler instead. Type :help for help.");
 
-        do rl::complete |line, suggest| {
-            if line.starts_with(":") {
-                suggest(~":clear");
-                suggest(~":exit");
-                suggest(~":help");
-                suggest(~":load");
-            }
+        unsafe {
+            rl::complete(@Completer as @CompletionCb)
         }
     }
 
@@ -549,6 +575,8 @@ pub fn main_args(args: &[~str]) {
             }
         }
     }
+
+    return 0;
 }
 
 #[cfg(test)]
diff --git a/src/librusti/utils.rs b/src/librusti/utils.rs
index 400399253a5..904594fdfb8 100644
--- a/src/librusti/utils.rs
+++ b/src/librusti/utils.rs
@@ -15,11 +15,11 @@ use syntax::print::pprust;
 use syntax::parse::token;
 use syntax::visit;
 
-struct EachBindingVisitor {
-    f: @fn(&ast::Path, ast::NodeId)
+struct EachBindingVisitor<'self> {
+    f: &'self fn(&ast::Path, ast::NodeId)
 }
 
-impl visit::Visitor<()> for EachBindingVisitor {
+impl<'self> visit::Visitor<()> for EachBindingVisitor<'self> {
     fn visit_pat(&mut self, pat:@ast::Pat, _:()) {
                 match pat.node {
                     ast::PatIdent(_, ref path, _) => {
@@ -32,7 +32,7 @@ impl visit::Visitor<()> for EachBindingVisitor {
     }
 }
 
-pub fn each_binding(l: @ast::Local, f: @fn(&ast::Path, ast::NodeId)) {
+pub fn each_binding(l: @ast::Local, f: &fn(&ast::Path, ast::NodeId)) {
     use syntax::visit::Visitor;
 
     let mut vt = EachBindingVisitor{ f: f };
diff --git a/src/librustpkg/rustpkg.rs b/src/librustpkg/rustpkg.rs
index 077d1cf02f8..c10ea2fb424 100644
--- a/src/librustpkg/rustpkg.rs
+++ b/src/librustpkg/rustpkg.rs
@@ -110,7 +110,9 @@ impl<'self> PkgScript<'self> {
             .. (*session::basic_options()).clone()
         };
         let input = driver::file_input(script.clone());
-        let sess = driver::build_session(options, diagnostic::emit);
+        let sess = driver::build_session(options,
+                                         @diagnostic::DefaultEmitter as
+                                            @diagnostic::Emitter);
         let cfg = driver::build_configuration(sess);
         let crate = driver::phase_1_parse_input(sess, cfg.clone(), &input);
         let crate = driver::phase_2_configure_and_expand(sess, cfg.clone(), crate);
@@ -613,11 +615,10 @@ impl CtxMethods for BuildContext {
 
 pub fn main() {
     io::println("WARNING: The Rust package manager is experimental and may be unstable");
-    let args = os::args();
-    main_args(args);
+    os::set_exit_status(main_args(os::args()));
 }
 
-pub fn main_args(args: &[~str]) {
+pub fn main_args(args: &[~str]) -> int {
     let opts = ~[getopts::optflag("h"), getopts::optflag("help"),
                                         getopts::optflag("no-link"),
                                         getopts::optflag("no-trans"),
@@ -643,7 +644,7 @@ pub fn main_args(args: &[~str]) {
         result::Err(f) => {
             error(fmt!("%s", f.to_err_msg()));
 
-            return;
+            return 1;
         }
     };
     let mut help = matches.opt_present("h") ||
@@ -660,7 +661,7 @@ pub fn main_args(args: &[~str]) {
     if matches.opt_present("v") ||
        matches.opt_present("version") {
         rustc::version(args[0]);
-        return;
+        return 0;
     }
 
     let use_rust_path_hack = matches.opt_present("r") ||
@@ -699,7 +700,8 @@ pub fn main_args(args: &[~str]) {
     args.shift();
 
     if (args.len() < 1) {
-        return usage::general();
+        usage::general();
+        return 1;
     }
 
     let rustc_flags = RustcFlags {
@@ -737,11 +739,14 @@ pub fn main_args(args: &[~str]) {
         }
     }
     let cmd = match cmd_opt {
-        None => return usage::general(),
+        None => {
+            usage::general();
+            return 0;
+        }
         Some(cmd) => {
             help |= context::flags_ok_for_cmd(&rustc_flags, cfgs, *cmd, user_supplied_opt_level);
             if help {
-                return match *cmd {
+                match *cmd {
                     ~"build" => usage::build(),
                     ~"clean" => usage::clean(),
                     ~"do" => usage::do_cmd(),
@@ -755,6 +760,7 @@ pub fn main_args(args: &[~str]) {
                     ~"unprefer" => usage::unprefer(),
                     _ => usage::general()
                 };
+                return 0;
             } else {
                 cmd
             }
@@ -792,8 +798,8 @@ pub fn main_args(args: &[~str]) {
     // and at least one test case succeeds if rustpkg returns COPY_FAILED_CODE,
     // when actually, it might set the exit code for that even if a different
     // unhandled condition got raised.
-    if result.is_err() { os::set_exit_status(COPY_FAILED_CODE); }
-
+    if result.is_err() { return COPY_FAILED_CODE; }
+    return 0;
 }
 
 /**
diff --git a/src/librustpkg/tests.rs b/src/librustpkg/tests.rs
index a0e9e49e507..79f137de853 100644
--- a/src/librustpkg/tests.rs
+++ b/src/librustpkg/tests.rs
@@ -985,6 +985,7 @@ fn no_rebuilding_dep() {
 }
 
 #[test]
+#[ignore]
 fn do_rebuild_dep_dates_change() {
     let p_id = PkgId::new("foo");
     let dep_id = PkgId::new("bar");
@@ -1001,6 +1002,7 @@ fn do_rebuild_dep_dates_change() {
 }
 
 #[test]
+#[ignore]
 fn do_rebuild_dep_only_contents_change() {
     let p_id = PkgId::new("foo");
     let dep_id = PkgId::new("bar");
@@ -1565,8 +1567,11 @@ fn test_linker_build() {
     let matches = getopts([], optgroups());
     let options = build_session_options(@"rustpkg",
                                         matches.get_ref(),
-                                        diagnostic::emit);
-    let sess = build_session(options, diagnostic::emit);
+                                        @diagnostic::DefaultEmitter as
+                                            @diagnostic::Emitter);
+    let sess = build_session(options,
+                             @diagnostic::DefaultEmitter as
+                                @diagnostic::Emitter);
     command_line_test([test_sysroot().to_str(),
                        ~"install",
                        ~"--linker",
diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs
index 906bed2f234..5d5e895a5ad 100644
--- a/src/librustpkg/util.rs
+++ b/src/librustpkg/util.rs
@@ -16,8 +16,11 @@ use extra::getopts::groups::getopts;
 use syntax::ast_util::*;
 use syntax::codemap::{dummy_sp, Spanned};
 use syntax::ext::base::ExtCtxt;
-use syntax::{ast, attr, codemap, diagnostic, fold};
+use syntax::{ast, attr, codemap, diagnostic, fold, visit};
 use syntax::attr::AttrMetaMethods;
+use syntax::fold::ast_fold;
+use syntax::visit::Visitor;
+use rustc::back::link::output_type_exe;
 use rustc::back::link;
 use rustc::driver::session::{lib_crate, bin_crate};
 use context::{in_target, StopBefore, Link, Assemble, BuildContext};
@@ -26,6 +29,7 @@ use package_source::PkgSrc;
 use workspace::pkg_parent_workspaces;
 use path_util::{installed_library_in_workspace, U_RWX, rust_path, system_library, target_build_dir};
 use messages::error;
+use conditions::nonexistent_package::cond;
 
 pub use target::{OutputType, Main, Lib, Bench, Test, JustOne, lib_name_of, lib_crate_filename};
 use workcache_support::{digest_file_with_date, digest_only_date};
@@ -70,9 +74,8 @@ struct ReadyCtx {
     fns: ~[ListenerFn]
 }
 
-fn fold_mod(_ctx: @mut ReadyCtx,
-            m: &ast::_mod,
-            fold: @fold::ast_fold) -> ast::_mod {
+fn fold_mod(_ctx: @mut ReadyCtx, m: &ast::_mod, fold: &CrateSetup)
+            -> ast::_mod {
     fn strip_main(item: @ast::item) -> @ast::item {
         @ast::item {
             attrs: do item.attrs.iter().filter_map |attr| {
@@ -94,9 +97,8 @@ fn fold_mod(_ctx: @mut ReadyCtx,
     }, fold)
 }
 
-fn fold_item(ctx: @mut ReadyCtx,
-             item: @ast::item,
-             fold: @fold::ast_fold) -> Option<@ast::item> {
+fn fold_item(ctx: @mut ReadyCtx, item: @ast::item, fold: &CrateSetup)
+             -> Option<@ast::item> {
     ctx.path.push(item.ident);
 
     let mut cmds = ~[];
@@ -134,6 +136,19 @@ fn fold_item(ctx: @mut ReadyCtx,
     res
 }
 
+struct CrateSetup {
+    ctx: @mut ReadyCtx,
+}
+
+impl fold::ast_fold for CrateSetup {
+    fn fold_item(&self, item: @ast::item) -> Option<@ast::item> {
+        fold_item(self.ctx, item, self)
+    }
+    fn fold_mod(&self, module: &ast::_mod) -> ast::_mod {
+        fold_mod(self.ctx, module, self)
+    }
+}
+
 /// Generate/filter main function, add the list of commands, etc.
 pub fn ready_crate(sess: session::Session,
                    crate: @ast::Crate) -> @ast::Crate {
@@ -144,15 +159,9 @@ pub fn ready_crate(sess: session::Session,
         path: ~[],
         fns: ~[]
     };
-    let precursor = @fold::AstFoldFns {
-        // fold_crate: fold::wrap(|a, b| fold_crate(ctx, a, b)),
-        fold_item: |a, b| fold_item(ctx, a, b),
-        fold_mod: |a, b| fold_mod(ctx, a, b),
-        .. *fold::default_ast_fold()
+    let fold = CrateSetup {
+        ctx: ctx,
     };
-
-    let fold = fold::make_fold(precursor);
-
     @fold.fold_crate(crate)
 }
 
@@ -225,7 +234,10 @@ pub fn compile_input(context: &BuildContext,
         maybe_sysroot: Some(sysroot_to_use),
         addl_lib_search_paths: @mut (~[]),
         output_type: output_type,
-        .. (*driver::build_session_options(binary, &matches, diagnostic::emit)).clone()
+        .. (*driver::build_session_options(binary,
+                                           &matches,
+                                           @diagnostic::DefaultEmitter as
+                                            @diagnostic::Emitter)).clone()
     };
 
     let addl_lib_search_paths = @mut options.addl_lib_search_paths;
@@ -240,7 +252,9 @@ pub fn compile_input(context: &BuildContext,
         }
     }
 
-    let sess = driver::build_session(options, diagnostic::emit);
+    let sess = driver::build_session(options,
+                                     @diagnostic::DefaultEmitter as
+                                        @diagnostic::Emitter);
 
     // Infer dependencies that rustpkg needs to build, by scanning for
     // `extern mod` directives.
@@ -383,31 +397,28 @@ pub fn compile_crate(ctxt: &BuildContext,
     compile_input(ctxt, exec, pkg_id, crate, workspace, flags, cfgs, opt, what)
 }
 
+struct ViewItemVisitor<'self> {
+    context: &'self BuildContext,
+    parent: &'self PkgId,
+    sess: session::Session,
+    exec: &'self mut workcache::Exec,
+    c: &'self ast::Crate,
+    save: &'self fn(Path),
+}
 
-/// Collect all `extern mod` directives in `c`, then
-/// try to install their targets, failing if any target
-/// can't be found.
-pub fn find_and_install_dependencies(context: &BuildContext,
-                                     parent: &PkgId,
-                                     sess: session::Session,
-                                     exec: &mut workcache::Exec,
-                                     c: &ast::Crate,
-                                     save: @fn(Path)
-                                     ) {
-    use conditions::nonexistent_package::cond;
-
-    do c.each_view_item() |vi: &ast::view_item| {
+impl<'self> Visitor<()> for ViewItemVisitor<'self> {
+    fn visit_view_item(&mut self, vi: &ast::view_item, env: ()) {
         debug!("A view item!");
         match vi.node {
             // ignore metadata, I guess
             ast::view_item_extern_mod(lib_ident, path_opt, _, _) => {
                 let lib_name = match path_opt {
                     Some(p) => p,
-                    None => sess.str_of(lib_ident)
+                    None => self.sess.str_of(lib_ident)
                 };
                 debug!("Finding and installing... %s", lib_name);
                 // Check standard Rust library path first
-                match system_library(&context.sysroot(), lib_name) {
+                match system_library(&self.context.sysroot(), lib_name) {
                     Some(ref installed_path) => {
                         debug!("It exists: %s", installed_path.to_str());
                         // Say that [path for c] has a discovered dependency on
@@ -416,8 +427,9 @@ pub fn find_and_install_dependencies(context: &BuildContext,
                         // I'm not sure what the right thing is.
                         // Now we know that this crate has a discovered dependency on
                         // installed_path
-                        exec.discover_input("binary", installed_path.to_str(),
-                                                      digest_only_date(installed_path));
+                        self.exec.discover_input("binary",
+                                                 installed_path.to_str(),
+                                                 digest_only_date(installed_path));
                     }
                     None => {
                         // FIXME #8711: need to parse version out of path_opt
@@ -425,35 +437,44 @@ pub fn find_and_install_dependencies(context: &BuildContext,
                                lib_name.to_str());
                         // Try to install it
                         let pkg_id = PkgId::new(lib_name);
-                        let workspaces = pkg_parent_workspaces(&context.context, &pkg_id);
+                        let workspaces = pkg_parent_workspaces(&self.context.context,
+                                                               &pkg_id);
                         let dep_workspace = if workspaces.is_empty() {
                             error(fmt!("Couldn't find package %s, which is needed by %s, \
                                             in any of the workspaces in the RUST_PATH (%?)",
-                                            lib_name, parent.to_str(), rust_path()));
+                                            lib_name,
+                                            self.parent.to_str(),
+                                            rust_path()));
                             cond.raise((pkg_id.clone(), ~"Dependency not found"))
                         }
                         else {
                             workspaces[0]
                         };
                         let (outputs_disc, inputs_disc) =
-                            context.install(PkgSrc::new(dep_workspace.clone(),
-                                false, pkg_id), &JustOne(Path(lib_crate_filename)));
+                            self.context.install(PkgSrc::new(dep_workspace.clone(),
+                                                             false,
+                                                             pkg_id),
+                                                 &JustOne(Path(
+                                                    lib_crate_filename)));
                         debug!("Installed %s, returned %? dependencies and \
                                %? transitive dependencies",
                                lib_name, outputs_disc.len(), inputs_disc.len());
                         for dep in outputs_disc.iter() {
                             debug!("Discovering a binary input: %s", dep.to_str());
-                            exec.discover_input("binary", dep.to_str(),
-                                                digest_only_date(dep));
+                            self.exec.discover_input("binary",
+                                                     dep.to_str(),
+                                                     digest_only_date(dep));
                         }
                         for &(ref what, ref dep) in inputs_disc.iter() {
                             if *what == ~"file" {
-                                exec.discover_input(*what, *dep,
-                                                    digest_file_with_date(&Path(*dep)));
+                                self.exec.discover_input(*what,
+                                                         *dep,
+                                                         digest_file_with_date(&Path(*dep)));
                             }
                             else if *what == ~"binary" {
-                                exec.discover_input(*what, *dep,
-                                                    digest_only_date(&Path(*dep)));
+                                self.exec.discover_input(*what,
+                                                         *dep,
+                                                         digest_only_date(&Path(*dep)));
                             }
                             else {
                                 fail!("Bad kind: %s", *what);
@@ -468,14 +489,36 @@ pub fn find_and_install_dependencies(context: &BuildContext,
                         let install_dir = installed_library.pop();
                         debug!("Installed %s into %s [%?]", lib_name, install_dir.to_str(),
                                datestamp(&installed_library));
-                        save(install_dir);
+                        (self.save)(install_dir);
                     }
                 }}
             // Ignore `use`s
             _ => ()
         }
-        true
+
+        visit::walk_view_item(self, vi, env)
+    }
+}
+
+/// Collect all `extern mod` directives in `c`, then
+/// try to install their targets, failing if any target
+/// can't be found.
+pub fn find_and_install_dependencies(context: &BuildContext,
+                                     parent: &PkgId,
+                                     sess: session::Session,
+                                     exec: &mut workcache::Exec,
+                                     c: &ast::Crate,
+                                     save: &fn(Path)) {
+    debug!("In find_and_install_dependencies...");
+    let mut visitor = ViewItemVisitor {
+        context: context,
+        parent: parent,
+        sess: sess,
+        exec: exec,
+        c: c,
+        save: save,
     };
+    visit::walk_crate(&mut visitor, c, ())
 }
 
 pub fn mk_string_lit(s: @str) -> ast::lit {
diff --git a/src/libstd/io.rs b/src/libstd/io.rs
index 890a53690d9..ab8af22e116 100644
--- a/src/libstd/io.rs
+++ b/src/libstd/io.rs
@@ -1846,31 +1846,38 @@ pub mod fsync {
     pub struct Arg<t> {
         val: t,
         opt_level: Option<Level>,
-        fsync_fn: @fn(f: &t, Level) -> int,
+        fsync_fn: extern "Rust" fn(f: &t, Level) -> int,
     }
 
     // fsync file after executing blk
     // FIXME (#2004) find better way to create resources within lifetime of
     // outer res
-    pub fn FILE_res_sync(file: &FILERes, opt_level: Option<Level>,
+    pub fn FILE_res_sync(file: &FILERes,
+                         opt_level: Option<Level>,
                          blk: &fn(v: Res<*libc::FILE>)) {
         blk(Res::new(Arg {
-            val: file.f, opt_level: opt_level,
-            fsync_fn: |file, l| fsync_fd(fileno(*file), l)
+            val: file.f,
+            opt_level: opt_level,
+            fsync_fn: fsync_FILE,
         }));
 
         fn fileno(stream: *libc::FILE) -> libc::c_int {
             #[fixed_stack_segment]; #[inline(never)];
             unsafe { libc::fileno(stream) }
         }
+
+        fn fsync_FILE(stream: &*libc::FILE, level: Level) -> int {
+            fsync_fd(fileno(*stream), level)
+        }
     }
 
     // fsync fd after executing blk
     pub fn fd_res_sync(fd: &FdRes, opt_level: Option<Level>,
                        blk: &fn(v: Res<fd_t>)) {
         blk(Res::new(Arg {
-            val: fd.fd, opt_level: opt_level,
-            fsync_fn: |fd, l| fsync_fd(*fd, l)
+            val: fd.fd,
+            opt_level: opt_level,
+            fsync_fn: fsync_fd_helper,
         }));
     }
 
@@ -1880,6 +1887,10 @@ pub mod fsync {
         os::fsync_fd(fd, level) as int
     }
 
+    fn fsync_fd_helper(fd_ptr: &libc::c_int, level: Level) -> int {
+        fsync_fd(*fd_ptr, level)
+    }
+
     // Type of objects that may want to fsync
     pub trait FSyncable { fn fsync(&self, l: Level) -> int; }
 
@@ -1887,10 +1898,15 @@ pub mod fsync {
     pub fn obj_sync(o: @FSyncable, opt_level: Option<Level>,
                     blk: &fn(v: Res<@FSyncable>)) {
         blk(Res::new(Arg {
-            val: o, opt_level: opt_level,
-            fsync_fn: |o, l| (*o).fsync(l)
+            val: o,
+            opt_level: opt_level,
+            fsync_fn: obj_fsync_fn,
         }));
     }
+
+    fn obj_fsync_fn(o: &@FSyncable, level: Level) -> int {
+        (*o).fsync(level)
+    }
 }
 
 #[cfg(test)]
diff --git a/src/libstd/local_data.rs b/src/libstd/local_data.rs
index 89bdb57e2bd..9c4e5ba60df 100644
--- a/src/libstd/local_data.rs
+++ b/src/libstd/local_data.rs
@@ -25,8 +25,8 @@ modify/read the slot specified by the key.
 ~~~{.rust}
 use std::local_data;
 
-local_data_key!(key_int: int);
-local_data_key!(key_vector: ~[int]);
+local_data_key!(key_int: int)
+local_data_key!(key_vector: ~[int])
 
 local_data::set(key_int, 3);
 local_data::get(key_int, |opt| assert_eq!(opt, Some(&3)));
@@ -72,7 +72,7 @@ impl<T: 'static> LocalData for T {}
 //
 // One of the most important operations is loaning a value via `get` to a
 // caller. In doing so, the slot that the TLS entry is occupying cannot be
-// invalidated because upon returning it's loan state must be updated. Currently
+// invalidated because upon returning its loan state must be updated. Currently
 // the TLS map is a vector, but this is possibly dangerous because the vector
 // can be reallocated/moved when new values are pushed onto it.
 //
diff --git a/src/libstd/reflect.rs b/src/libstd/reflect.rs
index 91e3719e3d0..833a9f5ed82 100644
--- a/src/libstd/reflect.rs
+++ b/src/libstd/reflect.rs
@@ -485,9 +485,11 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
     }
 
     fn visit_closure_ptr(&mut self, ck: uint) -> bool {
-        self.align_to::<@fn()>();
-        if ! self.inner.visit_closure_ptr(ck) { return false; }
-        self.bump_past::<@fn()>();
+        self.align_to::<~fn()>();
+        if ! self.inner.visit_closure_ptr(ck) {
+            return false
+        }
+        self.bump_past::<~fn()>();
         true
     }
 }
diff --git a/src/test/run-pass/fn-assign-managed-to-bare-2.rs b/src/libstd/routine.rs
index f8daacfa233..e8a91b49c8e 100644
--- a/src/test/run-pass/fn-assign-managed-to-bare-2.rs
+++ b/src/libstd/routine.rs
@@ -8,21 +8,21 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn add(n: int) -> @fn(int) -> int {
-    let result: @fn(int) -> int = |m| m + n;
-    result
-}
-
-pub fn main()
-{
-    assert_eq!(add(3)(4), 7);
+/*!
+ * Routines are like closures except that they own their arguments and can
+ * only run once.
+ */
 
-    let add1 : @fn(int)->int = add(1);
-    assert_eq!(add1(6), 7);
+/// A routine that takes no arguments and returns nothing.
+pub trait Runnable {
+    /// The entry point for the routine.
+    fn run(~self);
+}
 
-    let add2 : &(@fn(int)->int) = &add(2);
-    assert_eq!((*add2)(5), 7);
+/// A convenience routine that does nothing.
+pub struct NoOpRunnable;
 
-    let add3 : &fn(int)->int = add(3);
-    assert_eq!(add3(4), 7);
+impl Runnable for NoOpRunnable {
+    fn run(~self) {}
 }
+
diff --git a/src/libstd/rt/crate_map.rs b/src/libstd/rt/crate_map.rs
index 270b5e5b137..57abb7560a1 100644
--- a/src/libstd/rt/crate_map.rs
+++ b/src/libstd/rt/crate_map.rs
@@ -9,14 +9,29 @@
 // except according to those terms.
 
 
-use libc::{c_void, c_char};
+use libc::c_char;
+#[cfg(stage0)] use libc::c_void;
 use ptr;
 use ptr::RawPtr;
 use vec;
 use hashmap::HashSet;
 use container::MutableSet;
 
-pub struct ModEntry{
+// Need to tell the linker on OS X to not barf on undefined symbols
+// and instead look them up at runtime, which we need to resolve
+// the crate_map properly.
+#[cfg(target_os = "macos")]
+#[link_args = "-undefined dynamic_lookup"]
+extern {}
+
+#[cfg(not(windows))]
+extern {
+    #[weak_linkage]
+    #[link_name = "_rust_crate_map_toplevel"]
+    static CRATE_MAP: CrateMap;
+}
+
+pub struct ModEntry {
     name: *c_char,
     log_level: *mut u32
 }
@@ -25,6 +40,7 @@ struct CrateMapV0 {
     children: [*CrateMap, ..1]
 }
 
+#[cfg(stage0)]
 struct CrateMap {
     version: i32,
     annihilate_fn: *c_void,
@@ -34,6 +50,39 @@ struct CrateMap {
     children: [*CrateMap, ..1]
 }
 
+#[cfg(not(stage0))]
+struct CrateMap {
+    version: i32,
+    entries: *ModEntry,
+    /// a dynamically sized struct, where all pointers to children are listed adjacent
+    /// to the struct, terminated with NULL
+    children: [*CrateMap, ..1]
+}
+
+#[cfg(not(windows))]
+pub fn get_crate_map() -> *CrateMap {
+    &'static CRATE_MAP as *CrateMap
+}
+
+#[cfg(windows)]
+#[fixed_stack_segment]
+#[inline(never)]
+pub fn get_crate_map() -> *CrateMap {
+    use c_str::ToCStr;
+    use unstable::dynamic_lib::dl;
+
+    let sym = unsafe {
+        let module = dl::open_internal();
+        let sym = do "__rust_crate_map_toplevel".with_c_str |buf| {
+            dl::symbol(module, buf)
+        };
+        dl::close(module);
+        sym
+    };
+
+    sym as *CrateMap
+}
+
 unsafe fn version(crate_map: *CrateMap) -> i32 {
     match (*crate_map).version {
         1 => return 1,
@@ -41,15 +90,6 @@ unsafe fn version(crate_map: *CrateMap) -> i32 {
     }
 }
 
-/// Returns a pointer to the annihilate function of the CrateMap
-pub unsafe fn annihilate_fn(crate_map: *CrateMap) -> *c_void {
-    match version(crate_map) {
-        0 => return ptr::null(),
-        1 => return (*crate_map).annihilate_fn,
-        _ => fail!("Unknown crate map version!")
-    }
-}
-
 unsafe fn entries(crate_map: *CrateMap) -> *ModEntry {
     match version(crate_map) {
         0 => {
@@ -107,7 +147,6 @@ fn iter_crate_map_duplicates() {
 
     struct CrateMapT3 {
         version: i32,
-        annihilate_fn: *c_void,
         entries: *ModEntry,
         children: [*CrateMap, ..3]
     }
@@ -122,13 +161,12 @@ fn iter_crate_map_duplicates() {
         ];
         let child_crate = CrateMap {
             version: 1,
-            annihilate_fn: ptr::null(),
             entries: vec::raw::to_ptr(entries),
             children: [ptr::null()]
         };
 
         let root_crate = CrateMapT3 {
-            version: 1, annihilate_fn: ptr::null(),
+            version: 1,
             entries: vec::raw::to_ptr([ModEntry { name: ptr::null(), log_level: ptr::mut_null()}]),
             children: [&child_crate as *CrateMap, &child_crate as *CrateMap, ptr::null()]
         };
@@ -149,7 +187,6 @@ fn iter_crate_map_follow_children() {
 
     struct CrateMapT2 {
         version: i32,
-        annihilate_fn: *c_void,
         entries: *ModEntry,
         children: [*CrateMap, ..2]
     }
@@ -161,7 +198,6 @@ fn iter_crate_map_follow_children() {
         let mut level3: u32 = 3;
         let child_crate2 = CrateMap {
             version: 1,
-            annihilate_fn: ptr::null(),
             entries: vec::raw::to_ptr([
                 ModEntry { name: mod_name1.with_ref(|buf| buf), log_level: &mut level2},
                 ModEntry { name: mod_name2.with_ref(|buf| buf), log_level: &mut level3},
@@ -172,7 +208,6 @@ fn iter_crate_map_follow_children() {
 
         let child_crate1 = CrateMapT2 {
             version: 1,
-            annihilate_fn: ptr::null(),
             entries: vec::raw::to_ptr([
                 ModEntry { name: "t::f1".to_c_str().with_ref(|buf| buf), log_level: &mut 1},
                 ModEntry { name: ptr::null(), log_level: ptr::mut_null()}
@@ -182,7 +217,7 @@ fn iter_crate_map_follow_children() {
 
         let child_crate1_ptr: *CrateMap = transmute(&child_crate1);
         let root_crate = CrateMapT2 {
-            version: 1, annihilate_fn: ptr::null(),
+            version: 1,
             entries: vec::raw::to_ptr([
                 ModEntry { name: "t::f1".to_c_str().with_ref(|buf| buf), log_level: &mut 0},
                 ModEntry { name: ptr::null(), log_level: ptr::mut_null()}
diff --git a/src/libstd/rt/io/mod.rs b/src/libstd/rt/io/mod.rs
index 6b405b0948a..70fcf442f3f 100644
--- a/src/libstd/rt/io/mod.rs
+++ b/src/libstd/rt/io/mod.rs
@@ -472,7 +472,7 @@ pub trait Writer {
 
 pub trait Stream: Reader + Writer { }
 
-impl<T: Reader + Writer> Stream for T;
+impl<T: Reader + Writer> Stream for T {}
 
 pub enum SeekStyle {
     /// Seek from the beginning of the stream
diff --git a/src/libstd/rt/logging.rs b/src/libstd/rt/logging.rs
index fbe05267cf4..3dbf7a918b7 100644
--- a/src/libstd/rt/logging.rs
+++ b/src/libstd/rt/logging.rs
@@ -12,6 +12,7 @@ use libc::{uintptr_t, exit, STDERR_FILENO};
 use option::{Some, None, Option};
 use rt::util::dumb_println;
 use rt::crate_map::{ModEntry, iter_crate_map};
+use rt::crate_map::get_crate_map;
 use str::StrSlice;
 use str::raw::from_c_str;
 use u32;
@@ -210,10 +211,11 @@ impl Logger for StdErrLogger {
 }
 /// Configure logging by traversing the crate map and setting the
 /// per-module global logging flags based on the logging spec
-#[fixed_stack_segment] #[inline(never)]
-pub fn init(crate_map: *u8) {
+pub fn init() {
     use os;
 
+    let crate_map = get_crate_map() as *u8;
+
     let log_spec = os::getenv("RUST_LOG");
     match log_spec {
         Some(spec) => {
diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs
index df59e5538b4..2ece2800cf2 100644
--- a/src/libstd/rt/mod.rs
+++ b/src/libstd/rt/mod.rs
@@ -172,14 +172,13 @@ pub mod borrowck;
 ///
 /// * `argc` & `argv` - The argument vector. On Unix this information is used
 ///   by os::args.
-/// * `crate_map` - Runtime information about the executing crate, mostly for logging
 ///
 /// # Return value
 ///
 /// The return value is used as the process return code. 0 on success, 101 on error.
-pub fn start(argc: int, argv: **u8, crate_map: *u8, main: ~fn()) -> int {
+pub fn start(argc: int, argv: **u8, main: ~fn()) -> int {
 
-    init(argc, argv, crate_map);
+    init(argc, argv);
     let exit_code = run(main);
     cleanup();
 
@@ -191,8 +190,8 @@ pub fn start(argc: int, argv: **u8, crate_map: *u8, main: ~fn()) -> int {
 ///
 /// This is appropriate for running code that must execute on the main thread,
 /// such as the platform event loop and GUI.
-pub fn start_on_main_thread(argc: int, argv: **u8, crate_map: *u8, main: ~fn()) -> int {
-    init(argc, argv, crate_map);
+pub fn start_on_main_thread(argc: int, argv: **u8, main: ~fn()) -> int {
+    init(argc, argv);
     let exit_code = run_on_main_thread(main);
     cleanup();
 
@@ -204,13 +203,13 @@ pub fn start_on_main_thread(argc: int, argv: **u8, crate_map: *u8, main: ~fn())
 /// Initializes global state, including frobbing
 /// the crate's logging flags, registering GC
 /// metadata, and storing the process arguments.
-pub fn init(argc: int, argv: **u8, crate_map: *u8) {
+pub fn init(argc: int, argv: **u8) {
     // XXX: Derefing these pointers is not safe.
     // Need to propagate the unsafety to `start`.
     unsafe {
         args::init(argc, argv);
         env::init();
-        logging::init(crate_map);
+        logging::init();
     }
 }
 
diff --git a/src/libstd/rt/uv/file.rs b/src/libstd/rt/uv/file.rs
index ada558036cf..54cb40c9873 100644
--- a/src/libstd/rt/uv/file.rs
+++ b/src/libstd/rt/uv/file.rs
@@ -22,7 +22,7 @@ use libc::{c_int};
 use option::{None, Some, Option};
 
 pub struct FsRequest(*uvll::uv_fs_t);
-impl Request for FsRequest;
+impl Request for FsRequest {}
 
 pub struct RequestData {
     complete_cb: Option<FsCallback>
diff --git a/src/libstd/std.rs b/src/libstd/std.rs
index f7b55e977e0..5c1bac7418e 100644
--- a/src/libstd/std.rs
+++ b/src/libstd/std.rs
@@ -189,7 +189,7 @@ pub mod reflect;
 pub mod condition;
 pub mod logging;
 pub mod util;
-
+pub mod routine;
 
 /* Unsupported interfaces */
 
diff --git a/src/libstd/str.rs b/src/libstd/str.rs
index db4fe5fc762..c94d8f366a6 100644
--- a/src/libstd/str.rs
+++ b/src/libstd/str.rs
@@ -78,8 +78,8 @@ assert_eq!(buf, ~"testing 123");
 
 Rust's string type, `str`, is a sequence of unicode codepoints encoded as a
 stream of UTF-8 bytes. All safely-created strings are guaranteed to be validly
-encoded UTF-8 sequences. Additionally, strings are not guaranteed to be
-null-terminated (the null byte is a valid unicode codepoint).
+encoded UTF-8 sequences. Additionally, strings are not null-terminated
+and can contain null codepoints.
 
 The actual representation of strings have direct mappings to vectors:
 
diff --git a/src/libstd/unstable/dynamic_lib.rs b/src/libstd/unstable/dynamic_lib.rs
index 4c92d9c2e36..41ff79bc884 100644
--- a/src/libstd/unstable/dynamic_lib.rs
+++ b/src/libstd/unstable/dynamic_lib.rs
@@ -138,7 +138,7 @@ mod test {
 #[cfg(target_os = "android")]
 #[cfg(target_os = "macos")]
 #[cfg(target_os = "freebsd")]
-mod dl {
+pub mod dl {
     use c_str::ToCStr;
     use libc;
     use path;
@@ -207,7 +207,7 @@ mod dl {
 }
 
 #[cfg(target_os = "win32")]
-mod dl {
+pub mod dl {
     use os;
     use libc;
     use path;
diff --git a/src/libstd/unstable/extfmt.rs b/src/libstd/unstable/extfmt.rs
index f2cfd114349..4d53dd7d7bf 100644
--- a/src/libstd/unstable/extfmt.rs
+++ b/src/libstd/unstable/extfmt.rs
@@ -158,11 +158,14 @@ pub mod ct {
 
     // A fragment of the output sequence
     #[deriving(Eq)]
-    pub enum Piece { PieceString(~str), PieceConv(Conv), }
+    pub enum Piece {
+        PieceString(~str),
+        PieceConv(Conv),
+    }
 
-    pub type ErrorFn = @fn(&str) -> !;
+    pub type ErrorFn<'self> = &'self fn(&str) -> !;
 
-    pub fn parse_fmt_string(s: &str, err: ErrorFn) -> ~[Piece] {
+    pub fn parse_fmt_string<'a>(s: &str, err: ErrorFn<'a>) -> ~[Piece] {
         fn push_slice(ps: &mut ~[Piece], s: &str, from: uint, to: uint) {
             if to > from {
                 ps.push(PieceString(s.slice(from, to).to_owned()));
@@ -185,7 +188,10 @@ pub mod ct {
                     i += 1;
                 } else {
                     push_slice(&mut pieces, s, h, i - 1);
-                    let Parsed {val, next} = parse_conversion(s, i, lim, err);
+                    let Parsed {
+                        val,
+                        next
+                    } = parse_conversion(s, i, lim, |s| err(s));
                     pieces.push(val);
                     i = next;
                 }
@@ -224,8 +230,8 @@ pub mod ct {
         }
     }
 
-    pub fn parse_conversion(s: &str, i: uint, lim: uint, err: ErrorFn) ->
-        Parsed<Piece> {
+    pub fn parse_conversion<'a>(s: &str, i: uint, lim: uint, err: ErrorFn<'a>)
+                                -> Parsed<Piece> {
         let param = parse_parameter(s, i, lim);
         // avoid copying ~[Flag] by destructuring
         let Parsed {val: flags_val, next: flags_next} = parse_flags(s,
@@ -308,8 +314,8 @@ pub mod ct {
         }
     }
 
-    pub fn parse_type(s: &str, i: uint, lim: uint, err: ErrorFn) ->
-        Parsed<Ty> {
+    pub fn parse_type<'a>(s: &str, i: uint, lim: uint, err: ErrorFn<'a>)
+                          -> Parsed<Ty> {
         if i >= lim { err("missing type in conversion"); }
 
         // FIXME (#2249): Do we really want two signed types here?
diff --git a/src/libstd/unstable/finally.rs b/src/libstd/unstable/finally.rs
index 6833ca6d7cf..ba5986aa4ab 100644
--- a/src/libstd/unstable/finally.rs
+++ b/src/libstd/unstable/finally.rs
@@ -55,7 +55,6 @@ impl<'self,T> Finally<T> for &'self fn() -> T {
 }
 
 finally_fn!(~fn() -> T)
-finally_fn!(@fn() -> T)
 finally_fn!(extern "Rust" fn() -> T)
 
 struct Finallyalizer<'self> {
@@ -119,14 +118,3 @@ fn test_owned() {
     spawn_with_finalizer(owned);
 }
 
-#[test]
-fn test_managed() {
-    let i = @mut 10;
-    let managed: @fn() -> int = || {
-        let r = *i;
-        *i += 10;
-        r
-    };
-    assert_eq!(do managed.finally {}, 10);
-    assert_eq!(*i, 20);
-}
diff --git a/src/libstd/unstable/lang.rs b/src/libstd/unstable/lang.rs
index 1d839b55195..b2a0062d727 100644
--- a/src/libstd/unstable/lang.rs
+++ b/src/libstd/unstable/lang.rs
@@ -94,12 +94,11 @@ pub unsafe fn check_not_borrowed(a: *u8,
 }
 
 #[lang="start"]
-pub fn start(main: *u8, argc: int, argv: **c_char,
-             crate_map: *u8) -> int {
+pub fn start(main: *u8, argc: int, argv: **c_char) -> int {
     use rt;
 
     unsafe {
-        return do rt::start(argc, argv as **u8, crate_map) {
+        return do rt::start(argc, argv as **u8) {
             let main: extern "Rust" fn() = transmute(main);
             main();
         };
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index f0f86911f50..9e23501a13b 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -12,7 +12,6 @@ use ast::*;
 use ast;
 use ast_util;
 use codemap::{Span, dummy_sp};
-use fold;
 use opt_vec;
 use parse::token;
 use visit::Visitor;
@@ -371,21 +370,6 @@ pub fn empty_generics() -> Generics {
               ty_params: opt_vec::Empty}
 }
 
-///////////////////////////////////////////////////////////////////////////
-// Assigning node ids
-
-fn node_id_assigner(next_id: @fn() -> ast::NodeId) -> @fold::ast_fold {
-    let precursor = @fold::AstFoldFns {
-        new_id: |old_id| {
-            assert_eq!(old_id, ast::DUMMY_NODE_ID);
-            next_id()
-        },
-        ..*fold::default_ast_fold()
-    };
-
-    fold::make_fold(precursor)
-}
-
 // ______________________________________________________________________
 // Enumerating the IDs which appear in an AST
 
@@ -413,18 +397,22 @@ impl id_range {
     }
 }
 
-pub fn id_visitor(vfn: @fn(NodeId), pass_through_items: bool)
+pub fn id_visitor(operation: @IdVisitingOperation, pass_through_items: bool)
                   -> @mut Visitor<()> {
     let visitor = @mut IdVisitor {
-        visit_callback: vfn,
+        operation: operation,
         pass_through_items: pass_through_items,
         visited_outermost: false,
     };
     visitor as @mut Visitor<()>
 }
 
+pub trait IdVisitingOperation {
+    fn visit_id(&self, node_id: NodeId);
+}
+
 pub struct IdVisitor {
-    visit_callback: @fn(NodeId),
+    operation: @IdVisitingOperation,
     pass_through_items: bool,
     visited_outermost: bool,
 }
@@ -432,10 +420,10 @@ pub struct IdVisitor {
 impl IdVisitor {
     fn visit_generics_helper(&self, generics: &Generics) {
         for type_parameter in generics.ty_params.iter() {
-            (self.visit_callback)(type_parameter.id)
+            self.operation.visit_id(type_parameter.id)
         }
         for lifetime in generics.lifetimes.iter() {
-            (self.visit_callback)(lifetime.id)
+            self.operation.visit_id(lifetime.id)
         }
     }
 }
@@ -446,26 +434,26 @@ impl Visitor<()> for IdVisitor {
                  _: Span,
                  node_id: NodeId,
                  env: ()) {
-        (self.visit_callback)(node_id);
+        self.operation.visit_id(node_id);
         visit::walk_mod(self, module, env)
     }
 
     fn visit_view_item(&mut self, view_item: &view_item, env: ()) {
         match view_item.node {
             view_item_extern_mod(_, _, _, node_id) => {
-                (self.visit_callback)(node_id)
+                self.operation.visit_id(node_id)
             }
             view_item_use(ref view_paths) => {
                 for view_path in view_paths.iter() {
                     match view_path.node {
                         view_path_simple(_, _, node_id) |
                         view_path_glob(_, node_id) => {
-                            (self.visit_callback)(node_id)
+                            self.operation.visit_id(node_id)
                         }
                         view_path_list(_, ref paths, node_id) => {
-                            (self.visit_callback)(node_id);
+                            self.operation.visit_id(node_id);
                             for path in paths.iter() {
-                                (self.visit_callback)(path.node.id)
+                                self.operation.visit_id(path.node.id)
                             }
                         }
                     }
@@ -476,7 +464,7 @@ impl Visitor<()> for IdVisitor {
     }
 
     fn visit_foreign_item(&mut self, foreign_item: @foreign_item, env: ()) {
-        (self.visit_callback)(foreign_item.id);
+        self.operation.visit_id(foreign_item.id);
         visit::walk_foreign_item(self, foreign_item, env)
     }
 
@@ -489,11 +477,11 @@ impl Visitor<()> for IdVisitor {
             }
         }
 
-        (self.visit_callback)(item.id);
+        self.operation.visit_id(item.id);
         match item.node {
             item_enum(ref enum_definition, _) => {
                 for variant in enum_definition.variants.iter() {
-                    (self.visit_callback)(variant.node.id)
+                    self.operation.visit_id(variant.node.id)
                 }
             }
             _ => {}
@@ -505,22 +493,22 @@ impl Visitor<()> for IdVisitor {
     }
 
     fn visit_local(&mut self, local: @Local, env: ()) {
-        (self.visit_callback)(local.id);
+        self.operation.visit_id(local.id);
         visit::walk_local(self, local, env)
     }
 
     fn visit_block(&mut self, block: &Block, env: ()) {
-        (self.visit_callback)(block.id);
+        self.operation.visit_id(block.id);
         visit::walk_block(self, block, env)
     }
 
     fn visit_stmt(&mut self, statement: @Stmt, env: ()) {
-        (self.visit_callback)(ast_util::stmt_id(statement));
+        self.operation.visit_id(ast_util::stmt_id(statement));
         visit::walk_stmt(self, statement, env)
     }
 
     fn visit_pat(&mut self, pattern: @Pat, env: ()) {
-        (self.visit_callback)(pattern.id);
+        self.operation.visit_id(pattern.id);
         visit::walk_pat(self, pattern, env)
     }
 
@@ -529,17 +517,17 @@ impl Visitor<()> for IdVisitor {
         {
             let optional_callee_id = expression.get_callee_id();
             for callee_id in optional_callee_id.iter() {
-                (self.visit_callback)(*callee_id)
+                self.operation.visit_id(*callee_id)
             }
         }
-        (self.visit_callback)(expression.id);
+        self.operation.visit_id(expression.id);
         visit::walk_expr(self, expression, env)
     }
 
     fn visit_ty(&mut self, typ: &Ty, env: ()) {
-        (self.visit_callback)(typ.id);
+        self.operation.visit_id(typ.id);
         match typ.node {
-            ty_path(_, _, id) => (self.visit_callback)(id),
+            ty_path(_, _, id) => self.operation.visit_id(id),
             _ => {}
         }
         visit::walk_ty(self, typ, env)
@@ -565,21 +553,21 @@ impl Visitor<()> for IdVisitor {
             }
         }
 
-        (self.visit_callback)(node_id);
+        self.operation.visit_id(node_id);
 
         match *function_kind {
             visit::fk_item_fn(_, generics, _, _) => {
                 self.visit_generics_helper(generics)
             }
             visit::fk_method(_, generics, method) => {
-                (self.visit_callback)(method.self_id);
+                self.operation.visit_id(method.self_id);
                 self.visit_generics_helper(generics)
             }
             visit::fk_anon(_) | visit::fk_fn_block => {}
         }
 
         for argument in function_declaration.inputs.iter() {
-            (self.visit_callback)(argument.id)
+            self.operation.visit_id(argument.id)
         }
 
         visit::walk_fn(self,
@@ -599,25 +587,36 @@ impl Visitor<()> for IdVisitor {
     }
 
     fn visit_struct_field(&mut self, struct_field: @struct_field, env: ()) {
-        (self.visit_callback)(struct_field.node.id);
+        self.operation.visit_id(struct_field.node.id);
         visit::walk_struct_field(self, struct_field, env)
     }
 }
 
-pub fn visit_ids_for_inlined_item(item: &inlined_item, vfn: @fn(NodeId)) {
+pub fn visit_ids_for_inlined_item(item: &inlined_item,
+                                  operation: @IdVisitingOperation) {
     let mut id_visitor = IdVisitor {
-        visit_callback: vfn,
+        operation: operation,
         pass_through_items: true,
         visited_outermost: false,
     };
     item.accept((), &mut id_visitor);
 }
 
-pub fn compute_id_range(visit_ids_fn: &fn(@fn(NodeId))) -> id_range {
-    let result = @mut id_range::max();
-    do visit_ids_fn |id| {
-        result.add(id);
+struct IdRangeComputingVisitor {
+    result: @mut id_range,
+}
+
+impl IdVisitingOperation for IdRangeComputingVisitor {
+    fn visit_id(&self, id: NodeId) {
+        self.result.add(id)
     }
+}
+
+pub fn compute_id_range(visit_ids_fn: &fn(@IdVisitingOperation)) -> id_range {
+    let result = @mut id_range::max();
+    visit_ids_fn(@IdRangeComputingVisitor {
+        result: result,
+    } as @IdVisitingOperation);
     *result
 }
 
@@ -741,7 +740,7 @@ pub fn new_mark(m:Mrk, tail:SyntaxContext) -> SyntaxContext {
 }
 
 // Extend a syntax context with a given mark and table
-// FIXME #4536 : currently pub to allow testing
+// FIXME #8215 : currently pub to allow testing
 pub fn new_mark_internal(m:Mrk, tail:SyntaxContext,table:&mut SCTable)
     -> SyntaxContext {
     let key = (tail,m);
@@ -770,7 +769,7 @@ pub fn new_rename(id:Ident, to:Name, tail:SyntaxContext) -> SyntaxContext {
 }
 
 // Extend a syntax context with a given rename and sctable
-// FIXME #4536 : currently pub to allow testing
+// FIXME #8215 : currently pub to allow testing
 pub fn new_rename_internal(id:Ident, to:Name, tail:SyntaxContext, table: &mut SCTable)
     -> SyntaxContext {
     let key = (tail,id,to);
@@ -793,7 +792,7 @@ pub fn new_rename_internal(id:Ident, to:Name, tail:SyntaxContext, table: &mut SC
 
 /// Make a fresh syntax context table with EmptyCtxt in slot zero
 /// and IllegalCtxt in slot one.
-// FIXME #4536 : currently pub to allow testing
+// FIXME #8215 : currently pub to allow testing
 pub fn new_sctable_internal() -> SCTable {
     SCTable {
         table: ~[EmptyCtxt,IllegalCtxt],
@@ -835,7 +834,7 @@ pub fn mtwt_resolve(id : Ident) -> Name {
     resolve_internal(id, get_sctable(), get_resolve_table())
 }
 
-// FIXME #4536: must be pub for testing
+// FIXME #8215: must be pub for testing
 pub type ResolveTable = HashMap<(Name,SyntaxContext),Name>;
 
 // okay, I admit, putting this in TLS is not so nice:
@@ -854,7 +853,7 @@ pub fn get_resolve_table() -> @mut ResolveTable {
 
 // Resolve a syntax object to a name, per MTWT.
 // adding memoization to possibly resolve 500+ seconds in resolve for librustc (!)
-// FIXME #4536 : currently pub to allow testing
+// FIXME #8215 : currently pub to allow testing
 pub fn resolve_internal(id : Ident,
                         table : &mut SCTable,
                         resolve_table : &mut ResolveTable) -> Name {
diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs
index 5e9714ca5b2..aa06e1bee41 100644
--- a/src/libsyntax/diagnostic.rs
+++ b/src/libsyntax/diagnostic.rs
@@ -15,9 +15,12 @@ use std::io;
 use std::local_data;
 use extra::term;
 
-pub type Emitter = @fn(cmsp: Option<(@codemap::CodeMap, Span)>,
-                       msg: &str,
-                       lvl: level);
+pub trait Emitter {
+    fn emit(&self,
+            cmsp: Option<(@codemap::CodeMap, Span)>,
+            msg: &str,
+            lvl: level);
+}
 
 // a handler deals with errors; certain errors
 // (fatal, bug, unimpl) may cause immediate exit,
@@ -55,7 +58,7 @@ pub trait span_handler {
 
 struct HandlerT {
     err_count: uint,
-    emit: Emitter,
+    emit: @Emitter,
 }
 
 struct CodemapT {
@@ -91,11 +94,11 @@ impl span_handler for CodemapT {
 
 impl handler for HandlerT {
     fn fatal(@mut self, msg: &str) -> ! {
-        (self.emit)(None, msg, fatal);
+        self.emit.emit(None, msg, fatal);
         fail!();
     }
     fn err(@mut self, msg: &str) {
-        (self.emit)(None, msg, error);
+        self.emit.emit(None, msg, error);
         self.bump_err_count();
     }
     fn bump_err_count(@mut self) {
@@ -120,10 +123,10 @@ impl handler for HandlerT {
         self.fatal(s);
     }
     fn warn(@mut self, msg: &str) {
-        (self.emit)(None, msg, warning);
+        self.emit.emit(None, msg, warning);
     }
     fn note(@mut self, msg: &str) {
-        (self.emit)(None, msg, note);
+        self.emit.emit(None, msg, note);
     }
     fn bug(@mut self, msg: &str) -> ! {
         self.fatal(ice_msg(msg));
@@ -135,7 +138,7 @@ impl handler for HandlerT {
             cmsp: Option<(@codemap::CodeMap, Span)>,
             msg: &str,
             lvl: level) {
-        (self.emit)(cmsp, msg, lvl);
+        self.emit.emit(cmsp, msg, lvl);
     }
 }
 
@@ -145,19 +148,22 @@ pub fn ice_msg(msg: &str) -> ~str {
 
 pub fn mk_span_handler(handler: @mut handler, cm: @codemap::CodeMap)
                     -> @mut span_handler {
-    @mut CodemapT { handler: handler, cm: cm } as @mut span_handler
+    @mut CodemapT {
+        handler: handler,
+        cm: cm,
+    } as @mut span_handler
 }
 
-pub fn mk_handler(emitter: Option<Emitter>) -> @mut handler {
-    let emit: Emitter = match emitter {
+pub fn mk_handler(emitter: Option<@Emitter>) -> @mut handler {
+    let emit: @Emitter = match emitter {
         Some(e) => e,
-        None => {
-            let emit: Emitter = |cmsp, msg, t| emit(cmsp, msg, t);
-            emit
-        }
+        None => @DefaultEmitter as @Emitter
     };
 
-    @mut HandlerT { err_count: 0, emit: emit } as @mut handler
+    @mut HandlerT {
+        err_count: 0,
+        emit: emit,
+    } as @mut handler
 }
 
 #[deriving(Eq)]
@@ -230,31 +236,30 @@ fn print_diagnostic(topic: &str, lvl: level, msg: &str) {
     print_maybe_styled(fmt!("%s\n", msg), term::attr::Bold);
 }
 
-pub fn collect(messages: @mut ~[~str])
-            -> @fn(Option<(@codemap::CodeMap, Span)>, &str, level) {
-    let f: @fn(Option<(@codemap::CodeMap, Span)>, &str, level) =
-        |_o, msg: &str, _l| { messages.push(msg.to_str()); };
-    f
-}
+pub struct DefaultEmitter;
 
-pub fn emit(cmsp: Option<(@codemap::CodeMap, Span)>, msg: &str, lvl: level) {
-    match cmsp {
-      Some((cm, sp)) => {
-        let sp = cm.adjust_span(sp);
-        let ss = cm.span_to_str(sp);
-        let lines = cm.span_to_lines(sp);
-        print_diagnostic(ss, lvl, msg);
-        highlight_lines(cm, sp, lvl, lines);
-        print_macro_backtrace(cm, sp);
-      }
-      None => {
-        print_diagnostic("", lvl, msg);
-      }
+impl Emitter for DefaultEmitter {
+    fn emit(&self,
+            cmsp: Option<(@codemap::CodeMap, Span)>,
+            msg: &str,
+            lvl: level) {
+        match cmsp {
+            Some((cm, sp)) => {
+                let sp = cm.adjust_span(sp);
+                let ss = cm.span_to_str(sp);
+                let lines = cm.span_to_lines(sp);
+                print_diagnostic(ss, lvl, msg);
+                highlight_lines(cm, sp, lvl, lines);
+                print_macro_backtrace(cm, sp);
+            }
+            None => print_diagnostic("", lvl, msg),
+        }
     }
 }
 
 fn highlight_lines(cm: @codemap::CodeMap,
-                   sp: Span, lvl: level,
+                   sp: Span,
+                   lvl: level,
                    lines: @codemap::FileLines) {
     let fm = lines.file;
 
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 2bcfafc3bb4..48eb9a350f1 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -33,62 +33,120 @@ pub struct MacroDef {
     ext: SyntaxExtension
 }
 
-// No context arg for an Item Decorator macro, simply because
-// adding it would require adding a ctxt field to all items.
-// we could do this if it turns out to be useful.
-
-pub type ItemDecoratorFun = @fn(@ExtCtxt,
-                             Span,
-                             @ast::MetaItem,
-                             ~[@ast::item])
-                          -> ~[@ast::item];
-
-pub type SyntaxExpanderTTFun = @fn(@ExtCtxt,
-                                   Span,
-                                   &[ast::token_tree],
-                                   ast::SyntaxContext)
-                                -> MacResult;
-
-pub type SyntaxExpanderTTItemFun = @fn(@ExtCtxt,
-                                       Span,
-                                       ast::Ident,
-                                       ~[ast::token_tree],
-                                       ast::SyntaxContext)
-                                    -> MacResult;
-
-// oog... in order to make the presentation of builtin_normal_tt_no_ctxt
-// and builtin_ident_tt_no_ctxt palatable, we need one-off types for
-// functions that don't consume a ctxt:
-
-pub type SyntaxExpanderTTFunNoCtxt = @fn(@ExtCtxt,
-                                   Span,
-                                   &[ast::token_tree])
-                                -> MacResult;
-
-pub type SyntaxExpanderTTItemFunNoCtxt = @fn(@ExtCtxt,
-                                       Span,
-                                       ast::Ident,
-                                       ~[ast::token_tree])
-                                    -> MacResult;
+pub type ItemDecorator = extern "Rust" fn(@ExtCtxt,
+                                          Span,
+                                          @ast::MetaItem,
+                                          ~[@ast::item])
+                                          -> ~[@ast::item];
+
+pub struct SyntaxExpanderTT {
+    expander: SyntaxExpanderTTExpander,
+    span: Option<Span>
+}
+
+pub trait SyntaxExpanderTTTrait {
+    fn expand(&self,
+              ecx: @ExtCtxt,
+              span: Span,
+              token_tree: &[ast::token_tree],
+              context: ast::SyntaxContext)
+              -> MacResult;
+}
+
+pub type SyntaxExpanderTTFunNoCtxt =
+    extern "Rust" fn(ecx: @ExtCtxt,
+                     span: codemap::Span,
+                     token_tree: &[ast::token_tree])
+                     -> MacResult;
+
+enum SyntaxExpanderTTExpander {
+    SyntaxExpanderTTExpanderWithoutContext(SyntaxExpanderTTFunNoCtxt),
+}
+
+impl SyntaxExpanderTTTrait for SyntaxExpanderTT {
+    fn expand(&self,
+              ecx: @ExtCtxt,
+              span: Span,
+              token_tree: &[ast::token_tree],
+              _: ast::SyntaxContext)
+              -> MacResult {
+        match self.expander {
+            SyntaxExpanderTTExpanderWithoutContext(f) => {
+                f(ecx, span, token_tree)
+            }
+        }
+    }
+}
 
+enum SyntaxExpanderTTItemExpander {
+    SyntaxExpanderTTItemExpanderWithContext(SyntaxExpanderTTItemFun),
+    SyntaxExpanderTTItemExpanderWithoutContext(SyntaxExpanderTTItemFunNoCtxt),
+}
 
+pub struct SyntaxExpanderTTItem {
+    expander: SyntaxExpanderTTItemExpander,
+    span: Option<Span>
+}
+
+pub trait SyntaxExpanderTTItemTrait {
+    fn expand(&self,
+              cx: @ExtCtxt,
+              sp: Span,
+              ident: ast::Ident,
+              token_tree: ~[ast::token_tree],
+              context: ast::SyntaxContext)
+              -> MacResult;
+}
+
+impl SyntaxExpanderTTItemTrait for SyntaxExpanderTTItem {
+    fn expand(&self,
+              cx: @ExtCtxt,
+              sp: Span,
+              ident: ast::Ident,
+              token_tree: ~[ast::token_tree],
+              context: ast::SyntaxContext)
+              -> MacResult {
+        match self.expander {
+            SyntaxExpanderTTItemExpanderWithContext(fun) => {
+                fun(cx, sp, ident, token_tree, context)
+            }
+            SyntaxExpanderTTItemExpanderWithoutContext(fun) => {
+                fun(cx, sp, ident, token_tree)
+            }
+        }
+    }
+}
+
+pub type SyntaxExpanderTTItemFun = extern "Rust" fn(@ExtCtxt,
+                                                    Span,
+                                                    ast::Ident,
+                                                    ~[ast::token_tree],
+                                                    ast::SyntaxContext)
+                                                    -> MacResult;
+
+pub type SyntaxExpanderTTItemFunNoCtxt =
+    extern "Rust" fn(@ExtCtxt, Span, ast::Ident, ~[ast::token_tree])
+                     -> MacResult;
+
+pub trait AnyMacro {
+    fn make_expr(&self) -> @ast::Expr;
+    fn make_item(&self) -> Option<@ast::item>;
+    fn make_stmt(&self) -> @ast::Stmt;
+}
 
 pub enum MacResult {
     MRExpr(@ast::Expr),
     MRItem(@ast::item),
-    MRAny(@fn() -> @ast::Expr,
-          @fn() -> Option<@ast::item>,
-          @fn() -> @ast::Stmt),
-    MRDef(MacroDef)
+    MRAny(@AnyMacro),
+    MRDef(MacroDef),
 }
 
 pub enum SyntaxExtension {
-
     // #[auto_encode] and such
-    ItemDecorator(ItemDecoratorFun),
+    ItemDecorator(ItemDecorator),
 
     // Token-tree expanders
-    NormalTT(SyntaxExpanderTTFun, Option<Span>),
+    NormalTT(@SyntaxExpanderTTTrait, Option<Span>),
 
     // An IdentTT is a macro that has an
     // identifier in between the name of the
@@ -98,7 +156,7 @@ pub enum SyntaxExtension {
 
     // perhaps macro_rules! will lose its odd special identifier argument,
     // and this can go away also
-    IdentTT(SyntaxExpanderTTItemFun, Option<Span>),
+    IdentTT(@SyntaxExpanderTTItemTrait, Option<Span>),
 }
 
 
@@ -133,16 +191,22 @@ type RenameList = ~[(ast::Ident,Name)];
 // AST nodes into full ASTs
 pub fn syntax_expander_table() -> SyntaxEnv {
     // utility function to simplify creating NormalTT syntax extensions
-    // that ignore their contexts
-    fn builtin_normal_tt_no_ctxt(f: SyntaxExpanderTTFunNoCtxt) -> @Transformer {
-        let wrapped_expander : SyntaxExpanderTTFun = |a,b,c,_d|{f(a,b,c)};
-        @SE(NormalTT(wrapped_expander, None))
+    fn builtin_normal_tt_no_ctxt(f: SyntaxExpanderTTFunNoCtxt)
+                                 -> @Transformer {
+        @SE(NormalTT(@SyntaxExpanderTT{
+            expander: SyntaxExpanderTTExpanderWithoutContext(f),
+            span: None,
+        } as @SyntaxExpanderTTTrait,
+        None))
     }
     // utility function to simplify creating IdentTT syntax extensions
     // that ignore their contexts
     fn builtin_item_tt_no_ctxt(f: SyntaxExpanderTTItemFunNoCtxt) -> @Transformer {
-        let wrapped_expander : SyntaxExpanderTTItemFun = |a,b,c,d,_e|{f(a,b,c,d)};
-        @SE(IdentTT(wrapped_expander, None))
+        @SE(IdentTT(@SyntaxExpanderTTItem {
+            expander: SyntaxExpanderTTItemExpanderWithoutContext(f),
+            span: None,
+        } as @SyntaxExpanderTTItemTrait,
+        None))
     }
     let mut syntax_expanders = HashMap::new();
     // NB identifier starts with space, and can't conflict with legal idents
@@ -152,11 +216,18 @@ pub fn syntax_expander_table() -> SyntaxEnv {
                                 pending_renames : @mut ~[]
                             }));
     syntax_expanders.insert(intern(&"macro_rules"),
-                            @SE(IdentTT(ext::tt::macro_rules::add_new_extension, None)));
+                            @SE(IdentTT(@SyntaxExpanderTTItem {
+                                expander: SyntaxExpanderTTItemExpanderWithContext(
+                                    ext::tt::macro_rules::add_new_extension),
+                                span: None,
+                            } as @SyntaxExpanderTTItemTrait,
+                            None)));
     syntax_expanders.insert(intern(&"fmt"),
-                            builtin_normal_tt_no_ctxt(ext::fmt::expand_syntax_ext));
+                            builtin_normal_tt_no_ctxt(
+                                ext::fmt::expand_syntax_ext));
     syntax_expanders.insert(intern(&"format_args"),
-                            builtin_normal_tt_no_ctxt(ext::format::expand_args));
+                            builtin_normal_tt_no_ctxt(
+                                ext::format::expand_args));
     syntax_expanders.insert(
         intern(&"auto_encode"),
         @SE(ItemDecorator(ext::auto_encode::expand_auto_encode)));
@@ -164,67 +235,77 @@ pub fn syntax_expander_table() -> SyntaxEnv {
         intern(&"auto_decode"),
         @SE(ItemDecorator(ext::auto_encode::expand_auto_decode)));
     syntax_expanders.insert(intern(&"env"),
-                            builtin_normal_tt_no_ctxt(ext::env::expand_env));
+                            builtin_normal_tt_no_ctxt(
+                                    ext::env::expand_env));
     syntax_expanders.insert(intern(&"option_env"),
-                            builtin_normal_tt_no_ctxt(ext::env::expand_option_env));
+                            builtin_normal_tt_no_ctxt(
+                                    ext::env::expand_option_env));
     syntax_expanders.insert(intern("bytes"),
-                            builtin_normal_tt_no_ctxt(ext::bytes::expand_syntax_ext));
+                            builtin_normal_tt_no_ctxt(
+                                    ext::bytes::expand_syntax_ext));
     syntax_expanders.insert(intern("concat_idents"),
                             builtin_normal_tt_no_ctxt(
-                                ext::concat_idents::expand_syntax_ext));
+                                    ext::concat_idents::expand_syntax_ext));
     syntax_expanders.insert(intern(&"log_syntax"),
                             builtin_normal_tt_no_ctxt(
-                                ext::log_syntax::expand_syntax_ext));
+                                    ext::log_syntax::expand_syntax_ext));
     syntax_expanders.insert(intern(&"deriving"),
                             @SE(ItemDecorator(
                                 ext::deriving::expand_meta_deriving)));
 
     // Quasi-quoting expanders
     syntax_expanders.insert(intern(&"quote_tokens"),
-                            builtin_normal_tt_no_ctxt(
-                                ext::quote::expand_quote_tokens));
+                       builtin_normal_tt_no_ctxt(
+                            ext::quote::expand_quote_tokens));
     syntax_expanders.insert(intern(&"quote_expr"),
-                            builtin_normal_tt_no_ctxt(ext::quote::expand_quote_expr));
+                       builtin_normal_tt_no_ctxt(
+                            ext::quote::expand_quote_expr));
     syntax_expanders.insert(intern(&"quote_ty"),
-                            builtin_normal_tt_no_ctxt(ext::quote::expand_quote_ty));
+                       builtin_normal_tt_no_ctxt(
+                            ext::quote::expand_quote_ty));
     syntax_expanders.insert(intern(&"quote_item"),
-                            builtin_normal_tt_no_ctxt(ext::quote::expand_quote_item));
+                       builtin_normal_tt_no_ctxt(
+                            ext::quote::expand_quote_item));
     syntax_expanders.insert(intern(&"quote_pat"),
-                            builtin_normal_tt_no_ctxt(ext::quote::expand_quote_pat));
+                       builtin_normal_tt_no_ctxt(
+                            ext::quote::expand_quote_pat));
     syntax_expanders.insert(intern(&"quote_stmt"),
-                            builtin_normal_tt_no_ctxt(ext::quote::expand_quote_stmt));
+                       builtin_normal_tt_no_ctxt(
+                            ext::quote::expand_quote_stmt));
 
     syntax_expanders.insert(intern(&"line"),
                             builtin_normal_tt_no_ctxt(
-                                ext::source_util::expand_line));
+                                    ext::source_util::expand_line));
     syntax_expanders.insert(intern(&"col"),
                             builtin_normal_tt_no_ctxt(
-                                ext::source_util::expand_col));
+                                    ext::source_util::expand_col));
     syntax_expanders.insert(intern(&"file"),
                             builtin_normal_tt_no_ctxt(
-                                ext::source_util::expand_file));
+                                    ext::source_util::expand_file));
     syntax_expanders.insert(intern(&"stringify"),
                             builtin_normal_tt_no_ctxt(
-                                ext::source_util::expand_stringify));
+                                    ext::source_util::expand_stringify));
     syntax_expanders.insert(intern(&"include"),
                             builtin_normal_tt_no_ctxt(
-                                ext::source_util::expand_include));
+                                    ext::source_util::expand_include));
     syntax_expanders.insert(intern(&"include_str"),
                             builtin_normal_tt_no_ctxt(
-                                ext::source_util::expand_include_str));
+                                    ext::source_util::expand_include_str));
     syntax_expanders.insert(intern(&"include_bin"),
                             builtin_normal_tt_no_ctxt(
-                                ext::source_util::expand_include_bin));
+                                    ext::source_util::expand_include_bin));
     syntax_expanders.insert(intern(&"module_path"),
                             builtin_normal_tt_no_ctxt(
-                                ext::source_util::expand_mod));
+                                    ext::source_util::expand_mod));
     syntax_expanders.insert(intern(&"asm"),
-                            builtin_normal_tt_no_ctxt(ext::asm::expand_asm));
+                            builtin_normal_tt_no_ctxt(
+                                    ext::asm::expand_asm));
     syntax_expanders.insert(intern(&"cfg"),
-                            builtin_normal_tt_no_ctxt(ext::cfg::expand_cfg));
-    syntax_expanders.insert(
-        intern(&"trace_macros"),
-        builtin_normal_tt_no_ctxt(ext::trace_macros::expand_trace_macros));
+                            builtin_normal_tt_no_ctxt(
+                                    ext::cfg::expand_cfg));
+    syntax_expanders.insert(intern(&"trace_macros"),
+                            builtin_normal_tt_no_ctxt(
+                                    ext::trace_macros::expand_trace_macros));
     MapChain::new(~syntax_expanders)
 }
 
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 889c2a5976e..5111682f6d0 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -15,6 +15,7 @@ use ast_util;
 use codemap::{Span, respan, dummy_sp};
 use ext::base::ExtCtxt;
 use ext::quote::rt::*;
+use fold;
 use opt_vec;
 use opt_vec::OptVec;
 
@@ -701,7 +702,7 @@ impl AstBuilder for @ExtCtxt {
                     attrs: attrs,
                     id: ast::DUMMY_NODE_ID,
                     node: node,
-                    vis: ast::public,
+                    vis: ast::inherited,
                     span: span }
     }
 
@@ -862,3 +863,32 @@ impl AstBuilder for @ExtCtxt {
                                 ast::view_path_glob(self.path(sp, path), ast::DUMMY_NODE_ID))])
     }
 }
+
+struct Duplicator {
+    cx: @ExtCtxt,
+}
+
+impl fold::ast_fold for Duplicator {
+    fn new_id(&self, _: NodeId) -> NodeId {
+        ast::DUMMY_NODE_ID
+    }
+}
+
+pub trait Duplicate {
+    //
+    // Duplication functions
+    //
+    // These functions just duplicate AST nodes.
+    //
+
+    fn duplicate(&self, cx: @ExtCtxt) -> Self;
+}
+
+impl Duplicate for @ast::Expr {
+    fn duplicate(&self, cx: @ExtCtxt) -> @ast::Expr {
+        let folder = @Duplicator {
+            cx: cx,
+        } as @fold::ast_fold;
+        folder.fold_expr(*self)
+    }
+}
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 82d452bc734..64f30803ca7 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -10,7 +10,7 @@
 
 use ast::{Block, Crate, DeclLocal, Expr_, ExprMac, SyntaxContext};
 use ast::{Local, Ident, mac_invoc_tt};
-use ast::{item_mac, Mrk, Stmt_, StmtDecl, StmtMac, StmtExpr, StmtSemi};
+use ast::{item_mac, Mrk, Stmt, StmtDecl, StmtMac, StmtExpr, StmtSemi};
 use ast::{token_tree};
 use ast;
 use ast_util::{mtwt_outer_mark, new_rename, new_mark};
@@ -21,6 +21,7 @@ use codemap;
 use codemap::{Span, Spanned, ExpnInfo, NameAndSpan};
 use ext::base::*;
 use fold::*;
+use opt_vec;
 use parse;
 use parse::{parse_item_from_source_str};
 use parse::token;
@@ -32,12 +33,10 @@ use std::vec;
 
 pub fn expand_expr(extsbox: @mut SyntaxEnv,
                    cx: @ExtCtxt,
-                   e: &Expr_,
-                   span: Span,
-                   fld: @ast_fold,
-                   orig: @fn(&Expr_, Span, @ast_fold) -> (Expr_, Span))
-                -> (Expr_, Span) {
-    match *e {
+                   e: @ast::Expr,
+                   fld: &MacroExpander)
+                   -> @ast::Expr {
+    match e.node {
         // expr_mac should really be expr_ext or something; it's the
         // entry-point for all syntax extensions.
         ExprMac(ref mac) => {
@@ -66,7 +65,7 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv,
                         }
                         Some(@SE(NormalTT(expandfun, exp_span))) => {
                             cx.bt_push(ExpnInfo {
-                                call_site: span,
+                                call_site: e.span,
                                 callee: NameAndSpan {
                                     name: extnamestr,
                                     span: exp_span,
@@ -84,10 +83,12 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv,
                             let mac_span = original_span(cx);
 
                             let expanded =
-                                match expandfun(cx, mac_span.call_site,
-                                                marked_before, marked_ctxt) {
+                                match expandfun.expand(cx,
+                                                       mac_span.call_site,
+                                                       marked_before,
+                                                       marked_ctxt) {
                                     MRExpr(e) => e,
-                                    MRAny(expr_maker,_,_) => expr_maker(),
+                                    MRAny(any_macro) => any_macro.make_expr(),
                                     _ => {
                                         cx.span_fatal(
                                             pth.span,
@@ -101,12 +102,19 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv,
                             // mark after:
                             let marked_after = mark_expr(expanded,fm);
 
-                            //keep going, outside-in
+                            // Keep going, outside-in.
+                            //
+                            // XXX(pcwalton): Is it necessary to clone the
+                            // node here?
                             let fully_expanded =
                                 fld.fold_expr(marked_after).node.clone();
                             cx.bt_pop();
 
-                            (fully_expanded, span)
+                            @ast::Expr {
+                                id: ast::DUMMY_NODE_ID,
+                                node: fully_expanded,
+                                span: e.span,
+                            }
                         }
                         _ => {
                             cx.span_fatal(
@@ -125,8 +133,48 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv,
         ast::ExprForLoop(src_pat, src_expr, ref src_loop_block, opt_ident) => {
             // Expand any interior macros etc.
             // NB: we don't fold pats yet. Curious.
-            let src_expr = fld.fold_expr(src_expr);
-            let src_loop_block = fld.fold_block(src_loop_block);
+            let src_expr = fld.fold_expr(src_expr).clone();
+            let src_loop_block = fld.fold_block(src_loop_block).clone();
+
+            let span = e.span;
+
+            pub fn mk_expr(_: @ExtCtxt, span: Span, node: Expr_)
+                           -> @ast::Expr {
+                @ast::Expr {
+                    id: ast::DUMMY_NODE_ID,
+                    node: node,
+                    span: span,
+                }
+            }
+
+            fn mk_block(_: @ExtCtxt,
+                        stmts: &[@ast::Stmt],
+                        expr: Option<@ast::Expr>,
+                        span: Span)
+                        -> ast::Block {
+                ast::Block {
+                    view_items: ~[],
+                    stmts: stmts.to_owned(),
+                    expr: expr,
+                    id: ast::DUMMY_NODE_ID,
+                    rules: ast::DefaultBlock,
+                    span: span,
+                }
+            }
+
+            fn mk_simple_path(ident: ast::Ident, span: Span) -> ast::Path {
+                ast::Path {
+                    span: span,
+                    global: false,
+                    segments: ~[
+                        ast::PathSegment {
+                            identifier: ident,
+                            lifetime: None,
+                            types: opt_vec::Empty,
+                        }
+                    ],
+                }
+            }
 
             // to:
             //
@@ -182,10 +230,14 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv,
                                  ~[iter_decl_stmt],
                                  Some(loop_expr));
 
-            (ast::ExprBlock(block), span)
+            @ast::Expr {
+                id: ast::DUMMY_NODE_ID,
+                node: ast::ExprBlock(block),
+                span: span,
+            }
         }
 
-        _ => orig(e, span, fld)
+        _ => noop_fold_expr(e, fld)
     }
 }
 
@@ -201,12 +253,10 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv,
 pub fn expand_mod_items(extsbox: @mut SyntaxEnv,
                         cx: @ExtCtxt,
                         module_: &ast::_mod,
-                        fld: @ast_fold,
-                        orig: @fn(&ast::_mod, @ast_fold) -> ast::_mod)
-                     -> ast::_mod {
-
+                        fld: &MacroExpander)
+                        -> ast::_mod {
     // Fold the contents first:
-    let module_ = orig(module_, fld);
+    let module_ = noop_fold_mod(module_, fld);
 
     // For each item, look through the attributes.  If any of them are
     // decorated with "item decorators", then use that function to transform
@@ -233,7 +283,10 @@ pub fn expand_mod_items(extsbox: @mut SyntaxEnv,
         }
     };
 
-    ast::_mod { items: new_items, ..module_ }
+    ast::_mod {
+        items: new_items,
+        ..module_
+    }
 }
 
 // eval $e with a new exts frame:
@@ -256,19 +309,20 @@ static special_block_name : &'static str = " block";
 pub fn expand_item(extsbox: @mut SyntaxEnv,
                    cx: @ExtCtxt,
                    it: @ast::item,
-                   fld: @ast_fold,
-                   orig: @fn(@ast::item, @ast_fold) -> Option<@ast::item>)
-                -> Option<@ast::item> {
+                   fld: &MacroExpander)
+                   -> Option<@ast::item> {
     match it.node {
         ast::item_mac(*) => expand_item_mac(extsbox, cx, it, fld),
         ast::item_mod(_) | ast::item_foreign_mod(_) => {
             cx.mod_push(it.ident);
             let macro_escape = contains_macro_escape(it.attrs);
-            let result = with_exts_frame!(extsbox,macro_escape,orig(it,fld));
+            let result = with_exts_frame!(extsbox,
+                                          macro_escape,
+                                          noop_fold_item(it, fld));
             cx.mod_pop();
             result
         },
-        _ => orig(it,fld)
+        _ => noop_fold_item(it, fld)
     }
 }
 
@@ -280,11 +334,15 @@ pub fn contains_macro_escape(attrs: &[ast::Attribute]) -> bool {
 // Support for item-position macro invocations, exactly the same
 // logic as for expression-position macro invocations.
 pub fn expand_item_mac(extsbox: @mut SyntaxEnv,
-                       cx: @ExtCtxt, it: @ast::item,
-                       fld: @ast_fold)
-                    -> Option<@ast::item> {
+                       cx: @ExtCtxt,
+                       it: @ast::item,
+                       fld: &MacroExpander)
+                       -> Option<@ast::item> {
     let (pth, tts, ctxt) = match it.node {
-        item_mac(codemap::Spanned { node: mac_invoc_tt(ref pth, ref tts, ctxt), _}) => {
+        item_mac(codemap::Spanned {
+            node: mac_invoc_tt(ref pth, ref tts, ctxt),
+            _
+        }) => {
             (pth, (*tts).clone(), ctxt)
         }
         _ => cx.span_bug(it.span, "invalid item macro invocation")
@@ -314,7 +372,7 @@ pub fn expand_item_mac(extsbox: @mut SyntaxEnv,
             // mark before expansion:
             let marked_before = mark_tts(tts,fm);
             let marked_ctxt = new_mark(fm,ctxt);
-            expander(cx, it.span, marked_before, marked_ctxt)
+            expander.expand(cx, it.span, marked_before, marked_ctxt)
         }
         Some(@SE(IdentTT(expander, span))) => {
             if it.ident.name == parse::token::special_idents::invalid.name {
@@ -332,7 +390,7 @@ pub fn expand_item_mac(extsbox: @mut SyntaxEnv,
             // mark before expansion:
             let marked_tts = mark_tts(tts,fm);
             let marked_ctxt = new_mark(fm,ctxt);
-            expander(cx, it.span, it.ident, marked_tts, marked_ctxt)
+            expander.expand(cx, it.span, it.ident, marked_tts, marked_ctxt)
         }
         _ => cx.span_fatal(
             it.span, fmt!("%s! is not legal in item position", extnamestr))
@@ -346,10 +404,10 @@ pub fn expand_item_mac(extsbox: @mut SyntaxEnv,
         MRExpr(_) => {
             cx.span_fatal(pth.span, fmt!("expr macro in item position: %s", extnamestr))
         }
-        MRAny(_, item_maker, _) => {
-            item_maker()
-                .and_then(|i| mark_item(i,fm))
-                .and_then(|i| fld.fold_item(i))
+        MRAny(any_macro) => {
+            any_macro.make_item()
+                     .and_then(|i| mark_item(i,fm))
+                     .and_then(|i| fld.fold_item(i))
         }
         MRDef(ref mdef) => {
             // yikes... no idea how to apply the mark to this. I'm afraid
@@ -382,15 +440,12 @@ fn insert_macro(exts: SyntaxEnv, name: ast::Name, transformer: @Transformer) {
 // expand a stmt
 pub fn expand_stmt(extsbox: @mut SyntaxEnv,
                    cx: @ExtCtxt,
-                   s: &Stmt_,
-                   sp: Span,
-                   fld: @ast_fold,
-                   orig: @fn(&Stmt_, Span, @ast_fold)
-                             -> (Option<Stmt_>, Span))
-                -> (Option<Stmt_>, Span) {
+                   s: &Stmt,
+                   fld: &MacroExpander)
+                   -> Option<@Stmt> {
     // why the copying here and not in expand_expr?
     // looks like classic changed-in-only-one-place
-    let (pth, tts, semi, ctxt) = match *s {
+    let (pth, tts, semi, ctxt) = match s.node {
         StmtMac(ref mac, semi) => {
             match mac.node {
                 mac_invoc_tt(ref pth, ref tts, ctxt) => {
@@ -398,24 +453,26 @@ pub fn expand_stmt(extsbox: @mut SyntaxEnv,
                 }
             }
         }
-        _ => return expand_non_macro_stmt(*extsbox,s,sp,fld,orig)
+        _ => return expand_non_macro_stmt(*extsbox, s, fld)
     };
     if (pth.segments.len() > 1u) {
-        cx.span_fatal(
-            pth.span,
-            fmt!("expected macro name without module \
-                  separators"));
+        cx.span_fatal(pth.span,
+                      "expected macro name without module separators");
     }
     let extname = &pth.segments[0].identifier;
     let extnamestr = ident_to_str(extname);
-    let (fully_expanded, sp) = match (*extsbox).find(&extname.name) {
-        None =>
-            cx.span_fatal(pth.span, fmt!("macro undefined: '%s'", extnamestr)),
+    let fully_expanded: @ast::Stmt = match (*extsbox).find(&extname.name) {
+        None => {
+            cx.span_fatal(pth.span, fmt!("macro undefined: '%s'", extnamestr))
+        }
 
         Some(@SE(NormalTT(expandfun, exp_span))) => {
             cx.bt_push(ExpnInfo {
-                call_site: sp,
-                callee: NameAndSpan { name: extnamestr, span: exp_span }
+                call_site: s.span,
+                callee: NameAndSpan {
+                    name: extnamestr,
+                    span: exp_span,
+                }
             });
             let fm = fresh_mark();
             // mark before expansion:
@@ -426,24 +483,32 @@ pub fn expand_stmt(extsbox: @mut SyntaxEnv,
             // not the current mac.span.
             let mac_span = original_span(cx);
 
-            let expanded = match expandfun(cx, mac_span.call_site,
-                                           marked_tts, marked_ctxt) {
-                MRExpr(e) =>
-                    @codemap::Spanned { node: StmtExpr(e, ast::DUMMY_NODE_ID),
-                                        span: e.span},
-                MRAny(_,_,stmt_mkr) => stmt_mkr(),
+            let expanded = match expandfun.expand(cx,
+                                                  mac_span.call_site,
+                                                  marked_tts,
+                                                  marked_ctxt) {
+                MRExpr(e) => {
+                    @codemap::Spanned {
+                        node: StmtExpr(e, ast::DUMMY_NODE_ID),
+                        span: e.span,
+                    }
+                }
+                MRAny(any_macro) => any_macro.make_stmt(),
                 _ => cx.span_fatal(
                     pth.span,
                     fmt!("non-stmt macro in stmt pos: %s", extnamestr))
             };
             let marked_after = mark_stmt(expanded,fm);
 
-            //keep going, outside-in
+            // Keep going, outside-in.
             let fully_expanded = match fld.fold_stmt(marked_after) {
                 Some(stmt) => {
                     let fully_expanded = &stmt.node;
                     cx.bt_pop();
-                    (*fully_expanded).clone()
+                    @Spanned {
+                        span: stmt.span,
+                        node: (*fully_expanded).clone(),
+                    }
                 }
                 None => {
                     cx.span_fatal(pth.span,
@@ -451,7 +516,7 @@ pub fn expand_stmt(extsbox: @mut SyntaxEnv,
                 }
             };
 
-            (fully_expanded, sp)
+            fully_expanded
         }
 
         _ => {
@@ -460,24 +525,28 @@ pub fn expand_stmt(extsbox: @mut SyntaxEnv,
         }
     };
 
-    (match fully_expanded {
-        StmtExpr(e, stmt_id) if semi => Some(StmtSemi(e, stmt_id)),
-        _ => { Some(fully_expanded) } /* might already have a semi */
-    }, sp)
-
+    match fully_expanded.node {
+        StmtExpr(e, stmt_id) if semi => {
+            Some(@Spanned {
+                span: fully_expanded.span,
+                node: StmtSemi(e, stmt_id),
+            })
+        }
+        _ => Some(fully_expanded), /* might already have a semi */
+    }
 }
 
 // expand a non-macro stmt. this is essentially the fallthrough for
 // expand_stmt, above.
-fn expand_non_macro_stmt (exts: SyntaxEnv,
-                          s: &Stmt_,
-                          sp: Span,
-                          fld: @ast_fold,
-                          orig: @fn(&Stmt_, Span, @ast_fold) -> (Option<Stmt_>, Span))
-    -> (Option<Stmt_>,Span) {
+fn expand_non_macro_stmt(exts: SyntaxEnv, s: &Stmt, fld: &MacroExpander)
+                         -> Option<@Stmt> {
     // is it a let?
-    match *s {
-        StmtDecl(@Spanned{node: DeclLocal(ref local), span: stmt_span}, node_id) => {
+    match s.node {
+        StmtDecl(@Spanned {
+            node: DeclLocal(ref local),
+            span: stmt_span
+        },
+        node_id) => {
             let block_info = get_block_info(exts);
             let pending_renames = block_info.pending_renames;
 
@@ -515,19 +584,24 @@ fn expand_non_macro_stmt (exts: SyntaxEnv,
             // also, don't forget to expand the init:
             let new_init_opt = init.map(|e| fld.fold_expr(*e));
             let rewritten_local =
-                @Local{is_mutbl:is_mutbl,
-                       ty:ty,
-                       pat:rewritten_pat,
-                       init:new_init_opt,
-                       id:id,
-                       span:span};
-            (Some(StmtDecl(@Spanned{node:DeclLocal(rewritten_local),
-                                     span: stmt_span},node_id)),
-             sp)
+                @Local {
+                    is_mutbl: is_mutbl,
+                    ty: ty,
+                    pat: rewritten_pat,
+                    init: new_init_opt,
+                    id: id,
+                    span: span,
+                };
+            Some(@Spanned {
+                node: StmtDecl(@Spanned {
+                        node: DeclLocal(rewritten_local),
+                        span: stmt_span
+                    },
+                    node_id),
+                span: span
+            })
         },
-        _ => {
-            orig(s, sp, fld)
-        }
+        _ => noop_fold_stmt(s, fld),
     }
 }
 
@@ -628,18 +702,18 @@ pub fn new_path_finder(paths: @mut ~[ast::Path]) -> @mut Visitor<()> {
 
 // expand a block. pushes a new exts_frame, then calls expand_block_elts
 pub fn expand_block(extsbox: @mut SyntaxEnv,
-                    _cx: @ExtCtxt,
+                    _: @ExtCtxt,
                     blk: &Block,
-                    fld: @ast_fold,
-                    _orig: @fn(&Block, @ast_fold) -> Block)
-                 -> Block {
+                    fld: &MacroExpander)
+                    -> Block {
     // see note below about treatment of exts table
     with_exts_frame!(extsbox,false,
                      expand_block_elts(*extsbox, blk, fld))
 }
 
 // expand the elements of a block.
-pub fn expand_block_elts(exts: SyntaxEnv, b: &Block, fld: @ast_fold) -> Block {
+pub fn expand_block_elts(exts: SyntaxEnv, b: &Block, fld: &MacroExpander)
+                         -> Block {
     let block_info = get_block_info(exts);
     let pending_renames = block_info.pending_renames;
     let rename_fld = renames_to_fold(pending_renames);
@@ -680,9 +754,47 @@ fn get_block_info(exts : SyntaxEnv) -> BlockInfo {
     }
 }
 
+struct IdentRenamer {
+    renames: @mut ~[(ast::Ident,ast::Name)],
+}
+
+impl ast_fold for IdentRenamer {
+    fn fold_ident(&self, id: ast::Ident) -> ast::Ident {
+        let new_ctxt = self.renames.iter().fold(id.ctxt, |ctxt, &(from, to)| {
+            new_rename(from, to, ctxt)
+        });
+        ast::Ident {
+            name: id.name,
+            ctxt: new_ctxt,
+        }
+    }
+}
+
+// given a mutable list of renames, return a tree-folder that applies those
+// renames.
+pub fn renames_to_fold(renames: @mut ~[(ast::Ident,ast::Name)]) -> @ast_fold {
+    @IdentRenamer {
+        renames: renames,
+    } as @ast_fold
+}
+
+// perform a bunch of renames
+fn apply_pending_renames(folder : @ast_fold, stmt : ast::Stmt) -> @ast::Stmt {
+    match folder.fold_stmt(&stmt) {
+        Some(s) => s,
+        None => fail!(fmt!("renaming of stmt produced None"))
+    }
+}
+
+
+
 pub fn new_span(cx: @ExtCtxt, sp: Span) -> Span {
     /* this discards information in the case of macro-defining macros */
-    return Span {lo: sp.lo, hi: sp.hi, expn_info: cx.backtrace()};
+    Span {
+        lo: sp.lo,
+        hi: sp.hi,
+        expn_info: cx.backtrace(),
+    }
 }
 
 // FIXME (#2247): this is a moderately bad kludge to inject some macros into
@@ -1025,10 +1137,28 @@ pub fn std_macros() -> @str {
 }";
 }
 
+struct Injector {
+    sm: @ast::item,
+}
+
+impl ast_fold for Injector {
+    fn fold_mod(&self, module: &ast::_mod) -> ast::_mod {
+        // Just inject the standard macros at the start of the first module
+        // in the crate: that is, at the start of the crate file itself.
+        let items = vec::append(~[ self.sm ], module.items);
+        ast::_mod {
+            items: items,
+            ..(*module).clone() // FIXME #2543: Bad copy.
+        }
+    }
+}
+
 // add a bunch of macros as though they were placed at the head of the
 // program (ick). This should run before cfg stripping.
 pub fn inject_std_macros(parse_sess: @mut parse::ParseSess,
-                         cfg: ast::CrateConfig, c: &Crate) -> @Crate {
+                         cfg: ast::CrateConfig,
+                         c: @Crate)
+                         -> @Crate {
     let sm = match parse_item_from_source_str(@"<std-macros>",
                                               std_macros(),
                                               cfg.clone(),
@@ -1038,48 +1168,80 @@ pub fn inject_std_macros(parse_sess: @mut parse::ParseSess,
         None => fail!("expected core macros to parse correctly")
     };
 
-    let injecter = @AstFoldFns {
-        fold_mod: |modd, _| {
-            // just inject the std macros at the start of the first
-            // module in the crate (i.e the crate file itself.)
-            let items = vec::append(~[sm], modd.items);
-            ast::_mod {
-                items: items,
-                // FIXME #2543: Bad copy.
-                .. (*modd).clone()
-            }
-        },
-        .. *default_ast_fold()
-    };
-    @make_fold(injecter).fold_crate(c)
+    let injector = @Injector {
+        sm: sm,
+    } as @ast_fold;
+    @injector.fold_crate(c)
+}
+
+struct NoOpFolder {
+    contents: (),
+}
+
+impl ast_fold for NoOpFolder {}
+
+struct MacroExpander {
+    extsbox: @mut SyntaxEnv,
+    cx: @ExtCtxt,
+}
+
+impl ast_fold for MacroExpander {
+    fn fold_expr(&self, expr: @ast::Expr) -> @ast::Expr {
+        expand_expr(self.extsbox,
+                    self.cx,
+                    expr,
+                    self)
+    }
+
+    fn fold_mod(&self, module: &ast::_mod) -> ast::_mod {
+        expand_mod_items(self.extsbox,
+                         self.cx,
+                         module,
+                         self)
+    }
+
+    fn fold_item(&self, item: @ast::item) -> Option<@ast::item> {
+        expand_item(self.extsbox,
+                    self.cx,
+                    item,
+                    self)
+    }
+
+    fn fold_stmt(&self, stmt: &ast::Stmt) -> Option<@ast::Stmt> {
+        expand_stmt(self.extsbox,
+                    self.cx,
+                    stmt,
+                    self)
+    }
+
+    fn fold_block(&self, block: &ast::Block) -> ast::Block {
+        expand_block(self.extsbox,
+                     self.cx,
+                     block,
+                     self)
+    }
+
+    fn new_span(&self, span: Span) -> Span {
+        new_span(self.cx, span)
+    }
 }
 
 pub fn expand_crate(parse_sess: @mut parse::ParseSess,
-                    cfg: ast::CrateConfig, c: &Crate) -> @Crate {
+                    cfg: ast::CrateConfig,
+                    c: &Crate) -> @Crate {
     // adding *another* layer of indirection here so that the block
     // visitor can swap out one exts table for another for the duration
     // of the block.  The cleaner alternative would be to thread the
     // exts table through the fold, but that would require updating
     // every method/element of AstFoldFns in fold.rs.
-    let extsbox = @mut syntax_expander_table();
-    let afp = default_ast_fold();
+    let extsbox = syntax_expander_table();
     let cx = ExtCtxt::new(parse_sess, cfg.clone());
-    let f_pre = @AstFoldFns {
-        fold_expr: |expr,span,recur|
-            expand_expr(extsbox, cx, expr, span, recur, afp.fold_expr),
-        fold_mod: |modd,recur|
-            expand_mod_items(extsbox, cx, modd, recur, afp.fold_mod),
-        fold_item: |item,recur|
-            expand_item(extsbox, cx, item, recur, afp.fold_item),
-        fold_stmt: |stmt,span,recur|
-            expand_stmt(extsbox, cx, stmt, span, recur, afp.fold_stmt),
-        fold_block: |blk,recur|
-            expand_block(extsbox, cx, blk, recur, afp.fold_block),
-        new_span: |a| new_span(cx, a),
-        .. *afp};
-    let f = make_fold(f_pre);
-
-    let ret = @f.fold_crate(c);
+    let expander = @MacroExpander {
+        extsbox: @mut extsbox,
+        cx: cx,
+    } as @ast_fold;
+
+    let ret = @expander.fold_crate(c);
     parse_sess.span_diagnostic.handler().abort_if_errors();
     return ret;
 }
@@ -1145,53 +1307,56 @@ impl CtxtFn for Repainter {
     }
 }
 
-// given a function from ctxts to ctxts, produce
-// an ast_fold that applies that function to all ctxts:
-pub fn fun_to_ctxt_folder<T : 'static + CtxtFn>(cf: @T) -> @AstFoldFns {
-    let afp = default_ast_fold();
-    let fi : @fn(ast::Ident, @ast_fold) -> ast::Ident =
-        |ast::Ident{name, ctxt}, _| {
-        ast::Ident{name:name,ctxt:cf.f(ctxt)}
-    };
-    let fm : @fn(&ast::mac_, Span, @ast_fold) -> (ast::mac_,Span) =
-        |m, sp, fld| {
-        match *m {
-            mac_invoc_tt(ref path, ref tts, ctxt) =>
-            (mac_invoc_tt(fld.fold_path(path),
-                          fold_tts(*tts,fld),
-                          cf.f(ctxt)),
-            sp)
-        }
+pub struct ContextWrapper {
+    context_function: @CtxtFn,
+}
 
-    };
-    @AstFoldFns{
-        fold_ident : fi,
-        fold_mac : fm,
-        .. *afp
+impl ast_fold for ContextWrapper {
+    fn fold_ident(&self, id: ast::Ident) -> ast::Ident {
+        let ast::Ident {
+            name,
+            ctxt
+        } = id;
+        ast::Ident {
+            name: name,
+            ctxt: self.context_function.f(ctxt),
+        }
+    }
+    fn fold_mac(&self, m: &ast::mac) -> ast::mac {
+        let macro = match m.node {
+            mac_invoc_tt(ref path, ref tts, ctxt) => {
+                mac_invoc_tt(self.fold_path(path),
+                             fold_tts(*tts, self),
+                             self.context_function.f(ctxt))
+            }
+        };
+        Spanned {
+            node: macro,
+            span: m.span,
+        }
     }
 }
 
-
-
-// given a mutable list of renames, return a tree-folder that applies those
-// renames.
-// FIXME #4536: currently pub to allow testing
-pub fn renames_to_fold(renames : @mut ~[(ast::Ident,ast::Name)]) -> @AstFoldFns {
-    fun_to_ctxt_folder(@MultiRenamer{renames : renames})
+// given a function from ctxts to ctxts, produce
+// an ast_fold that applies that function to all ctxts:
+pub fn fun_to_ctxt_folder<T : 'static + CtxtFn>(cf: @T) -> @ContextWrapper {
+    @ContextWrapper {
+        context_function: cf as @CtxtFn,
+    }
 }
 
 // just a convenience:
-pub fn new_mark_folder(m : Mrk) -> @AstFoldFns {
+pub fn new_mark_folder(m: Mrk) -> @ContextWrapper {
     fun_to_ctxt_folder(@Marker{mark:m})
 }
 
-pub fn new_rename_folder(from : ast::Ident, to : ast::Name) -> @AstFoldFns {
+pub fn new_rename_folder(from: ast::Ident, to: ast::Name) -> @ContextWrapper {
     fun_to_ctxt_folder(@Renamer{from:from,to:to})
 }
 
 // apply a given mark to the given token trees. Used prior to expansion of a macro.
 fn mark_tts(tts : &[token_tree], m : Mrk) -> ~[token_tree] {
-    fold_tts(tts,new_mark_folder(m) as @ast_fold)
+    fold_tts(tts,new_mark_folder(m))
 }
 
 // apply a given mark to the given expr. Used following the expansion of a macro.
@@ -1359,7 +1524,7 @@ mod test {
         let ident_str = @"x";
         let tts = string_to_tts(ident_str);
         let fm = fresh_mark();
-        let marked_once = fold::fold_tts(tts,new_mark_folder(fm) as @fold::ast_fold);
+        let marked_once = fold::fold_tts(tts,new_mark_folder(fm));
         assert_eq!(marked_once.len(),1);
         let marked_once_ctxt =
             match marked_once[0] {
@@ -1475,9 +1640,10 @@ mod test {
                   macro_rules! user(($x:ident) => ({letty!($x); $x}))
                   fn main() -> int {user!(z)}",
                  ~[~[0]], false),
-                // FIXME #8062: this test exposes a *potential* bug; our system does
-                // not behave exactly like MTWT, but I haven't thought of a way that
-                // this could cause a bug in Rust, yet.
+                // no longer a fixme #8062: this test exposes a *potential* bug; our system does
+                // not behave exactly like MTWT, but a conversation with Matthew Flatt
+                // suggests that this can only occur in the presence of local-expand, which
+                // we have no plans to support.
                 // ("fn main() {let hrcoo = 19; macro_rules! getx(()=>(hrcoo)); getx!();}",
                 // ~[~[0]], true)
                 // FIXME #6994: the next string exposes the bug referred to in issue 6994, so I'm
@@ -1490,6 +1656,7 @@ mod test {
                 //   fn a(){g!(z)}"
                 // create a really evil test case where a $x appears inside a binding of $x
                 // but *shouldnt* bind because it was inserted by a different macro....
+                // can't write this test case until we have macro-generating macros.
             ];
         for (idx,s) in tests.iter().enumerate() {
             run_renaming_test(s,idx);
diff --git a/src/libsyntax/ext/fmt.rs b/src/libsyntax/ext/fmt.rs
index 9adb02ecc98..d48fa03c0ef 100644
--- a/src/libsyntax/ext/fmt.rs
+++ b/src/libsyntax/ext/fmt.rs
@@ -38,7 +38,7 @@ pub fn expand_syntax_ext(cx: @ExtCtxt, sp: Span, tts: &[ast::token_tree])
     fn parse_fmt_err_(cx: @ExtCtxt, sp: Span, msg: &str) -> ! {
         cx.span_fatal(sp, msg);
     }
-    let parse_fmt_err: @fn(&str) -> ! = |s| parse_fmt_err_(cx, fmtspan, s);
+    let parse_fmt_err: &fn(&str) -> ! = |s| parse_fmt_err_(cx, fmtspan, s);
     let pieces = parse_fmt_string(fmt, parse_fmt_err);
     MRExpr(pieces_to_expr(cx, sp, pieces, args))
 }
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index 74de8eaa09e..3fd394b3652 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -12,9 +12,9 @@ use ast::{Ident, matcher_, matcher, match_tok, match_nonterminal, match_seq};
 use ast::{tt_delim};
 use ast;
 use codemap::{Span, Spanned, dummy_sp};
-use ext::base::{ExtCtxt, MacResult, MRAny, MRDef, MacroDef, NormalTT};
+use ext::base::{AnyMacro, ExtCtxt, MacResult, MRAny, MRDef, MacroDef};
+use ext::base::{NormalTT, SyntaxExpanderTTTrait};
 use ext::base;
-use ext::expand;
 use ext::tt::macro_parser::{error};
 use ext::tt::macro_parser::{named_match, matched_seq, matched_nonterminal};
 use ext::tt::macro_parser::{parse, parse_or_else, success, failure};
@@ -24,6 +24,112 @@ use parse::token::{get_ident_interner, special_idents, gensym_ident, ident_to_st
 use parse::token::{FAT_ARROW, SEMI, nt_matchers, nt_tt};
 use print;
 
+struct ParserAnyMacro {
+    parser: @Parser,
+}
+
+impl AnyMacro for ParserAnyMacro {
+    fn make_expr(&self) -> @ast::Expr {
+        self.parser.parse_expr()
+    }
+    fn make_item(&self) -> Option<@ast::item> {
+        self.parser.parse_item(~[])     // no attrs
+    }
+    fn make_stmt(&self) -> @ast::Stmt {
+        self.parser.parse_stmt(~[])     // no attrs
+    }
+}
+
+struct MacroRulesSyntaxExpanderTTFun {
+    name: Ident,
+    lhses: @~[@named_match],
+    rhses: @~[@named_match],
+}
+
+impl SyntaxExpanderTTTrait for MacroRulesSyntaxExpanderTTFun {
+    fn expand(&self,
+              cx: @ExtCtxt,
+              sp: Span,
+              arg: &[ast::token_tree],
+              _: ast::SyntaxContext)
+              -> MacResult {
+        generic_extension(cx, sp, self.name, arg, *self.lhses, *self.rhses)
+    }
+}
+
+// Given `lhses` and `rhses`, this is the new macro we create
+fn generic_extension(cx: @ExtCtxt,
+                     sp: Span,
+                     name: Ident,
+                     arg: &[ast::token_tree],
+                     lhses: &[@named_match],
+                     rhses: &[@named_match])
+                     -> MacResult {
+    if cx.trace_macros() {
+        printfln!("%s! { %s }",
+                  cx.str_of(name),
+                  print::pprust::tt_to_str(
+                      &ast::tt_delim(@mut arg.to_owned()),
+                      get_ident_interner()));
+    }
+
+    // Which arm's failure should we report? (the one furthest along)
+    let mut best_fail_spot = dummy_sp();
+    let mut best_fail_msg = ~"internal error: ran no matchers";
+
+    let s_d = cx.parse_sess().span_diagnostic;
+
+    for (i, lhs) in lhses.iter().enumerate() { // try each arm's matchers
+        match *lhs {
+          @matched_nonterminal(nt_matchers(ref mtcs)) => {
+            // `none` is because we're not interpolating
+            let arg_rdr = new_tt_reader(
+                s_d,
+                None,
+                arg.to_owned()
+            ) as @mut reader;
+            match parse(cx.parse_sess(), cx.cfg(), arg_rdr, *mtcs) {
+              success(named_matches) => {
+                let rhs = match rhses[i] {
+                    // okay, what's your transcriber?
+                    @matched_nonterminal(nt_tt(@ref tt)) => {
+                        match (*tt) {
+                            // cut off delimiters; don't parse 'em
+                            tt_delim(ref tts) => {
+                                (*tts).slice(1u,(*tts).len()-1u).to_owned()
+                            }
+                            _ => cx.span_fatal(
+                                sp, "macro rhs must be delimited")
+                        }
+                    },
+                    _ => cx.span_bug(sp, "bad thing in rhs")
+                };
+                // rhs has holes ( `$id` and `$(...)` that need filled)
+                let trncbr = new_tt_reader(s_d, Some(named_matches),
+                                           rhs);
+                let p = @Parser(cx.parse_sess(),
+                                cx.cfg(),
+                                trncbr as @mut reader);
+
+                // Let the context choose how to interpret the result.
+                // Weird, but useful for X-macros.
+                return MRAny(@ParserAnyMacro {
+                    parser: p,
+                } as @AnyMacro)
+              }
+              failure(sp, ref msg) => if sp.lo >= best_fail_spot.lo {
+                best_fail_spot = sp;
+                best_fail_msg = (*msg).clone();
+              },
+              error(sp, ref msg) => cx.span_fatal(sp, (*msg))
+            }
+          }
+          _ => cx.bug("non-matcher found in parsed lhses")
+        }
+    }
+    cx.span_fatal(best_fail_spot, best_fail_msg);
+}
+
 // this procedure performs the expansion of the
 // macro_rules! macro. It parses the RHS and adds
 // an extension to the current context.
@@ -31,10 +137,8 @@ pub fn add_new_extension(cx: @ExtCtxt,
                          sp: Span,
                          name: Ident,
                          arg: ~[ast::token_tree],
-                         stx_ctxt: ast::SyntaxContext)
-                      -> base::MacResult {
-    let arg = expand::mtwt_cancel_outer_mark(arg,stx_ctxt);
-    // Wrap a matcher_ in a spanned to produce a matcher.
+                         _: ast::SyntaxContext)
+                         -> base::MacResult {
     // these spans won't matter, anyways
     fn ms(m: matcher_) -> matcher {
         Spanned {
@@ -82,11 +186,13 @@ pub fn add_new_extension(cx: @ExtCtxt,
     };
 
     // Given `lhses` and `rhses`, this is the new macro we create
-    fn generic_extension(cx: @ExtCtxt, sp: Span, name: Ident,
+    fn generic_extension(cx: @ExtCtxt,
+                         sp: Span,
+                         name: Ident,
                          arg: &[ast::token_tree],
-                         lhses: &[@named_match], rhses: &[@named_match])
-    -> MacResult {
-
+                         lhses: &[@named_match],
+                         rhses: &[@named_match])
+                         -> MacResult {
         if cx.trace_macros() {
             printfln!("%s! { %s }",
                       cx.str_of(name),
@@ -135,9 +241,9 @@ pub fn add_new_extension(cx: @ExtCtxt,
 
                     // Let the context choose how to interpret the result.
                     // Weird, but useful for X-macros.
-                    return MRAny(|| p.parse_expr(),
-                                  || p.parse_item(~[/* no attrs*/]),
-                                  || p.parse_stmt(~[/* no attrs*/]));
+                    return MRAny(@ParserAnyMacro {
+                        parser: p
+                    } as @AnyMacro);
                   }
                   failure(sp, ref msg) => if sp.lo >= best_fail_spot.lo {
                     best_fail_spot = sp;
@@ -152,10 +258,13 @@ pub fn add_new_extension(cx: @ExtCtxt,
         cx.span_fatal(best_fail_spot, best_fail_msg);
     }
 
-    let exp: @fn(@ExtCtxt, Span, &[ast::token_tree], ctxt: ast::SyntaxContext) -> MacResult =
-        |cx, sp, arg, _ctxt| generic_extension(cx, sp, name, arg, *lhses, *rhses);
+    let exp = @MacroRulesSyntaxExpanderTTFun {
+        name: name,
+        lhses: lhses,
+        rhses: rhses,
+    } as @SyntaxExpanderTTTrait;
 
-    return MRDef(MacroDef{
+    return MRDef(MacroDef {
         name: ident_to_str(&name),
         ext: NormalTT(exp, Some(sp))
     });
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 5472c61a155..a25f267c458 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -14,227 +14,434 @@ use codemap::{Span, Spanned};
 use parse::token;
 use opt_vec::OptVec;
 
-// this file defines an ast_fold trait for objects that can perform
-// a "fold" on Rust ASTs. It also contains a structure that implements
-// that trait, and a "default_fold" whose fields contain closures
-// that perform "default traversals", visiting all of the sub-elements
-// and re-assembling the result. The "fun_to_ident_folder" in the
-// test module provides a simple example of creating a very simple
-// fold that only looks at identifiers.
-
+// We may eventually want to be able to fold over type parameters, too.
 pub trait ast_fold {
-    fn fold_crate(@self, &Crate) -> Crate;
-    fn fold_view_item(@self, &view_item) -> view_item;
-    fn fold_foreign_item(@self, @foreign_item) -> @foreign_item;
-    fn fold_item(@self, @item) -> Option<@item>;
-    fn fold_struct_field(@self, @struct_field) -> @struct_field;
-    fn fold_item_underscore(@self, &item_) -> item_;
-    fn fold_type_method(@self, m: &TypeMethod) -> TypeMethod;
-    fn fold_method(@self, @method) -> @method;
-    fn fold_block(@self, &Block) -> Block;
-    fn fold_stmt(@self, &Stmt) -> Option<@Stmt>;
-    fn fold_arm(@self, &Arm) -> Arm;
-    fn fold_pat(@self, @Pat) -> @Pat;
-    fn fold_decl(@self, @Decl) -> Option<@Decl>;
-    fn fold_expr(@self, @Expr) -> @Expr;
-    fn fold_ty(@self, &Ty) -> Ty;
-    fn fold_mod(@self, &_mod) -> _mod;
-    fn fold_foreign_mod(@self, &foreign_mod) -> foreign_mod;
-    fn fold_variant(@self, &variant) -> variant;
-    fn fold_ident(@self, Ident) -> Ident;
-    fn fold_path(@self, &Path) -> Path;
-    fn fold_local(@self, @Local) -> @Local;
-    fn fold_mac(@self, &mac) -> mac;
-    fn map_exprs(@self, @fn(@Expr) -> @Expr, &[@Expr]) -> ~[@Expr];
-    fn new_id(@self, NodeId) -> NodeId;
-    fn new_span(@self, Span) -> Span;
-
-    // New style, using default methods:
-
-    fn fold_variant_arg(@self, va: &variant_arg) -> variant_arg {
-        variant_arg {
-            ty: self.fold_ty(&va.ty),
-            id: self.new_id(va.id)
-        }
-    }
-
-    fn fold_spanned<T>(@self, s: &Spanned<T>, f: &fn(&T) -> T) -> Spanned<T> {
-        Spanned {
-            node: f(&s.node),
-            span: self.new_span(s.span)
-        }
+    fn fold_crate(&self, c: &Crate) -> Crate {
+        noop_fold_crate(c, self)
     }
 
-    fn fold_view_path(@self, vp: &view_path) -> view_path {
-        self.fold_spanned(vp, |v| self.fold_view_path_(v))
+    fn fold_meta_items(&self, meta_items: &[@MetaItem]) -> ~[@MetaItem] {
+        meta_items.map(|x| fold_meta_item_(*x, self))
     }
 
-    fn fold_view_paths(@self, vps: &[@view_path]) -> ~[@view_path] {
-        vps.map(|vp| @self.fold_view_path(*vp))
+    fn fold_view_paths(&self, view_paths: &[@view_path]) -> ~[@view_path] {
+        view_paths.map(|view_path| {
+            let inner_view_path = match view_path.node {
+                view_path_simple(ref ident, ref path, node_id) => {
+                    view_path_simple(ident.clone(),
+                                     self.fold_path(path),
+                                     self.new_id(node_id))
+                }
+                view_path_glob(ref path, node_id) => {
+                    view_path_glob(self.fold_path(path), self.new_id(node_id))
+                }
+                view_path_list(ref path, ref path_list_idents, node_id) => {
+                    view_path_list(self.fold_path(path),
+                                   path_list_idents.map(|path_list_ident| {
+                                    let id = self.new_id(path_list_ident.node
+                                                                        .id);
+                                    Spanned {
+                                        node: path_list_ident_ {
+                                            name: path_list_ident.node
+                                                                 .name
+                                                                 .clone(),
+                                            id: id,
+                                        },
+                                        span: self.new_span(
+                                            path_list_ident.span)
+                                   }
+                                  }),
+                                  self.new_id(node_id))
+                }
+            };
+            @Spanned {
+                node: inner_view_path,
+                span: self.new_span(view_path.span),
+            }
+        })
     }
 
-    fn fold_view_path_(@self, vp: &view_path_) -> view_path_ {
-        match *vp {
-            view_path_simple(ident, ref path, node_id) => {
-                view_path_simple(self.fold_ident(ident),
-                                 self.fold_path(path),
-                                 self.new_id(node_id))
-            }
-            view_path_glob(ref path, node_id) => {
-                view_path_glob(self.fold_path(path),
-                               self.new_id(node_id))
+    fn fold_view_item(&self, vi: &view_item) -> view_item {
+        let inner_view_item = match vi.node {
+            view_item_extern_mod(ref ident,
+                                 string,
+                                 ref meta_items,
+                                 node_id) => {
+                view_item_extern_mod(ident.clone(),
+                                     string,
+                                     self.fold_meta_items(*meta_items),
+                                     self.new_id(node_id))
             }
-            view_path_list(ref path, ref idents, node_id) => {
-                view_path_list(self.fold_path(path),
-                               self.fold_path_list_idents(*idents),
-                               self.new_id(node_id))
+            view_item_use(ref view_paths) => {
+                view_item_use(self.fold_view_paths(*view_paths))
             }
+        };
+        view_item {
+            node: inner_view_item,
+            attrs: vi.attrs.map(|a| fold_attribute_(*a, self)),
+            vis: vi.vis,
+            span: self.new_span(vi.span),
+        }
+    }
+
+    fn fold_foreign_item(&self, ni: @foreign_item) -> @foreign_item {
+        let fold_attribute = |x| fold_attribute_(x, self);
+
+        @ast::foreign_item {
+            ident: self.fold_ident(ni.ident),
+            attrs: ni.attrs.map(|x| fold_attribute(*x)),
+            node:
+                match ni.node {
+                    foreign_item_fn(ref fdec, ref generics) => {
+                        foreign_item_fn(
+                            ast::fn_decl {
+                                inputs: fdec.inputs.map(|a| fold_arg_(a,
+                                                                      self)),
+                                output: self.fold_ty(&fdec.output),
+                                cf: fdec.cf,
+                            },
+                            fold_generics(generics, self))
+                    }
+                    foreign_item_static(ref t, m) => {
+                        foreign_item_static(self.fold_ty(t), m)
+                    }
+                },
+            id: self.new_id(ni.id),
+            span: self.new_span(ni.span),
+            vis: ni.vis,
         }
     }
 
-    fn fold_path_list_idents(@self, idents: &[path_list_ident]) -> ~[path_list_ident] {
-        idents.map(|i| self.fold_path_list_ident(i))
+    fn fold_item(&self, i: @item) -> Option<@item> {
+        noop_fold_item(i, self)
     }
 
-    fn fold_path_list_ident(@self, ident: &path_list_ident) -> path_list_ident {
-        self.fold_spanned(ident, |i| self.fold_path_list_ident_(i))
-    }
+    fn fold_struct_field(&self, sf: @struct_field) -> @struct_field {
+        let fold_attribute = |x| fold_attribute_(x, self);
 
-    fn fold_path_list_ident_(@self, ident: &path_list_ident_) -> path_list_ident_ {
-        path_list_ident_ {
-            name: self.fold_ident(ident.name),
-            id: self.new_id(ident.id)
+        @Spanned {
+            node: ast::struct_field_ {
+                kind: sf.node.kind,
+                id: self.new_id(sf.node.id),
+                ty: self.fold_ty(&sf.node.ty),
+                attrs: sf.node.attrs.map(|e| fold_attribute(*e))
+            },
+            span: self.new_span(sf.span)
         }
     }
 
-    fn fold_arg(@self, a: &arg) -> arg {
-        arg {
-            is_mutbl: a.is_mutbl,
-            ty: self.fold_ty(&a.ty),
-            pat: self.fold_pat(a.pat),
-            id: self.new_id(a.id),
+    fn fold_item_underscore(&self, i: &item_) -> item_ {
+        noop_fold_item_underscore(i, self)
+    }
+
+    fn fold_type_method(&self, m: &TypeMethod) -> TypeMethod {
+        noop_fold_type_method(m, self)
+    }
+
+    fn fold_method(&self, m: @method) -> @method {
+        @ast::method {
+            ident: self.fold_ident(m.ident),
+            attrs: m.attrs.map(|a| fold_attribute_(*a, self)),
+            generics: fold_generics(&m.generics, self),
+            explicit_self: m.explicit_self,
+            purity: m.purity,
+            decl: fold_fn_decl(&m.decl, self),
+            body: self.fold_block(&m.body),
+            id: self.new_id(m.id),
+            span: self.new_span(m.span),
+            self_id: self.new_id(m.self_id),
+            vis: m.vis,
         }
     }
 
-    fn fold_trait_ref(@self, p: &trait_ref) -> trait_ref {
-        trait_ref {
-            path: self.fold_path(&p.path),
-            ref_id: self.new_id(p.ref_id),
+    fn fold_block(&self, b: &Block) -> Block {
+        noop_fold_block(b, self)
+    }
+
+    fn fold_stmt(&self, s: &Stmt) -> Option<@Stmt> {
+        noop_fold_stmt(s, self)
+    }
+
+    fn fold_arm(&self, a: &Arm) -> Arm {
+        Arm {
+            pats: a.pats.map(|x| self.fold_pat(*x)),
+            guard: a.guard.map_move(|x| self.fold_expr(x)),
+            body: self.fold_block(&a.body),
         }
     }
 
-    fn fold_ty_param_bound(@self, tpb: &TyParamBound) -> TyParamBound {
-        match *tpb {
-            TraitTyParamBound(ref ty) => {
-                TraitTyParamBound(self.fold_trait_ref(ty))
+    fn fold_pat(&self, p: @Pat) -> @Pat {
+        let node = match p.node {
+            PatWild => PatWild,
+            PatIdent(binding_mode, ref pth, ref sub) => {
+                PatIdent(binding_mode,
+                         self.fold_path(pth),
+                         sub.map_move(|x| self.fold_pat(x)))
+            }
+            PatLit(e) => PatLit(self.fold_expr(e)),
+            PatEnum(ref pth, ref pats) => {
+                PatEnum(self.fold_path(pth),
+                        pats.map(|pats| pats.map(|x| self.fold_pat(*x))))
             }
-            RegionTyParamBound => {
-                RegionTyParamBound
+            PatStruct(ref pth, ref fields, etc) => {
+                let pth_ = self.fold_path(pth);
+                let fs = do fields.map |f| {
+                    ast::FieldPat {
+                        ident: f.ident,
+                        pat: self.fold_pat(f.pat)
+                    }
+                };
+                PatStruct(pth_, fs, etc)
             }
+            PatTup(ref elts) => PatTup(elts.map(|x| self.fold_pat(*x))),
+            PatBox(inner) => PatBox(self.fold_pat(inner)),
+            PatUniq(inner) => PatUniq(self.fold_pat(inner)),
+            PatRegion(inner) => PatRegion(self.fold_pat(inner)),
+            PatRange(e1, e2) => {
+                PatRange(self.fold_expr(e1), self.fold_expr(e2))
+            },
+            PatVec(ref before, ref slice, ref after) => {
+                PatVec(before.map(|x| self.fold_pat(*x)),
+                       slice.map_move(|x| self.fold_pat(x)),
+                       after.map(|x| self.fold_pat(*x)))
+            }
+        };
+
+        @Pat {
+            id: self.new_id(p.id),
+            span: self.new_span(p.span),
+            node: node,
         }
     }
 
-    fn fold_ty_param(@self, tp: &TyParam) -> TyParam {
-        TyParam {
-            ident: self.fold_ident(tp.ident),
-            id: self.new_id(tp.id),
-            bounds: tp.bounds.map(|x| self.fold_ty_param_bound(x))
+    fn fold_decl(&self, d: @Decl) -> Option<@Decl> {
+        let node = match d.node {
+            DeclLocal(ref l) => Some(DeclLocal(self.fold_local(*l))),
+            DeclItem(it) => {
+                match self.fold_item(it) {
+                    Some(it_folded) => Some(DeclItem(it_folded)),
+                    None => None,
+                }
+            }
+        };
+
+        node.map_move(|node| {
+            @Spanned {
+                node: node,
+                span: d.span,
+            }
+        })
+    }
+
+    fn fold_expr(&self, e: @Expr) -> @Expr {
+        noop_fold_expr(e, self)
+    }
+
+    fn fold_ty(&self, t: &Ty) -> Ty {
+        let node = match t.node {
+            ty_nil | ty_bot | ty_infer => t.node.clone(),
+            ty_box(ref mt) => ty_box(fold_mt(mt, self)),
+            ty_uniq(ref mt) => ty_uniq(fold_mt(mt, self)),
+            ty_vec(ref mt) => ty_vec(fold_mt(mt, self)),
+            ty_ptr(ref mt) => ty_ptr(fold_mt(mt, self)),
+            ty_rptr(region, ref mt) => ty_rptr(region, fold_mt(mt, self)),
+            ty_closure(ref f) => {
+                ty_closure(@TyClosure {
+                    sigil: f.sigil,
+                    purity: f.purity,
+                    region: f.region,
+                    onceness: f.onceness,
+                    bounds: fold_opt_bounds(&f.bounds, self),
+                    decl: fold_fn_decl(&f.decl, self),
+                    lifetimes: f.lifetimes.map(|l| fold_lifetime(l, self)),
+                })
+            }
+            ty_bare_fn(ref f) => {
+                ty_bare_fn(@TyBareFn {
+                    lifetimes: f.lifetimes.map(|l| fold_lifetime(l, self)),
+                    purity: f.purity,
+                    abis: f.abis,
+                    decl: fold_fn_decl(&f.decl, self)
+                })
+            }
+            ty_tup(ref tys) => ty_tup(tys.map(|ty| self.fold_ty(ty))),
+            ty_path(ref path, ref bounds, id) => {
+                ty_path(self.fold_path(path),
+                        fold_opt_bounds(bounds, self),
+                        self.new_id(id))
+            }
+            ty_fixed_length_vec(ref mt, e) => {
+                ty_fixed_length_vec(fold_mt(mt, self), self.fold_expr(e))
+            }
+            ty_mac(ref mac) => ty_mac(self.fold_mac(mac)),
+            ty_typeof(expr) => ty_typeof(self.fold_expr(expr)),
+        };
+        Ty {
+            id: self.new_id(t.id),
+            span: self.new_span(t.span),
+            node: node,
         }
     }
 
-    fn fold_ty_params(@self, tps: &OptVec<TyParam>) -> OptVec<TyParam> {
-        tps.map(|tp| self.fold_ty_param(tp))
+    fn fold_mod(&self, m: &_mod) -> _mod {
+        noop_fold_mod(m, self)
     }
 
-    fn fold_lifetime(@self, l: &Lifetime) -> Lifetime {
-        Lifetime {
-            id: self.new_id(l.id),
-            span: self.new_span(l.span),
-            ident: l.ident, // Folding this ident causes hygiene errors - ndm
+    fn fold_foreign_mod(&self, nm: &foreign_mod) -> foreign_mod {
+        ast::foreign_mod {
+            sort: nm.sort,
+            abis: nm.abis,
+            view_items: nm.view_items
+                          .iter()
+                          .map(|x| self.fold_view_item(x))
+                          .collect(),
+            items: nm.items
+                     .iter()
+                     .map(|x| self.fold_foreign_item(*x))
+                     .collect(),
         }
     }
 
-    fn fold_lifetimes(@self, lts: &OptVec<Lifetime>) -> OptVec<Lifetime> {
-        lts.map(|l| self.fold_lifetime(l))
+    fn fold_variant(&self, v: &variant) -> variant {
+        let kind;
+        match v.node.kind {
+            tuple_variant_kind(ref variant_args) => {
+                kind = tuple_variant_kind(variant_args.map(|x|
+                    fold_variant_arg_(x, self)))
+            }
+            struct_variant_kind(ref struct_def) => {
+                kind = struct_variant_kind(@ast::struct_def {
+                    fields: struct_def.fields.iter()
+                        .map(|f| self.fold_struct_field(*f)).collect(),
+                    ctor_id: struct_def.ctor_id.map(|c| self.new_id(*c))
+                })
+            }
+        }
+
+        let fold_attribute = |x| fold_attribute_(x, self);
+        let attrs = v.node.attrs.map(|x| fold_attribute(*x));
+
+        let de = match v.node.disr_expr {
+          Some(e) => Some(self.fold_expr(e)),
+          None => None
+        };
+        let node = ast::variant_ {
+            name: v.node.name,
+            attrs: attrs,
+            kind: kind,
+            id: self.new_id(v.node.id),
+            disr_expr: de,
+            vis: v.node.vis,
+        };
+        Spanned {
+            node: node,
+            span: self.new_span(v.span),
+        }
     }
 
+    fn fold_ident(&self, i: Ident) -> Ident {
+        i
+    }
 
-    fn fold_meta_item(@self, mi: &MetaItem) -> @MetaItem {
-        @self.fold_spanned(mi, |n| match *n {
-                MetaWord(id) => {
-                    MetaWord(id)
-                }
-                MetaList(id, ref mis) => {
-                    MetaList(id, self.fold_meta_items(*mis))
-                }
-                MetaNameValue(id, s) => {
-                    MetaNameValue(id, s)
-                }
+    fn fold_path(&self, p: &Path) -> Path {
+        ast::Path {
+            span: self.new_span(p.span),
+            global: p.global,
+            segments: p.segments.map(|segment| ast::PathSegment {
+                identifier: self.fold_ident(segment.identifier),
+                lifetime: segment.lifetime,
+                types: segment.types.map(|typ| self.fold_ty(typ)),
             })
+        }
     }
 
-    fn fold_meta_items(@self, mis: &[@MetaItem]) -> ~[@MetaItem] {
-        mis.map(|&mi| self.fold_meta_item(mi))
+    fn fold_local(&self, l: @Local) -> @Local {
+        @Local {
+            is_mutbl: l.is_mutbl,
+            ty: self.fold_ty(&l.ty),
+            pat: self.fold_pat(l.pat),
+            init: l.init.map_move(|e| self.fold_expr(e)),
+            id: self.new_id(l.id),
+            span: self.new_span(l.span),
+        }
     }
 
-    fn fold_attribute(@self, at: &Attribute) -> Attribute {
+    fn fold_mac(&self, macro: &mac) -> mac {
         Spanned {
-            span: self.new_span(at.span),
-            node: Attribute_ {
-                style: at.node.style,
-                value: self.fold_meta_item(at.node.value),
-                is_sugared_doc: at.node.is_sugared_doc
-            }
+            node: match macro.node {
+                mac_invoc_tt(ref p, ref tts, ctxt) => {
+                    mac_invoc_tt(self.fold_path(p),
+                                 fold_tts(*tts, self),
+                                 ctxt)
+                }
+            },
+            span: self.new_span(macro.span)
         }
     }
 
-    fn fold_attributes(@self, attrs: &[Attribute]) -> ~[Attribute] {
-        attrs.map(|x| self.fold_attribute(x))
+    fn map_exprs(&self, f: &fn(@Expr) -> @Expr, es: &[@Expr]) -> ~[@Expr] {
+        es.map(|x| f(*x))
+    }
+
+    fn new_id(&self, i: NodeId) -> NodeId {
+        i
+    }
+
+    fn new_span(&self, sp: Span) -> Span {
+        sp
     }
 }
 
-// We may eventually want to be able to fold over type parameters, too
-
-pub struct AstFoldFns {
-    //unlike the others, item_ is non-trivial
-    fold_crate: @fn(&Crate, @ast_fold) -> Crate,
-    fold_view_item: @fn(&view_item_, @ast_fold) -> view_item_,
-    fold_foreign_item: @fn(@foreign_item, @ast_fold) -> @foreign_item,
-    fold_item: @fn(@item, @ast_fold) -> Option<@item>,
-    fold_struct_field: @fn(@struct_field, @ast_fold) -> @struct_field,
-    fold_item_underscore: @fn(&item_, @ast_fold) -> item_,
-    fold_type_method: @fn(&TypeMethod, @ast_fold) -> TypeMethod,
-    fold_method: @fn(@method, @ast_fold) -> @method,
-    fold_block: @fn(&Block, @ast_fold) -> Block,
-    fold_stmt: @fn(&Stmt_, Span, @ast_fold) -> (Option<Stmt_>, Span),
-    fold_arm: @fn(&Arm, @ast_fold) -> Arm,
-    fold_pat: @fn(&Pat_, Span, @ast_fold) -> (Pat_, Span),
-    fold_decl: @fn(&Decl_, Span, @ast_fold) -> (Option<Decl_>, Span),
-    fold_expr: @fn(&Expr_, Span, @ast_fold) -> (Expr_, Span),
-    fold_ty: @fn(&ty_, Span, @ast_fold) -> (ty_, Span),
-    fold_mod: @fn(&_mod, @ast_fold) -> _mod,
-    fold_foreign_mod: @fn(&foreign_mod, @ast_fold) -> foreign_mod,
-    fold_variant: @fn(&variant_, Span, @ast_fold) -> (variant_, Span),
-    fold_ident: @fn(Ident, @ast_fold) -> Ident,
-    fold_path: @fn(&Path, @ast_fold) -> Path,
-    fold_local: @fn(@Local, @ast_fold) -> @Local,
-    fold_mac: @fn(&mac_, Span, @ast_fold) -> (mac_, Span),
-    map_exprs: @fn(@fn(@Expr) -> @Expr, &[@Expr]) -> ~[@Expr],
-    new_id: @fn(NodeId) -> NodeId,
-    new_span: @fn(Span) -> Span
+/* some little folds that probably aren't useful to have in ast_fold itself*/
+
+//used in noop_fold_item and noop_fold_crate and noop_fold_crate_directive
+fn fold_meta_item_<T:ast_fold>(mi: @MetaItem, fld: &T) -> @MetaItem {
+    @Spanned {
+        node:
+            match mi.node {
+                MetaWord(id) => MetaWord(id),
+                MetaList(id, ref mis) => {
+                    let fold_meta_item = |x| fold_meta_item_(x, fld);
+                    MetaList(
+                        id,
+                        mis.map(|e| fold_meta_item(*e))
+                    )
+                }
+                MetaNameValue(id, s) => MetaNameValue(id, s)
+            },
+        span: fld.new_span(mi.span) }
 }
 
-pub type ast_fold_fns = @AstFoldFns;
+//used in noop_fold_item and noop_fold_crate
+fn fold_attribute_<T:ast_fold>(at: Attribute, fld: &T) -> Attribute {
+    Spanned {
+        span: fld.new_span(at.span),
+        node: ast::Attribute_ {
+            style: at.node.style,
+            value: fold_meta_item_(at.node.value, fld),
+            is_sugared_doc: at.node.is_sugared_doc
+        }
+    }
+}
 
-/* some little folds that probably aren't useful to have in ast_fold itself*/
+//used in noop_fold_foreign_item and noop_fold_fn_decl
+fn fold_arg_<T:ast_fold>(a: &arg, fld: &T) -> arg {
+    ast::arg {
+        is_mutbl: a.is_mutbl,
+        ty: fld.fold_ty(&a.ty),
+        pat: fld.fold_pat(a.pat),
+        id: fld.new_id(a.id),
+    }
+}
 
-pub fn fold_tts(tts : &[token_tree], fld: @ast_fold) -> ~[token_tree] {
+// build a new vector of tts by appling the ast_fold's fold_ident to
+// all of the identifiers in the token trees.
+pub fn fold_tts<T:ast_fold>(tts: &[token_tree], fld: &T) -> ~[token_tree] {
     do tts.map |tt| {
         match *tt {
             tt_tok(span, ref tok) =>
             tt_tok(span,maybe_fold_ident(tok,fld)),
-            tt_delim(ref tts) =>
-            tt_delim(@mut fold_tts(**tts, fld)),
+            tt_delim(ref tts) => tt_delim(@mut fold_tts(**tts, fld)),
             tt_seq(span, ref pattern, ref sep, is_optional) =>
             tt_seq(span,
                    @mut fold_tts(**pattern, fld),
@@ -247,33 +454,68 @@ pub fn fold_tts(tts : &[token_tree], fld: @ast_fold) -> ~[token_tree] {
 }
 
 // apply ident folder if it's an ident, otherwise leave it alone
-fn maybe_fold_ident(t : &token::Token, f: @ast_fold) -> token::Token {
+fn maybe_fold_ident<T:ast_fold>(t: &token::Token, fld: &T) -> token::Token {
     match *t {
-        token::IDENT(id,followed_by_colons) =>
-        token::IDENT(f.fold_ident(id),followed_by_colons),
+        token::IDENT(id, followed_by_colons) => {
+            token::IDENT(fld.fold_ident(id), followed_by_colons)
+        }
         _ => (*t).clone()
     }
 }
 
-pub fn fold_fn_decl(decl: &ast::fn_decl, fld: @ast_fold) -> ast::fn_decl {
+pub fn fold_fn_decl<T:ast_fold>(decl: &ast::fn_decl, fld: &T)
+                                -> ast::fn_decl {
     ast::fn_decl {
-        inputs: decl.inputs.map(|x| fld.fold_arg(x)),
+        inputs: decl.inputs.map(|x| fold_arg_(x, fld)), // bad copy
         output: fld.fold_ty(&decl.output),
         cf: decl.cf,
     }
 }
 
-pub fn fold_generics(generics: &Generics, fld: @ast_fold) -> Generics {
-    Generics {ty_params: fld.fold_ty_params(&generics.ty_params),
-              lifetimes: fld.fold_lifetimes(&generics.lifetimes)}
+fn fold_ty_param_bound<T:ast_fold>(tpb: &TyParamBound, fld: &T)
+                                   -> TyParamBound {
+    match *tpb {
+        TraitTyParamBound(ref ty) => TraitTyParamBound(fold_trait_ref(ty, fld)),
+        RegionTyParamBound => RegionTyParamBound
+    }
 }
 
-pub fn noop_fold_crate(c: &Crate, fld: @ast_fold) -> Crate {
-    Crate {
-        module: fld.fold_mod(&c.module),
-        attrs: fld.fold_attributes(c.attrs),
-        config: fld.fold_meta_items(c.config),
-        span: fld.new_span(c.span),
+pub fn fold_ty_param<T:ast_fold>(tp: &TyParam, fld: &T) -> TyParam {
+    TyParam {
+        ident: tp.ident,
+        id: fld.new_id(tp.id),
+        bounds: tp.bounds.map(|x| fold_ty_param_bound(x, fld)),
+    }
+}
+
+pub fn fold_ty_params<T:ast_fold>(tps: &OptVec<TyParam>, fld: &T)
+                                  -> OptVec<TyParam> {
+    tps.map(|tp| fold_ty_param(tp, fld))
+}
+
+pub fn fold_lifetime<T:ast_fold>(l: &Lifetime, fld: &T) -> Lifetime {
+    Lifetime {
+        id: fld.new_id(l.id),
+        span: fld.new_span(l.span),
+        ident: l.ident
+    }
+}
+
+pub fn fold_lifetimes<T:ast_fold>(lts: &OptVec<Lifetime>, fld: &T)
+                                  -> OptVec<Lifetime> {
+    lts.map(|l| fold_lifetime(l, fld))
+}
+
+pub fn fold_generics<T:ast_fold>(generics: &Generics, fld: &T) -> Generics {
+    Generics {ty_params: fold_ty_params(&generics.ty_params, fld),
+              lifetimes: fold_lifetimes(&generics.lifetimes, fld)}
+}
+
+fn fold_struct_def<T:ast_fold>(struct_def: @ast::struct_def, fld: &T)
+                               -> @ast::struct_def {
+    @ast::struct_def {
+        fields: struct_def.fields.map(|f| fold_struct_field(*f, fld)),
+        ctor_id: struct_def.ctor_id.map(|cid| fld.new_id(*cid)),
     }
 }
 
@@ -291,753 +533,333 @@ fn noop_fold_view_item(vi: &view_item_, fld: @ast_fold) -> view_item_ {
     }
 }
 
-fn noop_fold_foreign_item(ni: @foreign_item, fld: @ast_fold)
-    -> @foreign_item {
-    @ast::foreign_item {
-        ident: fld.fold_ident(ni.ident),
-        attrs: fld.fold_attributes(ni.attrs),
-        node:
-            match ni.node {
-                foreign_item_fn(ref fdec, ref generics) => {
-                    foreign_item_fn(
-                        ast::fn_decl {
-                            inputs: fdec.inputs.map(|a| fld.fold_arg(a)),
-                            output: fld.fold_ty(&fdec.output),
-                            cf: fdec.cf,
-                        },
-                        fold_generics(generics, fld))
-                }
-                foreign_item_static(ref t, m) => {
-                    foreign_item_static(fld.fold_ty(t), m)
-                }
-            },
-        id: fld.new_id(ni.id),
-        span: fld.new_span(ni.span),
-        vis: ni.vis,
+fn fold_trait_ref<T:ast_fold>(p: &trait_ref, fld: &T) -> trait_ref {
+    ast::trait_ref {
+        path: fld.fold_path(&p.path),
+        ref_id: fld.new_id(p.ref_id),
     }
 }
 
-pub fn noop_fold_item(i: @item, fld: @ast_fold) -> Option<@item> {
-    Some(@ast::item { ident: fld.fold_ident(i.ident),
-                      attrs: fld.fold_attributes(i.attrs),
-                      id: fld.new_id(i.id),
-                      node: fld.fold_item_underscore(&i.node),
-                      vis: i.vis,
-                      span: fld.new_span(i.span) })
-}
-
-fn noop_fold_struct_field(sf: @struct_field, fld: @ast_fold)
-                       -> @struct_field {
+fn fold_struct_field<T:ast_fold>(f: @struct_field, fld: &T) -> @struct_field {
     @Spanned {
         node: ast::struct_field_ {
-            kind: sf.node.kind,
-            id: fld.new_id(sf.node.id),
-            ty: fld.fold_ty(&sf.node.ty),
-            attrs: fld.fold_attributes(sf.node.attrs),
+            kind: f.node.kind,
+            id: fld.new_id(f.node.id),
+            ty: fld.fold_ty(&f.node.ty),
+            attrs: f.node.attrs.map(|a| fold_attribute_(*a, fld)),
         },
-        span: sf.span
+        span: fld.new_span(f.span),
     }
 }
 
-pub fn noop_fold_type_method(m: &TypeMethod, fld: @ast_fold) -> TypeMethod {
-    TypeMethod {
-        ident: fld.fold_ident(m.ident),
-        attrs: fld.fold_attributes(m.attrs),
-        purity: m.purity,
-        decl: fold_fn_decl(&m.decl, fld),
-        generics: fold_generics(&m.generics, fld),
-        explicit_self: m.explicit_self,
-        id: fld.new_id(m.id),
-        span: fld.new_span(m.span),
+fn fold_field_<T:ast_fold>(field: Field, folder: &T) -> Field {
+    ast::Field {
+        ident: folder.fold_ident(field.ident),
+        expr: folder.fold_expr(field.expr),
+        span: folder.new_span(field.span),
     }
 }
 
-pub fn noop_fold_item_underscore(i: &item_, fld: @ast_fold) -> item_ {
+fn fold_mt<T:ast_fold>(mt: &mt, folder: &T) -> mt {
+    mt {
+        ty: ~folder.fold_ty(mt.ty),
+        mutbl: mt.mutbl,
+    }
+}
+
+fn fold_field<T:ast_fold>(f: TypeField, folder: &T) -> TypeField {
+    ast::TypeField {
+        ident: folder.fold_ident(f.ident),
+        mt: fold_mt(&f.mt, folder),
+        span: folder.new_span(f.span),
+    }
+}
+
+fn fold_opt_bounds<T:ast_fold>(b: &Option<OptVec<TyParamBound>>, folder: &T)
+                               -> Option<OptVec<TyParamBound>> {
+    do b.map |bounds| {
+        do bounds.map |bound| {
+            fold_ty_param_bound(bound, folder)
+        }
+    }
+}
+
+fn fold_variant_arg_<T:ast_fold>(va: &variant_arg, folder: &T)
+                                 -> variant_arg {
+    ast::variant_arg {
+        ty: folder.fold_ty(&va.ty),
+        id: folder.new_id(va.id)
+    }
+}
+
+pub fn noop_fold_block<T:ast_fold>(b: &Block, folder: &T) -> Block {
+    let view_items = b.view_items.map(|x| folder.fold_view_item(x));
+    let mut stmts = ~[];
+    for stmt in b.stmts.iter() {
+        match folder.fold_stmt(*stmt) {
+            None => {}
+            Some(stmt) => stmts.push(stmt)
+        }
+    }
+    ast::Block {
+        view_items: view_items,
+        stmts: stmts,
+        expr: b.expr.map(|x| folder.fold_expr(*x)),
+        id: folder.new_id(b.id),
+        rules: b.rules,
+        span: folder.new_span(b.span),
+    }
+}
+
+pub fn noop_fold_item_underscore<T:ast_fold>(i: &item_, folder: &T) -> item_ {
     match *i {
         item_static(ref t, m, e) => {
-            item_static(fld.fold_ty(t), m, fld.fold_expr(e))
+            item_static(folder.fold_ty(t), m, folder.fold_expr(e))
         }
         item_fn(ref decl, purity, abi, ref generics, ref body) => {
             item_fn(
-                fold_fn_decl(decl, fld),
+                fold_fn_decl(decl, folder),
                 purity,
                 abi,
-                fold_generics(generics, fld),
-                fld.fold_block(body)
+                fold_generics(generics, folder),
+                folder.fold_block(body)
             )
         }
-        item_mod(ref m) => {
-            item_mod(fld.fold_mod(m))
-        }
+        item_mod(ref m) => item_mod(folder.fold_mod(m)),
         item_foreign_mod(ref nm) => {
-            item_foreign_mod(fld.fold_foreign_mod(nm))
+            item_foreign_mod(folder.fold_foreign_mod(nm))
         }
         item_ty(ref t, ref generics) => {
-            item_ty(fld.fold_ty(t), fold_generics(generics, fld))
+            item_ty(folder.fold_ty(t),
+                    fold_generics(generics, folder))
         }
         item_enum(ref enum_definition, ref generics) => {
             item_enum(
                 ast::enum_def {
                     variants: do enum_definition.variants.map |x| {
-                        fld.fold_variant(x)
+                        folder.fold_variant(x)
                     },
                 },
-                fold_generics(generics, fld))
+                fold_generics(generics, folder))
         }
         item_struct(ref struct_def, ref generics) => {
-            let struct_def = fold_struct_def(*struct_def, fld);
-            item_struct(struct_def, fold_generics(generics, fld))
+            let struct_def = fold_struct_def(*struct_def, folder);
+            item_struct(struct_def, fold_generics(generics, folder))
         }
         item_impl(ref generics, ref ifce, ref ty, ref methods) => {
-            item_impl(
-                fold_generics(generics, fld),
-                ifce.map(|p| fld.fold_trait_ref(p)),
-                fld.fold_ty(ty),
-                methods.map(|x| fld.fold_method(*x))
+            item_impl(fold_generics(generics, folder),
+                      ifce.map(|p| fold_trait_ref(p, folder)),
+                      folder.fold_ty(ty),
+                      methods.map(|x| folder.fold_method(*x))
             )
         }
         item_trait(ref generics, ref traits, ref methods) => {
             let methods = do methods.map |method| {
                 match *method {
-                    required(ref m) => required(fld.fold_type_method(m)),
-                    provided(method) => provided(fld.fold_method(method))
+                    required(ref m) => required(folder.fold_type_method(m)),
+                    provided(method) => provided(folder.fold_method(method))
                 }
             };
-            item_trait(
-                fold_generics(generics, fld),
-                traits.map(|p| fld.fold_trait_ref(p)),
-                methods
-            )
-        }
-        item_mac(ref m) => {
-            item_mac(fld.fold_mac(m))
+            item_trait(fold_generics(generics, folder),
+                       traits.map(|p| fold_trait_ref(p, folder)),
+                       methods)
         }
+        item_mac(ref m) => item_mac(folder.fold_mac(m)),
     }
 }
 
-fn fold_struct_def(struct_def: @ast::struct_def, fld: @ast_fold)
-                -> @ast::struct_def {
-    @ast::struct_def {
-        fields: struct_def.fields.map(|f| fold_struct_field(*f, fld)),
-        ctor_id: struct_def.ctor_id.map(|cid| fld.new_id(*cid)),
-    }
-}
-
-fn fold_struct_field(f: @struct_field, fld: @ast_fold) -> @struct_field {
-    @Spanned {
-        node: ast::struct_field_ {
-            kind: f.node.kind,
-            id: fld.new_id(f.node.id),
-            ty: fld.fold_ty(&f.node.ty),
-            attrs: fld.fold_attributes(f.node.attrs),
-        },
-        span: fld.new_span(f.span),
-    }
-}
-
-fn noop_fold_method(m: @method, fld: @ast_fold) -> @method {
-    @ast::method {
+pub fn noop_fold_type_method<T:ast_fold>(m: &TypeMethod, fld: &T)
+                                         -> TypeMethod {
+    TypeMethod {
         ident: fld.fold_ident(m.ident),
-        attrs: fld.fold_attributes(m.attrs),
-        generics: fold_generics(&m.generics, fld),
-        explicit_self: m.explicit_self,
+        attrs: m.attrs.map(|a| fold_attribute_(*a, fld)),
         purity: m.purity,
         decl: fold_fn_decl(&m.decl, fld),
-        body: fld.fold_block(&m.body),
+        generics: fold_generics(&m.generics, fld),
+        explicit_self: m.explicit_self,
         id: fld.new_id(m.id),
         span: fld.new_span(m.span),
-        self_id: fld.new_id(m.self_id),
-        vis: m.vis,
-    }
-}
-
-
-pub fn noop_fold_block(b: &Block, fld: @ast_fold) -> Block {
-    let view_items = b.view_items.map(|x| fld.fold_view_item(x));
-    let mut stmts = ~[];
-    for stmt in b.stmts.iter() {
-        match fld.fold_stmt(*stmt) {
-            None => {}
-            Some(stmt) => stmts.push(stmt)
-        }
-    }
-    ast::Block {
-        view_items: view_items,
-        stmts: stmts,
-        expr: b.expr.map(|x| fld.fold_expr(*x)),
-        id: fld.new_id(b.id),
-        rules: b.rules,
-        span: b.span,
     }
 }
 
-fn noop_fold_stmt(s: &Stmt_, fld: @ast_fold) -> Option<Stmt_> {
-    match *s {
-        StmtDecl(d, nid) => {
-            match fld.fold_decl(d) {
-                Some(d) => Some(StmtDecl(d, fld.new_id(nid))),
-                None => None,
-            }
-        }
-        StmtExpr(e, nid) => {
-            Some(StmtExpr(fld.fold_expr(e), fld.new_id(nid)))
-        }
-        StmtSemi(e, nid) => {
-            Some(StmtSemi(fld.fold_expr(e), fld.new_id(nid)))
-        }
-        StmtMac(ref mac, semi) => Some(StmtMac(fld.fold_mac(mac), semi))
+pub fn noop_fold_mod<T:ast_fold>(m: &_mod, folder: &T) -> _mod {
+    ast::_mod {
+        view_items: m.view_items
+                     .iter()
+                     .map(|x| folder.fold_view_item(x)).collect(),
+        items: m.items.iter().filter_map(|x| folder.fold_item(*x)).collect(),
     }
 }
 
-fn noop_fold_arm(a: &Arm, fld: @ast_fold) -> Arm {
-    Arm {
-        pats: a.pats.map(|x| fld.fold_pat(*x)),
-        guard: a.guard.map_move(|x| fld.fold_expr(x)),
-        body: fld.fold_block(&a.body),
-    }
-}
+pub fn noop_fold_crate<T:ast_fold>(c: &Crate, folder: &T) -> Crate {
+    let fold_meta_item = |x| fold_meta_item_(x, folder);
+    let fold_attribute = |x| fold_attribute_(x, folder);
 
-pub fn noop_fold_pat(p: &Pat_, fld: @ast_fold) -> Pat_ {
-    match *p {
-        PatWild => PatWild,
-        PatIdent(binding_mode, ref pth, ref sub) => {
-            PatIdent(
-                binding_mode,
-                fld.fold_path(pth),
-                sub.map_move(|x| fld.fold_pat(x))
-            )
-        }
-        PatLit(e) => PatLit(fld.fold_expr(e)),
-        PatEnum(ref pth, ref pats) => {
-            PatEnum(
-                fld.fold_path(pth),
-                pats.map(|pats| pats.map(|x| fld.fold_pat(*x)))
-            )
-        }
-        PatStruct(ref pth, ref fields, etc) => {
-            let pth_ = fld.fold_path(pth);
-            let fs = do fields.map |f| {
-                ast::FieldPat {
-                    ident: f.ident,
-                    pat: fld.fold_pat(f.pat)
-                }
-            };
-            PatStruct(pth_, fs, etc)
-        }
-        PatTup(ref elts) => PatTup(elts.map(|x| fld.fold_pat(*x))),
-        PatBox(inner) => PatBox(fld.fold_pat(inner)),
-        PatUniq(inner) => PatUniq(fld.fold_pat(inner)),
-        PatRegion(inner) => PatRegion(fld.fold_pat(inner)),
-        PatRange(e1, e2) => {
-            PatRange(fld.fold_expr(e1), fld.fold_expr(e2))
-        },
-        PatVec(ref before, ref slice, ref after) => {
-            PatVec(
-                before.map(|x| fld.fold_pat(*x)),
-                slice.map_move(|x| fld.fold_pat(x)),
-                after.map(|x| fld.fold_pat(*x))
-            )
-        }
+    Crate {
+        module: folder.fold_mod(&c.module),
+        attrs: c.attrs.map(|x| fold_attribute(*x)),
+        config: c.config.map(|x| fold_meta_item(*x)),
+        span: folder.new_span(c.span),
     }
 }
 
-fn noop_fold_decl(d: &Decl_, fld: @ast_fold) -> Option<Decl_> {
-    match *d {
-        DeclLocal(ref l) => Some(DeclLocal(fld.fold_local(*l))),
-        DeclItem(it) => {
-            match fld.fold_item(it) {
-                Some(it_folded) => Some(DeclItem(it_folded)),
-                None => None,
-            }
-        }
-    }
-}
+pub fn noop_fold_item<T:ast_fold>(i: @ast::item, folder: &T)
+                                  -> Option<@ast::item> {
+    let fold_attribute = |x| fold_attribute_(x, folder);
 
-// lift a function in ast-thingy X fold -> ast-thingy to a function
-// in (ast-thingy X span X fold) -> (ast-thingy X span). Basically,
-// carries the span around.
-// It seems strange to me that the call to new_fold doesn't happen
-// here but instead in the impl down below.... probably just an
-// accident?
-pub fn wrap<T>(f: @fn(&T, @ast_fold) -> T)
-            -> @fn(&T, Span, @ast_fold) -> (T, Span) {
-    let result: @fn(&T, Span, @ast_fold) -> (T, Span) = |x, s, fld| {
-        (f(x, fld), s)
-    };
-    result
+    Some(@ast::item {
+        ident: folder.fold_ident(i.ident),
+        attrs: i.attrs.map(|e| fold_attribute(*e)),
+        id: folder.new_id(i.id),
+        node: folder.fold_item_underscore(&i.node),
+        vis: i.vis,
+        span: folder.new_span(i.span)
+    })
 }
 
-pub fn noop_fold_expr(e: &Expr_, fld: @ast_fold) -> Expr_ {
-    fn fold_field_(field: Field, fld: @ast_fold) -> Field {
-        ast::Field {
-            ident: fld.fold_ident(field.ident),
-            expr: fld.fold_expr(field.expr),
-            span: fld.new_span(field.span),
-        }
-    }
-    let fold_field = |x| fold_field_(x, fld);
+pub fn noop_fold_expr<T:ast_fold>(e: @ast::Expr, folder: &T) -> @ast::Expr {
+    let fold_field = |x| fold_field_(x, folder);
 
-    match *e {
+    let node = match e.node {
         ExprVstore(e, v) => {
-            ExprVstore(fld.fold_expr(e), v)
+            ExprVstore(folder.fold_expr(e), v)
         }
         ExprVec(ref exprs, mutt) => {
-            ExprVec(fld.map_exprs(|x| fld.fold_expr(x), *exprs), mutt)
+            ExprVec(folder.map_exprs(|x| folder.fold_expr(x), *exprs), mutt)
         }
         ExprRepeat(expr, count, mutt) => {
-            ExprRepeat(fld.fold_expr(expr), fld.fold_expr(count), mutt)
+            ExprRepeat(folder.fold_expr(expr), folder.fold_expr(count), mutt)
         }
-        ExprTup(ref elts) => ExprTup(elts.map(|x| fld.fold_expr(*x))),
+        ExprTup(ref elts) => ExprTup(elts.map(|x| folder.fold_expr(*x))),
         ExprCall(f, ref args, blk) => {
-            ExprCall(
-                fld.fold_expr(f),
-                fld.map_exprs(|x| fld.fold_expr(x), *args),
-                blk
-            )
+            ExprCall(folder.fold_expr(f),
+                     folder.map_exprs(|x| folder.fold_expr(x), *args),
+                     blk)
         }
         ExprMethodCall(callee_id, f, i, ref tps, ref args, blk) => {
             ExprMethodCall(
-                fld.new_id(callee_id),
-                fld.fold_expr(f),
-                fld.fold_ident(i),
-                tps.map(|x| fld.fold_ty(x)),
-                fld.map_exprs(|x| fld.fold_expr(x), *args),
+                folder.new_id(callee_id),
+                folder.fold_expr(f),
+                folder.fold_ident(i),
+                tps.map(|x| folder.fold_ty(x)),
+                folder.map_exprs(|x| folder.fold_expr(x), *args),
                 blk
             )
         }
         ExprBinary(callee_id, binop, lhs, rhs) => {
-            ExprBinary(
-                fld.new_id(callee_id),
-                binop,
-                fld.fold_expr(lhs),
-                fld.fold_expr(rhs)
-            )
+            ExprBinary(folder.new_id(callee_id),
+                       binop,
+                       folder.fold_expr(lhs),
+                       folder.fold_expr(rhs))
         }
         ExprUnary(callee_id, binop, ohs) => {
-            ExprUnary(
-                fld.new_id(callee_id),
-                binop,
-                fld.fold_expr(ohs)
-            )
+            ExprUnary(folder.new_id(callee_id), binop, folder.fold_expr(ohs))
         }
-        ExprDoBody(f) => ExprDoBody(fld.fold_expr(f)),
-        ExprLit(_) => (*e).clone(),
+        ExprDoBody(f) => ExprDoBody(folder.fold_expr(f)),
+        ExprLit(_) => e.node.clone(),
         ExprCast(expr, ref ty) => {
-            ExprCast(fld.fold_expr(expr), fld.fold_ty(ty))
+            ExprCast(folder.fold_expr(expr), folder.fold_ty(ty))
         }
-        ExprAddrOf(m, ohs) => ExprAddrOf(m, fld.fold_expr(ohs)),
+        ExprAddrOf(m, ohs) => ExprAddrOf(m, folder.fold_expr(ohs)),
         ExprIf(cond, ref tr, fl) => {
-            ExprIf(
-                fld.fold_expr(cond),
-                fld.fold_block(tr),
-                fl.map_move(|x| fld.fold_expr(x))
-            )
+            ExprIf(folder.fold_expr(cond),
+                   folder.fold_block(tr),
+                   fl.map_move(|x| folder.fold_expr(x)))
         }
         ExprWhile(cond, ref body) => {
-            ExprWhile(fld.fold_expr(cond), fld.fold_block(body))
+            ExprWhile(folder.fold_expr(cond), folder.fold_block(body))
         }
-        ExprForLoop(pat, iter, ref body, opt_ident) => {
-            ExprForLoop(fld.fold_pat(pat),
-                        fld.fold_expr(iter),
-                        fld.fold_block(body),
-                        opt_ident.map_move(|x| fld.fold_ident(x)))
+        ExprForLoop(pat, iter, ref body, ref maybe_ident) => {
+            ExprForLoop(folder.fold_pat(pat),
+                        folder.fold_expr(iter),
+                        folder.fold_block(body),
+                        maybe_ident.map_move(|i| folder.fold_ident(i)))
         }
         ExprLoop(ref body, opt_ident) => {
-            ExprLoop(
-                fld.fold_block(body),
-                opt_ident.map_move(|x| fld.fold_ident(x))
-            )
+            ExprLoop(folder.fold_block(body),
+                     opt_ident.map_move(|x| folder.fold_ident(x)))
         }
         ExprMatch(expr, ref arms) => {
-            ExprMatch(
-                fld.fold_expr(expr),
-                arms.map(|x| fld.fold_arm(x))
-            )
+            ExprMatch(folder.fold_expr(expr),
+                      arms.map(|x| folder.fold_arm(x)))
         }
         ExprFnBlock(ref decl, ref body) => {
             ExprFnBlock(
-                fold_fn_decl(decl, fld),
-                fld.fold_block(body)
+                fold_fn_decl(decl, folder),
+                folder.fold_block(body)
             )
         }
-        ExprBlock(ref blk) => ExprBlock(fld.fold_block(blk)),
+        ExprBlock(ref blk) => ExprBlock(folder.fold_block(blk)),
         ExprAssign(el, er) => {
-            ExprAssign(fld.fold_expr(el), fld.fold_expr(er))
+            ExprAssign(folder.fold_expr(el), folder.fold_expr(er))
         }
         ExprAssignOp(callee_id, op, el, er) => {
-            ExprAssignOp(
-                fld.new_id(callee_id),
-                op,
-                fld.fold_expr(el),
-                fld.fold_expr(er)
-            )
+            ExprAssignOp(folder.new_id(callee_id),
+                         op,
+                         folder.fold_expr(el),
+                         folder.fold_expr(er))
         }
         ExprField(el, id, ref tys) => {
-            ExprField(
-                fld.fold_expr(el), fld.fold_ident(id),
-                tys.map(|x| fld.fold_ty(x))
-            )
+            ExprField(folder.fold_expr(el), folder.fold_ident(id),
+                      tys.map(|x| folder.fold_ty(x)))
         }
         ExprIndex(callee_id, el, er) => {
-            ExprIndex(
-                fld.new_id(callee_id),
-                fld.fold_expr(el),
-                fld.fold_expr(er)
-            )
+            ExprIndex(folder.new_id(callee_id),
+                      folder.fold_expr(el),
+                      folder.fold_expr(er))
         }
-        ExprPath(ref pth) => ExprPath(fld.fold_path(pth)),
+        ExprPath(ref pth) => ExprPath(folder.fold_path(pth)),
         ExprSelf => ExprSelf,
-        ExprBreak(ref opt_ident) => {
-            // FIXME #6993: add fold_name to fold.... then cut out the
-            // bogus Name->Ident->Name conversion.
-            ExprBreak(opt_ident.map_move(|x| {
-                // FIXME #9129: Assigning the new ident to a temporary to work around codegen bug
-                let newx = Ident::new(x);
-                fld.fold_ident(newx).name
-            }))
-        }
-        ExprAgain(ref opt_ident) => {
-            // FIXME #6993: add fold_name to fold....
-            ExprAgain(opt_ident.map_move(|x| {
-                // FIXME #9129: Assigning the new ident to a temporary to work around codegen bug
-                let newx = Ident::new(x);
-                fld.fold_ident(newx).name
-            }))
-        }
+        ExprLogLevel => ExprLogLevel,
+        ExprBreak(opt_ident) => ExprBreak(opt_ident),
+        ExprAgain(opt_ident) => ExprAgain(opt_ident),
         ExprRet(ref e) => {
-            ExprRet(e.map_move(|x| fld.fold_expr(x)))
+            ExprRet(e.map_move(|x| folder.fold_expr(x)))
         }
-        ExprLogLevel => ExprLogLevel,
         ExprInlineAsm(ref a) => {
             ExprInlineAsm(inline_asm {
-                inputs: a.inputs.map(|&(c, input)| (c, fld.fold_expr(input))),
-                outputs: a.outputs.map(|&(c, out)| (c, fld.fold_expr(out))),
+                inputs: a.inputs.map(|&(c, input)| (c, folder.fold_expr(input))),
+                outputs: a.outputs.map(|&(c, out)| (c, folder.fold_expr(out))),
                 .. (*a).clone()
             })
         }
-        ExprMac(ref mac) => ExprMac(fld.fold_mac(mac)),
+        ExprMac(ref mac) => ExprMac(folder.fold_mac(mac)),
         ExprStruct(ref path, ref fields, maybe_expr) => {
-            ExprStruct(
-                fld.fold_path(path),
-                fields.map(|x| fold_field(*x)),
-                maybe_expr.map_move(|x| fld.fold_expr(x))
-            )
+            ExprStruct(folder.fold_path(path),
+                       fields.map(|x| fold_field(*x)),
+                       maybe_expr.map_move(|x| folder.fold_expr(x)))
         },
-        ExprParen(ex) => ExprParen(fld.fold_expr(ex))
-    }
-}
-
-pub fn noop_fold_ty(t: &ty_, fld: @ast_fold) -> ty_ {
-    fn fold_mt(mt: &mt, fld: @ast_fold) -> mt {
-        mt {
-            ty: ~fld.fold_ty(mt.ty),
-            mutbl: mt.mutbl,
-        }
-    }
-    fn fold_field(f: TypeField, fld: @ast_fold) -> TypeField {
-        ast::TypeField {
-            ident: fld.fold_ident(f.ident),
-            mt: fold_mt(&f.mt, fld),
-            span: fld.new_span(f.span),
-        }
-    }
-    fn fold_opt_bounds(b: &Option<OptVec<TyParamBound>>, fld: @ast_fold)
-                        -> Option<OptVec<TyParamBound>> {
-        do b.map |bounds| {
-            do bounds.map |bound| { fld.fold_ty_param_bound(bound) }
-        }
-    }
-    match *t {
-        ty_nil | ty_bot | ty_infer => (*t).clone(),
-        ty_box(ref mt) => ty_box(fold_mt(mt, fld)),
-        ty_uniq(ref mt) => ty_uniq(fold_mt(mt, fld)),
-        ty_vec(ref mt) => ty_vec(fold_mt(mt, fld)),
-        ty_ptr(ref mt) => ty_ptr(fold_mt(mt, fld)),
-        ty_rptr(region, ref mt) => ty_rptr(region, fold_mt(mt, fld)),
-        ty_closure(ref f) => {
-            ty_closure(@TyClosure {
-                sigil: f.sigil,
-                purity: f.purity,
-                region: f.region,
-                onceness: f.onceness,
-                bounds: fold_opt_bounds(&f.bounds, fld),
-                decl: fold_fn_decl(&f.decl, fld),
-                lifetimes: fld.fold_lifetimes(&f.lifetimes)
-            })
-        }
-        ty_bare_fn(ref f) => {
-            ty_bare_fn(@TyBareFn {
-                lifetimes: fld.fold_lifetimes(&f.lifetimes),
-                purity: f.purity,
-                abis: f.abis,
-                decl: fold_fn_decl(&f.decl, fld)
-            })
-        }
-        ty_tup(ref tys) => ty_tup(tys.map(|ty| fld.fold_ty(ty))),
-        ty_path(ref path, ref bounds, id) =>
-            ty_path(fld.fold_path(path), fold_opt_bounds(bounds, fld), fld.new_id(id)),
-        ty_fixed_length_vec(ref mt, e) => {
-            ty_fixed_length_vec(
-                fold_mt(mt, fld),
-                fld.fold_expr(e)
-            )
-        }
-        ty_typeof(e) => ty_typeof(fld.fold_expr(e)),
-        ty_mac(ref mac) => ty_mac(fld.fold_mac(mac))
-    }
-}
-
-// ...nor do modules
-pub fn noop_fold_mod(m: &_mod, fld: @ast_fold) -> _mod {
-    ast::_mod {
-        view_items: m.view_items.iter().map(|x| fld.fold_view_item(x)).collect(),
-        items: m.items.iter().filter_map(|x| fld.fold_item(*x)).collect(),
-    }
-}
-
-fn noop_fold_foreign_mod(nm: &foreign_mod, fld: @ast_fold) -> foreign_mod {
-    ast::foreign_mod {
-        sort: nm.sort,
-        abis: nm.abis,
-        view_items: nm.view_items.iter().map(|x| fld.fold_view_item(x)).collect(),
-        items: nm.items.iter().map(|x| fld.fold_foreign_item(*x)).collect(),
-    }
-}
-
-fn noop_fold_variant(v: &variant_, fld: @ast_fold) -> variant_ {
-    let kind = match v.kind {
-        tuple_variant_kind(ref variant_args) => {
-            tuple_variant_kind(variant_args.map(|x| fld.fold_variant_arg(x)))
-        }
-        struct_variant_kind(ref struct_def) => {
-            struct_variant_kind(@ast::struct_def {
-                fields: struct_def.fields.iter()
-                    .map(|f| fld.fold_struct_field(*f)).collect(),
-                ctor_id: struct_def.ctor_id.map(|c| fld.new_id(*c))
-            })
-        }
-    };
-
-    let attrs = fld.fold_attributes(v.attrs);
-
-    let de = match v.disr_expr {
-      Some(e) => Some(fld.fold_expr(e)),
-      None => None
+        ExprParen(ex) => ExprParen(folder.fold_expr(ex))
     };
-    ast::variant_ {
-        name: v.name,
-        attrs: attrs,
-        kind: kind,
-        id: fld.new_id(v.id),
-        disr_expr: de,
-        vis: v.vis,
-    }
-}
-
-fn noop_fold_ident(i: Ident, _fld: @ast_fold) -> Ident {
-    i
-}
 
-fn noop_fold_path(p: &Path, fld: @ast_fold) -> Path {
-    ast::Path {
-        span: fld.new_span(p.span),
-        global: p.global,
-        segments: p.segments.map(|segment| ast::PathSegment {
-            identifier: fld.fold_ident(segment.identifier),
-            lifetime: segment.lifetime,
-            types: segment.types.map(|typ| fld.fold_ty(typ)),
-        })
+    @Expr {
+        id: folder.new_id(e.id),
+        node: node,
+        span: folder.new_span(e.span),
     }
 }
 
-fn noop_fold_local(l: @Local, fld: @ast_fold) -> @Local {
-    @Local {
-        is_mutbl: l.is_mutbl,
-        ty: fld.fold_ty(&l.ty),
-        pat: fld.fold_pat(l.pat),
-        init: l.init.map_move(|e| fld.fold_expr(e)),
-        id: fld.new_id(l.id),
-        span: fld.new_span(l.span),
-    }
-}
-
-// the default macro traversal. visit the path
-// using fold_path, and the tts using fold_tts,
-// and the span using new_span
-fn noop_fold_mac(m: &mac_, fld: @ast_fold) -> mac_ {
-    match *m {
-        mac_invoc_tt(ref p,ref tts,ctxt) =>
-        mac_invoc_tt(fld.fold_path(p),
-                     fold_tts(*tts,fld),
-                     ctxt)
-    }
-}
-
-
-/* temporarily eta-expand because of a compiler bug with using `fn<T>` as a
-   value */
-fn noop_map_exprs(f: @fn(@Expr) -> @Expr, es: &[@Expr]) -> ~[@Expr] {
-    es.map(|x| f(*x))
-}
-
-fn noop_id(i: NodeId) -> NodeId { return i; }
-
-fn noop_span(sp: Span) -> Span { return sp; }
-
-pub fn default_ast_fold() -> ast_fold_fns {
-    @AstFoldFns {
-        fold_crate: noop_fold_crate,
-        fold_view_item: noop_fold_view_item,
-        fold_foreign_item: noop_fold_foreign_item,
-        fold_item: noop_fold_item,
-        fold_struct_field: noop_fold_struct_field,
-        fold_item_underscore: noop_fold_item_underscore,
-        fold_type_method: noop_fold_type_method,
-        fold_method: noop_fold_method,
-        fold_block: noop_fold_block,
-        fold_stmt: |x, s, fld| (noop_fold_stmt(x, fld), s),
-        fold_arm: noop_fold_arm,
-        fold_pat: wrap(noop_fold_pat),
-        fold_decl: |x, s, fld| (noop_fold_decl(x, fld), s),
-        fold_expr: wrap(noop_fold_expr),
-        fold_ty: wrap(noop_fold_ty),
-        fold_mod: noop_fold_mod,
-        fold_foreign_mod: noop_fold_foreign_mod,
-        fold_variant: wrap(noop_fold_variant),
-        fold_ident: noop_fold_ident,
-        fold_path: noop_fold_path,
-        fold_local: noop_fold_local,
-        fold_mac: wrap(noop_fold_mac),
-        map_exprs: noop_map_exprs,
-        new_id: noop_id,
-        new_span: noop_span,
-    }
-}
-
-impl ast_fold for AstFoldFns {
-    /* naturally, a macro to write these would be nice */
-    fn fold_crate(@self, c: &Crate) -> Crate {
-        (self.fold_crate)(c, self as @ast_fold)
-    }
-    fn fold_view_item(@self, x: &view_item) -> view_item {
-        ast::view_item {
-            node: (self.fold_view_item)(&x.node, self as @ast_fold),
-            attrs: self.fold_attributes(x.attrs),
-            vis: x.vis,
-            span: (self.new_span)(x.span),
-        }
-    }
-    fn fold_foreign_item(@self, x: @foreign_item) -> @foreign_item {
-        (self.fold_foreign_item)(x, self as @ast_fold)
-    }
-    fn fold_item(@self, i: @item) -> Option<@item> {
-        (self.fold_item)(i, self as @ast_fold)
-    }
-    fn fold_struct_field(@self, sf: @struct_field) -> @struct_field {
-        @Spanned {
-            node: ast::struct_field_ {
-                kind: sf.node.kind,
-                id: (self.new_id)(sf.node.id),
-                ty: self.fold_ty(&sf.node.ty),
-                attrs: self.fold_attributes(sf.node.attrs),
-            },
-            span: (self.new_span)(sf.span),
-        }
-    }
-    fn fold_item_underscore(@self, i: &item_) -> item_ {
-        (self.fold_item_underscore)(i, self as @ast_fold)
-    }
-    fn fold_type_method(@self, m: &TypeMethod) -> TypeMethod {
-        (self.fold_type_method)(m, self as @ast_fold)
-    }
-    fn fold_method(@self, x: @method) -> @method {
-        (self.fold_method)(x, self as @ast_fold)
-    }
-    fn fold_block(@self, x: &Block) -> Block {
-        (self.fold_block)(x, self as @ast_fold)
-    }
-    fn fold_stmt(@self, x: &Stmt) -> Option<@Stmt> {
-        let (n_opt, s) = (self.fold_stmt)(&x.node, x.span, self as @ast_fold);
-        match n_opt {
-            Some(n) => Some(@Spanned { node: n, span: (self.new_span)(s) }),
-            None => None,
-        }
-    }
-    fn fold_arm(@self, x: &Arm) -> Arm {
-        (self.fold_arm)(x, self as @ast_fold)
-    }
-    fn fold_pat(@self, x: @Pat) -> @Pat {
-        let (n, s) =  (self.fold_pat)(&x.node, x.span, self as @ast_fold);
-        @Pat {
-            id: (self.new_id)(x.id),
-            node: n,
-            span: (self.new_span)(s),
-        }
-    }
-    fn fold_decl(@self, x: @Decl) -> Option<@Decl> {
-        let (n_opt, s) = (self.fold_decl)(&x.node, x.span, self as @ast_fold);
-        match n_opt {
-            Some(n) => Some(@Spanned { node: n, span: (self.new_span)(s) }),
-            None => None,
+pub fn noop_fold_stmt<T:ast_fold>(s: &Stmt, folder: &T) -> Option<@Stmt> {
+    let node = match s.node {
+        StmtDecl(d, nid) => {
+            match folder.fold_decl(d) {
+                Some(d) => Some(StmtDecl(d, folder.new_id(nid))),
+                None => None,
+            }
         }
-    }
-    fn fold_expr(@self, x: @Expr) -> @Expr {
-        let (n, s) = (self.fold_expr)(&x.node, x.span, self as @ast_fold);
-        @Expr {
-            id: (self.new_id)(x.id),
-            node: n,
-            span: (self.new_span)(s),
+        StmtExpr(e, nid) => {
+            Some(StmtExpr(folder.fold_expr(e), folder.new_id(nid)))
         }
-    }
-    fn fold_ty(@self, x: &Ty) -> Ty {
-        let (n, s) = (self.fold_ty)(&x.node, x.span, self as @ast_fold);
-        Ty {
-            id: (self.new_id)(x.id),
-            node: n,
-            span: (self.new_span)(s),
+        StmtSemi(e, nid) => {
+            Some(StmtSemi(folder.fold_expr(e), folder.new_id(nid)))
         }
-    }
-    fn fold_mod(@self, x: &_mod) -> _mod {
-        (self.fold_mod)(x, self as @ast_fold)
-    }
-    fn fold_foreign_mod(@self, x: &foreign_mod) -> foreign_mod {
-        (self.fold_foreign_mod)(x, self as @ast_fold)
-    }
-    fn fold_variant(@self, x: &variant) -> variant {
-        let (n, s) = (self.fold_variant)(&x.node, x.span, self as @ast_fold);
-        Spanned { node: n, span: (self.new_span)(s) }
-    }
-    fn fold_ident(@self, x: Ident) -> Ident {
-        (self.fold_ident)(x, self as @ast_fold)
-    }
-    fn fold_path(@self, x: &Path) -> Path {
-        (self.fold_path)(x, self as @ast_fold)
-    }
-    fn fold_local(@self, x: @Local) -> @Local {
-        (self.fold_local)(x, self as @ast_fold)
-    }
-    fn fold_mac(@self, x: &mac) -> mac {
-        let (n, s) = (self.fold_mac)(&x.node, x.span, self as @ast_fold);
-        Spanned { node: n, span: (self.new_span)(s) }
-    }
-    fn map_exprs(@self,
-                 f: @fn(@Expr) -> @Expr,
-                 e: &[@Expr])
-              -> ~[@Expr] {
-        (self.map_exprs)(f, e)
-    }
-    fn new_id(@self, node_id: ast::NodeId) -> NodeId {
-        (self.new_id)(node_id)
-    }
-    fn new_span(@self, span: Span) -> Span {
-        (self.new_span)(span)
-    }
-}
+        StmtMac(ref mac, semi) => Some(StmtMac(folder.fold_mac(mac), semi))
+    };
 
-// brson agrees with me that this function's existence is probably
-// not a good or useful thing.
-pub fn make_fold(afp: ast_fold_fns) -> @ast_fold {
-    afp as @ast_fold
+    node.map_move(|node| @Spanned {
+        node: node,
+        span: folder.new_span(s.span),
+    })
 }
 
 #[cfg(test)]
@@ -1048,27 +870,18 @@ mod test {
     use print::pprust;
     use super::*;
 
-    // taken from expand
-    // given a function from idents to idents, produce
-    // an ast_fold that applies that function:
-    pub fn fun_to_ident_folder(f: @fn(ast::Ident)->ast::Ident) -> @ast_fold{
-        let afp = default_ast_fold();
-        let f_pre = @AstFoldFns{
-            fold_ident : |id, _| f(id),
-            .. *afp
-        };
-        make_fold(f_pre)
-    }
-
     // this version doesn't care about getting comments or docstrings in.
     fn fake_print_crate(s: @pprust::ps, crate: &ast::Crate) {
         pprust::print_mod(s, &crate.module, crate.attrs);
     }
 
     // change every identifier to "zz"
-    pub fn to_zz() -> @fn(ast::Ident)->ast::Ident {
-        let zz_id = token::str_to_ident("zz");
-        |_id| {zz_id}
+    struct ToZzIdentFolder;
+
+    impl ast_fold for ToZzIdentFolder {
+        fn fold_ident(&self, _: ast::Ident) -> ast::Ident {
+            token::str_to_ident("zz")
+        }
     }
 
     // maybe add to expand.rs...
@@ -1088,7 +901,7 @@ mod test {
 
     // make sure idents get transformed everywhere
     #[test] fn ident_transformation () {
-        let zz_fold = fun_to_ident_folder(to_zz());
+        let zz_fold = ToZzIdentFolder;
         let ast = string_to_crate(@"#[a] mod b {fn c (d : e, f : g) {h!(i,j,k);l;m}}");
         assert_pred!(matches_codepattern,
                      "matches_codepattern",
@@ -1099,7 +912,7 @@ mod test {
 
     // even inside macro defs....
     #[test] fn ident_transformation_in_defs () {
-        let zz_fold = fun_to_ident_folder(to_zz());
+        let zz_fold = ToZzIdentFolder;
         let ast = string_to_crate(@"macro_rules! a {(b $c:expr $(d $e:token)f+
 => (g $(d $d $e)+))} ");
         assert_pred!(matches_codepattern,
@@ -1108,15 +921,5 @@ mod test {
                                     token::get_ident_interner()),
                      ~"zz!zz((zz$zz:zz$(zz $zz:zz)zz+=>(zz$(zz$zz$zz)+)))");
     }
-
-    // and in cast expressions... this appears to be an existing bug.
-    #[test] fn ident_transformation_in_types () {
-        let zz_fold = fun_to_ident_folder(to_zz());
-        let ast = string_to_crate(@"fn a() {let z = 13 as int;}");
-        assert_pred!(matches_codepattern,
-                     "matches_codepattern",
-                     pprust::to_str(&zz_fold.fold_crate(ast),fake_print_crate,
-                                    token::get_ident_interner()),
-                     ~"fn zz(){let zz=13 as zz;}");
-    }
 }
+
diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs
index d3b0866d4a7..09adcc66ea5 100644
--- a/src/libsyntax/parse/lexer.rs
+++ b/src/libsyntax/parse/lexer.rs
@@ -747,27 +747,34 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token {
         }
 
         // Otherwise it is a character constant:
-        if c2 == '\\' {
-            // '\X' for some X must be a character constant:
-            let escaped = rdr.curr;
-            let escaped_pos = rdr.last_pos;
-            bump(rdr);
-            match escaped {
-              'n' => { c2 = '\n'; }
-              'r' => { c2 = '\r'; }
-              't' => { c2 = '\t'; }
-              '\\' => { c2 = '\\'; }
-              '\'' => { c2 = '\''; }
-              '"' => { c2 = '"'; }
-              '0' => { c2 = '\x00'; }
-              'x' => { c2 = scan_numeric_escape(rdr, 2u); }
-              'u' => { c2 = scan_numeric_escape(rdr, 4u); }
-              'U' => { c2 = scan_numeric_escape(rdr, 8u); }
-              c2 => {
-                fatal_span_char(rdr, escaped_pos, rdr.last_pos,
-                                ~"unknown character escape", c2);
-              }
+        match c2 {
+            '\\' => {
+                // '\X' for some X must be a character constant:
+                let escaped = rdr.curr;
+                let escaped_pos = rdr.last_pos;
+                bump(rdr);
+                match escaped {
+                    'n' => { c2 = '\n'; }
+                    'r' => { c2 = '\r'; }
+                    't' => { c2 = '\t'; }
+                    '\\' => { c2 = '\\'; }
+                    '\'' => { c2 = '\''; }
+                    '"' => { c2 = '"'; }
+                    '0' => { c2 = '\x00'; }
+                    'x' => { c2 = scan_numeric_escape(rdr, 2u); }
+                    'u' => { c2 = scan_numeric_escape(rdr, 4u); }
+                    'U' => { c2 = scan_numeric_escape(rdr, 8u); }
+                    c2 => {
+                        fatal_span_char(rdr, escaped_pos, rdr.last_pos,
+                                        ~"unknown character escape", c2);
+                    }
+                }
+            }
+            '\t' | '\n' | '\r' | '\'' => {
+                fatal_span_char(rdr, start, rdr.last_pos,
+                                ~"character constant must be escaped", c2);
             }
+            _ => {}
         }
         if rdr.curr != '\'' {
             fatal_span_verbose(rdr,
@@ -868,7 +875,6 @@ fn consume_whitespace(rdr: @mut StringReader) {
 mod test {
     use super::*;
 
-    use ast;
     use codemap::{BytePos, CodeMap, Span};
     use diagnostic;
     use parse::token;
@@ -973,7 +979,7 @@ mod test {
     }
 
     #[test] fn character_escaped() {
-        let env = setup(@"'\n'");
+        let env = setup(@"'\\n'");
         let TokenAndSpan {tok, sp: _} =
             env.string_reader.next_token();
         assert_eq!(tok, token::LIT_CHAR('\n' as u32));
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 9645dab4e8b..37f2f8345cd 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -45,7 +45,7 @@ pub struct ParseSess {
     included_mod_stack: ~[Path],
 }
 
-pub fn new_parse_sess(demitter: Option<Emitter>) -> @mut ParseSess {
+pub fn new_parse_sess(demitter: Option<@Emitter>) -> @mut ParseSess {
     let cm = @CodeMap::new();
     @mut ParseSess {
         cm: cm,
@@ -324,17 +324,10 @@ mod test {
     use abi;
     use parse::parser::Parser;
     use parse::token::{str_to_ident};
-    use util::parser_testing::{string_to_tts_and_sess, string_to_parser};
+    use util::parser_testing::{string_to_tts, string_to_parser};
     use util::parser_testing::{string_to_expr, string_to_item};
     use util::parser_testing::string_to_stmt;
 
-    // map a string to tts, return the tt without its parsesess
-    fn string_to_tts_only(source_str : @str) -> ~[ast::token_tree] {
-        let (tts,_ps) = string_to_tts_and_sess(source_str);
-        tts
-    }
-
-
     #[cfg(test)] fn to_json_str<E : Encodable<extra::json::Encoder>>(val: @E) -> ~str {
         do io::with_str_writer |writer| {
             let mut encoder = extra::json::Encoder(writer);
@@ -395,8 +388,53 @@ mod test {
         string_to_expr(@"::abc::def::return");
     }
 
+    // check the token-tree-ization of macros
+    #[test] fn string_to_tts_macro () {
+        let tts = string_to_tts(@"macro_rules! zip (($a)=>($a))");
+        match tts {
+            [ast::tt_tok(_,_),
+             ast::tt_tok(_,token::NOT),
+             ast::tt_tok(_,_),
+             ast::tt_delim(delim_elts)] =>
+                match *delim_elts {
+                [ast::tt_tok(_,token::LPAREN),
+                 ast::tt_delim(first_set),
+                 ast::tt_tok(_,token::FAT_ARROW),
+                 ast::tt_delim(second_set),
+                 ast::tt_tok(_,token::RPAREN)] =>
+                    match *first_set {
+                    [ast::tt_tok(_,token::LPAREN),
+                     ast::tt_tok(_,token::DOLLAR),
+                     ast::tt_tok(_,_),
+                     ast::tt_tok(_,token::RPAREN)] =>
+                        match *second_set {
+                        [ast::tt_tok(_,token::LPAREN),
+                         ast::tt_tok(_,token::DOLLAR),
+                         ast::tt_tok(_,_),
+                         ast::tt_tok(_,token::RPAREN)] =>
+                            assert_eq!("correct","correct"),
+                        _ => assert_eq!("wrong 4","correct")
+                    },
+                    _ => {
+                        error!("failing value 3: %?",first_set);
+                        assert_eq!("wrong 3","correct")
+                    }
+                },
+                _ => {
+                    error!("failing value 2: %?",delim_elts);
+                    assert_eq!("wrong","correct");
+                }
+
+            },
+            _ => {
+                error!("failing value: %?",tts);
+                assert_eq!("wrong 1","correct");
+            }
+        }
+    }
+
     #[test] fn string_to_tts_1 () {
-        let (tts,_ps) = string_to_tts_and_sess(@"fn a (b : int) { b; }");
+        let tts = string_to_tts(@"fn a (b : int) { b; }");
         assert_eq!(to_json_str(@tts),
         ~"[\
     {\
diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs
index b056b39eb6e..66774cb275b 100644
--- a/src/libsyntax/parse/obsolete.rs
+++ b/src/libsyntax/parse/obsolete.rs
@@ -44,7 +44,6 @@ pub enum ObsoleteSyntax {
     ObsoleteImplSyntax,
     ObsoleteMutOwnedPointer,
     ObsoleteMutVector,
-    ObsoleteImplVisibility,
     ObsoleteRecordType,
     ObsoleteRecordPattern,
     ObsoletePostFnTySigil,
@@ -60,11 +59,10 @@ pub enum ObsoleteSyntax {
     ObsoleteNamedExternModule,
     ObsoleteMultipleLocalDecl,
     ObsoleteMutWithMultipleBindings,
-    ObsoleteExternVisibility,
     ObsoleteUnsafeExternFn,
-    ObsoletePrivVisibility,
     ObsoleteTraitFuncVisibility,
     ObsoleteConstPointer,
+    ObsoleteEmptyImpl,
 }
 
 impl to_bytes::IterBytes for ObsoleteSyntax {
@@ -161,11 +159,6 @@ impl ParserObsoleteMethods for Parser {
                  in a mutable location, like a mutable local variable or an \
                  `@mut` box"
             ),
-            ObsoleteImplVisibility => (
-                "visibility-qualified implementation",
-                "`pub` or `priv` goes on individual functions; remove the \
-                 `pub` or `priv`"
-            ),
             ObsoleteRecordType => (
                 "structural record type",
                 "use a structure instead"
@@ -233,20 +226,11 @@ impl ParserObsoleteMethods for Parser {
                 "use multiple local declarations instead of e.g. `let mut \
                  (x, y) = ...`."
             ),
-            ObsoleteExternVisibility => (
-                "`pub extern` or `priv extern`",
-                "place the `pub` or `priv` on the individual external items \
-                 instead"
-            ),
             ObsoleteUnsafeExternFn => (
                 "unsafe external function",
                 "external functions are always unsafe; remove the `unsafe` \
                  keyword"
             ),
-            ObsoletePrivVisibility => (
-                "`priv` not necessary",
-                "an item without a visibility qualifier is private by default"
-            ),
             ObsoleteTraitFuncVisibility => (
                 "visibility not necessary",
                 "trait functions inherit the visibility of the trait itself"
@@ -256,6 +240,10 @@ impl ParserObsoleteMethods for Parser {
                 "instead of `&const Foo` or `@const Foo`, write `&Foo` or \
                  `@Foo`"
             ),
+            ObsoleteEmptyImpl => (
+                "empty implementation",
+                "instead of `impl A;`, write `impl A {}`"
+            ),
         };
 
         self.report(sp, kind, kind_str, desc);
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 4aad5c24d0f..74447b5dae1 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -922,7 +922,7 @@ impl Parser {
             let attrs = p.parse_outer_attributes();
             let lo = p.span.lo;
 
-            let vis = p.parse_non_priv_visibility();
+            let vis = p.parse_visibility();
             let pur = p.parse_fn_purity();
             // NB: at the moment, trait methods are public by default; this
             // could change.
@@ -2035,6 +2035,11 @@ impl Parser {
 
     // parse a single token tree from the input.
     pub fn parse_token_tree(&self) -> token_tree {
+        // FIXME #6994: currently, this is too eager. It
+        // parses token trees but also identifies tt_seq's
+        // and tt_nonterminals; it's too early to know yet
+        // whether something will be a nonterminal or a seq
+        // yet.
         maybe_whole!(deref self, nt_tt);
 
         // this is the fall-through for the 'match' below.
@@ -3753,7 +3758,7 @@ impl Parser {
         let attrs = self.parse_outer_attributes();
         let lo = self.span.lo;
 
-        let visa = self.parse_non_priv_visibility();
+        let visa = self.parse_visibility();
         let pur = self.parse_fn_purity();
         let ident = self.parse_ident();
         let generics = self.parse_generics();
@@ -3801,7 +3806,7 @@ impl Parser {
     // Parses two variants (with the region/type params always optional):
     //    impl<T> Foo { ... }
     //    impl<T> ToStr for ~[T] { ... }
-    fn parse_item_impl(&self, visibility: ast::visibility) -> item_info {
+    fn parse_item_impl(&self) -> item_info {
         // First, parse type parameters if necessary.
         let generics = self.parse_generics();
 
@@ -3846,13 +3851,10 @@ impl Parser {
             None
         };
 
-        // Do not allow visibility to be specified.
-        if visibility != ast::inherited {
-            self.obsolete(*self.span, ObsoleteImplVisibility);
-        }
-
         let mut meths = ~[];
-        if !self.eat(&token::SEMI) {
+        if self.eat(&token::SEMI) {
+            self.obsolete(*self.span, ObsoleteEmptyImpl);
+        } else {
             self.expect(&token::LBRACE);
             while !self.eat(&token::RBRACE) {
                 meths.push(self.parse_method());
@@ -4012,18 +4014,6 @@ impl Parser {
         else { inherited }
     }
 
-    // parse visibility, but emits an obsolete error if it's private
-    fn parse_non_priv_visibility(&self) -> visibility {
-        match self.parse_visibility() {
-            public => public,
-            inherited => inherited,
-            private => {
-                self.obsolete(*self.last_span, ObsoletePrivVisibility);
-                inherited
-            }
-        }
-    }
-
     fn parse_staticness(&self) -> bool {
         if self.eat_keyword(keywords::Static) {
             self.obsolete(*self.last_span, ObsoleteStaticMethod);
@@ -4216,7 +4206,7 @@ impl Parser {
     // parse a function declaration from a foreign module
     fn parse_item_foreign_fn(&self,  attrs: ~[Attribute]) -> @foreign_item {
         let lo = self.span.lo;
-        let vis = self.parse_non_priv_visibility();
+        let vis = self.parse_visibility();
 
         // Parse obsolete purity.
         let purity = self.parse_fn_purity();
@@ -4352,11 +4342,6 @@ impl Parser {
                 self.obsolete(*self.last_span, ObsoleteNamedExternModule);
             }
 
-            // Do not allow visibility to be specified.
-            if visibility != ast::inherited {
-                self.obsolete(*self.last_span, ObsoleteExternVisibility);
-            }
-
             let abis = opt_abis.unwrap_or(AbiSet::C());
 
             let (inner, next) = self.parse_inner_attrs_and_next();
@@ -4367,7 +4352,7 @@ impl Parser {
                                           self.last_span.hi,
                                           ident,
                                           item_foreign_mod(m),
-                                          public,
+                                          visibility,
                                           maybe_append(attrs, Some(inner))));
         }
 
@@ -4614,7 +4599,7 @@ impl Parser {
 
         let lo = self.span.lo;
 
-        let visibility = self.parse_non_priv_visibility();
+        let visibility = self.parse_visibility();
 
         // must be a view item:
         if self.eat_keyword(keywords::Use) {
@@ -4722,8 +4707,7 @@ impl Parser {
         }
         if self.eat_keyword(keywords::Impl) {
             // IMPL ITEM
-            let (ident, item_, extra_attrs) =
-                self.parse_item_impl(visibility);
+            let (ident, item_, extra_attrs) = self.parse_item_impl();
             return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
                                           visibility,
                                           maybe_append(attrs, extra_attrs)));
@@ -4746,7 +4730,7 @@ impl Parser {
         maybe_whole!(iovi self, nt_item);
         let lo = self.span.lo;
 
-        let visibility = self.parse_non_priv_visibility();
+        let visibility = self.parse_visibility();
 
         if (self.is_keyword(keywords::Const) || self.is_keyword(keywords::Static)) {
             // FOREIGN CONST ITEM
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index b5868cbc63d..dee8d710a73 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -37,16 +37,26 @@ pub enum ann_node<'self> {
     node_expr(@ps, &'self ast::Expr),
     node_pat(@ps, &'self ast::Pat),
 }
-pub struct pp_ann {
-    pre: @fn(ann_node),
-    post: @fn(ann_node)
+
+pub trait pp_ann {
+    fn pre(&self, _node: ann_node) {}
+    fn post(&self, _node: ann_node) {}
+}
+
+pub struct no_ann {
+    contents: (),
 }
 
-pub fn no_ann() -> pp_ann {
-    fn ignore(_node: ann_node) { }
-    return pp_ann {pre: ignore, post: ignore};
+impl no_ann {
+    pub fn new() -> no_ann {
+        no_ann {
+            contents: (),
+        }
+    }
 }
 
+impl pp_ann for no_ann {}
+
 pub struct CurrentCommentAndLiteral {
     cur_cmnt: uint,
     cur_lit: uint,
@@ -60,7 +70,7 @@ pub struct ps {
     literals: Option<~[comments::lit]>,
     cur_cmnt_and_lit: @mut CurrentCommentAndLiteral,
     boxes: @mut ~[pp::breaks],
-    ann: pp_ann
+    ann: @pp_ann
 }
 
 pub fn ibox(s: @ps, u: uint) {
@@ -74,12 +84,13 @@ pub fn end(s: @ps) {
 }
 
 pub fn rust_printer(writer: @io::Writer, intr: @ident_interner) -> @ps {
-    return rust_printer_annotated(writer, intr, no_ann());
+    return rust_printer_annotated(writer, intr, @no_ann::new() as @pp_ann);
 }
 
 pub fn rust_printer_annotated(writer: @io::Writer,
                               intr: @ident_interner,
-                              ann: pp_ann) -> @ps {
+                              ann: @pp_ann)
+                              -> @ps {
     return @ps {
         s: pp::mk_printer(writer, default_columns),
         cm: None::<@CodeMap>,
@@ -109,7 +120,7 @@ pub fn print_crate(cm: @CodeMap,
                    filename: @str,
                    input: @io::Reader,
                    out: @io::Writer,
-                   ann: pp_ann,
+                   ann: @pp_ann,
                    is_expanded: bool) {
     let (cmnts, lits) = comments::gather_comments_and_literals(
         span_diagnostic,
@@ -484,7 +495,7 @@ pub fn print_item(s: @ps, item: &ast::item) {
     maybe_print_comment(s, item.span.lo);
     print_outer_attributes(s, item.attrs);
     let ann_node = node_item(s, item);
-    (s.ann.pre)(ann_node);
+    s.ann.pre(ann_node);
     match item.node {
       ast::item_static(ref ty, m, expr) => {
         head(s, visibility_qualified(item.vis, "static"));
@@ -587,18 +598,12 @@ pub fn print_item(s: @ps, item: &ast::item) {
 
         print_type(s, ty);
 
-        if methods.len() == 0 {
-            word(s.s, ";");
-            end(s); // end the head-ibox
-            end(s); // end the outer cbox
-        } else {
-            space(s.s);
-            bopen(s);
-            for meth in methods.iter() {
-               print_method(s, *meth);
-            }
-            bclose(s, item.span);
+        space(s.s);
+        bopen(s);
+        for meth in methods.iter() {
+           print_method(s, *meth);
         }
+        bclose(s, item.span);
       }
       ast::item_trait(ref generics, ref traits, ref methods) => {
         head(s, visibility_qualified(item.vis, "trait"));
@@ -635,7 +640,7 @@ pub fn print_item(s: @ps, item: &ast::item) {
         end(s);
       }
     }
-    (s.ann.post)(ann_node);
+    s.ann.post(ann_node);
 }
 
 fn print_trait_ref(s: @ps, t: &ast::trait_ref) {
@@ -958,7 +963,7 @@ pub fn print_possibly_embedded_block_(s: @ps,
     }
     maybe_print_comment(s, blk.span.lo);
     let ann_node = node_block(s, blk);
-    (s.ann.pre)(ann_node);
+    s.ann.pre(ann_node);
     match embedded {
       block_block_fn => end(s),
       block_normal => bopen(s)
@@ -979,7 +984,7 @@ pub fn print_possibly_embedded_block_(s: @ps,
       _ => ()
     }
     bclose_maybe_open(s, blk.span, indented, close_box);
-    (s.ann.post)(ann_node);
+    s.ann.post(ann_node);
 }
 
 pub fn print_if(s: @ps, test: &ast::Expr, blk: &ast::Block,
@@ -1121,7 +1126,7 @@ pub fn print_expr(s: @ps, expr: &ast::Expr) {
     maybe_print_comment(s, expr.span.lo);
     ibox(s, indent_unit);
     let ann_node = node_expr(s, expr);
-    (s.ann.pre)(ann_node);
+    s.ann.pre(ann_node);
     match expr.node {
         ast::ExprVstore(e, v) => {
             print_expr_vstore(s, v);
@@ -1456,7 +1461,7 @@ pub fn print_expr(s: @ps, expr: &ast::Expr) {
           pclose(s);
       }
     }
-    (s.ann.post)(ann_node);
+    s.ann.post(ann_node);
     end(s);
 }
 
@@ -1578,7 +1583,7 @@ pub fn print_bounded_path(s: @ps, path: &ast::Path,
 pub fn print_pat(s: @ps, pat: &ast::Pat) {
     maybe_print_comment(s, pat.span.lo);
     let ann_node = node_pat(s, pat);
-    (s.ann.pre)(ann_node);
+    s.ann.pre(ann_node);
     /* Pat isn't normalized, but the beauty of it
      is that it doesn't matter */
     match pat.node {
@@ -1678,7 +1683,7 @@ pub fn print_pat(s: @ps, pat: &ast::Pat) {
         word(s.s, "]");
       }
     }
-    (s.ann.post)(ann_node);
+    s.ann.post(ann_node);
 }
 
 pub fn explicit_self_to_str(explicit_self: &ast::explicit_self_, intr: @ident_interner) -> ~str {
@@ -2254,17 +2259,6 @@ pub fn print_fn_header_info(s: @ps,
     print_opt_sigil(s, opt_sigil);
 }
 
-pub fn opt_sigil_to_str(opt_p: Option<ast::Sigil>) -> &'static str {
-    match opt_p {
-      None => "fn",
-      Some(p) => match p {
-          ast::BorrowedSigil => "fn&",
-          ast::OwnedSigil => "fn~",
-          ast::ManagedSigil => "fn@"
-      }
-    }
-}
-
 pub fn purity_to_str(p: ast::purity) -> &'static str {
     match p {
       ast::impure_fn => "impure",
diff --git a/src/snapshots.txt b/src/snapshots.txt
index 705cf50632a..3d3f314b994 100644
--- a/src/snapshots.txt
+++ b/src/snapshots.txt
@@ -1,3 +1,11 @@
+S 2013-09-23 348d844
+  freebsd-x86_64 8b99ec197e441f013c5ba0788f8bcfa689bfc75e
+  linux-i386 9a237fcbe4d29986a360b1dc8984da3b946463e6
+  linux-x86_64 47906010eb676cbf9e0caa0773d9ef2dce89e9f8
+  macos-i386 7085e4dd6bc63864f2ad8a3a21dab945ffd99d8d
+  macos-x86_64 efefdca6b4a40ebeb977037ebbf46c1353f09ee5
+  winnt-i386 7988b58a9530a4ac0688ec978e9124c5db56717c
+
 S 2013-09-17 cbd1eef
   freebsd-x86_64 9166867a8859076343cb3e57da918b5c0eea720b
   linux-i386 38347b579312ff30c36d257a1161660eb0ae8422
diff --git a/src/test/auxiliary/cci_nested_lib.rs b/src/test/auxiliary/cci_nested_lib.rs
index c9809438d94..350bd09826f 100644
--- a/src/test/auxiliary/cci_nested_lib.rs
+++ b/src/test/auxiliary/cci_nested_lib.rs
@@ -14,7 +14,7 @@ pub struct Entry<A,B> {
 }
 
 pub struct alist<A,B> {
-    eq_fn: @fn(A,A) -> bool,
+    eq_fn: extern "Rust" fn(A,A) -> bool,
     data: @mut ~[Entry<A,B>]
 }
 
diff --git a/src/test/auxiliary/issue2378a.rs b/src/test/auxiliary/issue2378a.rs
index 88439e32b0d..ea14229cc48 100644
--- a/src/test/auxiliary/issue2378a.rs
+++ b/src/test/auxiliary/issue2378a.rs
@@ -11,7 +11,7 @@
 #[link (name = "issue2378a")];
 #[crate_type = "lib"];
 
-enum maybe<T> { just(T), nothing }
+pub enum maybe<T> { just(T), nothing }
 
 impl <T:Clone> Index<uint,T> for maybe<T> {
     fn index(&self, _idx: &uint) -> T {
diff --git a/src/test/auxiliary/issue2378b.rs b/src/test/auxiliary/issue2378b.rs
index d2c42bacc63..71c0bab138f 100644
--- a/src/test/auxiliary/issue2378b.rs
+++ b/src/test/auxiliary/issue2378b.rs
@@ -15,7 +15,7 @@ extern mod issue2378a;
 
 use issue2378a::maybe;
 
-struct two_maybes<T> {a: maybe<T>, b: maybe<T>}
+pub struct two_maybes<T> {a: maybe<T>, b: maybe<T>}
 
 impl<T:Clone> Index<uint,(T,T)> for two_maybes<T> {
     fn index(&self, idx: &uint) -> (T, T) {
diff --git a/src/test/auxiliary/nested_item.rs b/src/test/auxiliary/nested_item.rs
index c2f38134d1e..96bae656390 100644
--- a/src/test/auxiliary/nested_item.rs
+++ b/src/test/auxiliary/nested_item.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // original problem
-fn foo<T>() -> int {
+pub fn foo<T>() -> int {
     {
         static foo: int = 2;
         foo
diff --git a/src/test/auxiliary/packed.rs b/src/test/auxiliary/packed.rs
index 478d51b540c..150de8d314d 100644
--- a/src/test/auxiliary/packed.rs
+++ b/src/test/auxiliary/packed.rs
@@ -1,5 +1,5 @@
 #[packed]
-struct S {
+pub struct S {
     a: u8,
     b: u32
 }
diff --git a/src/test/auxiliary/static_priv_by_default.rs b/src/test/auxiliary/static_priv_by_default.rs
new file mode 100644
index 00000000000..d46ccf299e8
--- /dev/null
+++ b/src/test/auxiliary/static_priv_by_default.rs
@@ -0,0 +1,57 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[crate_type = "lib"];
+#[no_std];
+
+static private: int = 0;
+pub static public: int = 0;
+
+pub struct A(());
+
+impl A {
+    fn foo() {}
+}
+
+mod foo {
+    pub static a: int = 0;
+    pub fn b() {}
+    pub struct c;
+    pub enum d {}
+
+    pub struct A(());
+
+    impl A {
+        fn foo() {}
+    }
+
+    // these are public so the parent can reexport them.
+    pub static reexported_a: int = 0;
+    pub fn reexported_b() {}
+    pub struct reexported_c;
+    pub enum reexported_d {}
+}
+
+pub mod bar {
+    pub use e = foo::reexported_a;
+    pub use f = foo::reexported_b;
+    pub use g = foo::reexported_c;
+    pub use h = foo::reexported_d;
+}
+
+pub static a: int = 0;
+pub fn b() {}
+pub struct c;
+pub enum d {}
+
+static i: int = 0;
+fn j() {}
+struct k;
+enum l {}
diff --git a/src/test/auxiliary/trait_inheritance_overloading_xc.rs b/src/test/auxiliary/trait_inheritance_overloading_xc.rs
index f938c9c56ed..8694871417a 100644
--- a/src/test/auxiliary/trait_inheritance_overloading_xc.rs
+++ b/src/test/auxiliary/trait_inheritance_overloading_xc.rs
@@ -35,6 +35,6 @@ impl Eq for MyInt {
     fn ne(&self, other: &MyInt) -> bool { !self.eq(other) }
 }
 
-impl MyNum for MyInt;
+impl MyNum for MyInt {}
 
 fn mi(v: int) -> MyInt { MyInt { val: v } }
diff --git a/src/test/bench/task-perf-alloc-unwind.rs b/src/test/bench/task-perf-alloc-unwind.rs
index f383f7a101f..991c102e9f0 100644
--- a/src/test/bench/task-perf-alloc-unwind.rs
+++ b/src/test/bench/task-perf-alloc-unwind.rs
@@ -46,7 +46,6 @@ type nillist = List<()>;
 struct State {
     box: @nillist,
     unique: ~nillist,
-    fn_box: @fn() -> @nillist,
     tuple: (@nillist, ~nillist),
     vec: ~[@nillist],
     res: r
@@ -79,19 +78,15 @@ fn recurse_or_fail(depth: int, st: Option<State>) {
             State {
                 box: @Nil,
                 unique: ~Nil,
-                fn_box: || @Nil::<()>,
                 tuple: (@Nil, ~Nil),
                 vec: ~[@Nil],
                 res: r(@Nil)
             }
           }
           Some(st) => {
-            let fn_box = st.fn_box;
-
             State {
                 box: @Cons((), st.box),
                 unique: ~Cons((), @*st.unique),
-                fn_box: || @Cons((), fn_box()),
                 tuple: (@Cons((), st.tuple.first()),
                         ~Cons((), @*st.tuple.second())),
                 vec: st.vec + &[@Cons((), *st.vec.last())],
diff --git a/src/test/run-pass/issue-4929.rs b/src/test/compile-fail/bad-char-literals.rs
index 5803c3da6cc..53723c87a52 100644
--- a/src/test/run-pass/issue-4929.rs
+++ b/src/test/compile-fail/bad-char-literals.rs
@@ -8,5 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn make_adder(x: int) -> @fn(int) -> int { |y| x + y }
-pub fn main() { }
+fn main() {
+    // these literals are just silly.
+    ''';
+    //~^ ERROR: character constant must be escaped
+}
diff --git a/src/test/run-fail/unwind-closure.rs b/src/test/compile-fail/bad-char-literals2.rs
index 5ea71c94e14..c5226cfec45 100644
--- a/src/test/run-fail/unwind-closure.rs
+++ b/src/test/compile-fail/bad-char-literals2.rs
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,14 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:fail
-
-fn f(_a: @int) {
-    fail!();
-}
-
 fn main() {
-    let b = @0;
-    let g: @fn() = || f(b);
-    g();
+    // note that this is a literal "\n" byte
+    '
+';
+    //~^^ ERROR: character constant must be escaped
 }
diff --git a/src/test/auxiliary/issue4516_ty_param_lib.rs b/src/test/compile-fail/bad-char-literals3.rs
index cd90c9b06c4..9bbe5c75b17 100644
--- a/src/test/auxiliary/issue4516_ty_param_lib.rs
+++ b/src/test/compile-fail/bad-char-literals3.rs
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,7 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub fn to_closure<A:'static + Clone>(x: A) -> @fn() -> A {
-    let result: @fn() -> A = || x.clone();
-    result
+fn main() {
+    // note that this is a literal "\r" byte
+    '
';
+    //~^ ERROR: character constant must be escaped
 }
diff --git a/src/test/run-pass/fn-bare-coerce-to-shared.rs b/src/test/compile-fail/bad-char-literals4.rs
index 853b44ed76c..675ff742d5c 100644
--- a/src/test/run-pass/fn-bare-coerce-to-shared.rs
+++ b/src/test/compile-fail/bad-char-literals4.rs
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,10 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn bare() {}
-
-fn likes_shared(f: @fn()) { f() }
-
-pub fn main() {
-    likes_shared(bare);
+fn main() {
+    // note that this is a literal tab character here
+    '	';
+    //~^ ERROR: character constant must be escaped
 }
diff --git a/src/test/compile-fail/borrowck-addr-of-upvar.rs b/src/test/compile-fail/borrowck-addr-of-upvar.rs
deleted file mode 100644
index 83baedc7892..00000000000
--- a/src/test/compile-fail/borrowck-addr-of-upvar.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn foo(x: @int) -> @fn() -> &'static int {
-    let result: @fn() -> &'static int = || &*x;  //~ ERROR cannot root
-    result
-}
-
-fn bar(x: @int) -> @fn() -> &int {
-    let result: @fn() -> &int = || &*x; //~ ERROR cannot root
-    result
-}
-
-fn zed(x: @int) -> @fn() -> int {
-    let result: @fn() -> int = || *&*x;
-    result
-}
-
-fn main() {
-}
diff --git a/src/test/compile-fail/borrowck-move-by-capture.rs b/src/test/compile-fail/borrowck-move-by-capture.rs
index ecb18993d93..5994b9e85d5 100644
--- a/src/test/compile-fail/borrowck-move-by-capture.rs
+++ b/src/test/compile-fail/borrowck-move-by-capture.rs
@@ -1,13 +1,13 @@
 pub fn main() {
     let foo = ~3;
     let _pfoo = &foo;
-    let _f: @fn() -> int = || *foo + 5;
+    let _f: ~fn() -> int = || *foo + 5;
     //~^ ERROR cannot move `foo`
 
     // FIXME(#2202) - Due to the way that borrowck treats closures,
     // you get two error reports here.
     let bar = ~3;
     let _g = || { //~ ERROR capture of moved value
-        let _h: @fn() -> int = || *bar; //~ ERROR capture of moved value
+        let _h: ~fn() -> int = || *bar; //~ ERROR capture of moved value
     };
 }
diff --git a/src/test/compile-fail/closure-bounds-cant-promote-superkind-in-struct.rs b/src/test/compile-fail/closure-bounds-cant-promote-superkind-in-struct.rs
index b38cb895488..525f8f4a932 100644
--- a/src/test/compile-fail/closure-bounds-cant-promote-superkind-in-struct.rs
+++ b/src/test/compile-fail/closure-bounds-cant-promote-superkind-in-struct.rs
@@ -9,10 +9,10 @@
 // except according to those terms.
 
 struct X {
-    field: @fn:Send(),
+    field: ~fn:Send(),
 }
 
-fn foo(blk: @fn:()) -> X {
+fn foo(blk: ~fn:()) -> X {
     return X { field: blk }; //~ ERROR expected bounds `Send` but found no bounds
 }
 
diff --git a/src/test/compile-fail/dead-code-ret.rs b/src/test/compile-fail/dead-code-ret.rs
index 2e4ae7f8544..b6976b2c355 100644
--- a/src/test/compile-fail/dead-code-ret.rs
+++ b/src/test/compile-fail/dead-code-ret.rs
@@ -1,3 +1,8 @@
+// xfail-test
+
+// xfail'd because the lint pass doesn't know to ignore standard library
+// stuff.
+
 // -*- rust -*-
 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
diff --git a/src/test/compile-fail/do2.rs b/src/test/compile-fail/do2.rs
index 4466c07518f..1bffdaa682c 100644
--- a/src/test/compile-fail/do2.rs
+++ b/src/test/compile-fail/do2.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn f(f: @fn(int) -> bool) -> bool { f(10i) }
+fn f(f: &fn(int) -> bool) -> bool { f(10i) }
 
 fn main() {
     assert!(do f() |i| { i == 10i } == 10i);
diff --git a/src/test/compile-fail/fn-variance-2.rs b/src/test/compile-fail/fn-variance-2.rs
deleted file mode 100644
index ab559190034..00000000000
--- a/src/test/compile-fail/fn-variance-2.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn reproduce<T>(t: T) -> @fn() -> T {
-    let result: @fn() -> T = || t;
-    result
-}
-
-fn main() {
-    // type of x is the variable X,
-    // with the lower bound @mut int
-    let x = @mut 3;
-
-    // type of r is @fn() -> X
-    let r = reproduce(x);
-
-    // Requires that X be a subtype of
-    // @mut int.
-    let f: @mut int = r();
-
-    // Bad.
-    let h: @int = r(); //~ ERROR (values differ in mutability)
-}
diff --git a/src/test/compile-fail/fn-variance-3.rs b/src/test/compile-fail/fn-variance-3.rs
deleted file mode 100644
index e42c6b658e4..00000000000
--- a/src/test/compile-fail/fn-variance-3.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn mk_identity<T>() -> @fn(T) -> T {
-    let result: @fn(t: T) -> T = |t| t;
-    result
-}
-
-fn main() {
-    // type of r is @fn(X) -> X
-    // for some fresh X
-    let r = mk_identity();
-
-    // @mut int <: X
-    r(@mut 3);
-
-    // @int <: X
-    //
-    // Here the type check fails because @const is gone and there is no
-    // supertype.
-    r(@3);  //~ ERROR mismatched types
-
-    // Here the type check succeeds.
-    *r(@mut 3) = 4;
-}
diff --git a/src/test/compile-fail/issue-1451.rs b/src/test/compile-fail/issue-1451.rs
index a295e8eb7ed..0d8acaa4464 100644
--- a/src/test/compile-fail/issue-1451.rs
+++ b/src/test/compile-fail/issue-1451.rs
@@ -9,8 +9,8 @@
 // except according to those terms.
 
 // xfail-test
-struct T { f: @fn() };
-struct S { f: @fn() };
+struct T { f: extern "Rust" fn() };
+struct S { f: extern "Rust" fn() };
 
 fn fooS(t: S) {
 }
@@ -22,11 +22,11 @@ fn bar() {
 }
 
 fn main() {
-    let x: @fn() = bar;
+    let x: extern "Rust" fn() = bar;
     fooS(S {f: x});
     fooS(S {f: bar});
 
-    let x: @fn() = bar;
+    let x: extern "Rust" fn() = bar;
     fooT(T {f: x});
     fooT(T {f: bar});
 }
diff --git a/src/test/compile-fail/issue-1896-1.rs b/src/test/compile-fail/issue-1896-1.rs
deleted file mode 100644
index 4750f68d59b..00000000000
--- a/src/test/compile-fail/issue-1896-1.rs
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Test that we require managed closures to be rooted when borrowed.
-
-struct boxedFn<'self> { theFn: &'self fn() -> uint }
-
-fn createClosure (closedUint: uint) -> boxedFn {
-    let theFn: @fn() -> uint = || closedUint;
-    boxedFn {theFn: theFn} //~ ERROR cannot root
-}
-
-fn main () {
-    let aFn: boxedFn = createClosure(10);
-
-    let myInt: uint = (aFn.theFn)();
-
-    assert_eq!(myInt, 10);
-}
diff --git a/src/test/compile-fail/issue-2074.rs b/src/test/compile-fail/issue-2074.rs
index 40c2772f234..7815fca16c6 100644
--- a/src/test/compile-fail/issue-2074.rs
+++ b/src/test/compile-fail/issue-2074.rs
@@ -10,11 +10,11 @@
 
 // xfail-test
 fn main() {
-    let one: @fn() -> uint = || {
+    let one: &fn() -> uint = || {
         enum r { a };
         a as uint
     };
-    let two = @fn() -> uint = || {
+    let two = &fn() -> uint = || {
         enum r { a };
         a as uint
     };
diff --git a/src/test/compile-fail/issue-897-2.rs b/src/test/compile-fail/issue-897-2.rs
index eb60e34df8f..c39c258c701 100644
--- a/src/test/compile-fail/issue-897-2.rs
+++ b/src/test/compile-fail/issue-897-2.rs
@@ -1,3 +1,7 @@
+// xfail-test
+// xfail'd because the lint pass doesn't know to ignore standard library
+// stuff.
+
 // 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.
diff --git a/src/test/compile-fail/issue-897.rs b/src/test/compile-fail/issue-897.rs
index 103156175a3..8df73aef610 100644
--- a/src/test/compile-fail/issue-897.rs
+++ b/src/test/compile-fail/issue-897.rs
@@ -1,3 +1,5 @@
+// xfail-test
+
 // 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.
diff --git a/src/test/compile-fail/kindck-owned.rs b/src/test/compile-fail/kindck-owned.rs
deleted file mode 100644
index 2dfdb2629f7..00000000000
--- a/src/test/compile-fail/kindck-owned.rs
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn copy1<T:Clone>(t: T) -> @fn() -> T {
-    let result: @fn() -> T = || t.clone();  //~ ERROR does not fulfill `'static`
-    result
-}
-
-fn copy2<T:Clone + 'static>(t: T) -> @fn() -> T {
-    let result: @fn() -> T = || t.clone();
-    result
-}
-
-fn main() {
-    let x = &3;
-    copy2(&x); //~ ERROR does not fulfill `'static`
-
-    copy2(@3);
-    copy2(@&x); //~ ERROR value may contain borrowed pointers
-    //~^ ERROR does not fulfill `'static`
-}
diff --git a/src/test/compile-fail/lambda-mutate-nested.rs b/src/test/compile-fail/lambda-mutate-nested.rs
deleted file mode 100644
index bfd1e12f3a6..00000000000
--- a/src/test/compile-fail/lambda-mutate-nested.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Make sure that nesting a block within a @fn doesn't let us
-// mutate upvars from a @fn.
-fn f2(x: &fn()) { x(); }
-
-fn main() {
-    let i = 0;
-    let ctr: @fn() -> int = || { f2(|| i = i + 1 ); i };
-    //~^ ERROR cannot assign
-    error!(ctr());
-    error!(ctr());
-    error!(ctr());
-    error!(ctr());
-    error!(ctr());
-    error!(i);
-}
diff --git a/src/test/compile-fail/lambda-mutate.rs b/src/test/compile-fail/lambda-mutate.rs
deleted file mode 100644
index a848d8698a3..00000000000
--- a/src/test/compile-fail/lambda-mutate.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Make sure we can't write to upvars from @fns
-fn main() {
-    let i = 0;
-    let ctr: @fn() -> int = || { i = i + 1; i };
-    //~^ ERROR cannot assign
-    error!(ctr());
-    error!(ctr());
-    error!(ctr());
-    error!(ctr());
-    error!(ctr());
-    error!(i);
-}
diff --git a/src/test/compile-fail/liveness-init-in-called-fn-expr.rs b/src/test/compile-fail/liveness-init-in-called-fn-expr.rs
index 1fddea80966..7054cb0d901 100644
--- a/src/test/compile-fail/liveness-init-in-called-fn-expr.rs
+++ b/src/test/compile-fail/liveness-init-in-called-fn-expr.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 fn main() {
-    let j: @fn() -> int = || {
+    let j: &fn() -> int = || {
         let i: int;
         i //~ ERROR use of possibly uninitialized variable: `i`
     };
diff --git a/src/test/compile-fail/liveness-init-in-fn-expr.rs b/src/test/compile-fail/liveness-init-in-fn-expr.rs
index b7a715d2958..b6c7895235b 100644
--- a/src/test/compile-fail/liveness-init-in-fn-expr.rs
+++ b/src/test/compile-fail/liveness-init-in-fn-expr.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 fn main() {
-    let f: @fn() -> int = || {
+    let f: &fn() -> int = || {
         let i: int;
         i //~ ERROR use of possibly uninitialized variable: `i`
     };
diff --git a/src/test/compile-fail/missing-derivable-attr.rs b/src/test/compile-fail/missing-derivable-attr.rs
index eb27d51061f..70c16e0baef 100644
--- a/src/test/compile-fail/missing-derivable-attr.rs
+++ b/src/test/compile-fail/missing-derivable-attr.rs
@@ -20,7 +20,7 @@ impl MyEq for int {
     fn eq(&self, other: &int) -> bool { *self == *other }
 }
 
-impl MyEq for A;  //~ ERROR missing method
+impl MyEq for A {}  //~ ERROR missing method
 
 fn main() {
 }
diff --git a/src/test/compile-fail/obsolete-syntax.rs b/src/test/compile-fail/obsolete-syntax.rs
index 49af0972341..872f3b1010e 100644
--- a/src/test/compile-fail/obsolete-syntax.rs
+++ b/src/test/compile-fail/obsolete-syntax.rs
@@ -54,9 +54,9 @@ extern mod obsolete_name {
     fn bar();
 }
 
-pub extern {
-    //~^ ERROR obsolete syntax: `pub extern`
-    pub fn bar();
+trait A {
+    pub fn foo(); //~ ERROR: visibility not necessary
+    pub fn bar(); //~ ERROR: visibility not necessary
 }
 
 fn main() { }
diff --git a/src/test/run-pass/issue-5783.rs b/src/test/compile-fail/priv-in-bad-locations.rs
index 7f988dc6489..db649ed0cc6 100644
--- a/src/test/run-pass/issue-5783.rs
+++ b/src/test/compile-fail/priv-in-bad-locations.rs
@@ -8,12 +8,21 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// Issue #5783
-// Nondeterministic behavior when referencing a closure more than once
+pub extern {
+    //~^ ERROR unnecessary visibility
+    pub fn bar();
+}
+
+trait A {
+    fn foo() {}
+}
 
-fn main() {
-    let a: &fn(int) -> @fn(int) -> int = |x:int| |y:int| -> int x + y;
-    let b = a(2);
-    assert!(a(2)(3) == 5);
-    assert!(b(6) == 8);
+struct B;
+
+pub impl B {} //~ ERROR: unnecessary visibility
+
+pub impl A for B { //~ ERROR: unnecessary visibility
+    pub fn foo() {} //~ ERROR: unnecessary visibility
 }
+
+pub fn main() {}
diff --git a/src/test/compile-fail/regions-fn-subtyping.rs b/src/test/compile-fail/regions-fn-subtyping.rs
index face9c74214..5928d31a668 100644
--- a/src/test/compile-fail/regions-fn-subtyping.rs
+++ b/src/test/compile-fail/regions-fn-subtyping.rs
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn of<T>() -> @fn(T) { fail!(); }
-fn subtype<T>(x: @fn(T)) { fail!(); }
+fn of<T>() -> &fn(T) { fail!(); }
+fn subtype<T>(x: &fn(T)) { fail!(); }
 
 fn test_fn<'x,'y,'z,T>(_x: &'x T, _y: &'y T, _z: &'z T) {
     // Here, x, y, and z are free.  Other letters
@@ -40,18 +40,6 @@ fn test_fn<'x,'y,'z,T>(_x: &'x T, _y: &'y T, _z: &'z T) {
 
     subtype::<&fn<'x,'y>(&'x T, &'y T)>(
         of::<&fn<'a,'b>(&'a T, &'b T)>()); //~ ERROR mismatched types
-
-    subtype::<&fn<'x,'a>(&'x T) -> @fn(&'a T)>(
-        of::<&fn<'x,'a>(&'x T) -> @fn(&'a T)>());
-
-    subtype::<&fn<'a>(&'a T) -> @fn(&'a T)>(
-        of::<&fn<'a,'b>(&'a T) -> @fn(&'b T)>()); //~ ERROR mismatched types
-
-    subtype::<&fn<'a>(&'a T) -> @fn(&'a T)>(
-        of::<&fn<'x,'b>(&'x T) -> @fn(&'b T)>()); //~ ERROR mismatched types
-
-    subtype::<&fn<'a,'b>(&'a T) -> @fn(&'b T)>(
-        of::<&fn<'a>(&'a T) -> @fn(&'a T)>());
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/regions-fns.rs b/src/test/compile-fail/regions-fns.rs
index 4f6cbdfdd65..715261d816a 100644
--- a/src/test/compile-fail/regions-fns.rs
+++ b/src/test/compile-fail/regions-fns.rs
@@ -12,7 +12,7 @@
 // we reported errors in this case:
 
 fn not_ok<'b>(a: &uint, b: &'b uint) {
-    let mut g: @fn(x: &uint) = |x: &'b uint| {};
+    let mut g: &fn(x: &uint) = |x: &'b uint| {};
     //~^ ERROR mismatched types
     g(a);
 }
diff --git a/src/test/compile-fail/regions-infer-at-fn-not-param.rs b/src/test/compile-fail/regions-infer-at-fn-not-param.rs
index 488d1f3940d..3ddae976ce3 100644
--- a/src/test/compile-fail/regions-infer-at-fn-not-param.rs
+++ b/src/test/compile-fail/regions-infer-at-fn-not-param.rs
@@ -13,11 +13,11 @@ struct parameterized1<'self> {
 }
 
 struct not_parameterized1 {
-    g: @fn()
+    g: &'static fn()
 }
 
 struct not_parameterized2 {
-    g: @fn()
+    g: &'static fn()
 }
 
 fn take1(p: parameterized1) -> parameterized1 { p }
diff --git a/src/test/compile-fail/regions-infer-contravariance-due-to-ret.rs b/src/test/compile-fail/regions-infer-contravariance-due-to-ret.rs
index 15f40a91735..3fcc5184b4a 100644
--- a/src/test/compile-fail/regions-infer-contravariance-due-to-ret.rs
+++ b/src/test/compile-fail/regions-infer-contravariance-due-to-ret.rs
@@ -14,7 +14,7 @@
 // the normal case.
 
 struct contravariant<'self> {
-    f: @fn() -> &'self int
+    f: &'static fn() -> &'self int
 }
 
 fn to_same_lifetime<'r>(bi: contravariant<'r>) {
diff --git a/src/test/compile-fail/regions-infer-covariance-due-to-arg.rs b/src/test/compile-fail/regions-infer-covariance-due-to-arg.rs
index c33ca2dab2e..4b26e6b6021 100644
--- a/src/test/compile-fail/regions-infer-covariance-due-to-arg.rs
+++ b/src/test/compile-fail/regions-infer-covariance-due-to-arg.rs
@@ -13,7 +13,7 @@
 // You can upcast to a *larger region* but not a smaller one.
 
 struct covariant<'self> {
-    f: @fn(x: &'self int) -> int
+    f: &'static fn(x: &'self int) -> int
 }
 
 fn to_same_lifetime<'r>(bi: covariant<'r>) {
diff --git a/src/test/compile-fail/regions-infer-invariance-due-to-mutability-3.rs b/src/test/compile-fail/regions-infer-invariance-due-to-mutability-3.rs
index 92447c1ef8d..6e322b170e8 100644
--- a/src/test/compile-fail/regions-infer-invariance-due-to-mutability-3.rs
+++ b/src/test/compile-fail/regions-infer-invariance-due-to-mutability-3.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 struct invariant<'self> {
-    f: @fn(x: @mut &'self int)
+    f: &'static fn(x: @mut &'self int)
 }
 
 fn to_same_lifetime<'r>(bi: invariant<'r>) {
diff --git a/src/test/compile-fail/regions-infer-invariance-due-to-mutability-4.rs b/src/test/compile-fail/regions-infer-invariance-due-to-mutability-4.rs
index 61adba3aec1..380e9b27ff9 100644
--- a/src/test/compile-fail/regions-infer-invariance-due-to-mutability-4.rs
+++ b/src/test/compile-fail/regions-infer-invariance-due-to-mutability-4.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 struct invariant<'self> {
-    f: @fn() -> @mut &'self int
+    f: &'static fn() -> @mut &'self int
 }
 
 fn to_same_lifetime<'r>(bi: invariant<'r>) {
diff --git a/src/test/compile-fail/regions-infer-not-param.rs b/src/test/compile-fail/regions-infer-not-param.rs
index fa853b82d9e..47c1f7a5757 100644
--- a/src/test/compile-fail/regions-infer-not-param.rs
+++ b/src/test/compile-fail/regions-infer-not-param.rs
@@ -14,12 +14,12 @@ struct direct<'self> {
 
 struct indirect1 {
     // Here the lifetime parameter of direct is bound by the fn()
-    g: @fn(direct)
+    g: &'static fn(direct)
 }
 
 struct indirect2<'self> {
     // But here it is set to 'self
-    g: @fn(direct<'self>)
+    g: &'static fn(direct<'self>)
 }
 
 fn take_direct(p: direct) -> direct { p } //~ ERROR mismatched types
diff --git a/src/test/compile-fail/sendfn-is-not-a-lambda.rs b/src/test/compile-fail/sendfn-is-not-a-lambda.rs
deleted file mode 100644
index 609439d7b8e..00000000000
--- a/src/test/compile-fail/sendfn-is-not-a-lambda.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn test(f: @fn(uint) -> uint) -> uint {
-    return f(22u);
-}
-
-fn main() {
-    let f: ~fn(x: uint) -> uint = |x| 4u;
-    info!(test(f)); //~ ERROR expected @ closure, found ~ closure
-}
diff --git a/src/test/compile-fail/static-priv-by-default.rs b/src/test/compile-fail/static-priv-by-default.rs
new file mode 100644
index 00000000000..59d7e23855c
--- /dev/null
+++ b/src/test/compile-fail/static-priv-by-default.rs
@@ -0,0 +1,39 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:static_priv_by_default.rs
+
+#[no_std];
+
+extern mod static_priv_by_default;
+
+mod child {
+    pub mod childs_child {
+        static private: int = 0;
+        pub static public: int = 0;
+    }
+}
+
+fn foo(_: int) {}
+
+fn full_ref() {
+    foo(static_priv_by_default::private); //~ ERROR: unresolved name
+    foo(static_priv_by_default::public);
+    foo(child::childs_child::private); //~ ERROR: unresolved name
+    foo(child::childs_child::public);
+}
+
+fn medium_ref() {
+    use child::childs_child;
+    foo(childs_child::private); //~ ERROR: unresolved name
+    foo(childs_child::public);
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/static-priv-by-default2.rs b/src/test/compile-fail/static-priv-by-default2.rs
new file mode 100644
index 00000000000..28a17cf5e1c
--- /dev/null
+++ b/src/test/compile-fail/static-priv-by-default2.rs
@@ -0,0 +1,29 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:static_priv_by_default.rs
+
+extern mod static_priv_by_default;
+
+mod child {
+    pub mod childs_child {
+        static private: int = 0;
+        pub static public: int = 0;
+    }
+}
+
+fn main() {
+    use static_priv_by_default::private; //~ ERROR: unresolved import
+    //~^ ERROR: failed to resolve
+    use static_priv_by_default::public;
+    use child::childs_child::private; //~ ERROR: unresolved import
+    //~^ ERROR: failed to resolve
+    use child::childs_child::public;
+}
diff --git a/src/test/compile-fail/useless-priv2.rs b/src/test/compile-fail/useless-priv2.rs
index 0d94300329c..29c87e77ac0 100644
--- a/src/test/compile-fail/useless-priv2.rs
+++ b/src/test/compile-fail/useless-priv2.rs
@@ -12,8 +12,3 @@ pub trait E {
     pub fn foo();               //~ ERROR: obsolete syntax
 }
 trait F { pub fn foo(); }       //~ ERROR: obsolete syntax
-
-struct B;
-impl E for B {
-    priv fn foo() {}             //~ ERROR: obsolete syntax
-}
diff --git a/src/test/compile-fail/xc-private-method.rs b/src/test/compile-fail/xc-private-method.rs
index 371bac7a902..b4a999766b5 100644
--- a/src/test/compile-fail/xc-private-method.rs
+++ b/src/test/compile-fail/xc-private-method.rs
@@ -1,16 +1,22 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
 // xfail-fast
 // aux-build:xc_private_method_lib.rs
 
 extern mod xc_private_method_lib;
 
 fn main() {
-    // normal method on struct
-    let _ = xc_private_method_lib::Struct{ x: 10 }.meth_struct();  //~ ERROR method `meth_struct` is private
-    // static method on struct
-    let _ = xc_private_method_lib::Struct::static_meth_struct();  //~ ERROR method `static_meth_struct` is private
+    let _ = xc_private_method_lib::Struct::static_meth_struct();
+    //~^ ERROR: unresolved name
 
-    // normal method on enum
-    let _ = xc_private_method_lib::Variant1(20).meth_enum();  //~ ERROR method `meth_enum` is private
-    // static method on enum
-    let _ = xc_private_method_lib::Enum::static_meth_enum();  //~ ERROR method `static_meth_enum` is private
+    let _ = xc_private_method_lib::Enum::static_meth_enum();
+    //~^ ERROR: unresolved name
 }
diff --git a/src/test/run-fail/unwind-box-fn.rs b/src/test/compile-fail/xc-private-method2.rs
index a94f904c492..c2eaa9287f4 100644
--- a/src/test/run-fail/unwind-box-fn.rs
+++ b/src/test/compile-fail/xc-private-method2.rs
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,17 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:fail
+// xfail-fast
+// aux-build:xc_private_method_lib.rs
 
-fn failfn() {
-    fail!();
-}
+extern mod xc_private_method_lib;
 
 fn main() {
-    let y = ~0;
-    let x: @@fn() = @|| {
-        error!(y.clone());
-    };
-    failfn();
-    error!(x);
+    let _ = xc_private_method_lib::Struct{ x: 10 }.meth_struct();  //~ ERROR method `meth_struct` is private
+
+    let _ = xc_private_method_lib::Variant1(20).meth_enum();  //~ ERROR method `meth_enum` is private
 }
diff --git a/src/test/compile-fail/xcrate-private-by-default.rs b/src/test/compile-fail/xcrate-private-by-default.rs
new file mode 100644
index 00000000000..38649981f93
--- /dev/null
+++ b/src/test/compile-fail/xcrate-private-by-default.rs
@@ -0,0 +1,57 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:static_priv_by_default.rs
+
+#[allow(unused_imports)];
+#[no_std];
+
+extern mod static_priv_by_default;
+
+fn foo<T>() {}
+
+#[start]
+fn main(_: int, _: **u8, _: *u8) -> int {
+    // Actual public items should be public
+    static_priv_by_default::a;
+    static_priv_by_default::b;
+    static_priv_by_default::c;
+    foo::<static_priv_by_default::d>();
+
+    // publicly re-exported items should be available
+    static_priv_by_default::bar::e;
+    static_priv_by_default::bar::f;
+    static_priv_by_default::bar::g;
+    foo::<static_priv_by_default::bar::h>();
+
+    // private items at the top should be inaccessible
+    static_priv_by_default::i;
+    //~^ ERROR: unresolved name
+    static_priv_by_default::j;
+    //~^ ERROR: unresolved name
+    static_priv_by_default::k;
+    //~^ ERROR: unresolved name
+    foo::<static_priv_by_default::l>();
+    //~^ ERROR: use of undeclared type name
+    //~^^ ERROR: use of undeclared type name
+
+    // public items in a private mod should be inaccessible
+    static_priv_by_default::foo::a;
+    //~^ ERROR: unresolved name
+    static_priv_by_default::foo::b;
+    //~^ ERROR: unresolved name
+    static_priv_by_default::foo::c;
+    //~^ ERROR: unresolved name
+    foo::<static_priv_by_default::foo::d>();
+    //~^ ERROR: use of undeclared type name
+    //~^^ ERROR: use of undeclared type name
+
+    3
+}
diff --git a/src/test/debug-info/generic-trait-generic-static-default-method.rs b/src/test/debug-info/generic-trait-generic-static-default-method.rs
index 8523a947aac..4355b4b98fe 100644
--- a/src/test/debug-info/generic-trait-generic-static-default-method.rs
+++ b/src/test/debug-info/generic-trait-generic-static-default-method.rs
@@ -40,7 +40,7 @@ trait Trait<T1> {
     }
 }
 
-impl<T> Trait<T> for Struct;
+impl<T> Trait<T> for Struct {}
 
 fn main() {
 
diff --git a/src/test/debug-info/lexical-scope-in-managed-closure.rs b/src/test/debug-info/lexical-scope-in-managed-closure.rs
deleted file mode 100644
index 96da78a9192..00000000000
--- a/src/test/debug-info/lexical-scope-in-managed-closure.rs
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// compile-flags:-Z extra-debug-info
-// debugger:rbreak zzz
-// debugger:run
-
-// debugger:finish
-// debugger:print x
-// check:$1 = false
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$2 = false
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$3 = 1000
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$4 = 2.5
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$5 = true
-// debugger:continue
-
-// debugger:finish
-// debugger:print x
-// check:$6 = false
-// debugger:continue
-
-fn main() {
-
-    let x = false;
-
-    zzz();
-    sentinel();
-
-    let managed_closure: @fn(int) = |x| {
-        zzz();
-        sentinel();
-
-        let x = 2.5;
-
-        zzz();
-        sentinel();
-
-        let x = true;
-
-        zzz();
-        sentinel();
-    };
-
-    zzz();
-    sentinel();
-
-    managed_closure(1000);
-
-    zzz();
-    sentinel();
-}
-
-fn zzz() {()}
-fn sentinel() {()}
diff --git a/src/test/debug-info/self-in-default-method.rs b/src/test/debug-info/self-in-default-method.rs
index 53b2e9ee21d..fde58f76acc 100644
--- a/src/test/debug-info/self-in-default-method.rs
+++ b/src/test/debug-info/self-in-default-method.rs
@@ -118,7 +118,7 @@ trait Trait {
     }
 }
 
-impl Trait for Struct;
+impl Trait for Struct {}
 
 fn main() {
     let stack = Struct { x: 100 };
diff --git a/src/test/debug-info/self-in-generic-default-method.rs b/src/test/debug-info/self-in-generic-default-method.rs
index 47f58930760..3daf7afd4b1 100644
--- a/src/test/debug-info/self-in-generic-default-method.rs
+++ b/src/test/debug-info/self-in-generic-default-method.rs
@@ -119,7 +119,7 @@ trait Trait {
     }
 }
 
-impl Trait for Struct;
+impl Trait for Struct {}
 
 fn main() {
     let stack = Struct { x: 987 };
diff --git a/src/test/debug-info/trait-generic-static-default-method.rs b/src/test/debug-info/trait-generic-static-default-method.rs
index 1f6e6992e27..05258d53586 100644
--- a/src/test/debug-info/trait-generic-static-default-method.rs
+++ b/src/test/debug-info/trait-generic-static-default-method.rs
@@ -40,7 +40,7 @@ trait Trait {
     }
 }
 
-impl Trait for Struct;
+impl Trait for Struct {}
 
 fn main() {
 
diff --git a/src/test/debug-info/var-captured-in-managed-closure.rs b/src/test/debug-info/var-captured-in-managed-closure.rs
deleted file mode 100644
index b20f40378d3..00000000000
--- a/src/test/debug-info/var-captured-in-managed-closure.rs
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// compile-flags:-Z extra-debug-info
-// debugger:rbreak zzz
-// debugger:run
-// debugger:finish
-
-// debugger:print constant
-// check:$1 = 1
-// debugger:print a_struct
-// check:$2 = {a = -2, b = 3.5, c = 4}
-// debugger:print *owned
-// check:$3 = 5
-// debugger:print managed->val
-// check:$4 = 6
-
-#[allow(unused_variable)];
-
-struct Struct {
-    a: int,
-    b: float,
-    c: uint
-}
-
-fn main() {
-    let constant = 1;
-
-    let a_struct = Struct {
-        a: -2,
-        b: 3.5,
-        c: 4
-    };
-
-    let owned = ~5;
-    let managed = @6;
-
-    let closure: @fn() = || {
-        zzz();
-        do_something(&constant, &a_struct.a, owned, managed);
-    };
-
-    closure();
-}
-
-fn do_something(_: &int, _:&int, _:&int, _:&int) {
-}
-
-fn zzz() {()}
diff --git a/src/test/pretty/block-arg-disambig.rs b/src/test/pretty/block-arg-disambig.rs
deleted file mode 100644
index c0f173a1a0d..00000000000
--- a/src/test/pretty/block-arg-disambig.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn blk1(_b: &fn()) -> @fn() { return || { }; }
-fn test1() { (do blk1 { info!("hi"); })(); }
diff --git a/src/test/pretty/do1.rs b/src/test/pretty/do1.rs
index 6f9aa28f11a..751aedb39a3 100644
--- a/src/test/pretty/do1.rs
+++ b/src/test/pretty/do1.rs
@@ -10,6 +10,6 @@
 
 // pp-exact
 
-fn f(f: @fn(int)) { f(10) }
+fn f(f: &fn(int)) { f(10) }
 
 fn main() { do f |i| { assert!(i == 10) } }
diff --git a/src/test/pretty/empty-impl.pp b/src/test/pretty/empty-impl.pp
index af401bd25ca..685cdcdaead 100644
--- a/src/test/pretty/empty-impl.pp
+++ b/src/test/pretty/empty-impl.pp
@@ -1,5 +1,5 @@
 trait X { }
-impl X for uint;
+impl X for uint { }
 
 trait Y { }
-impl Y for uint;
+impl Y for uint { }
diff --git a/src/test/pretty/empty-impl.rs b/src/test/pretty/empty-impl.rs
index af401bd25ca..685cdcdaead 100644
--- a/src/test/pretty/empty-impl.rs
+++ b/src/test/pretty/empty-impl.rs
@@ -1,5 +1,5 @@
 trait X { }
-impl X for uint;
+impl X for uint { }
 
 trait Y { }
-impl Y for uint;
+impl Y for uint { }
diff --git a/src/test/pretty/fn-types.rs b/src/test/pretty/fn-types.rs
index 0545e9ed166..b000c9f9137 100644
--- a/src/test/pretty/fn-types.rs
+++ b/src/test/pretty/fn-types.rs
@@ -12,6 +12,5 @@
 
 fn from_foreign_fn(_x: extern "Rust" fn()) { }
 fn from_stack_closure(_x: &fn()) { }
-fn from_box_closure(_x: @fn()) { }
 fn from_unique_closure(_x: ~fn()) { }
 fn main() { }
diff --git a/src/test/pretty/path-type-bounds.rs b/src/test/pretty/path-type-bounds.rs
index a62fbdeeb18..4a402132254 100644
--- a/src/test/pretty/path-type-bounds.rs
+++ b/src/test/pretty/path-type-bounds.rs
@@ -1,7 +1,7 @@
 // pp-exact
 
 trait Tr { }
-impl Tr for int;
+impl Tr for int { }
 
 fn foo(x: ~Tr: Freeze) -> ~Tr: Freeze { x }
 
diff --git a/src/test/run-fail/unwind-lambda.rs b/src/test/run-fail/unwind-lambda.rs
index 74d6ab00802..65d9fce5ff5 100644
--- a/src/test/run-fail/unwind-lambda.rs
+++ b/src/test/run-fail/unwind-lambda.rs
@@ -14,7 +14,7 @@ fn main() {
     let cheese = ~"roquefort";
     let carrots = @~"crunchy";
 
-    let result: @fn(@~str, &fn(~str)) = (|tasties, macerate| {
+    let result: &'static fn(@~str, &fn(~str)) = (|tasties, macerate| {
         macerate((*tasties).clone());
     });
     result(carrots, |food| {
diff --git a/src/test/run-pass/alignment-gep-tup-like-1.rs b/src/test/run-pass/alignment-gep-tup-like-1.rs
index a821e4647c1..4352c139b62 100644
--- a/src/test/run-pass/alignment-gep-tup-like-1.rs
+++ b/src/test/run-pass/alignment-gep-tup-like-1.rs
@@ -12,13 +12,30 @@ struct pair<A,B> {
     a: A, b: B
 }
 
-fn f<A:Clone + 'static>(a: A, b: u16) -> @fn() -> (A, u16) {
-    let result: @fn() -> (A, u16) = || (a.clone(), b);
-    result
+trait Invokable<A> {
+    fn f(&self) -> (A, u16);
+}
+
+struct Invoker<A> {
+    a: A,
+    b: u16,
+}
+
+impl<A:Clone> Invokable<A> for Invoker<A> {
+    fn f(&self) -> (A, u16) {
+        (self.a.clone(), self.b)
+    }
+}
+
+fn f<A:Clone + 'static>(a: A, b: u16) -> @Invokable<A> {
+    @Invoker {
+        a: a,
+        b: b,
+    } as @Invokable<A>
 }
 
 pub fn main() {
-    let (a, b) = f(22_u64, 44u16)();
+    let (a, b) = f(22_u64, 44u16).f();
     info!("a=%? b=%?", a, b);
     assert_eq!(a, 22u64);
     assert_eq!(b, 44u16);
diff --git a/src/test/run-pass/alignment-gep-tup-like-2.rs b/src/test/run-pass/alignment-gep-tup-like-2.rs
index e924c31bad6..9bf95968a9a 100644
--- a/src/test/run-pass/alignment-gep-tup-like-2.rs
+++ b/src/test/run-pass/alignment-gep-tup-like-2.rs
@@ -23,13 +23,30 @@ fn make_cycle<A:'static>(a: A) {
     g.rec = Some(g);
 }
 
+struct Invoker<A,B> {
+    a: A,
+    b: B,
+}
+
+trait Invokable<A,B> {
+    fn f(&self) -> (A, B);
+}
+
+impl<A:Clone,B:Clone> Invokable<A,B> for Invoker<A,B> {
+    fn f(&self) -> (A, B) {
+        (self.a.clone(), self.b.clone())
+    }
+}
+
 fn f<A:Send + Clone + 'static,
      B:Send + Clone + 'static>(
      a: A,
      b: B)
-     -> @fn() -> (A, B) {
-    let result: @fn() -> (A, B) = || (a.clone(), b.clone());
-    result
+     -> @Invokable<A,B> {
+    @Invoker {
+        a: a,
+        b: b,
+    } as @Invokable<A,B>
 }
 
 pub fn main() {
@@ -37,7 +54,7 @@ pub fn main() {
     let y = 44_u64;
     let z = f(~x, y);
     make_cycle(z);
-    let (a, b) = z();
+    let (a, b) = z.f();
     info!("a=%u b=%u", *a as uint, b as uint);
     assert_eq!(*a, x);
     assert_eq!(b, y);
diff --git a/src/test/run-pass/attr-no-drop-flag-size.rs b/src/test/run-pass/attr-no-drop-flag-size.rs
index e5470a1cff4..bbc6501bc77 100644
--- a/src/test/run-pass/attr-no-drop-flag-size.rs
+++ b/src/test/run-pass/attr-no-drop-flag-size.rs
@@ -20,6 +20,6 @@ impl<T> Drop for Test<T> {
     fn drop(&mut self) { }
 }
 
-fn main() {
+pub fn main() {
     assert_eq!(size_of::<int>(), size_of::<Test<int>>());
 }
diff --git a/src/test/run-pass/attr-start.rs b/src/test/run-pass/attr-start.rs
index ba54e92ef99..ca75af90129 100644
--- a/src/test/run-pass/attr-start.rs
+++ b/src/test/run-pass/attr-start.rs
@@ -11,6 +11,6 @@
 //xfail-fast
 
 #[start]
-fn start(_argc: int, _argv: **u8, _crate_map: *u8) -> int {
+fn start(_argc: int, _argv: **u8) -> int {
     return 0;
 }
diff --git a/src/test/run-pass/block-arg-call-as.rs b/src/test/run-pass/block-arg-call-as.rs
index d68b0be632e..6a59278982a 100644
--- a/src/test/run-pass/block-arg-call-as.rs
+++ b/src/test/run-pass/block-arg-call-as.rs
@@ -14,10 +14,6 @@ fn asSendfn( f : ~fn()->uint ) -> uint {
    return f();
 }
 
-fn asLambda( f : @fn()->uint ) -> uint {
-   return f();
-}
-
 fn asBlock( f : &fn()->uint ) -> uint {
    return f();
 }
@@ -25,8 +21,6 @@ fn asBlock( f : &fn()->uint ) -> uint {
 pub fn main() {
    let x = asSendfn(|| 22u);
    assert_eq!(x, 22u);
-   let x = asLambda(|| 22u);
-   assert_eq!(x, 22u);
    let x = asBlock(|| 22u);
    assert_eq!(x, 22u);
 }
diff --git a/src/test/run-pass/block-arg-used-as-lambda.rs b/src/test/run-pass/block-arg-used-as-lambda.rs
deleted file mode 100644
index 34fa7e36d97..00000000000
--- a/src/test/run-pass/block-arg-used-as-lambda.rs
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn to_lambda(f: @fn(uint) -> uint) -> @fn(uint) -> uint {
-    return f;
-}
-
-pub fn main() {
-    let x: @fn(uint) -> uint = to_lambda(|x| x * 2u );
-    let y = to_lambda(x);
-
-    let x_r = x(22u);
-    let y_r = y(x_r);
-
-    assert_eq!(x_r, 44u);
-    assert_eq!(y_r, 88u);
-}
diff --git a/src/test/run-pass/borrowck-macro-interaction-issue-6304.rs b/src/test/run-pass/borrowck-macro-interaction-issue-6304.rs
index 65d377173c8..4e79013de83 100644
--- a/src/test/run-pass/borrowck-macro-interaction-issue-6304.rs
+++ b/src/test/run-pass/borrowck-macro-interaction-issue-6304.rs
@@ -26,4 +26,4 @@ impl Foo {
   fn check_id(&mut self, s: int) { fail!() }
 }
  
-fn main() { }
+pub fn main() { }
diff --git a/src/test/run-pass/borrowck-move-by-capture-ok.rs b/src/test/run-pass/borrowck-move-by-capture-ok.rs
index 095e2ba6fea..f6328c8c658 100644
--- a/src/test/run-pass/borrowck-move-by-capture-ok.rs
+++ b/src/test/run-pass/borrowck-move-by-capture-ok.rs
@@ -1,5 +1,5 @@
 pub fn main() {
     let bar = ~3;
-    let h: @fn() -> int = || *bar;
+    let h: ~fn() -> int = || *bar;
     assert_eq!(h(), 3);
 }
diff --git a/src/test/run-pass/borrowck-pat-enum.rs b/src/test/run-pass/borrowck-pat-enum.rs
index f320de39c8c..79cad643dfd 100644
--- a/src/test/run-pass/borrowck-pat-enum.rs
+++ b/src/test/run-pass/borrowck-pat-enum.rs
@@ -43,5 +43,5 @@ fn match_mut_reg(v: &mut Option<int>) {
     }
 }
 
-fn main() {
+pub fn main() {
 }
diff --git a/src/test/run-pass/borrowck-static-item-in-fn.rs b/src/test/run-pass/borrowck-static-item-in-fn.rs
index a3a7a1b8969..366752f46b0 100644
--- a/src/test/run-pass/borrowck-static-item-in-fn.rs
+++ b/src/test/run-pass/borrowck-static-item-in-fn.rs
@@ -10,6 +10,6 @@
 
 // Regression test for issue #7740
 
-fn main() {
+pub fn main() {
     static A: &'static char = &'A';
 }
diff --git a/src/test/run-pass/borrowck-unary-move-2.rs b/src/test/run-pass/borrowck-unary-move-2.rs
index 2ab0f4262fb..87d42943fac 100644
--- a/src/test/run-pass/borrowck-unary-move-2.rs
+++ b/src/test/run-pass/borrowck-unary-move-2.rs
@@ -26,7 +26,7 @@ fn noncopyable() -> noncopyable {
 
 struct wrapper(noncopyable);
 
-fn main() {
+pub fn main() {
     let x1 = wrapper(noncopyable());
     let _x2 = *x1;
 }
diff --git a/src/test/run-pass/borrowck-uniq-via-ref.rs b/src/test/run-pass/borrowck-uniq-via-ref.rs
index 44f3a8f518a..d50b4f15f4e 100644
--- a/src/test/run-pass/borrowck-uniq-via-ref.rs
+++ b/src/test/run-pass/borrowck-uniq-via-ref.rs
@@ -50,5 +50,5 @@ fn box_imm_recs(v: &Outer) {
     borrow(v.f.g.h); // OK
 }
 
-fn main() {
+pub fn main() {
 }
diff --git a/src/test/run-pass/borrowck-wg-autoderef-and-autoborrowvec-combined-issue-6272.rs b/src/test/run-pass/borrowck-wg-autoderef-and-autoborrowvec-combined-issue-6272.rs
index 5da7a6f2b56..4ee0d42ae13 100644
--- a/src/test/run-pass/borrowck-wg-autoderef-and-autoborrowvec-combined-issue-6272.rs
+++ b/src/test/run-pass/borrowck-wg-autoderef-and-autoborrowvec-combined-issue-6272.rs
@@ -27,7 +27,7 @@
 // run-fail/borrowck-wg-autoderef-and-autoborrowvec-combined-fail-issue-6272.rs
 
 
-fn main() {
+pub fn main() {
     let a = @mut 3i;
     let b = @mut [a];
     let c = @mut [3];
diff --git a/src/test/run-pass/bug-7183-generics.rs b/src/test/run-pass/bug-7183-generics.rs
index 52264da2e80..45f4302a5af 100644
--- a/src/test/run-pass/bug-7183-generics.rs
+++ b/src/test/run-pass/bug-7183-generics.rs
@@ -33,7 +33,7 @@ impl<T: Speak> Speak for Option<T> {
 }
 
 
-fn main() {
+pub fn main() {
     assert_eq!(3.hi(), ~"hello: 3");
     assert_eq!(Some(Some(3)).hi(), ~"something!something!hello: 3");
     assert_eq!(None::<int>.hi(), ~"hello - none");
diff --git a/src/test/run-pass/builtin-superkinds-capabilities-transitive.rs b/src/test/run-pass/builtin-superkinds-capabilities-transitive.rs
index 74a218ac469..ec5af692976 100644
--- a/src/test/run-pass/builtin-superkinds-capabilities-transitive.rs
+++ b/src/test/run-pass/builtin-superkinds-capabilities-transitive.rs
@@ -26,7 +26,7 @@ fn foo<T: Foo>(val: T, chan: comm::Chan<T>) {
     chan.send(val);
 }
 
-fn main() {
+pub fn main() {
     let (p,c) = comm::stream();
     foo(31337, c);
     assert!(p.recv() == 31337);
diff --git a/src/test/run-pass/builtin-superkinds-capabilities.rs b/src/test/run-pass/builtin-superkinds-capabilities.rs
index c2d2129b1c1..148fb5a340f 100644
--- a/src/test/run-pass/builtin-superkinds-capabilities.rs
+++ b/src/test/run-pass/builtin-superkinds-capabilities.rs
@@ -22,7 +22,7 @@ fn foo<T: Foo>(val: T, chan: comm::Chan<T>) {
     chan.send(val);
 }
 
-fn main() {
+pub fn main() {
     let (p,c) = comm::stream();
     foo(31337, c);
     assert!(p.recv() == 31337);
diff --git a/src/test/run-pass/builtin-superkinds-phantom-typaram.rs b/src/test/run-pass/builtin-superkinds-phantom-typaram.rs
index b6e58bfbf3d..740b8c2016a 100644
--- a/src/test/run-pass/builtin-superkinds-phantom-typaram.rs
+++ b/src/test/run-pass/builtin-superkinds-phantom-typaram.rs
@@ -18,4 +18,4 @@ struct X<T>(());
 
 impl <T> Foo for X<T> { }
 
-fn main() { }
+pub fn main() { }
diff --git a/src/test/run-pass/builtin-superkinds-self-type.rs b/src/test/run-pass/builtin-superkinds-self-type.rs
index 2285c471c91..a8f5f27b4d9 100644
--- a/src/test/run-pass/builtin-superkinds-self-type.rs
+++ b/src/test/run-pass/builtin-superkinds-self-type.rs
@@ -21,7 +21,7 @@ trait Foo : Send {
 
 impl <T: Send> Foo for T { }
 
-fn main() {
+pub fn main() {
     let (p,c) = comm::stream();
     1193182.foo(c);
     assert!(p.recv() == 1193182);
diff --git a/src/test/run-pass/builtin-superkinds-simple.rs b/src/test/run-pass/builtin-superkinds-simple.rs
index 61a22d97498..9643e2986d2 100644
--- a/src/test/run-pass/builtin-superkinds-simple.rs
+++ b/src/test/run-pass/builtin-superkinds-simple.rs
@@ -14,4 +14,4 @@ trait Foo : Send { }
 
 impl Foo for int { }
 
-fn main() { }
+pub fn main() { }
diff --git a/src/test/run-pass/builtin-superkinds-typaram.rs b/src/test/run-pass/builtin-superkinds-typaram.rs
index 7dfd1e0629f..d96679c69fd 100644
--- a/src/test/run-pass/builtin-superkinds-typaram.rs
+++ b/src/test/run-pass/builtin-superkinds-typaram.rs
@@ -15,4 +15,4 @@ trait Foo : Send { }
 
 impl <T: Send> Foo for T { }
 
-fn main() { }
+pub fn main() { }
diff --git a/src/test/run-pass/call-closure-from-overloaded-op.rs b/src/test/run-pass/call-closure-from-overloaded-op.rs
index cc8d8e96195..16728dffd19 100644
--- a/src/test/run-pass/call-closure-from-overloaded-op.rs
+++ b/src/test/run-pass/call-closure-from-overloaded-op.rs
@@ -11,7 +11,7 @@
 fn foo() -> int { 22 }
 
 pub fn main() {
-    let mut x: ~[@fn() -> int] = ~[];
+    let mut x: ~[extern "Rust" fn() -> int] = ~[];
     x.push(foo);
     assert_eq!((x[0])(), 22);
 }
diff --git a/src/test/run-pass/cap-clause-move.rs b/src/test/run-pass/cap-clause-move.rs
index aadd6a72494..64be8dab6e7 100644
--- a/src/test/run-pass/cap-clause-move.rs
+++ b/src/test/run-pass/cap-clause-move.rs
@@ -11,16 +11,6 @@
 use std::ptr;
 
 pub fn main() {
-    let x = ~1;
-    let y = ptr::to_unsafe_ptr(&(*x)) as uint;
-    let lam_move: @fn() -> uint = || ptr::to_unsafe_ptr(&(*x)) as uint;
-    assert_eq!(lam_move(), y);
-
-    let x = ~2;
-    let y = ptr::to_unsafe_ptr(&(*x)) as uint;
-    let lam_move: @fn() -> uint = || ptr::to_unsafe_ptr(&(*x)) as uint;
-    assert_eq!(lam_move(), y);
-
     let x = ~3;
     let y = ptr::to_unsafe_ptr(&(*x)) as uint;
     let snd_move: ~fn() -> uint = || ptr::to_unsafe_ptr(&(*x)) as uint;
diff --git a/src/test/run-pass/cast-mutable-trait.rs b/src/test/run-pass/cast-mutable-trait.rs
index 633188b9a62..ce026d3e2e0 100644
--- a/src/test/run-pass/cast-mutable-trait.rs
+++ b/src/test/run-pass/cast-mutable-trait.rs
@@ -25,10 +25,10 @@ fn bar(t: @mut T) {
     t.foo();
 }
 
-fn main() {
+pub fn main() {
     let s = @mut S { unused: 0 };
     let s2 = s as @mut T;
     s2.foo();
     bar(s2);
     bar(s as @mut T);
-}
\ No newline at end of file
+}
diff --git a/src/test/run-pass/close-over-big-then-small-data.rs b/src/test/run-pass/close-over-big-then-small-data.rs
index 01c6442fa00..8b7967ac150 100644
--- a/src/test/run-pass/close-over-big-then-small-data.rs
+++ b/src/test/run-pass/close-over-big-then-small-data.rs
@@ -16,13 +16,30 @@ struct Pair<A,B> {
     a: A, b: B
 }
 
-fn f<A:Clone + 'static>(a: A, b: u16) -> @fn() -> (A, u16) {
-    let result: @fn() -> (A, u16) = || (a.clone(), b);
-    result
+struct Invoker<A> {
+    a: A,
+    b: u16,
+}
+
+trait Invokable<A> {
+    fn f(&self) -> (A, u16);
+}
+
+impl<A:Clone> Invokable<A> for Invoker<A> {
+    fn f(&self) -> (A, u16) {
+        (self.a.clone(), self.b)
+    }
+}
+
+fn f<A:Clone + 'static>(a: A, b: u16) -> @Invokable<A> {
+    @Invoker {
+        a: a,
+        b: b,
+    } as @Invokable<A>
 }
 
 pub fn main() {
-    let (a, b) = f(22_u64, 44u16)();
+    let (a, b) = f(22_u64, 44u16).f();
     info!("a=%? b=%?", a, b);
     assert_eq!(a, 22u64);
     assert_eq!(b, 44u16);
diff --git a/src/test/run-pass/closure-bounds-can-capture-chan.rs b/src/test/run-pass/closure-bounds-can-capture-chan.rs
index 95b0c9d79b7..d35d6d9f07e 100644
--- a/src/test/run-pass/closure-bounds-can-capture-chan.rs
+++ b/src/test/run-pass/closure-bounds-can-capture-chan.rs
@@ -14,7 +14,7 @@ fn foo(blk: ~fn:Send()) {
     blk();
 }
 
-fn main() {
+pub fn main() {
     let (p,c) = comm::stream();
     do foo {
         c.send(());
diff --git a/src/test/run-pass/const-binops.rs b/src/test/run-pass/const-binops.rs
index cd87ca3ab53..b3cb8580f7d 100644
--- a/src/test/run-pass/const-binops.rs
+++ b/src/test/run-pass/const-binops.rs
@@ -56,7 +56,7 @@ static am: bool = 2 > 1;
 static an: bool = 2 > -2;
 static ao: bool = 1.0 > -2.0;
 
-fn main() {
+pub fn main() {
     assert_eq!(a, -1);
     assert_eq!(a2, 6);
     assert_approx_eq!(b, 5.7);
diff --git a/src/test/run-pass/const-struct-offsets.rs b/src/test/run-pass/const-struct-offsets.rs
index cd39c8df872..2bb0516cad4 100644
--- a/src/test/run-pass/const-struct-offsets.rs
+++ b/src/test/run-pass/const-struct-offsets.rs
@@ -10,4 +10,4 @@ struct Bar {
 
 static bar: Bar = Bar { i: 0, v: IntVal(0) };
 
-fn main() {}
+pub fn main() {}
diff --git a/src/test/run-pass/core-rt-smoke.rs b/src/test/run-pass/core-rt-smoke.rs
index 10bd013b618..6e3d9629da0 100644
--- a/src/test/run-pass/core-rt-smoke.rs
+++ b/src/test/run-pass/core-rt-smoke.rs
@@ -13,8 +13,8 @@
 // A simple test of starting the runtime manually
 
 #[start]
-fn start(argc: int, argv: **u8, crate_map: *u8) -> int {
-    do std::rt::start(argc, argv, crate_map) {
+fn start(argc: int, argv: **u8) -> int {
+    do std::rt::start(argc, argv) {
         info!("creating my own runtime is joy");
     }
 }
diff --git a/src/test/run-pass/cycle-collection2.rs b/src/test/run-pass/cycle-collection2.rs
index cd148417f4c..46c0c52e0c7 100644
--- a/src/test/run-pass/cycle-collection2.rs
+++ b/src/test/run-pass/cycle-collection2.rs
@@ -8,13 +8,33 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct foo { z: @fn() }
+struct foo {
+    z: Option<@Invokable>,
+}
+
+struct Thing {
+    w: @mut foo,
+}
+
+trait Invokable {
+    fn f(&self);
+}
+
+impl Invokable for Thing {
+    fn f(&self) {
+        nop_foo(self.w);
+    }
+}
 
 fn nop() { }
 fn nop_foo(_x : @mut foo) { }
 
 pub fn main() {
-    let w = @mut foo{ z: || nop() };
-    let x: @fn() = || nop_foo(w);
-    w.z = x;
+    let w = @mut foo {
+        z: None,
+    };
+    let x = @Thing {
+        w: w,
+    } as @Invokable;
+    w.z = Some(x);
 }
diff --git a/src/test/run-pass/cycle-collection4.rs b/src/test/run-pass/cycle-collection4.rs
deleted file mode 100644
index 8b613093944..00000000000
--- a/src/test/run-pass/cycle-collection4.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-struct foo { z : @fn() }
-
-fn nop() { }
-fn nop_foo(_y: ~[int], _x : @mut foo) { }
-
-pub fn main() {
-    let w = @mut foo{ z: || nop() };
-    let x : @fn() = || nop_foo(~[], w);
-    w.z = x;
-}
diff --git a/src/test/run-pass/cycle-collection5.rs b/src/test/run-pass/cycle-collection5.rs
deleted file mode 100644
index f724a86555c..00000000000
--- a/src/test/run-pass/cycle-collection5.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-struct foo { z: @fn() }
-
-fn nop() { }
-fn nop_foo(_y: @int, _x: @mut foo) { }
-
-fn o() -> @int { @10 }
-
-pub fn main() {
-    let w = @mut foo { z: || nop() };
-    let x : @fn() = || nop_foo(o(), w);
-    w.z = x;
-}
diff --git a/src/test/run-pass/default-method-parsing.rs b/src/test/run-pass/default-method-parsing.rs
index ec607102566..639ea59585e 100644
--- a/src/test/run-pass/default-method-parsing.rs
+++ b/src/test/run-pass/default-method-parsing.rs
@@ -12,4 +12,4 @@ trait Foo {
     fn m(&self, _:int) { }
 }
 
-fn main() { }
+pub fn main() { }
diff --git a/src/test/run-pass/default-method-supertrait-vtable.rs b/src/test/run-pass/default-method-supertrait-vtable.rs
index 90a2b914021..2bcf264bb1f 100644
--- a/src/test/run-pass/default-method-supertrait-vtable.rs
+++ b/src/test/run-pass/default-method-supertrait-vtable.rs
@@ -29,8 +29,8 @@ impl Y for int {
     fn y(self) -> int { self }
 }
 
-impl Z for int;
+impl Z for int {}
 
-fn main() {
+pub fn main() {
     assert_eq!(12.x(), 12);
 }
diff --git a/src/test/run-pass/deriving-clone-generic-enum.rs b/src/test/run-pass/deriving-clone-generic-enum.rs
index 78abbf504f3..61696c2eeac 100644
--- a/src/test/run-pass/deriving-clone-generic-enum.rs
+++ b/src/test/run-pass/deriving-clone-generic-enum.rs
@@ -15,7 +15,7 @@ enum E<T,U> {
     C
 }
 
-fn main() {
+pub fn main() {
     let _ = A::<int, int>(1i).clone();
     let _ = B(1i, 1.234).deep_clone();
 }
diff --git a/src/test/run-pass/deriving-clone-generic-tuple-struct.rs b/src/test/run-pass/deriving-clone-generic-tuple-struct.rs
index c082a11eab8..02043b524a9 100644
--- a/src/test/run-pass/deriving-clone-generic-tuple-struct.rs
+++ b/src/test/run-pass/deriving-clone-generic-tuple-struct.rs
@@ -11,6 +11,6 @@
 #[deriving(Clone, DeepClone)]
 struct S<T>(T, ());
 
-fn main() {
+pub fn main() {
     let _ = S(1i, ()).clone().deep_clone();
 }
diff --git a/src/test/run-pass/deriving-clone-struct.rs b/src/test/run-pass/deriving-clone-struct.rs
index d540b047af7..412cc3b3a85 100644
--- a/src/test/run-pass/deriving-clone-struct.rs
+++ b/src/test/run-pass/deriving-clone-struct.rs
@@ -31,4 +31,4 @@ struct S {
     _nil: ()
 }
 
-fn main() {}
+pub fn main() {}
diff --git a/src/test/run-pass/deriving-cmp-shortcircuit.rs b/src/test/run-pass/deriving-cmp-shortcircuit.rs
index 7f5c78cf602..431c856ee88 100644
--- a/src/test/run-pass/deriving-cmp-shortcircuit.rs
+++ b/src/test/run-pass/deriving-cmp-shortcircuit.rs
@@ -35,7 +35,7 @@ struct ShortCircuit {
     y: FailCmp
 }
 
-fn main() {
+pub fn main() {
     let a = ShortCircuit { x: 1, y: FailCmp };
     let b = ShortCircuit { x: 2, y: FailCmp };
 
diff --git a/src/test/run-pass/deriving-self-lifetime.rs b/src/test/run-pass/deriving-self-lifetime.rs
index e65e189ea93..2b0245fa5d2 100644
--- a/src/test/run-pass/deriving-self-lifetime.rs
+++ b/src/test/run-pass/deriving-self-lifetime.rs
@@ -13,7 +13,7 @@ struct A<'self> {
     x: &'self int
 }
 
-fn main() {
+pub fn main() {
     let a = A { x: &1 };
     let b = A { x: &2 };
 
diff --git a/src/test/run-pass/deriving-to-str.rs b/src/test/run-pass/deriving-to-str.rs
index 1fc1d6815f5..a6068b52740 100644
--- a/src/test/run-pass/deriving-to-str.rs
+++ b/src/test/run-pass/deriving-to-str.rs
@@ -34,7 +34,7 @@ impl ToStr for Custom {
     fn to_str(&self) -> ~str { ~"yay" }
 }
 
-fn main() {
+pub fn main() {
     assert_eq!(B1.to_str(), ~"B1");
     assert_eq!(B2.to_str(), ~"B2");
     assert_eq!(C1(3).to_str(), ~"C1(3)");
diff --git a/src/test/run-pass/deriving-zero.rs b/src/test/run-pass/deriving-zero.rs
index fb4ffb2c3c1..59acc353fed 100644
--- a/src/test/run-pass/deriving-zero.rs
+++ b/src/test/run-pass/deriving-zero.rs
@@ -33,7 +33,7 @@ struct Lots {
     j: (),
 }
 
-fn main() {
+pub fn main() {
     let lots: Lots = Zero::zero();
     assert!(lots.is_zero());
 }
diff --git a/src/test/run-pass/do-no-args.rs b/src/test/run-pass/do-no-args.rs
index 6aef1f5f9e5..1f725ffb357 100644
--- a/src/test/run-pass/do-no-args.rs
+++ b/src/test/run-pass/do-no-args.rs
@@ -10,9 +10,9 @@
 
 // Testing that we can drop the || in do exprs
 
-fn f(_f: @fn() -> bool) -> bool { true }
+fn f(_f: &fn() -> bool) -> bool { true }
 
-fn d(_f: @fn()) { }
+fn d(_f: &fn()) { }
 
 pub fn main() {
     do d { }
diff --git a/src/test/run-pass/do1.rs b/src/test/run-pass/do1.rs
index 735621a19fe..0444b269cb3 100644
--- a/src/test/run-pass/do1.rs
+++ b/src/test/run-pass/do1.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn f(f: @fn(int)) { f(10) }
+fn f(f: &fn(int)) { f(10) }
 
 pub fn main() {
     do f() |i| { assert!(i == 10) }
diff --git a/src/test/run-pass/do2.rs b/src/test/run-pass/do2.rs
index 684a2c108eb..9feededc980 100644
--- a/src/test/run-pass/do2.rs
+++ b/src/test/run-pass/do2.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn f(f: @fn(int) -> int) -> int { f(10) }
+fn f(f: &fn(int) -> int) -> int { f(10) }
 
 pub fn main() {
     assert_eq!(do f() |i| { i }, 10);
diff --git a/src/test/run-pass/do3.rs b/src/test/run-pass/do3.rs
index b0d49fd2bdd..eeb983b4557 100644
--- a/src/test/run-pass/do3.rs
+++ b/src/test/run-pass/do3.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn f(f: @fn(int) -> int) -> int { f(10) }
+fn f(f: &fn(int) -> int) -> int { f(10) }
 
 pub fn main() {
     assert_eq!(do f |i| { i }, 10);
diff --git a/src/test/run-pass/enum-discr.rs b/src/test/run-pass/enum-discr.rs
index 5a14f0050e8..28f38829167 100644
--- a/src/test/run-pass/enum-discr.rs
+++ b/src/test/run-pass/enum-discr.rs
@@ -12,7 +12,7 @@ enum Hero {
     Spiderman = -4
 }
 
-fn main() {
+pub fn main() {
     let pet: Animal = Snake;
     let hero: Hero = Superman;
     assert!(pet as uint == 3);
diff --git a/src/test/run-pass/enum-vec-initializer.rs b/src/test/run-pass/enum-vec-initializer.rs
index d240e849ad0..a55b5eebefb 100644
--- a/src/test/run-pass/enum-vec-initializer.rs
+++ b/src/test/run-pass/enum-vec-initializer.rs
@@ -15,7 +15,7 @@ enum Flopsy {
 static BAR:uint = Bunny as uint;
 static BAR2:uint = BAR;
 
-fn main() {
+pub fn main() {
     let _v = [0, .. Bunny as uint];
     let _v = [0, .. BAR];
     let _v = [0, .. BAR2];
diff --git a/src/test/run-pass/expr-block-fn.rs b/src/test/run-pass/expr-block-fn.rs
index dbb1ac1f649..63e5c7688d3 100644
--- a/src/test/run-pass/expr-block-fn.rs
+++ b/src/test/run-pass/expr-block-fn.rs
@@ -11,7 +11,7 @@
 
 
 fn test_fn() {
-    type t = @fn() -> int;
+    type t = &'static fn() -> int;
     fn ten() -> int { return 10; }
     let rs: t = { ten };
     assert!((rs() == 10));
diff --git a/src/test/run-pass/expr-block-generic-box1.rs b/src/test/run-pass/expr-block-generic-box1.rs
index 2c902181810..12b387b7eae 100644
--- a/src/test/run-pass/expr-block-generic-box1.rs
+++ b/src/test/run-pass/expr-block-generic-box1.rs
@@ -12,7 +12,7 @@
 
 
 // -*- rust -*-
-type compare<T> = @fn(@T, @T) -> bool;
+type compare<T> = &'static fn(@T, @T) -> bool;
 
 fn test_generic<T>(expected: @T, eq: compare<T>) {
     let actual: @T = { expected };
diff --git a/src/test/run-pass/expr-block-generic-box2.rs b/src/test/run-pass/expr-block-generic-box2.rs
index 7d849bbff01..cfa59d68635 100644
--- a/src/test/run-pass/expr-block-generic-box2.rs
+++ b/src/test/run-pass/expr-block-generic-box2.rs
@@ -11,7 +11,7 @@
 
 // xfail-fast
 
-type compare<T> = @fn(T, T) -> bool;
+type compare<'self, T> = &'self fn(T, T) -> bool;
 
 fn test_generic<T:Clone>(expected: T, eq: compare<T>) {
     let actual: T = { expected.clone() };
diff --git a/src/test/run-pass/expr-block-generic-unique1.rs b/src/test/run-pass/expr-block-generic-unique1.rs
index 0249820410c..3f9c101761f 100644
--- a/src/test/run-pass/expr-block-generic-unique1.rs
+++ b/src/test/run-pass/expr-block-generic-unique1.rs
@@ -11,7 +11,7 @@
 
 
 // -*- rust -*-
-type compare<T> = @fn(~T, ~T) -> bool;
+type compare<'self, T> = &'self fn(~T, ~T) -> bool;
 
 fn test_generic<T:Clone>(expected: ~T, eq: compare<T>) {
     let actual: ~T = { expected.clone() };
diff --git a/src/test/run-pass/expr-block-generic-unique2.rs b/src/test/run-pass/expr-block-generic-unique2.rs
index 389a42ae7af..3484a4f7f5a 100644
--- a/src/test/run-pass/expr-block-generic-unique2.rs
+++ b/src/test/run-pass/expr-block-generic-unique2.rs
@@ -11,7 +11,7 @@
 // xfail-fast
 // -*- rust -*-
 
-type compare<T> = @fn(T, T) -> bool;
+type compare<'self, T> = &'self fn(T, T) -> bool;
 
 fn test_generic<T:Clone>(expected: T, eq: compare<T>) {
     let actual: T = { expected.clone() };
diff --git a/src/test/run-pass/expr-block-generic.rs b/src/test/run-pass/expr-block-generic.rs
index 7091fceb771..2f379602c6b 100644
--- a/src/test/run-pass/expr-block-generic.rs
+++ b/src/test/run-pass/expr-block-generic.rs
@@ -13,7 +13,7 @@
 // xfail-fast
 
 // Tests for standalone blocks as expressions with dynamic type sizes
-type compare<T> = @fn(T, T) -> bool;
+type compare<'self, T> = &'self fn(T, T) -> bool;
 
 fn test_generic<T:Clone>(expected: T, eq: compare<T>) {
     let actual: T = { expected.clone() };
diff --git a/src/test/run-pass/expr-if-generic-box1.rs b/src/test/run-pass/expr-if-generic-box1.rs
index def991adea8..8bf6e658408 100644
--- a/src/test/run-pass/expr-if-generic-box1.rs
+++ b/src/test/run-pass/expr-if-generic-box1.rs
@@ -12,7 +12,7 @@
 
 
 // -*- rust -*-
-type compare<T> = @fn(@T, @T) -> bool;
+type compare<T> = &'static fn(@T, @T) -> bool;
 
 fn test_generic<T>(expected: @T, not_expected: @T, eq: compare<T>) {
     let actual: @T = if true { expected } else { not_expected };
diff --git a/src/test/run-pass/expr-if-generic-box2.rs b/src/test/run-pass/expr-if-generic-box2.rs
index a2d28a2be04..2c4707a87d5 100644
--- a/src/test/run-pass/expr-if-generic-box2.rs
+++ b/src/test/run-pass/expr-if-generic-box2.rs
@@ -11,7 +11,7 @@
 // xfail-fast
 // -*- rust -*-
 
-type compare<T> = @fn(T, T) -> bool;
+type compare<T> = &'static fn(T, T) -> bool;
 
 fn test_generic<T:Clone>(expected: T, not_expected: T, eq: compare<T>) {
     let actual: T = if true { expected.clone() } else { not_expected };
diff --git a/src/test/run-pass/expr-if-generic.rs b/src/test/run-pass/expr-if-generic.rs
index f5b2a1a7986..1bbf3a537db 100644
--- a/src/test/run-pass/expr-if-generic.rs
+++ b/src/test/run-pass/expr-if-generic.rs
@@ -12,7 +12,7 @@
 // -*- rust -*-
 
 // Tests for if as expressions with dynamic type sizes
-type compare<T> = @fn(T, T) -> bool;
+type compare<T> = &'static fn(T, T) -> bool;
 
 fn test_generic<T:Clone>(expected: T, not_expected: T, eq: compare<T>) {
     let actual: T = if true { expected.clone() } else { not_expected };
diff --git a/src/test/run-pass/expr-match-generic-box1.rs b/src/test/run-pass/expr-match-generic-box1.rs
index 4ea2d0fba9b..064e3343620 100644
--- a/src/test/run-pass/expr-match-generic-box1.rs
+++ b/src/test/run-pass/expr-match-generic-box1.rs
@@ -12,7 +12,7 @@
 
 
 // -*- rust -*-
-type compare<T> = @fn(@T, @T) -> bool;
+type compare<T> = &'static fn(@T, @T) -> bool;
 
 fn test_generic<T>(expected: @T, eq: compare<T>) {
     let actual: @T = match true { true => { expected }, _ => fail!() };
diff --git a/src/test/run-pass/expr-match-generic-box2.rs b/src/test/run-pass/expr-match-generic-box2.rs
index a2ccf5c0fb9..bca06ebdbb5 100644
--- a/src/test/run-pass/expr-match-generic-box2.rs
+++ b/src/test/run-pass/expr-match-generic-box2.rs
@@ -11,7 +11,7 @@
 // xfail-fast
 // -*- rust -*-
 
-type compare<T> = @fn(T, T) -> bool;
+type compare<T> = &'static fn(T, T) -> bool;
 
 fn test_generic<T:Clone>(expected: T, eq: compare<T>) {
     let actual: T = match true { true => { expected.clone() }, _ => fail!("wat") };
diff --git a/src/test/run-pass/expr-match-generic-unique1.rs b/src/test/run-pass/expr-match-generic-unique1.rs
index 0f564e6a780..7371f8fd89b 100644
--- a/src/test/run-pass/expr-match-generic-unique1.rs
+++ b/src/test/run-pass/expr-match-generic-unique1.rs
@@ -11,7 +11,7 @@
 
 
 // -*- rust -*-
-type compare<T> = @fn(~T, ~T) -> bool;
+type compare<T> = &'static fn(~T, ~T) -> bool;
 
 fn test_generic<T:Clone>(expected: ~T, eq: compare<T>) {
     let actual: ~T = match true {
diff --git a/src/test/run-pass/expr-match-generic-unique2.rs b/src/test/run-pass/expr-match-generic-unique2.rs
index ae88d48bc44..d07d40e6757 100644
--- a/src/test/run-pass/expr-match-generic-unique2.rs
+++ b/src/test/run-pass/expr-match-generic-unique2.rs
@@ -11,7 +11,7 @@
 // xfail-fast
 // -*- rust -*-
 
-type compare<T> = @fn(T, T) -> bool;
+type compare<'self, T> = &'self fn(T, T) -> bool;
 
 fn test_generic<T:Clone>(expected: T, eq: compare<T>) {
     let actual: T = match true {
diff --git a/src/test/run-pass/expr-match-generic.rs b/src/test/run-pass/expr-match-generic.rs
index 59f1ff14f59..b43085d346f 100644
--- a/src/test/run-pass/expr-match-generic.rs
+++ b/src/test/run-pass/expr-match-generic.rs
@@ -11,7 +11,7 @@
 // xfail-fast
 // -*- rust -*-
 
-type compare<T> = @fn(T, T) -> bool;
+type compare<T> = extern "Rust" fn(T, T) -> bool;
 
 fn test_generic<T:Clone>(expected: T, eq: compare<T>) {
   let actual: T = match true { true => { expected.clone() }, _ => fail!("wat") };
diff --git a/src/test/run-pass/expr-repeat-vstore.rs b/src/test/run-pass/expr-repeat-vstore.rs
index 5c94f059b49..48bce39970f 100644
--- a/src/test/run-pass/expr-repeat-vstore.rs
+++ b/src/test/run-pass/expr-repeat-vstore.rs
@@ -1,6 +1,6 @@
 use std::io::println;
 
-fn main() {
+pub fn main() {
     let v: ~[int] = ~[ 1, ..5 ];
     println(v[0].to_str());
     println(v[1].to_str());
diff --git a/src/test/run-pass/extern-call-direct.rs b/src/test/run-pass/extern-call-direct.rs
index bc6ee63c0f4..925ec8e7ff7 100644
--- a/src/test/run-pass/extern-call-direct.rs
+++ b/src/test/run-pass/extern-call-direct.rs
@@ -12,7 +12,7 @@
 
 extern fn f(x: uint) -> uint { x * 2 }
 
-fn main() {
+pub fn main() {
     #[fixed_stack_segment];
 
     let x = f(22);
diff --git a/src/test/run-pass/extern-compare-with-return-type.rs b/src/test/run-pass/extern-compare-with-return-type.rs
index 5406fa283e7..53a5d3e9621 100644
--- a/src/test/run-pass/extern-compare-with-return-type.rs
+++ b/src/test/run-pass/extern-compare-with-return-type.rs
@@ -19,7 +19,7 @@ extern fn uintvoidret(_x: uint) {}
 
 extern fn uintuintuintuintret(x: uint, y: uint, z: uint) -> uint { x+y+z }
 
-fn main() {
+pub fn main() {
     assert_eq!(voidret1, voidret1);
     assert!(voidret1 != voidret2);
 
diff --git a/src/test/run-pass/extoption_env-not-defined.rs b/src/test/run-pass/extoption_env-not-defined.rs
index cbf4c36c5df..891133c78d4 100644
--- a/src/test/run-pass/extoption_env-not-defined.rs
+++ b/src/test/run-pass/extoption_env-not-defined.rs
@@ -8,6 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn main() {
+pub fn main() {
     assert!(option_env!("__HOPEFULLY_DOESNT_EXIST__").is_none());
 }
diff --git a/src/test/run-pass/filter-block-view-items.rs b/src/test/run-pass/filter-block-view-items.rs
index 42861833717..34272b145a2 100644
--- a/src/test/run-pass/filter-block-view-items.rs
+++ b/src/test/run-pass/filter-block-view-items.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn main() {
+pub fn main() {
     // Make sure that this view item is filtered out because otherwise it would
     // trigger a compilation error
     #[cfg(not_present)] use foo = bar;
diff --git a/src/test/run-pass/fixed-point-bind-box.rs b/src/test/run-pass/fixed-point-bind-box.rs
deleted file mode 100644
index 4c28151224c..00000000000
--- a/src/test/run-pass/fixed-point-bind-box.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// xfail-fast
-
-fn fix_help<A, B>(f: extern fn(@fn(A) -> B, A) -> B, x: A) -> B {
-    return f( |a| fix_help(f, a), x);
-}
-
-fn fix<A, B>(f: extern fn(@fn(A) -> B, A) -> B) -> @fn(A) -> B {
-    return |a| fix_help(f, a);
-}
-
-fn fact_(f: @fn(v: int) -> int, n: int) -> int {
-    // fun fact 0 = 1
-    return if n == 0 { 1 } else { n * f(n - 1) };
-}
-
-pub fn main() {
-    let fact = fix(fact_);
-    assert_eq!(fact(5), 120);
-    assert_eq!(fact(2), 2);
-}
diff --git a/src/test/run-pass/fixed-point-bind-unique.rs b/src/test/run-pass/fixed-point-bind-unique.rs
deleted file mode 100644
index c7b64fde3fd..00000000000
--- a/src/test/run-pass/fixed-point-bind-unique.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// xfail-fast
-
-fn fix_help<A:'static,B:Send>(f: extern fn(@fn(A) -> B, A) -> B, x: A) -> B {
-    return f(|a| fix_help(f, a), x);
-}
-
-fn fix<A:'static,B:Send>(f: extern fn(@fn(A) -> B, A) -> B) -> @fn(A) -> B {
-    return |a| fix_help(f, a);
-}
-
-fn fact_(f: @fn(v: int) -> int, n: int) -> int {
-    // fun fact 0 = 1
-    return if n == 0 { 1 } else { n * f(n - 1) };
-}
-
-pub fn main() {
-    let fact = fix(fact_);
-    assert_eq!(fact(5), 120);
-    assert_eq!(fact(2), 2);
-}
diff --git a/src/test/run-pass/fn-assign-managed-to-bare-1.rs b/src/test/run-pass/fn-assign-managed-to-bare-1.rs
deleted file mode 100644
index dece77595bc..00000000000
--- a/src/test/run-pass/fn-assign-managed-to-bare-1.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn add(n: int) -> @fn(int) -> int {
-    let result: @fn(int) -> int = |m| m + n;
-    result
-}
-
-pub fn main() {
-      assert_eq!(add(3)(4), 7);
-      let add3 : &fn(int)->int = add(3);
-      assert_eq!(add3(4), 7);
-}
diff --git a/src/test/run-pass/fn-coerce-field.rs b/src/test/run-pass/fn-coerce-field.rs
index 22aab1aa661..ae2e353f913 100644
--- a/src/test/run-pass/fn-coerce-field.rs
+++ b/src/test/run-pass/fn-coerce-field.rs
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct r {
-    field: @fn()
+struct r<'self> {
+    field: &'self fn()
 }
 
 pub fn main() {
diff --git a/src/test/run-pass/fn-type-infer.rs b/src/test/run-pass/fn-type-infer.rs
index bb9254589f7..09e7ababa6c 100644
--- a/src/test/run-pass/fn-type-infer.rs
+++ b/src/test/run-pass/fn-type-infer.rs
@@ -11,7 +11,7 @@
 #[allow(unused_variable)];
 
 pub fn main() {
-    // We should be able to type infer inside of @fns.
+    // We should be able to type infer inside of &fns.
     let _f = || {
         let i = 10;
     };
diff --git a/src/test/run-pass/foreach-external-iterators-break.rs b/src/test/run-pass/foreach-external-iterators-break.rs
index f5e7d91c225..87ed7826fed 100644
--- a/src/test/run-pass/foreach-external-iterators-break.rs
+++ b/src/test/run-pass/foreach-external-iterators-break.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn main() {
+pub fn main() {
     let x = [1,..100];
     let mut y = 0;
     for i in x.iter() {
diff --git a/src/test/run-pass/foreach-external-iterators-hashmap-break-restart.rs b/src/test/run-pass/foreach-external-iterators-hashmap-break-restart.rs
index 17c5bb5c0e2..34ce8c47113 100644
--- a/src/test/run-pass/foreach-external-iterators-hashmap-break-restart.rs
+++ b/src/test/run-pass/foreach-external-iterators-hashmap-break-restart.rs
@@ -14,7 +14,7 @@ use std::hashmap::HashMap;
 // outside the loop, breaks, then _picks back up_ and continues
 // iterating with it.
 
-fn main() {
+pub fn main() {
     let mut h = HashMap::new();
     let kvs = [(1, 10), (2, 20), (3, 30)];
     for &(k,v) in kvs.iter() {
@@ -38,4 +38,4 @@ fn main() {
 
     assert_eq!(x, 6);
     assert_eq!(y, 60);
-}
\ No newline at end of file
+}
diff --git a/src/test/run-pass/foreach-external-iterators-hashmap.rs b/src/test/run-pass/foreach-external-iterators-hashmap.rs
index 908adc0d762..365cde34dce 100644
--- a/src/test/run-pass/foreach-external-iterators-hashmap.rs
+++ b/src/test/run-pass/foreach-external-iterators-hashmap.rs
@@ -10,7 +10,7 @@
 
 use std::hashmap::HashMap;
 
-fn main() {
+pub fn main() {
     let mut h = HashMap::new();
     let kvs = [(1, 10), (2, 20), (3, 30)];
     for &(k,v) in kvs.iter() {
@@ -24,4 +24,4 @@ fn main() {
     }
     assert_eq!(x, 6);
     assert_eq!(y, 60);
-}
\ No newline at end of file
+}
diff --git a/src/test/run-pass/foreach-external-iterators-loop.rs b/src/test/run-pass/foreach-external-iterators-loop.rs
index c999d810ec6..ced538e163e 100644
--- a/src/test/run-pass/foreach-external-iterators-loop.rs
+++ b/src/test/run-pass/foreach-external-iterators-loop.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn main() {
+pub fn main() {
     let x = [1,..100];
     let mut y = 0;
     for (n,i) in x.iter().enumerate() {
diff --git a/src/test/run-pass/foreach-external-iterators-nested.rs b/src/test/run-pass/foreach-external-iterators-nested.rs
index 904c90dc815..78aba778421 100644
--- a/src/test/run-pass/foreach-external-iterators-nested.rs
+++ b/src/test/run-pass/foreach-external-iterators-nested.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn main() {
+pub fn main() {
     let x = [1,..100];
     let y = [2,..100];
     let mut p = 0;
diff --git a/src/test/run-pass/foreach-external-iterators.rs b/src/test/run-pass/foreach-external-iterators.rs
index c6f903821dd..593a996d8df 100644
--- a/src/test/run-pass/foreach-external-iterators.rs
+++ b/src/test/run-pass/foreach-external-iterators.rs
@@ -8,11 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn main() {
+pub fn main() {
     let x = [1,..100];
     let mut y = 0;
     for i in x.iter() {
         y += *i
     }
     assert!(y == 100);
-}
\ No newline at end of file
+}
diff --git a/src/test/run-pass/fun-call-variants.rs b/src/test/run-pass/fun-call-variants.rs
index 52e6a4649a8..5011998f929 100644
--- a/src/test/run-pass/fun-call-variants.rs
+++ b/src/test/run-pass/fun-call-variants.rs
@@ -9,7 +9,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn ho(f: @fn(int) -> int) -> int { let n: int = f(3); return n; }
+fn ho(f: &fn(int) -> int) -> int { let n: int = f(3); return n; }
 
 fn direct(x: int) -> int { return x + 1; }
 
diff --git a/src/test/run-pass/func-arg-incomplete-pattern.rs b/src/test/run-pass/func-arg-incomplete-pattern.rs
index b08d3beae1b..93c9d6b50ec 100644
--- a/src/test/run-pass/func-arg-incomplete-pattern.rs
+++ b/src/test/run-pass/func-arg-incomplete-pattern.rs
@@ -11,10 +11,10 @@ fn foo(Foo {x, _}: Foo) -> *uint {
     addr
 }
 
-fn main() {
+pub fn main() {
     let obj = ~1;
     let objptr: *uint = &*obj;
     let f = Foo {x: obj, y: ~2};
     let xptr = foo(f);
     assert_eq!(objptr, xptr);
-}
\ No newline at end of file
+}
diff --git a/src/test/run-pass/func-arg-ref-pattern.rs b/src/test/run-pass/func-arg-ref-pattern.rs
index 84c2b3acf35..1b7d641fa82 100644
--- a/src/test/run-pass/func-arg-ref-pattern.rs
+++ b/src/test/run-pass/func-arg-ref-pattern.rs
@@ -13,7 +13,7 @@ fn checkval(~ref x: ~uint) -> uint {
     *x
 }
 
-fn main() {
+pub fn main() {
     let obj = ~1;
     let objptr: *uint = &*obj;
     let xptr = getaddr(obj);
diff --git a/src/test/run-pass/func-arg-wild-pattern.rs b/src/test/run-pass/func-arg-wild-pattern.rs
index c2d60c85329..ec58198d4a3 100644
--- a/src/test/run-pass/func-arg-wild-pattern.rs
+++ b/src/test/run-pass/func-arg-wild-pattern.rs
@@ -5,6 +5,6 @@ fn foo((x, _): (int, int)) -> int {
     x
 }
 
-fn main() {
+pub fn main() {
     assert_eq!(foo((22, 23)), 22);
 }
diff --git a/src/test/run-pass/generic-static-methods.rs b/src/test/run-pass/generic-static-methods.rs
index 4945a25967a..2e281812d13 100755
--- a/src/test/run-pass/generic-static-methods.rs
+++ b/src/test/run-pass/generic-static-methods.rs
@@ -22,6 +22,6 @@ impl<T> vec_utils<T> for ~[T] {
     }
 }
 
-fn main() {
+pub fn main() {
     assert_eq!(vec_utils::map_(&~[1,2,3], |&x| x+1), ~[2,3,4]);
 }
diff --git a/src/test/run-pass/generic-tag-corruption.rs b/src/test/run-pass/generic-tag-corruption.rs
index 4fd8b73c819..deab9c71523 100644
--- a/src/test/run-pass/generic-tag-corruption.rs
+++ b/src/test/run-pass/generic-tag-corruption.rs
@@ -11,7 +11,7 @@
 
 
 
-// This causes memory corruption in stage0.
+// This used to cause memory corruption in stage 0.
 enum thing<K> { some(K), }
 
 pub fn main() { let _x = some(~"hi"); }
diff --git a/src/test/run-pass/hashmap-memory.rs b/src/test/run-pass/hashmap-memory.rs
index 7cd26dd84c4..15286a85c01 100644
--- a/src/test/run-pass/hashmap-memory.rs
+++ b/src/test/run-pass/hashmap-memory.rs
@@ -24,7 +24,7 @@ mod map_reduce {
     use std::str;
     use std::task;
 
-    pub type putter = @fn(~str, ~str);
+    pub type putter<'self> = &'self fn(~str, ~str);
 
     pub type mapper = extern fn(~str, putter);
 
diff --git a/src/test/run-pass/hygiene-dodging-1.rs b/src/test/run-pass/hygiene-dodging-1.rs
index 55e15cc02dd..3969394a26b 100644
--- a/src/test/run-pass/hygiene-dodging-1.rs
+++ b/src/test/run-pass/hygiene-dodging-1.rs
@@ -12,7 +12,7 @@ mod x {
     pub fn g() -> uint {14}
 }
 
-fn main(){
+pub fn main(){
     // should *not* shadow the module x:
     let x = 9;
     // use it to avoid warnings:
diff --git a/src/test/run-pass/infer-with-expected.rs b/src/test/run-pass/infer-with-expected.rs
deleted file mode 100644
index 6f2fd54bc9c..00000000000
--- a/src/test/run-pass/infer-with-expected.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Tests the passing down of expected types through boxing and
-// wrapping in a record or tuple. (The a.x would complain about 'this
-// type must be known in this context' if the passing down doesn't
-// happen.)
-
-fn eat_tup(_r: ~@(int, @fn(Pair) -> int)) {}
-fn eat_rec(_r: ~Rec) {}
-
-struct Rec<'self> { a: int, b: &'self fn(Pair) -> int }
-struct Pair { x: int, y: int }
-
-pub fn main() {
-    eat_tup(~@(10, |a| a.x ));
-    eat_rec(~Rec{a: 10, b: |a| a.x });
-}
diff --git a/src/test/run-pass/issue-1516.rs b/src/test/run-pass/issue-1516.rs
index 2767ac6d69f..4b73d83595e 100644
--- a/src/test/run-pass/issue-1516.rs
+++ b/src/test/run-pass/issue-1516.rs
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 pub fn main() {
-    let early_error: @fn(&str) -> !  = |_msg| { fail!() };
+    let early_error: &'static fn(&str) -> !  = |_msg| { fail!() };
 }
diff --git a/src/test/run-pass/issue-2185.rs b/src/test/run-pass/issue-2185.rs
index c84386c722d..a1ea1b90809 100644
--- a/src/test/run-pass/issue-2185.rs
+++ b/src/test/run-pass/issue-2185.rs
@@ -18,11 +18,11 @@
 //
 // Running /usr/local/bin/rustc:
 // issue-2185.rs:24:0: 26:1 error: conflicting implementations for a trait
-// issue-2185.rs:24 impl iterable<uint> for @fn(&fn(uint)) {
+// issue-2185.rs:24 impl iterable<uint> for &'static fn(&fn(uint)) {
 // issue-2185.rs:25     fn iter(&self, blk: &fn(v: uint)) { self( |i| blk(i) ) }
 // issue-2185.rs:26 }
 // issue-2185.rs:20:0: 22:1 note: note conflicting implementation here
-// issue-2185.rs:20 impl<A> iterable<A> for @fn(&fn(A)) {
+// issue-2185.rs:20 impl<A> iterable<A> for &'static fn(&fn(A)) {
 // issue-2185.rs:21     fn iter(&self, blk: &fn(A)) { self(blk); }
 // issue-2185.rs:22 }
 //
@@ -42,15 +42,17 @@ trait iterable<A> {
     fn iter(&self, blk: &fn(A));
 }
 
-impl<A> iterable<A> for @fn(&fn(A)) {
+impl<A> iterable<A> for &'static fn(&fn(A)) {
     fn iter(&self, blk: &fn(A)) { self(blk); }
 }
 
-impl iterable<uint> for @fn(&fn(uint)) {
+impl iterable<uint> for &'static fn(&fn(uint)) {
     fn iter(&self, blk: &fn(v: uint)) { self( |i| blk(i) ) }
 }
 
-fn filter<A,IA:iterable<A>>(self: IA, prd: @fn(A) -> bool, blk: &fn(A)) {
+fn filter<A,IA:iterable<A>>(self: IA,
+                            prd: &'static fn(A) -> bool,
+                            blk: &fn(A)) {
     do self.iter |a| {
         if prd(a) { blk(a) }
     }
@@ -73,8 +75,8 @@ fn range(lo: uint, hi: uint, it: &fn(uint)) {
 }
 
 pub fn main() {
-    let range: @fn(&fn(uint)) = |a| range(0u, 1000u, a);
-    let filt: @fn(&fn(v: uint)) = |a| filter(
+    let range: &'static fn(&fn(uint)) = |a| range(0u, 1000u, a);
+    let filt: &'static fn(&fn(v: uint)) = |a| filter(
         range,
         |&&n: uint| n % 3u != 0u && n % 5u != 0u,
         a);
diff --git a/src/test/run-pass/issue-2611-3.rs b/src/test/run-pass/issue-2611-3.rs
index 56c18d557f0..3cc7296fa4a 100644
--- a/src/test/run-pass/issue-2611-3.rs
+++ b/src/test/run-pass/issue-2611-3.rs
@@ -23,4 +23,4 @@ impl A for E {
   fn b<F,G>(_x: F) -> F { fail!() } //~ ERROR in method `b`, type parameter 0 has 1 bound, but
 }
 
-fn main() {}
+pub fn main() {}
diff --git a/src/test/run-pass/issue-2633.rs b/src/test/run-pass/issue-2633.rs
index e7da1286137..bde18d77b9a 100644
--- a/src/test/run-pass/issue-2633.rs
+++ b/src/test/run-pass/issue-2633.rs
@@ -9,12 +9,16 @@
 // except according to those terms.
 
 struct cat {
-    meow: @fn(),
+    meow: extern "Rust" fn(),
+}
+
+fn meow() {
+    error!("meow")
 }
 
 fn cat() -> cat {
     cat {
-        meow: || error!("meow")
+        meow: meow,
     }
 }
 
diff --git a/src/test/run-pass/issue-3052.rs b/src/test/run-pass/issue-3052.rs
index 852c6d995c6..cb1ffc38908 100644
--- a/src/test/run-pass/issue-3052.rs
+++ b/src/test/run-pass/issue-3052.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-type Connection = @fn(~[u8]);
+type Connection = &'static fn(~[u8]);
 
 fn f() -> Option<Connection> {
     let mock_connection: Connection = |_| {};
diff --git a/src/test/run-pass/issue-3429.rs b/src/test/run-pass/issue-3429.rs
index abea01cefd3..fc493485b79 100644
--- a/src/test/run-pass/issue-3429.rs
+++ b/src/test/run-pass/issue-3429.rs
@@ -10,6 +10,6 @@
 
 pub fn main() {
   let x = 1;
-  let y: @fn() -> int = || x;
+  let y: &fn() -> int = || x;
   let _z = y();
 }
diff --git a/src/test/run-pass/issue-3979-generics.rs b/src/test/run-pass/issue-3979-generics.rs
index 867301121da..86cdd6135ec 100644
--- a/src/test/run-pass/issue-3979-generics.rs
+++ b/src/test/run-pass/issue-3979-generics.rs
@@ -31,7 +31,7 @@ impl Positioned<int> for Point {
     }
 }
 
-impl Movable<int> for Point;
+impl Movable<int> for Point {}
 
 pub fn main() {
     let mut p = Point{ x: 1, y: 2};
diff --git a/src/test/run-pass/issue-3979-xcrate.rs b/src/test/run-pass/issue-3979-xcrate.rs
index caf6d202316..63d2562f541 100644
--- a/src/test/run-pass/issue-3979-xcrate.rs
+++ b/src/test/run-pass/issue-3979-xcrate.rs
@@ -24,7 +24,7 @@ impl Positioned for Point {
     }
 }
 
-impl Movable for Point;
+impl Movable for Point {}
 
 pub fn main() {
     let mut p = Point{ x: 1, y: 2};
diff --git a/src/test/run-pass/issue-3979.rs b/src/test/run-pass/issue-3979.rs
index 2e53fb5d3f9..4f69342830b 100644
--- a/src/test/run-pass/issue-3979.rs
+++ b/src/test/run-pass/issue-3979.rs
@@ -32,7 +32,7 @@ impl Positioned for Point {
     }
 }
 
-impl Movable for Point;
+impl Movable for Point {}
 
 pub fn main() {
     let mut p = Point{ x: 1, y: 2};
diff --git a/src/test/run-pass/issue-3991.rs b/src/test/run-pass/issue-3991.rs
index 842605b5929..d5dd090009a 100644
--- a/src/test/run-pass/issue-3991.rs
+++ b/src/test/run-pass/issue-3991.rs
@@ -18,4 +18,4 @@ impl HasNested {
     }
 }
 
-fn main() {}
+pub fn main() {}
diff --git a/src/test/run-pass/issue-4333.rs b/src/test/run-pass/issue-4333.rs
index 98280271bde..ebf29be6d5e 100644
--- a/src/test/run-pass/issue-4333.rs
+++ b/src/test/run-pass/issue-4333.rs
@@ -10,7 +10,7 @@
 
 use std::io;
 
-fn main() {
+pub fn main() {
     let stdout = &io::stdout() as &io::WriterUtil;
     stdout.write_line("Hello!");
 }
diff --git a/src/test/run-pass/issue-4446.rs b/src/test/run-pass/issue-4446.rs
index accf7c4e6cd..ddcb544c64f 100644
--- a/src/test/run-pass/issue-4446.rs
+++ b/src/test/run-pass/issue-4446.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn main() {
+pub fn main() {
     let (port, chan) = stream();
 
     do spawn {
diff --git a/src/test/run-pass/issue-4735.rs b/src/test/run-pass/issue-4735.rs
index 8451d281aa0..b28ba6811b7 100644
--- a/src/test/run-pass/issue-4735.rs
+++ b/src/test/run-pass/issue-4735.rs
@@ -21,7 +21,7 @@ impl Drop for NonCopyable {
     }
 }
 
-fn main() {
+pub fn main() {
     let t = ~0;
     let p = unsafe { transmute::<~int, *c_void>(t) };
     let _z = NonCopyable(p);
diff --git a/src/test/run-pass/issue-5008-borrowed-traitobject-method-call.rs b/src/test/run-pass/issue-5008-borrowed-traitobject-method-call.rs
index ce9bb725a1b..dd3f54d97ec 100644
--- a/src/test/run-pass/issue-5008-borrowed-traitobject-method-call.rs
+++ b/src/test/run-pass/issue-5008-borrowed-traitobject-method-call.rs
@@ -37,7 +37,7 @@ fn print_name(x: &Debuggable)
     println(fmt!("debug_name = %s", x.debug_name()));
 }
 
-fn main() {
+pub fn main() {
     let thing = Thing::new();
     print_name(&thing as &Debuggable);
 }
diff --git a/src/test/run-pass/issue-5060.rs b/src/test/run-pass/issue-5060.rs
index 0922f555bea..c9881106071 100644
--- a/src/test/run-pass/issue-5060.rs
+++ b/src/test/run-pass/issue-5060.rs
@@ -22,7 +22,7 @@ macro_rules! print_hd_tl (
     })
 )
 
-fn main() {
+pub fn main() {
     print_hd_tl!(x, y, z, w)
 }
 
diff --git a/src/test/run-pass/issue-5192.rs b/src/test/run-pass/issue-5192.rs
index b9048257cfb..202a3cbcafa 100644
--- a/src/test/run-pass/issue-5192.rs
+++ b/src/test/run-pass/issue-5192.rs
@@ -39,6 +39,6 @@ impl Scheduler {
     }
 }
 
-fn main() {
+pub fn main() {
     let _sched = Scheduler::new(~UvEventLoop::new() as ~EventLoop);
 }
diff --git a/src/test/run-pass/issue-5239-2.rs b/src/test/run-pass/issue-5239-2.rs
index dac3c95e08a..ba70fac0e4e 100644
--- a/src/test/run-pass/issue-5239-2.rs
+++ b/src/test/run-pass/issue-5239-2.rs
@@ -10,7 +10,7 @@
 
 // Regression test for issue #5239
 
-fn main() { 
+pub fn main() { 
     let _f: &fn(int) -> int = |ref x: int| { *x };
     let foo = 10;
     assert!(_f(foo) == 10);
diff --git a/src/test/run-pass/issue-5280.rs b/src/test/run-pass/issue-5280.rs
index 77df670ffb1..16fd45a5615 100644
--- a/src/test/run-pass/issue-5280.rs
+++ b/src/test/run-pass/issue-5280.rs
@@ -20,6 +20,6 @@ impl FontTableTagConversions for FontTableTag {
   }
 }
 
-fn main() {
+pub fn main() {
     5.tag_to_str();
 }
diff --git a/src/test/run-pass/issue-5315.rs b/src/test/run-pass/issue-5315.rs
index dde226ad9d8..1d2e7b79931 100644
--- a/src/test/run-pass/issue-5315.rs
+++ b/src/test/run-pass/issue-5315.rs
@@ -10,7 +10,7 @@
 
 struct A(bool);
 
-fn main() {
+pub fn main() {
     let f = A;
     f(true);
 }
diff --git a/src/test/run-pass/issue-5321-immediates-with-bare-self.rs b/src/test/run-pass/issue-5321-immediates-with-bare-self.rs
index 3f4b732af32..3f1dc2f6986 100644
--- a/src/test/run-pass/issue-5321-immediates-with-bare-self.rs
+++ b/src/test/run-pass/issue-5321-immediates-with-bare-self.rs
@@ -20,6 +20,6 @@ impl Fooable for uint {
     }
 }
 
-fn main() {
+pub fn main() {
     2.yes();
 }
diff --git a/src/test/run-pass/issue-5353.rs b/src/test/run-pass/issue-5353.rs
index cc1bb2dd037..cf11b9aa7b6 100644
--- a/src/test/run-pass/issue-5353.rs
+++ b/src/test/run-pass/issue-5353.rs
@@ -21,4 +21,4 @@ fn gl_err_str(err: u32) -> ~str
   }
 }
 
-fn main() {}
+pub fn main() {}
diff --git a/src/test/run-pass/issue-5517.rs b/src/test/run-pass/issue-5517.rs
index b929dbf51d3..d63d8b13b43 100644
--- a/src/test/run-pass/issue-5517.rs
+++ b/src/test/run-pass/issue-5517.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn main() {
+pub fn main() {
     let box1 = @mut 42;
     let _x = *(&mut *box1) == 42 || *(&mut *box1) == 31337;
 }
diff --git a/src/test/run-pass/issue-5550.rs b/src/test/run-pass/issue-5550.rs
index c1875988dc6..d68766d5886 100644
--- a/src/test/run-pass/issue-5550.rs
+++ b/src/test/run-pass/issue-5550.rs
@@ -10,7 +10,7 @@
 
 #[allow(dead_assignment)];
 
-fn main() {
+pub fn main() {
     let s: ~str = ~"foobar";
     let mut t: &str = s;
     t = t.slice(0, 3); // for master: str::view(t, 0, 3) maybe
diff --git a/src/test/run-pass/issue-5572.rs b/src/test/run-pass/issue-5572.rs
index daf5edd1d28..d1a1fbf0940 100644
--- a/src/test/run-pass/issue-5572.rs
+++ b/src/test/run-pass/issue-5572.rs
@@ -1,3 +1,3 @@
 fn foo<T: ::std::cmp::Eq>(_t: T) { }
 
-fn main() { }
+pub fn main() { }
diff --git a/src/test/run-pass/issue-5688.rs b/src/test/run-pass/issue-5688.rs
index 440e2a43e42..4ac4b3b33b7 100644
--- a/src/test/run-pass/issue-5688.rs
+++ b/src/test/run-pass/issue-5688.rs
@@ -19,7 +19,7 @@ failed to typecheck correctly.
 
 struct X { vec: &'static [int] }
 static V: &'static [X] = &[X { vec: &[1, 2, 3] }];
-fn main() {
+pub fn main() {
     for &v in V.iter() {
         println(fmt!("%?", v.vec));
     }
diff --git a/src/test/run-pass/issue-5708.rs b/src/test/run-pass/issue-5708.rs
index 51f6ad6aa30..aee1f8415ef 100644
--- a/src/test/run-pass/issue-5708.rs
+++ b/src/test/run-pass/issue-5708.rs
@@ -39,7 +39,7 @@ impl<'self> Outer<'self> {
     }
 }
 
-fn main() {
+pub fn main() {
     let inner = 5;
     let outer = Outer::new(&inner as &Inner);
     outer.inner.print();
diff --git a/src/test/run-pass/issue-5741.rs b/src/test/run-pass/issue-5741.rs
index 039d9bcd16e..46ec68675e7 100644
--- a/src/test/run-pass/issue-5741.rs
+++ b/src/test/run-pass/issue-5741.rs
@@ -12,7 +12,7 @@
 
 use std::io;
 
-fn main() {
+pub fn main() {
     return;
     while io::stdin().read_line() != ~"quit" { };
 }
diff --git a/src/test/run-pass/issue-5917.rs b/src/test/run-pass/issue-5917.rs
index 326e92d3b70..6fb5c25f731 100644
--- a/src/test/run-pass/issue-5917.rs
+++ b/src/test/run-pass/issue-5917.rs
@@ -10,6 +10,6 @@
 
 struct T (&'static [int]);
 static t : T = T (&'static [5, 4, 3]);
-fn main () {
+pub fn main () {
     assert_eq!(t[0], 5);
 }
diff --git a/src/test/run-pass/issue-6128.rs b/src/test/run-pass/issue-6128.rs
index 54df0523dbb..a01a04ebf82 100644
--- a/src/test/run-pass/issue-6128.rs
+++ b/src/test/run-pass/issue-6128.rs
@@ -21,7 +21,7 @@ impl<E> Graph<int, E> for HashMap<int, int> {
     }
 }
 
-fn main() {
+pub fn main() {
     let g : ~HashMap<int, int> = ~HashMap::new();
     let _g2 : ~Graph<int,int> = g as ~Graph<int,int>;
 }
diff --git a/src/test/run-pass/issue-6130.rs b/src/test/run-pass/issue-6130.rs
index 642308c0ca1..d88397499fe 100644
--- a/src/test/run-pass/issue-6130.rs
+++ b/src/test/run-pass/issue-6130.rs
@@ -10,7 +10,7 @@
 
 #[deny(type_limits)];
 
-fn main() {
+pub fn main() {
     let i: uint = 0;
     assert!(i <= 0xFFFF_FFFF_u);
 
diff --git a/src/test/run-pass/issue-6141-leaking-owned-fn.rs b/src/test/run-pass/issue-6141-leaking-owned-fn.rs
index fe11bb0a972..98d2ca5d942 100644
--- a/src/test/run-pass/issue-6141-leaking-owned-fn.rs
+++ b/src/test/run-pass/issue-6141-leaking-owned-fn.rs
@@ -2,7 +2,7 @@ fn run(f: &fn()) {
     f()
 }
 
-fn main() {
+pub fn main() {
     let f: ~fn() = || ();
     run(f);
-}
\ No newline at end of file
+}
diff --git a/src/test/run-pass/issue-6153.rs b/src/test/run-pass/issue-6153.rs
index a51b595f59f..668d6f3ae45 100644
--- a/src/test/run-pass/issue-6153.rs
+++ b/src/test/run-pass/issue-6153.rs
@@ -13,7 +13,7 @@ fn swap(f: &fn(~[int]) -> ~[int]) -> ~[int] {
     f(x)
 }
 
-fn main() {
+pub fn main() {
     let v = swap(|mut x| { x.push(4); x });
     let w = do swap |mut x| { x.push(4); x };
     assert_eq!(v, w);
diff --git a/src/test/run-pass/issue-6341.rs b/src/test/run-pass/issue-6341.rs
index f57482b67e0..3859d155851 100644
--- a/src/test/run-pass/issue-6341.rs
+++ b/src/test/run-pass/issue-6341.rs
@@ -15,4 +15,4 @@ impl Drop for A {
     fn drop(&mut self) {}
 }
 
-fn main() {}
\ No newline at end of file
+pub fn main() {}
diff --git a/src/test/run-pass/issue-6344-let.rs b/src/test/run-pass/issue-6344-let.rs
index 6e0b6101d37..9343f2b61c9 100644
--- a/src/test/run-pass/issue-6344-let.rs
+++ b/src/test/run-pass/issue-6344-let.rs
@@ -13,7 +13,7 @@ impl Drop for A {
     fn drop(&mut self) {}
 }
 
-fn main() {
+pub fn main() {
     let a = A { x: 0 };
 
     let A { x: ref x } = a;
diff --git a/src/test/run-pass/issue-6344-match.rs b/src/test/run-pass/issue-6344-match.rs
index b9429fc63fd..18d327aa360 100644
--- a/src/test/run-pass/issue-6344-match.rs
+++ b/src/test/run-pass/issue-6344-match.rs
@@ -13,7 +13,7 @@ impl Drop for A {
     fn drop(&mut self) {}
 }
 
-fn main() {
+pub fn main() {
     let a = A { x: 0 };
 
     match a {
diff --git a/src/test/run-pass/issue-7012.rs b/src/test/run-pass/issue-7012.rs
index 777803d75a5..2a56f2ad8bc 100644
--- a/src/test/run-pass/issue-7012.rs
+++ b/src/test/run-pass/issue-7012.rs
@@ -21,7 +21,7 @@ static test1: signature<'static> =  signature {
   pattern: &[0x243f6a88u32,0x85a308d3u32,0x13198a2eu32,0x03707344u32,0xa4093822u32,0x299f31d0u32]
 };
 
-fn main() {
+pub fn main() {
   let test = &[0x243f6a88u32,0x85a308d3u32,0x13198a2eu32,0x03707344u32,0xa4093822u32,0x299f31d0u32];
   println(fmt!("%b",test==test1.pattern));
 }
diff --git a/src/test/run-pass/issue-7344.rs b/src/test/run-pass/issue-7344.rs
index acf55d2463b..9b1643bb224 100644
--- a/src/test/run-pass/issue-7344.rs
+++ b/src/test/run-pass/issue-7344.rs
@@ -22,7 +22,7 @@ fn baz() {
     if "" == "" {}
 }
 
-fn main() {
+pub fn main() {
     bar();
     baz();
 }
diff --git a/src/test/run-pass/issue-7519-match-unit-in-arg.rs b/src/test/run-pass/issue-7519-match-unit-in-arg.rs
index ba84dd44b2f..75123243f47 100644
--- a/src/test/run-pass/issue-7519-match-unit-in-arg.rs
+++ b/src/test/run-pass/issue-7519-match-unit-in-arg.rs
@@ -14,6 +14,6 @@
 
 fn foo(():()) { }
 
-fn main() {
+pub fn main() {
     foo(());
 }
diff --git a/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs b/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs
index 2f2b736294a..af8b453856b 100644
--- a/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs
+++ b/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs
@@ -14,7 +14,7 @@
 
 */
 
-fn main() {}
+pub fn main() {}
 
 trait A {}
 impl<T: 'static> A for T {}
diff --git a/src/test/run-pass/issue-7712.rs b/src/test/run-pass/issue-7712.rs
index 1ea8312ddd9..fa7d68cf921 100644
--- a/src/test/run-pass/issue-7712.rs
+++ b/src/test/run-pass/issue-7712.rs
@@ -20,6 +20,6 @@ struct MyStruct;
 
 impl TraitWithDefaultMethod for MyStruct { }
 
-fn main() {
+pub fn main() {
     MyStruct.method();
 }
diff --git a/src/test/run-pass/issue-8171-default-method-self-inherit-builtin-trait.rs b/src/test/run-pass/issue-8171-default-method-self-inherit-builtin-trait.rs
index be68d50c961..aaf2ecb7129 100644
--- a/src/test/run-pass/issue-8171-default-method-self-inherit-builtin-trait.rs
+++ b/src/test/run-pass/issue-8171-default-method-self-inherit-builtin-trait.rs
@@ -22,4 +22,4 @@ trait TragicallySelfIsNotSend: Send {
     }
 }
 
-fn main(){}
+pub fn main(){}
diff --git a/src/test/run-pass/issue-8248.rs b/src/test/run-pass/issue-8248.rs
index 48f34805fee..377b9ce262c 100644
--- a/src/test/run-pass/issue-8248.rs
+++ b/src/test/run-pass/issue-8248.rs
@@ -14,7 +14,7 @@ impl A for B {}
 
 fn foo(_: &mut A) {}
 
-fn main() {
+pub fn main() {
     let mut b = B;
     foo(&mut b as &mut A);
 }
diff --git a/src/test/run-pass/issue-8249.rs b/src/test/run-pass/issue-8249.rs
index ad37196dce4..bfc1d943690 100644
--- a/src/test/run-pass/issue-8249.rs
+++ b/src/test/run-pass/issue-8249.rs
@@ -20,6 +20,6 @@ fn foo(a: &mut A) {
     C{ foo: a };
 }
 
-fn main() {
+pub fn main() {
 }
 
diff --git a/src/test/run-pass/issue-8398.rs b/src/test/run-pass/issue-8398.rs
index 5e04c96af72..31ac2c46293 100644
--- a/src/test/run-pass/issue-8398.rs
+++ b/src/test/run-pass/issue-8398.rs
@@ -14,5 +14,5 @@ fn foo(a: &mut io::Writer) {
     a.write([])
 }
 
-fn main(){}
+pub fn main(){}
 
diff --git a/src/test/run-pass/issue-9047.rs b/src/test/run-pass/issue-9047.rs
index fc9c22fb82c..053d6aa3c90 100644
--- a/src/test/run-pass/issue-9047.rs
+++ b/src/test/run-pass/issue-9047.rs
@@ -16,4 +16,4 @@ fn decode() -> ~str {
     ~""
 }
 
-fn main() {}
+pub fn main() {}
diff --git a/src/test/run-pass/issue-9110.rs b/src/test/run-pass/issue-9110.rs
index 56f87f5e686..27c2ed9e5ad 100644
--- a/src/test/run-pass/issue-9110.rs
+++ b/src/test/run-pass/issue-9110.rs
@@ -19,4 +19,4 @@ macro_rules! silly_macro(
 
 silly_macro!()
 
-fn main() {}
+pub fn main() {}
diff --git a/src/test/run-pass/issue4516_ty_param.rs b/src/test/run-pass/issue4516_ty_param.rs
deleted file mode 100644
index 35df47df036..00000000000
--- a/src/test/run-pass/issue4516_ty_param.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// xfail-fast - check-fast doesn't understand aux-build
-// aux-build:issue4516_ty_param_lib.rs
-
-// Trigger a bug concerning inlining of generic functions.
-// The def-ids in type parameters were not being correctly
-// resolved and hence when we checked the type of the closure
-// variable (see the library mod) to determine if the value
-// should be moved into the closure, trans failed to find
-// the relevant kind bounds.
-
-extern mod issue4516_ty_param_lib;
-use issue4516_ty_param_lib::to_closure;
-pub fn main() {
-    to_closure(22)();
-}
diff --git a/src/test/run-pass/lambda-infer-unresolved.rs b/src/test/run-pass/lambda-infer-unresolved.rs
index 9eecc788a69..d55150e448e 100644
--- a/src/test/run-pass/lambda-infer-unresolved.rs
+++ b/src/test/run-pass/lambda-infer-unresolved.rs
@@ -9,13 +9,13 @@
 // except according to those terms.
 
 // This should typecheck even though the type of e is not fully
-// resolved when we finish typechecking the @fn.
+// resolved when we finish typechecking the &fn.
 
 
 struct Refs { refs: ~[int], n: int }
 
 pub fn main() {
     let e = @mut Refs{refs: ~[], n: 0};
-    let _f: @fn() = || error!(e.n);
+    let _f: &fn() = || error!(e.n);
     e.refs.push(1);
 }
diff --git a/src/test/run-pass/lambda-no-leak.rs b/src/test/run-pass/lambda-no-leak.rs
deleted file mode 100644
index e19503240f0..00000000000
--- a/src/test/run-pass/lambda-no-leak.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Make sure we don't leak @fns in silly ways.
-fn force(f: @fn()) { f() }
-pub fn main() {
-    let x = 7;
-    let _f: @fn() = || error!(x);
-    force(|| error!(x));
-}
diff --git a/src/test/run-pass/last-use-in-cap-clause.rs b/src/test/run-pass/last-use-in-cap-clause.rs
index 75c3008af8e..d014a3cf1a1 100644
--- a/src/test/run-pass/last-use-in-cap-clause.rs
+++ b/src/test/run-pass/last-use-in-cap-clause.rs
@@ -12,10 +12,10 @@
 
 struct A { a: ~int }
 
-fn foo() -> @fn() -> int {
+fn foo() -> &'static fn() -> int {
     let k = ~22;
     let _u = A {a: k.clone()};
-    let result: @fn() -> int = || 22;
+    let result: &'static fn() -> int = || 22;
     result
 }
 
diff --git a/src/test/run-pass/last-use-is-capture.rs b/src/test/run-pass/last-use-is-capture.rs
index 2c62b6894d0..079d2374a29 100644
--- a/src/test/run-pass/last-use-is-capture.rs
+++ b/src/test/run-pass/last-use-is-capture.rs
@@ -13,7 +13,7 @@
 struct A { a: ~int }
 
 pub fn main() {
-    fn invoke(f: @fn()) { f(); }
+    fn invoke(f: &fn()) { f(); }
     let k = ~22;
     let _u = A {a: k.clone()};
     invoke(|| error!(k.clone()) )
diff --git a/src/test/run-pass/let-destruct-ref.rs b/src/test/run-pass/let-destruct-ref.rs
index 7f3f9110b1c..fdb2805ae18 100644
--- a/src/test/run-pass/let-destruct-ref.rs
+++ b/src/test/run-pass/let-destruct-ref.rs
@@ -1,4 +1,4 @@
-fn main() {
+pub fn main() {
     let x = ~"hello";
     let ref y = x;
     assert_eq!(x.slice(0, x.len()), y.slice(0, y.len()));
diff --git a/src/test/run-pass/let-var-hygiene.rs b/src/test/run-pass/let-var-hygiene.rs
index 1e29d2e8969..93bb2ca98e8 100644
--- a/src/test/run-pass/let-var-hygiene.rs
+++ b/src/test/run-pass/let-var-hygiene.rs
@@ -10,7 +10,7 @@
 
 // shouldn't affect evaluation of $ex:
 macro_rules! bad_macro (($ex:expr) => ({let _x = 9; $ex}))
-fn main() {
+pub fn main() {
     let _x = 8;
     assert_eq!(bad_macro!(_x),8)
 }
diff --git a/src/test/run-pass/link-section.rs b/src/test/run-pass/link-section.rs
index ff1e4740394..a5ea32e5157 100644
--- a/src/test/run-pass/link-section.rs
+++ b/src/test/run-pass/link-section.rs
@@ -26,7 +26,7 @@ static magic: uint = 42;
 #[link_section="__DATA,__mut"]
 static mut frobulator: uint = 0xdeadbeef;
 
-fn main() {
+pub fn main() {
     unsafe {
         frobulator = 0xcafebabe;
         printfln!("%? %? %?", i_live_in_more_text(), magic, frobulator);
diff --git a/src/test/run-pass/lint-cstack.rs b/src/test/run-pass/lint-cstack.rs
index b9e61b47e22..80901475c04 100644
--- a/src/test/run-pass/lint-cstack.rs
+++ b/src/test/run-pass/lint-cstack.rs
@@ -23,5 +23,5 @@ trait A {
     }
 }
 
-fn main() {
+pub fn main() {
 }
diff --git a/src/test/run-pass/lint-non-camel-case-types-non-uppercase-statics-unicode.rs b/src/test/run-pass/lint-non-camel-case-types-non-uppercase-statics-unicode.rs
index 8c1dc366f23..e3a0c8417d0 100644
--- a/src/test/run-pass/lint-non-camel-case-types-non-uppercase-statics-unicode.rs
+++ b/src/test/run-pass/lint-non-camel-case-types-non-uppercase-statics-unicode.rs
@@ -18,4 +18,4 @@ struct ヒ;
 
 static ラ: uint = 0;
 
-fn main() {}
+pub fn main() {}
diff --git a/src/test/run-pass/lint-non-uppercase-statics-lowercase-mut-statics.rs b/src/test/run-pass/lint-non-uppercase-statics-lowercase-mut-statics.rs
index 3a3648fbf6d..cf6640275ed 100644
--- a/src/test/run-pass/lint-non-uppercase-statics-lowercase-mut-statics.rs
+++ b/src/test/run-pass/lint-non-uppercase-statics-lowercase-mut-statics.rs
@@ -14,4 +14,4 @@
 
 static mut bar: int = 2;
 
-fn main() {}
+pub fn main() {}
diff --git a/src/test/run-pass/macro-local-data-key.rs b/src/test/run-pass/macro-local-data-key.rs
index b53d7b36d79..23f418cfc69 100644
--- a/src/test/run-pass/macro-local-data-key.rs
+++ b/src/test/run-pass/macro-local-data-key.rs
@@ -16,7 +16,7 @@ mod bar {
     local_data_key!(pub baz: float)
 }
 
-fn main() {
+pub fn main() {
     local_data::get(foo, |x| assert!(x.is_none()));
     local_data::get(bar::baz, |y| assert!(y.is_none()));
 
diff --git a/src/test/run-pass/match-drop-strs-issue-4541.rs b/src/test/run-pass/match-drop-strs-issue-4541.rs
index 92095335fc4..e90d6b28626 100644
--- a/src/test/run-pass/match-drop-strs-issue-4541.rs
+++ b/src/test/run-pass/match-drop-strs-issue-4541.rs
@@ -22,6 +22,6 @@ fn parse_args() -> ~str {
     return ~""
 }
 
-fn main() {
+pub fn main() {
     io::println(parse_args());
 }
diff --git a/src/test/run-pass/match-in-macro.rs b/src/test/run-pass/match-in-macro.rs
index 83d10627d2e..671ec5a3965 100644
--- a/src/test/run-pass/match-in-macro.rs
+++ b/src/test/run-pass/match-in-macro.rs
@@ -20,6 +20,6 @@ macro_rules! match_inside_expansion(
     )
 )
 
-fn main() {
+pub fn main() {
     assert_eq!(match_inside_expansion!(),129);
 }
diff --git a/src/test/run-pass/match-pipe-binding.rs b/src/test/run-pass/match-pipe-binding.rs
index b4933773c03..6df4c812361 100644
--- a/src/test/run-pass/match-pipe-binding.rs
+++ b/src/test/run-pass/match-pipe-binding.rs
@@ -59,7 +59,7 @@ fn test5() {
     }
 }
 
-fn main() {
+pub fn main() {
     test1();
     test2();
     test3();
diff --git a/src/test/run-pass/match-range-static.rs b/src/test/run-pass/match-range-static.rs
index aa216b8d054..0bf0d6e41fa 100644
--- a/src/test/run-pass/match-range-static.rs
+++ b/src/test/run-pass/match-range-static.rs
@@ -1,7 +1,7 @@
 static s: int = 1;
 static e: int = 42;
 
-fn main() {
+pub fn main() {
     match 7 {
         s..e => (),
         _ => (),
diff --git a/src/test/run-pass/match-vec-rvalue.rs b/src/test/run-pass/match-vec-rvalue.rs
index 5f68b0e9a69..a6e61fbacd4 100644
--- a/src/test/run-pass/match-vec-rvalue.rs
+++ b/src/test/run-pass/match-vec-rvalue.rs
@@ -1,6 +1,6 @@
 // Tests that matching rvalues with drops does not crash.
 
-fn main() {
+pub fn main() {
     match ~[1, 2, 3] {
         x => {
             assert_eq!(x.len(), 3);
diff --git a/src/test/run-pass/mid-path-type-params.rs b/src/test/run-pass/mid-path-type-params.rs
index 1bc37a035e0..09435962ef7 100644
--- a/src/test/run-pass/mid-path-type-params.rs
+++ b/src/test/run-pass/mid-path-type-params.rs
@@ -26,7 +26,7 @@ impl Trait<int> for S2 {
     }
 }
 
-fn main() {
+pub fn main() {
     let _ = S::<int>::new::<float>(1, 1.0);
     let _: S2 = Trait::<int>::new::<float>(1, 1.0);
 }
diff --git a/src/test/run-pass/monomorphize-trait-in-fn-at.rs b/src/test/run-pass/monomorphize-trait-in-fn-at.rs
deleted file mode 100644
index 8e36b1138bd..00000000000
--- a/src/test/run-pass/monomorphize-trait-in-fn-at.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// test that invoking functions which require
-// dictionaries from inside an @fn works
-// (at one point, it didn't)
-
-fn mk_nil<C:ty_ops>(cx: C) -> uint {
-    cx.mk()
-}
-
-trait ty_ops {
-    fn mk(&self) -> uint;
-}
-
-impl ty_ops for () {
-    fn mk(&self) -> uint { 22u }
-}
-
-pub fn main() {
-    let fn_env: @fn() -> uint = || mk_nil(());
-    assert_eq!(fn_env(), 22u);
-}
diff --git a/src/test/run-pass/move-nullary-fn.rs b/src/test/run-pass/move-nullary-fn.rs
index 464d915b2c4..87281c2fd22 100644
--- a/src/test/run-pass/move-nullary-fn.rs
+++ b/src/test/run-pass/move-nullary-fn.rs
@@ -9,9 +9,9 @@
 // except according to those terms.
 
 // Issue #922
-fn f2(_thing: @fn()) { }
+fn f2(_thing: &fn()) { }
 
-fn f(thing: @fn()) {
+fn f(thing: &fn()) {
     f2(thing);
 }
 
diff --git a/src/test/run-pass/move-out-of-field.rs b/src/test/run-pass/move-out-of-field.rs
index 93ea35e2629..6cf207e5cbc 100644
--- a/src/test/run-pass/move-out-of-field.rs
+++ b/src/test/run-pass/move-out-of-field.rs
@@ -12,7 +12,7 @@ fn to_str(sb: StringBuffer) -> ~str {
     sb.s
 }
 
-fn main() {
+pub fn main() {
     let mut sb = StringBuffer {s: ~""};
     sb.append("Hello, ");
     sb.append("World!");
diff --git a/src/test/run-pass/multibyte.rs b/src/test/run-pass/multibyte.rs
index 417662b65c6..a28008f3e0b 100644
--- a/src/test/run-pass/multibyte.rs
+++ b/src/test/run-pass/multibyte.rs
@@ -9,6 +9,6 @@
 // except according to those terms.
 
 // Test that multibyte characters don't crash the compiler
-fn main() {
+pub fn main() {
     println("마이너스 사인이 없으면");
 }
diff --git a/src/test/run-pass/nested-enum-same-names.rs b/src/test/run-pass/nested-enum-same-names.rs
index 7d9b744ab0f..33c4ed6234e 100644
--- a/src/test/run-pass/nested-enum-same-names.rs
+++ b/src/test/run-pass/nested-enum-same-names.rs
@@ -30,20 +30,4 @@ impl Foo {
     }
 }
 
-/*
-#2074 duplicate symbols with enum in boxed closure
-*/
-
-fn foo() {
-    let one: @fn() -> uint = || {
-        enum r { a }
-        a as uint
-    };
-    let two: @fn() -> uint = || {
-        enum r { a }
-        a as uint
-    };
-    one(); two();
-}
-
-fn main() {}
+pub fn main() {}
diff --git a/src/test/run-pass/nested-function-names-issue-8587.rs b/src/test/run-pass/nested-function-names-issue-8587.rs
index 054e0e3ae26..f697f0b59d6 100644
--- a/src/test/run-pass/nested-function-names-issue-8587.rs
+++ b/src/test/run-pass/nested-function-names-issue-8587.rs
@@ -41,7 +41,7 @@ impl X {
     }
 }
 
-fn main() {
+pub fn main() {
     let n = X;
     assert_eq!(n.f(), 0);
     assert_eq!(n.g(), 1);
diff --git a/src/test/run-pass/newlambdas-ret-infer.rs b/src/test/run-pass/newlambdas-ret-infer.rs
index 10ac45922aa..6d6757890ad 100644
--- a/src/test/run-pass/newlambdas-ret-infer.rs
+++ b/src/test/run-pass/newlambdas-ret-infer.rs
@@ -11,8 +11,6 @@
 // Test that the lambda kind is inferred correctly as a return
 // expression
 
-fn shared() -> @fn() { return || (); }
-
 fn unique() -> ~fn() { return || (); }
 
 pub fn main() {
diff --git a/src/test/run-pass/newlambdas-ret-infer2.rs b/src/test/run-pass/newlambdas-ret-infer2.rs
index 4dfe3575eb5..17ff8ce94d9 100644
--- a/src/test/run-pass/newlambdas-ret-infer2.rs
+++ b/src/test/run-pass/newlambdas-ret-infer2.rs
@@ -11,8 +11,6 @@
 // Test that the lambda kind is inferred correctly as a return
 // expression
 
-fn shared() -> @fn() { || () }
-
 fn unique() -> ~fn() { || () }
 
 pub fn main() {
diff --git a/src/test/run-pass/newlambdas.rs b/src/test/run-pass/newlambdas.rs
index 9c2a223174c..d9d0daa7138 100644
--- a/src/test/run-pass/newlambdas.rs
+++ b/src/test/run-pass/newlambdas.rs
@@ -14,16 +14,9 @@ fn f(i: int, f: &fn(int) -> int) -> int { f(i) }
 
 fn g(_g: &fn()) { }
 
-fn ff() -> @fn(int) -> int {
-    return |x| x + 1;
-}
-
 pub fn main() {
     assert_eq!(f(10, |a| a), 10);
     g(||());
     assert_eq!(do f(10) |a| { a }, 10);
     do g() { }
-    let _x: @fn() -> int = || 10;
-    let _y: @fn(int) -> int = |a| a;
-    assert_eq!(ff()(10), 11);
 }
diff --git a/src/test/run-pass/newtype-struct-drop-run.rs b/src/test/run-pass/newtype-struct-drop-run.rs
index 578f80f1ca5..54c4c06c548 100644
--- a/src/test/run-pass/newtype-struct-drop-run.rs
+++ b/src/test/run-pass/newtype-struct-drop-run.rs
@@ -19,7 +19,7 @@ impl Drop for Foo {
     }
 }
 
-fn main() {
+pub fn main() {
     let y = @mut 32;
     {
         let _x = Foo(y);
diff --git a/src/test/run-pass/newtype-temporary.rs b/src/test/run-pass/newtype-temporary.rs
index d2407f3d605..03e5d926761 100644
--- a/src/test/run-pass/newtype-temporary.rs
+++ b/src/test/run-pass/newtype-temporary.rs
@@ -14,6 +14,6 @@ fn foo() -> Foo {
     Foo(42)
 }
 
-fn main() {
+pub fn main() {
     assert_eq!(*foo(), 42);
 }
diff --git a/src/test/run-pass/objects-coerce-freeze-borrored.rs b/src/test/run-pass/objects-coerce-freeze-borrored.rs
index 4dda5ca556e..0bdc36750ae 100644
--- a/src/test/run-pass/objects-coerce-freeze-borrored.rs
+++ b/src/test/run-pass/objects-coerce-freeze-borrored.rs
@@ -39,7 +39,7 @@ fn do_it_imm(obj: &Foo, v: uint) {
     assert_eq!(v, y);
 }
 
-fn main() {
+pub fn main() {
     let mut x = 22_u;
     let obj = &mut x as &mut Foo;
     do_it_mut(obj);
diff --git a/src/test/run-pass/objects-coerce-from-managed-to-borrowed.rs b/src/test/run-pass/objects-coerce-from-managed-to-borrowed.rs
index fe4eb2ea48e..40c854879bf 100644
--- a/src/test/run-pass/objects-coerce-from-managed-to-borrowed.rs
+++ b/src/test/run-pass/objects-coerce-from-managed-to-borrowed.rs
@@ -37,7 +37,7 @@ fn do_it_imm(obj: &Foo, v: uint) {
     assert_eq!(v, y);
 }
 
-fn main() {
+pub fn main() {
     let x = @mut 22u as @mut Foo;
     do_it_mut(x);
     do_it_imm(x, 23u);
diff --git a/src/test/run-pass/owned-implies-static.rs b/src/test/run-pass/owned-implies-static.rs
index 4ee55239476..f327f6bc0dc 100644
--- a/src/test/run-pass/owned-implies-static.rs
+++ b/src/test/run-pass/owned-implies-static.rs
@@ -10,6 +10,6 @@
 
 fn f<T: 'static>(_x: T) {}
 
-fn main() {
+pub fn main() {
     f(~5);
 }
diff --git a/src/test/run-pass/packed-struct-borrow-element.rs b/src/test/run-pass/packed-struct-borrow-element.rs
index a331b80a894..1434e1da4c7 100644
--- a/src/test/run-pass/packed-struct-borrow-element.rs
+++ b/src/test/run-pass/packed-struct-borrow-element.rs
@@ -14,7 +14,7 @@ struct Foo {
     baz: uint
 }
 
-fn main() {
+pub fn main() {
     let foo = Foo { bar: 1, baz: 2 };
     let brw = &foo.baz;
 
diff --git a/src/test/run-pass/packed-struct-generic-layout.rs b/src/test/run-pass/packed-struct-generic-layout.rs
index 18b3cf2f91e..91b49944be2 100644
--- a/src/test/run-pass/packed-struct-generic-layout.rs
+++ b/src/test/run-pass/packed-struct-generic-layout.rs
@@ -17,7 +17,7 @@ struct S<T, S> {
     c: S
 }
 
-fn main() {
+pub fn main() {
     unsafe {
         let s = S { a: 0xff_ff_ff_ffu32, b: 1, c: 0xaa_aa_aa_aa as i32 };
         let transd : [u8, .. 9] = cast::transmute(s);
diff --git a/src/test/run-pass/packed-struct-generic-size.rs b/src/test/run-pass/packed-struct-generic-size.rs
index 98e922c3288..798acc646be 100644
--- a/src/test/run-pass/packed-struct-generic-size.rs
+++ b/src/test/run-pass/packed-struct-generic-size.rs
@@ -17,7 +17,7 @@ struct S<T, S> {
     c: S
 }
 
-fn main() {
+pub fn main() {
     assert_eq!(sys::size_of::<S<u8, u8>>(), 3);
 
     assert_eq!(sys::size_of::<S<u64, u16>>(), 11);
diff --git a/src/test/run-pass/packed-struct-layout.rs b/src/test/run-pass/packed-struct-layout.rs
index ea51bbcea32..f361db4a4b5 100644
--- a/src/test/run-pass/packed-struct-layout.rs
+++ b/src/test/run-pass/packed-struct-layout.rs
@@ -22,7 +22,7 @@ struct S5 {
     b: u32
 }
 
-fn main() {
+pub fn main() {
     unsafe {
         let s4 = S4 { a: 1, b: [2,3,4] };
         let transd : [u8, .. 4] = cast::transmute(s4);
diff --git a/src/test/run-pass/packed-struct-match.rs b/src/test/run-pass/packed-struct-match.rs
index 15e7b6b0ce0..27ab2c83e55 100644
--- a/src/test/run-pass/packed-struct-match.rs
+++ b/src/test/run-pass/packed-struct-match.rs
@@ -14,7 +14,7 @@ struct Foo {
     baz: uint
 }
 
-fn main() {
+pub fn main() {
     let foo = Foo { bar: 1, baz: 2 };
     match foo {
         Foo {bar, baz} => {
diff --git a/src/test/run-pass/packed-struct-size.rs b/src/test/run-pass/packed-struct-size.rs
index 6dcb1f04a4d..f0175da9cba 100644
--- a/src/test/run-pass/packed-struct-size.rs
+++ b/src/test/run-pass/packed-struct-size.rs
@@ -51,7 +51,7 @@ struct S7_Option {
 }
 
 
-fn main() {
+pub fn main() {
     assert_eq!(sys::size_of::<S4>(), 4);
     assert_eq!(sys::size_of::<S5>(), 5);
     assert_eq!(sys::size_of::<S13_str>(), 13 + sys::size_of::<~str>());
diff --git a/src/test/run-pass/packed-struct-vec.rs b/src/test/run-pass/packed-struct-vec.rs
index e66c4619b3c..6cf519a387f 100644
--- a/src/test/run-pass/packed-struct-vec.rs
+++ b/src/test/run-pass/packed-struct-vec.rs
@@ -19,7 +19,7 @@ struct Foo {
     baz: u64
 }
 
-fn main() {
+pub fn main() {
     let foos = [Foo { bar: 1, baz: 2 }, .. 10];
 
     assert_eq!(sys::size_of::<[Foo, .. 10]>(), 90);
diff --git a/src/test/run-pass/packed-tuple-struct-layout.rs b/src/test/run-pass/packed-tuple-struct-layout.rs
index 3691f475098..b3261faddfa 100644
--- a/src/test/run-pass/packed-tuple-struct-layout.rs
+++ b/src/test/run-pass/packed-tuple-struct-layout.rs
@@ -16,7 +16,7 @@ struct S4(u8,[u8, .. 3]);
 #[packed]
 struct S5(u8,u32);
 
-fn main() {
+pub fn main() {
     unsafe {
         let s4 = S4(1, [2,3,4]);
         let transd : [u8, .. 4] = cast::transmute(s4);
diff --git a/src/test/run-pass/packed-tuple-struct-size.rs b/src/test/run-pass/packed-tuple-struct-size.rs
index c8f2dda61db..dd38a6b7d12 100644
--- a/src/test/run-pass/packed-tuple-struct-size.rs
+++ b/src/test/run-pass/packed-tuple-struct-size.rs
@@ -30,7 +30,7 @@ struct S3_Foo(u8, u16, Foo);
 #[packed]
 struct S7_Option(f32, u8, u16, Option<@mut f64>);
 
-fn main() {
+pub fn main() {
     assert_eq!(sys::size_of::<S4>(), 4);
 
     assert_eq!(sys::size_of::<S5>(), 5);
diff --git a/src/test/run-pass/propagate-expected-type-through-block.rs b/src/test/run-pass/propagate-expected-type-through-block.rs
deleted file mode 100644
index f8f824cd596..00000000000
--- a/src/test/run-pass/propagate-expected-type-through-block.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-// Test that expected type propagates through `{}` expressions.  If it
-// did not, then the type of `x` would not be known and a compilation
-// error would result.
-
-pub fn main() {
-    let y = ~3;
-    let foo: @fn(&int) -> int = {
-        let y = y.clone();
-        |x| *x + *y
-    };
-    assert_eq!(foo(@22), 25);
-}
diff --git a/src/test/run-pass/pub-extern-privacy.rs b/src/test/run-pass/pub-extern-privacy.rs
index 360ac75b3e7..e4e260ab36e 100644
--- a/src/test/run-pass/pub-extern-privacy.rs
+++ b/src/test/run-pass/pub-extern-privacy.rs
@@ -7,7 +7,7 @@ mod a {
 }
 
 #[fixed_stack_segment] #[inline(never)]
-fn main() {
+pub fn main() {
     unsafe {
         a::free(transmute(0));
     }
diff --git a/src/test/run-pass/reflect-visit-data.rs b/src/test/run-pass/reflect-visit-data.rs
index 2d9f4a2ff6f..cf6f12a06e5 100644
--- a/src/test/run-pass/reflect-visit-data.rs
+++ b/src/test/run-pass/reflect-visit-data.rs
@@ -460,9 +460,9 @@ impl<V:TyVisitor + movable_ptr> TyVisitor for ptr_visit_adaptor<V> {
     }
 
     fn visit_closure_ptr(&mut self, ck: uint) -> bool {
-        self.align_to::<@fn()>();
+        self.align_to::<(uint,uint)>();
         if ! self.inner.visit_closure_ptr(ck) { return false; }
-        self.bump_past::<@fn()>();
+        self.bump_past::<(uint,uint)>();
         true
     }
 }
diff --git a/src/test/run-pass/region-dependent-autofn.rs b/src/test/run-pass/region-dependent-autofn.rs
index 82d4115d66d..bce2159cc7b 100644
--- a/src/test/run-pass/region-dependent-autofn.rs
+++ b/src/test/run-pass/region-dependent-autofn.rs
@@ -17,6 +17,6 @@ fn both<'r>(v: &'r fn()) -> &'r fn() {
     subslice(subslice(v))
 }
 
-fn main() {
+pub fn main() {
     both(main);
 }
diff --git a/src/test/run-pass/region-dependent-autoslice.rs b/src/test/run-pass/region-dependent-autoslice.rs
index 10c2988fc9f..dab881549c4 100644
--- a/src/test/run-pass/region-dependent-autoslice.rs
+++ b/src/test/run-pass/region-dependent-autoslice.rs
@@ -17,7 +17,7 @@ fn both<'r>(v: &'r [uint]) -> &'r [uint] {
     subslice1(subslice1(v))
 }
 
-fn main() {
+pub fn main() {
     let v = ~[1,2,3];
     both(v);
 }
diff --git a/src/test/run-pass/regions-fn-subtyping.rs b/src/test/run-pass/regions-fn-subtyping.rs
index a6b43df1f88..06c8aca4741 100644
--- a/src/test/run-pass/regions-fn-subtyping.rs
+++ b/src/test/run-pass/regions-fn-subtyping.rs
@@ -14,21 +14,21 @@
 #[allow(unused_variable)];
 
 // Should pass region checking.
-fn ok(f: @fn(x: &uint)) {
+fn ok(f: &fn(x: &uint)) {
     // Here, g is a function that can accept a uint pointer with
     // lifetime r, and f is a function that can accept a uint pointer
     // with any lifetime.  The assignment g = f should be OK (i.e.,
     // f's type should be a subtype of g's type), because f can be
     // used in any context that expects g's type.  But this currently
     // fails.
-    let mut g: @fn<'r>(y: &'r uint) = |x| { };
+    let mut g: &fn<'r>(y: &'r uint) = |x| { };
     g = f;
 }
 
 // This version is the same as above, except that here, g's type is
 // inferred.
-fn ok_inferred(f: @fn(x: &uint)) {
-    let mut g: @fn<'r>(x: &'r uint) = |_| {};
+fn ok_inferred(f: &fn(x: &uint)) {
+    let mut g: &fn<'r>(x: &'r uint) = |_| {};
     g = f;
 }
 
diff --git a/src/test/run-pass/rl-human-test.rs b/src/test/run-pass/rl-human-test.rs
index 558e0b6820d..6a87a6502d2 100644
--- a/src/test/run-pass/rl-human-test.rs
+++ b/src/test/run-pass/rl-human-test.rs
@@ -22,6 +22,20 @@ use extra::rl;
 
 static HISTORY_FILE: &'static str = "rl-human-test-history.txt";
 
+struct TestCompleter;
+
+impl rl::CompletionCb for TestCompleter {
+    fn complete(&self, line: ~str, suggest: &fn(~str)) {
+        if line.is_empty() {
+            suggest(~"empty")
+        } else {
+            for c in line.rev_iter().take(3) {
+                suggest(format!("{0}{1}{1}{1}", line, c))
+            }
+        }
+    }
+}
+
 fn main() {
     // don't run this in robot mode, but still typecheck it.
     if !cfg!(robot_mode) {
@@ -42,14 +56,8 @@ The bool return values of each step are printed.",
 
         println!("restricting history length: {}", rl::set_history_max_len(3));
 
-        do rl::complete |line, suggest| {
-            if line.is_empty() {
-                suggest(~"empty")
-            } else {
-                for c in line.rev_iter().take(3) {
-                    suggest(format!("{0}{1}{1}{1}", line, c))
-                }
-            }
+        unsafe {
+            rl::complete(@TestCompleter as @rl::CompletionCb);
         }
 
         println!("adding 'one': {}", rl::add_history("one"));
diff --git a/src/test/run-pass/rt-start-main-thread.rs b/src/test/run-pass/rt-start-main-thread.rs
index 8328e7416c5..47a723ce6e1 100644
--- a/src/test/run-pass/rt-start-main-thread.rs
+++ b/src/test/run-pass/rt-start-main-thread.rs
@@ -11,11 +11,11 @@
 // xfail-fast
 
 #[start]
-fn start(argc: int, argv: **u8, crate_map: *u8) -> int {
-    do std::rt::start_on_main_thread(argc, argv, crate_map) {
+fn start(argc: int, argv: **u8) -> int {
+    do std::rt::start_on_main_thread(argc, argv) {
         info!("running on main thread");
         do spawn {
             info!("running on another thread");
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/test/run-pass/send_str_hashmap.rs b/src/test/run-pass/send_str_hashmap.rs
index a33cb99682b..1e3bd5897a9 100644
--- a/src/test/run-pass/send_str_hashmap.rs
+++ b/src/test/run-pass/send_str_hashmap.rs
@@ -19,7 +19,7 @@ use std::to_str::ToStr;
 use std::hashmap::HashMap;
 use std::option::Some;
 
-fn main() {
+pub fn main() {
     let mut map: HashMap<SendStr, uint> = HashMap::new();
     assert!(map.insert(SendStrStatic("foo"), 42));
     assert!(!map.insert(SendStrOwned(~"foo"), 42));
diff --git a/src/test/run-pass/send_str_treemap.rs b/src/test/run-pass/send_str_treemap.rs
index 7094dca7c4d..23ad0ac3091 100644
--- a/src/test/run-pass/send_str_treemap.rs
+++ b/src/test/run-pass/send_str_treemap.rs
@@ -21,7 +21,7 @@ use std::to_str::ToStr;
 use self::extra::treemap::TreeMap;
 use std::option::Some;
 
-fn main() {
+pub fn main() {
     let mut map: TreeMap<SendStr, uint> = TreeMap::new();
     assert!(map.insert(SendStrStatic("foo"), 42));
     assert!(!map.insert(SendStrOwned(~"foo"), 42));
diff --git a/src/test/run-pass/simd-binop.rs b/src/test/run-pass/simd-binop.rs
index 1e6c8b07fa0..74502b54d8e 100644
--- a/src/test/run-pass/simd-binop.rs
+++ b/src/test/run-pass/simd-binop.rs
@@ -22,7 +22,7 @@ fn test_float(e: f32) -> f32 {
     e2
 }
 
-fn main() {
+pub fn main() {
     assert_eq!(test_int(3i32), 9i32);
     assert_eq!(test_float(3f32), 9f32);
 }
diff --git a/src/test/run-pass/simd-type.rs b/src/test/run-pass/simd-type.rs
index c3bcc9d0b7a..643daad397c 100644
--- a/src/test/run-pass/simd-type.rs
+++ b/src/test/run-pass/simd-type.rs
@@ -6,4 +6,4 @@ struct RGBA {
     a: f32
 }
 
-fn main() {}
+pub fn main() {}
diff --git a/src/test/run-pass/sized-borrowed-pointer.rs b/src/test/run-pass/sized-borrowed-pointer.rs
index 90127918002..348b7562f84 100644
--- a/src/test/run-pass/sized-borrowed-pointer.rs
+++ b/src/test/run-pass/sized-borrowed-pointer.rs
@@ -12,4 +12,4 @@
 
 fn bar<T: Sized>() { }
 fn foo<T>() { bar::<&T>() }
-fn main() { }
+pub fn main() { }
diff --git a/src/test/run-pass/sized-owned-pointer.rs b/src/test/run-pass/sized-owned-pointer.rs
index fe9c63621b2..0c05fdd616b 100644
--- a/src/test/run-pass/sized-owned-pointer.rs
+++ b/src/test/run-pass/sized-owned-pointer.rs
@@ -12,4 +12,4 @@
 
 fn bar<T: Sized>() { }
 fn foo<T>() { bar::<~T>() }
-fn main() { }
+pub fn main() { }
diff --git a/src/test/run-pass/static-assert.rs b/src/test/run-pass/static-assert.rs
index 81b0c9ff28c..93c8d67c9c0 100644
--- a/src/test/run-pass/static-assert.rs
+++ b/src/test/run-pass/static-assert.rs
@@ -10,5 +10,5 @@ static d: bool = 1 != 2;
 #[static_assert]
 static f: bool = (4/2) == 2;
 
-fn main() {
+pub fn main() {
 }
diff --git a/src/test/run-pass/struct-update-moves-and-copies.rs b/src/test/run-pass/struct-update-moves-and-copies.rs
index f257b9ac0de..a0fb31e64bf 100644
--- a/src/test/run-pass/struct-update-moves-and-copies.rs
+++ b/src/test/run-pass/struct-update-moves-and-copies.rs
@@ -94,7 +94,7 @@ fn test2() {
     assert_eq!(c.noncopy.v, 22);
 }
 
-fn main() {
+pub fn main() {
     test0();
     test1();
     test2();
diff --git a/src/test/run-pass/supertrait-default-generics.rs b/src/test/run-pass/supertrait-default-generics.rs
index ae7e18d532b..2cfc22111a7 100644
--- a/src/test/run-pass/supertrait-default-generics.rs
+++ b/src/test/run-pass/supertrait-default-generics.rs
@@ -33,7 +33,7 @@ impl<S: Clone> Positioned<S> for Point<S> {
     }
 }
 
-impl<S: Clone + Add<S, S>> Movable<S> for Point<S>;
+impl<S: Clone + Add<S, S>> Movable<S> for Point<S> {}
 
 pub fn main() {
     let mut p = Point{ x: 1, y: 2};
diff --git a/src/test/run-pass/syntax-extension-bytes.rs b/src/test/run-pass/syntax-extension-bytes.rs
index bdaae65bc3c..5b66d5f28a9 100644
--- a/src/test/run-pass/syntax-extension-bytes.rs
+++ b/src/test/run-pass/syntax-extension-bytes.rs
@@ -10,7 +10,7 @@
 
 static static_vec: &'static [u8] = bytes!("abc", 0xFF, '!');
 
-fn main() {
+pub fn main() {
     let vec = bytes!("abc");
     assert_eq!(vec, &[97_u8, 98_u8, 99_u8]);
 
diff --git a/src/test/run-pass/tag-variant-disr-type-mismatch.rs b/src/test/run-pass/tag-variant-disr-type-mismatch.rs
index 514f868db54..3d63acd5b83 100644
--- a/src/test/run-pass/tag-variant-disr-type-mismatch.rs
+++ b/src/test/run-pass/tag-variant-disr-type-mismatch.rs
@@ -13,4 +13,4 @@ enum color {
     blue = 2,
 }
 
-fn main() {}
+pub fn main() {}
diff --git a/src/test/run-pass/trait-bounds-basic.rs b/src/test/run-pass/trait-bounds-basic.rs
index cc2c12e4109..9fef70a4dda 100644
--- a/src/test/run-pass/trait-bounds-basic.rs
+++ b/src/test/run-pass/trait-bounds-basic.rs
@@ -29,4 +29,4 @@ fn e(x: ~Foo) { // sugar for ~Foo:Owned
     b(x);
 }
 
-fn main() { }
+pub fn main() { }
diff --git a/src/test/run-pass/trait-bounds-recursion.rs b/src/test/run-pass/trait-bounds-recursion.rs
index 043aa358fa0..49f8999cd45 100644
--- a/src/test/run-pass/trait-bounds-recursion.rs
+++ b/src/test/run-pass/trait-bounds-recursion.rs
@@ -24,4 +24,4 @@ trait C {
     fn id<T:J<T>>(x:T) -> T { x.j() }
 }
 
-fn main() { }
+pub fn main() { }
diff --git a/src/test/run-pass/trait-inheritance-overloading-simple.rs b/src/test/run-pass/trait-inheritance-overloading-simple.rs
index 041452176e0..3a0f2dd9464 100644
--- a/src/test/run-pass/trait-inheritance-overloading-simple.rs
+++ b/src/test/run-pass/trait-inheritance-overloading-simple.rs
@@ -19,7 +19,7 @@ impl Eq for MyInt {
     fn ne(&self, other: &MyInt) -> bool { !self.eq(other) }
 }
 
-impl MyNum for MyInt;
+impl MyNum for MyInt {}
 
 fn f<T:MyNum>(x: T, y: T) -> bool {
     return x == y;
diff --git a/src/test/run-pass/trait-inheritance-overloading.rs b/src/test/run-pass/trait-inheritance-overloading.rs
index d5321ea5298..fb19bfa674f 100644
--- a/src/test/run-pass/trait-inheritance-overloading.rs
+++ b/src/test/run-pass/trait-inheritance-overloading.rs
@@ -31,7 +31,7 @@ impl Eq for MyInt {
     fn ne(&self, other: &MyInt) -> bool { !self.eq(other) }
 }
 
-impl MyNum for MyInt;
+impl MyNum for MyInt {}
 
 fn f<T:MyNum>(x: T, y: T) -> (T, T, T) {
     return (x + y, x - y, x * y);
diff --git a/src/test/run-pass/trait-inheritance-subst.rs b/src/test/run-pass/trait-inheritance-subst.rs
index 479f293a396..cd57e6a7dd0 100644
--- a/src/test/run-pass/trait-inheritance-subst.rs
+++ b/src/test/run-pass/trait-inheritance-subst.rs
@@ -20,7 +20,7 @@ impl Add<MyInt, MyInt> for MyInt {
     fn add(&self, other: &MyInt) -> MyInt { mi(self.val + other.val) }
 }
 
-impl MyNum for MyInt;
+impl MyNum for MyInt {}
 
 fn f<T:MyNum>(x: T, y: T) -> T {
     return x.add(&y);
diff --git a/src/test/run-pass/trait-inheritance-subst2.rs b/src/test/run-pass/trait-inheritance-subst2.rs
index 214505172a5..ebddfafc3b4 100644
--- a/src/test/run-pass/trait-inheritance-subst2.rs
+++ b/src/test/run-pass/trait-inheritance-subst2.rs
@@ -30,7 +30,7 @@ impl Add<MyInt, MyInt> for MyInt {
     fn add(&self, other: &MyInt) -> MyInt { self.chomp(other) }
 }
 
-impl MyNum for MyInt;
+impl MyNum for MyInt {}
 
 fn f<T:MyNum>(x: T, y: T) -> T {
     return x.add(&y).chomp(&y);
diff --git a/src/test/run-pass/trait-inheritance2.rs b/src/test/run-pass/trait-inheritance2.rs
index 6046da41217..7fa895ddf98 100644
--- a/src/test/run-pass/trait-inheritance2.rs
+++ b/src/test/run-pass/trait-inheritance2.rs
@@ -19,7 +19,7 @@ struct A { x: int }
 impl Foo for A { fn f(&self) -> int { 10 } }
 impl Bar for A { fn g(&self) -> int { 20 } }
 impl Baz for A { fn h(&self) -> int { 30 } }
-impl Quux for A;
+impl Quux for A {}
 
 fn f<T:Quux + Foo + Bar + Baz>(a: &T) {
     assert_eq!(a.f(), 10);
diff --git a/src/test/run-pass/trait-object-generics.rs b/src/test/run-pass/trait-object-generics.rs
index 12b6af29520..3629316e14d 100644
--- a/src/test/run-pass/trait-object-generics.rs
+++ b/src/test/run-pass/trait-object-generics.rs
@@ -40,7 +40,7 @@ impl<V> Trait<u8,V> for () {
     fn method(&self, _x: Type<(u8,V)>) -> int { 0 }
 }
 
-fn main () {
+pub fn main () {
     let a = @() as @Trait<u8, u8>;
     assert_eq!(a.method(Constant), 0);
 }
diff --git a/src/test/run-pass/trait-with-bounds-default.rs b/src/test/run-pass/trait-with-bounds-default.rs
index 689df437fb4..ba2f32a0499 100644
--- a/src/test/run-pass/trait-with-bounds-default.rs
+++ b/src/test/run-pass/trait-with-bounds-default.rs
@@ -34,7 +34,7 @@ impl<T: Clone> Getter<T> for Option<T> {
 }
 
 
-fn main() {
+pub fn main() {
     assert_eq!(3.do_get2(), (3, 3));
     assert_eq!(Some(~"hi").do_get2(), (~"hi", ~"hi"));
 }
diff --git a/src/test/run-pass/traits-default-method-mut.rs b/src/test/run-pass/traits-default-method-mut.rs
index 0c5be72432c..4b217ba0ebb 100644
--- a/src/test/run-pass/traits-default-method-mut.rs
+++ b/src/test/run-pass/traits-default-method-mut.rs
@@ -15,4 +15,4 @@ trait Foo {
     fn foo(&self, mut v: int) { v = 1; }
 }
 
-fn main() {}
+pub fn main() {}
diff --git a/src/test/run-pass/transmute-non-immediate-to-immediate.rs b/src/test/run-pass/transmute-non-immediate-to-immediate.rs
index 2f097bc90a9..9cdcd875952 100644
--- a/src/test/run-pass/transmute-non-immediate-to-immediate.rs
+++ b/src/test/run-pass/transmute-non-immediate-to-immediate.rs
@@ -11,7 +11,7 @@
 // Issue #7988
 // Transmuting non-immediate type to immediate type
 
-fn main() {
+pub fn main() {
     unsafe {
         ::std::cast::transmute::<[int,..1],int>([1])
     };
diff --git a/src/test/run-pass/tuple-struct-constructor-pointer.rs b/src/test/run-pass/tuple-struct-constructor-pointer.rs
index dbb5db649ef..e51e6ffd52a 100644
--- a/src/test/run-pass/tuple-struct-constructor-pointer.rs
+++ b/src/test/run-pass/tuple-struct-constructor-pointer.rs
@@ -13,7 +13,7 @@ struct Foo(int);
 #[deriving(Eq)]
 struct Bar(int, int);
 
-fn main() {
+pub fn main() {
     let f: extern fn(int) -> Foo = Foo;
     let g: extern fn(int, int) -> Bar = Bar;
     assert_eq!(f(42), Foo(42));
diff --git a/src/test/run-pass/typeck-macro-interaction-issue-8852.rs b/src/test/run-pass/typeck-macro-interaction-issue-8852.rs
index a1368365c40..19a3c52dea8 100644
--- a/src/test/run-pass/typeck-macro-interaction-issue-8852.rs
+++ b/src/test/run-pass/typeck-macro-interaction-issue-8852.rs
@@ -17,6 +17,6 @@ macro_rules! test(
 
 test!(x + y)
 
-fn main() {
+pub fn main() {
     foo(A(1), A(2));
-}
\ No newline at end of file
+}
diff --git a/src/test/run-pass/unfold-cross-crate.rs b/src/test/run-pass/unfold-cross-crate.rs
index 42e680d95e1..0b8447aa0cd 100644
--- a/src/test/run-pass/unfold-cross-crate.rs
+++ b/src/test/run-pass/unfold-cross-crate.rs
@@ -13,7 +13,7 @@ use std::iter::*;
 // Unfold had a bug with 'self that mean it didn't work
 // cross-crate
 
-fn main() {
+pub fn main() {
     fn count(st: &mut uint) -> Option<uint> {
         if *st < 10 {
             let ret = Some(*st);
diff --git a/src/test/run-pass/unused-move-capture.rs b/src/test/run-pass/unused-move-capture.rs
index dd70b7daa70..662121a0993 100644
--- a/src/test/run-pass/unused-move-capture.rs
+++ b/src/test/run-pass/unused-move-capture.rs
@@ -10,6 +10,6 @@
 
 pub fn main() {
     let _x = ~1;
-    let lam_move: @fn() = || {};
+    let lam_move: &fn() = || {};
     lam_move();
 }